OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/chromeos/dbus/power_manager_client.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/callback.h" | |
11 #include "base/format_macros.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/observer_list.h" | |
14 #include "base/stringprintf.h" | |
15 #include "base/time.h" | |
16 #include "base/timer.h" | |
17 #include "chrome/browser/chromeos/dbus/power_supply_properties.pb.h" | |
18 #include "chrome/browser/chromeos/dbus/power_state_control.pb.h" | |
19 #include "dbus/bus.h" | |
20 #include "dbus/message.h" | |
21 #include "dbus/object_path.h" | |
22 #include "dbus/object_proxy.h" | |
23 #include "third_party/cros_system_api/dbus/service_constants.h" | |
24 | |
25 namespace chromeos { | |
26 | |
27 // The PowerManagerClient implementation used in production. | |
28 class PowerManagerClientImpl : public PowerManagerClient { | |
29 public: | |
30 explicit PowerManagerClientImpl(dbus::Bus* bus) | |
31 : power_manager_proxy_(NULL), | |
32 weak_ptr_factory_(this) { | |
33 power_manager_proxy_ = bus->GetObjectProxy( | |
34 power_manager::kPowerManagerServiceName, | |
35 dbus::ObjectPath(power_manager::kPowerManagerServicePath)); | |
36 | |
37 session_manager_proxy_ = bus->GetObjectProxy( | |
38 login_manager::kSessionManagerServiceName, | |
39 dbus::ObjectPath(login_manager::kSessionManagerServicePath)); | |
40 | |
41 // Monitor the D-Bus signal for brightness changes. Only the power | |
42 // manager knows the actual brightness level. We don't cache the | |
43 // brightness level in Chrome as it'll make things less reliable. | |
44 power_manager_proxy_->ConnectToSignal( | |
45 power_manager::kPowerManagerInterface, | |
46 power_manager::kBrightnessChangedSignal, | |
47 base::Bind(&PowerManagerClientImpl::BrightnessChangedReceived, | |
48 weak_ptr_factory_.GetWeakPtr()), | |
49 base::Bind(&PowerManagerClientImpl::SignalConnected, | |
50 weak_ptr_factory_.GetWeakPtr())); | |
51 | |
52 power_manager_proxy_->ConnectToSignal( | |
53 power_manager::kPowerManagerInterface, | |
54 power_manager::kPowerSupplyPollSignal, | |
55 base::Bind(&PowerManagerClientImpl::PowerSupplyPollReceived, | |
56 weak_ptr_factory_.GetWeakPtr()), | |
57 base::Bind(&PowerManagerClientImpl::SignalConnected, | |
58 weak_ptr_factory_.GetWeakPtr())); | |
59 | |
60 power_manager_proxy_->ConnectToSignal( | |
61 power_manager::kPowerManagerInterface, | |
62 power_manager::kPowerStateChangedSignal, | |
63 base::Bind(&PowerManagerClientImpl::PowerStateChangedSignalReceived, | |
64 weak_ptr_factory_.GetWeakPtr()), | |
65 base::Bind(&PowerManagerClientImpl::SignalConnected, | |
66 weak_ptr_factory_.GetWeakPtr())); | |
67 | |
68 power_manager_proxy_->ConnectToSignal( | |
69 power_manager::kPowerManagerInterface, | |
70 power_manager::kButtonEventSignal, | |
71 base::Bind(&PowerManagerClientImpl::ButtonEventSignalReceived, | |
72 weak_ptr_factory_.GetWeakPtr()), | |
73 base::Bind(&PowerManagerClientImpl::SignalConnected, | |
74 weak_ptr_factory_.GetWeakPtr())); | |
75 | |
76 session_manager_proxy_->ConnectToSignal( | |
77 chromium::kChromiumInterface, | |
78 chromium::kLockScreenSignal, | |
79 base::Bind(&PowerManagerClientImpl::ScreenLockSignalReceived, | |
80 weak_ptr_factory_.GetWeakPtr()), | |
81 base::Bind(&PowerManagerClientImpl::SignalConnected, | |
82 weak_ptr_factory_.GetWeakPtr())); | |
83 | |
84 session_manager_proxy_->ConnectToSignal( | |
85 chromium::kChromiumInterface, | |
86 chromium::kUnlockScreenSignal, | |
87 base::Bind(&PowerManagerClientImpl::ScreenUnlockSignalReceived, | |
88 weak_ptr_factory_.GetWeakPtr()), | |
89 base::Bind(&PowerManagerClientImpl::SignalConnected, | |
90 weak_ptr_factory_.GetWeakPtr())); | |
91 session_manager_proxy_->ConnectToSignal( | |
92 chromium::kChromiumInterface, | |
93 chromium::kUnlockScreenFailedSignal, | |
94 base::Bind(&PowerManagerClientImpl::ScreenUnlockFailedSignalReceived, | |
95 weak_ptr_factory_.GetWeakPtr()), | |
96 base::Bind(&PowerManagerClientImpl::SignalConnected, | |
97 weak_ptr_factory_.GetWeakPtr())); | |
98 | |
99 power_manager_proxy_->ConnectToSignal( | |
100 power_manager::kPowerManagerInterface, | |
101 power_manager::kIdleNotifySignal, | |
102 base::Bind(&PowerManagerClientImpl::IdleNotifySignalReceived, | |
103 weak_ptr_factory_.GetWeakPtr()), | |
104 base::Bind(&PowerManagerClientImpl::SignalConnected, | |
105 weak_ptr_factory_.GetWeakPtr())); | |
106 | |
107 power_manager_proxy_->ConnectToSignal( | |
108 power_manager::kPowerManagerInterface, | |
109 power_manager::kActiveNotifySignal, | |
110 base::Bind(&PowerManagerClientImpl::ActiveNotifySignalReceived, | |
111 weak_ptr_factory_.GetWeakPtr()), | |
112 base::Bind(&PowerManagerClientImpl::SignalConnected, | |
113 weak_ptr_factory_.GetWeakPtr())); | |
114 } | |
115 | |
116 virtual ~PowerManagerClientImpl() { | |
117 } | |
118 | |
119 // PowerManagerClient overrides: | |
120 | |
121 virtual void AddObserver(Observer* observer) OVERRIDE { | |
122 CHECK(observer); // http://crbug.com/119976 | |
123 observers_.AddObserver(observer); | |
124 } | |
125 | |
126 virtual void RemoveObserver(Observer* observer) OVERRIDE { | |
127 observers_.RemoveObserver(observer); | |
128 } | |
129 | |
130 virtual bool HasObserver(Observer* observer) OVERRIDE { | |
131 return observers_.HasObserver(observer); | |
132 } | |
133 | |
134 virtual void DecreaseScreenBrightness(bool allow_off) OVERRIDE { | |
135 dbus::MethodCall method_call( | |
136 power_manager::kPowerManagerInterface, | |
137 power_manager::kDecreaseScreenBrightness); | |
138 dbus::MessageWriter writer(&method_call); | |
139 writer.AppendBool(allow_off); | |
140 power_manager_proxy_->CallMethod( | |
141 &method_call, | |
142 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
143 dbus::ObjectProxy::EmptyResponseCallback()); | |
144 } | |
145 | |
146 virtual void IncreaseScreenBrightness() OVERRIDE { | |
147 SimpleMethodCallToPowerManager(power_manager::kIncreaseScreenBrightness); | |
148 } | |
149 | |
150 virtual void SetScreenBrightnessPercent(double percent, bool gradual) { | |
151 dbus::MethodCall method_call( | |
152 power_manager::kPowerManagerInterface, | |
153 power_manager::kSetScreenBrightnessPercent); | |
154 dbus::MessageWriter writer(&method_call); | |
155 writer.AppendDouble(percent); | |
156 writer.AppendInt32( | |
157 gradual ? | |
158 power_manager::kBrightnessTransitionGradual : | |
159 power_manager::kBrightnessTransitionInstant); | |
160 power_manager_proxy_->CallMethod( | |
161 &method_call, | |
162 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
163 dbus::ObjectProxy::EmptyResponseCallback()); | |
164 } | |
165 | |
166 virtual void GetScreenBrightnessPercent( | |
167 const GetScreenBrightnessPercentCallback& callback) OVERRIDE { | |
168 dbus::MethodCall method_call(power_manager::kPowerManagerInterface, | |
169 power_manager::kGetScreenBrightnessPercent); | |
170 power_manager_proxy_->CallMethod( | |
171 &method_call, | |
172 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
173 base::Bind(&PowerManagerClientImpl::OnGetScreenBrightnessPercent, | |
174 weak_ptr_factory_.GetWeakPtr(), callback)); | |
175 } | |
176 | |
177 virtual void RequestStatusUpdate(UpdateRequestType update_type) OVERRIDE { | |
178 dbus::MethodCall method_call( | |
179 power_manager::kPowerManagerInterface, | |
180 power_manager::kGetPowerSupplyPropertiesMethod); | |
181 power_manager_proxy_->CallMethod( | |
182 &method_call, | |
183 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
184 base::Bind(&PowerManagerClientImpl::OnGetPowerSupplyPropertiesMethod, | |
185 weak_ptr_factory_.GetWeakPtr())); | |
186 } | |
187 | |
188 virtual void RequestRestart() OVERRIDE { | |
189 SimpleMethodCallToPowerManager(power_manager::kRequestRestartMethod); | |
190 }; | |
191 | |
192 virtual void RequestShutdown() OVERRIDE { | |
193 SimpleMethodCallToPowerManager(power_manager::kRequestShutdownMethod); | |
194 } | |
195 | |
196 virtual void CalculateIdleTime(const CalculateIdleTimeCallback& callback) | |
197 OVERRIDE { | |
198 dbus::MethodCall method_call(power_manager::kPowerManagerInterface, | |
199 power_manager::kGetIdleTime); | |
200 power_manager_proxy_->CallMethod( | |
201 &method_call, | |
202 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
203 base::Bind(&PowerManagerClientImpl::OnGetIdleTime, | |
204 weak_ptr_factory_.GetWeakPtr(), callback)); | |
205 } | |
206 | |
207 virtual void RequestIdleNotification(int64 threshold) OVERRIDE { | |
208 dbus::MethodCall method_call(power_manager::kPowerManagerInterface, | |
209 power_manager::kRequestIdleNotification); | |
210 dbus::MessageWriter writer(&method_call); | |
211 writer.AppendInt64(threshold); | |
212 | |
213 power_manager_proxy_->CallMethod( | |
214 &method_call, | |
215 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
216 dbus::ObjectProxy::EmptyResponseCallback()); | |
217 } | |
218 | |
219 virtual void RequestActiveNotification() OVERRIDE { | |
220 RequestIdleNotification(0); | |
221 } | |
222 | |
223 virtual void RequestPowerStateOverrides( | |
224 uint32 request_id, | |
225 uint32 duration, | |
226 int overrides, | |
227 PowerStateRequestIdCallback callback) OVERRIDE { | |
228 dbus::MethodCall method_call(power_manager::kPowerManagerInterface, | |
229 power_manager::kStateOverrideRequest); | |
230 dbus::MessageWriter writer(&method_call); | |
231 | |
232 PowerStateControl protobuf; | |
233 protobuf.set_request_id(request_id); | |
234 protobuf.set_duration(duration); | |
235 protobuf.set_disable_idle_dim(overrides & DISABLE_IDLE_DIM); | |
236 protobuf.set_disable_idle_blank(overrides & DISABLE_IDLE_BLANK); | |
237 protobuf.set_disable_idle_suspend(overrides & DISABLE_IDLE_SUSPEND); | |
238 protobuf.set_disable_lid_suspend(overrides & DISABLE_IDLE_LID_SUSPEND); | |
239 | |
240 writer.AppendProtoAsArrayOfBytes(protobuf); | |
241 power_manager_proxy_->CallMethod( | |
242 &method_call, | |
243 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
244 base::Bind(&PowerManagerClientImpl::OnPowerStateOverride, | |
245 weak_ptr_factory_.GetWeakPtr(), callback)); | |
246 } | |
247 | |
248 virtual void NotifyScreenLockRequested() OVERRIDE { | |
249 SimpleMethodCallToPowerManager(power_manager::kRequestLockScreenMethod); | |
250 } | |
251 | |
252 virtual void NotifyScreenLockCompleted() OVERRIDE { | |
253 SimpleMethodCallToPowerManager(power_manager::kScreenIsLockedMethod); | |
254 } | |
255 | |
256 virtual void NotifyScreenUnlockRequested() OVERRIDE { | |
257 SimpleMethodCallToPowerManager(power_manager::kRequestUnlockScreenMethod); | |
258 } | |
259 | |
260 virtual void NotifyScreenUnlockCompleted() OVERRIDE { | |
261 SimpleMethodCallToPowerManager(power_manager::kScreenIsUnlockedMethod); | |
262 } | |
263 | |
264 private: | |
265 // Called when a dbus signal is initially connected. | |
266 void SignalConnected(const std::string& interface_name, | |
267 const std::string& signal_name, | |
268 bool success) { | |
269 LOG_IF(WARNING, !success) << "Failed to connect to signal " | |
270 << signal_name << "."; | |
271 } | |
272 | |
273 // Make a method call to power manager with no arguments and no response. | |
274 void SimpleMethodCallToPowerManager(const std::string& method_name) { | |
275 dbus::MethodCall method_call(power_manager::kPowerManagerInterface, | |
276 method_name); | |
277 power_manager_proxy_->CallMethod( | |
278 &method_call, | |
279 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT, | |
280 dbus::ObjectProxy::EmptyResponseCallback()); | |
281 } | |
282 | |
283 void BrightnessChangedReceived(dbus::Signal* signal) { | |
284 dbus::MessageReader reader(signal); | |
285 int32 brightness_level = 0; | |
286 bool user_initiated = 0; | |
287 if (!(reader.PopInt32(&brightness_level) && | |
288 reader.PopBool(&user_initiated))) { | |
289 LOG(ERROR) << "Brightness changed signal had incorrect parameters: " | |
290 << signal->ToString(); | |
291 return; | |
292 } | |
293 VLOG(1) << "Brightness changed to " << brightness_level | |
294 << ": user initiated " << user_initiated; | |
295 FOR_EACH_OBSERVER(Observer, observers_, | |
296 BrightnessChanged(brightness_level, user_initiated)); | |
297 } | |
298 | |
299 void PowerStateChangedSignalReceived(dbus::Signal* signal) { | |
300 VLOG(1) << "Received power state changed signal."; | |
301 dbus::MessageReader reader(signal); | |
302 std::string power_state_string; | |
303 if (!reader.PopString(&power_state_string)) { | |
304 LOG(ERROR) << "Error reading signal args: " << signal->ToString(); | |
305 return; | |
306 } | |
307 if (power_state_string != "on") | |
308 return; | |
309 FOR_EACH_OBSERVER(Observer, observers_, SystemResumed()); | |
310 } | |
311 | |
312 void ButtonEventSignalReceived(dbus::Signal* signal) { | |
313 dbus::MessageReader reader(signal); | |
314 std::string button_name; | |
315 bool down = false; | |
316 int64 timestamp_internal = 0; | |
317 if (!reader.PopString(&button_name) || | |
318 !reader.PopBool(&down) || | |
319 !reader.PopInt64(×tamp_internal)) { | |
320 LOG(ERROR) << "Button signal had incorrect parameters: " | |
321 << signal->ToString(); | |
322 return; | |
323 } | |
324 base::TimeTicks timestamp = | |
325 base::TimeTicks::FromInternalValue(timestamp_internal); | |
326 | |
327 if (button_name == power_manager::kPowerButtonName) { | |
328 FOR_EACH_OBSERVER( | |
329 Observer, observers_, PowerButtonStateChanged(down, timestamp)); | |
330 } else if (button_name == power_manager::kLockButtonName) { | |
331 FOR_EACH_OBSERVER( | |
332 Observer, observers_, LockButtonStateChanged(down, timestamp)); | |
333 } | |
334 } | |
335 | |
336 void PowerSupplyPollReceived(dbus::Signal* unused_signal) { | |
337 VLOG(1) << "Received power supply poll signal."; | |
338 RequestStatusUpdate(UPDATE_POLL); | |
339 } | |
340 | |
341 void OnGetPowerSupplyPropertiesMethod(dbus::Response* response) { | |
342 if (!response) { | |
343 LOG(ERROR) << "Error calling " | |
344 << power_manager::kGetPowerSupplyPropertiesMethod; | |
345 return; | |
346 } | |
347 | |
348 dbus::MessageReader reader(response); | |
349 PowerSupplyProperties protobuf; | |
350 reader.PopArrayOfBytesAsProto(&protobuf); | |
351 | |
352 PowerSupplyStatus status; | |
353 status.line_power_on = protobuf.line_power_on(); | |
354 status.battery_seconds_to_empty = protobuf.battery_time_to_empty(); | |
355 status.battery_seconds_to_full = protobuf.battery_time_to_full(); | |
356 status.battery_percentage = protobuf.battery_percentage(); | |
357 status.battery_is_present = protobuf.battery_is_present(); | |
358 status.battery_is_full = protobuf.battery_is_charged(); | |
359 | |
360 VLOG(1) << "Power status: " << status.ToString(); | |
361 FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(status)); | |
362 } | |
363 | |
364 void OnGetIdleTime(const CalculateIdleTimeCallback& callback, | |
365 dbus::Response* response) { | |
366 if (!response) { | |
367 LOG(ERROR) << "Error calling " << power_manager::kGetIdleTime; | |
368 return; | |
369 } | |
370 dbus::MessageReader reader(response); | |
371 int64 idle_time_ms = 0; | |
372 if (!reader.PopInt64(&idle_time_ms)) { | |
373 LOG(ERROR) << "Error reading response from powerd: " | |
374 << response->ToString(); | |
375 callback.Run(-1); | |
376 return; | |
377 } | |
378 if (idle_time_ms < 0) { | |
379 LOG(ERROR) << "Power manager failed to calculate idle time."; | |
380 callback.Run(-1); | |
381 return; | |
382 } | |
383 callback.Run(idle_time_ms/1000); | |
384 } | |
385 | |
386 void OnPowerStateOverride(const PowerStateRequestIdCallback& callback, | |
387 dbus::Response* response) { | |
388 if (!response) { | |
389 LOG(ERROR) << "Error calling " << power_manager::kStateOverrideRequest; | |
390 return; | |
391 } | |
392 | |
393 dbus::MessageReader reader(response); | |
394 uint32 request_id = 0; | |
395 if (!reader.PopUint32(&request_id)) { | |
396 LOG(ERROR) << "Error reading response from powerd: " | |
397 << response->ToString(); | |
398 callback.Run(0); | |
399 return; | |
400 } | |
401 | |
402 callback.Run(request_id); | |
403 } | |
404 | |
405 void OnGetScreenBrightnessPercent( | |
406 const GetScreenBrightnessPercentCallback& callback, | |
407 dbus::Response* response) { | |
408 if (!response) { | |
409 LOG(ERROR) << "Error calling " | |
410 << power_manager::kGetScreenBrightnessPercent; | |
411 return; | |
412 } | |
413 dbus::MessageReader reader(response); | |
414 double percent = 0.0; | |
415 if (!reader.PopDouble(&percent)) | |
416 LOG(ERROR) << "Error reading response from powerd: " | |
417 << response->ToString(); | |
418 callback.Run(percent); | |
419 } | |
420 | |
421 void ScreenLockSignalReceived(dbus::Signal* signal) { | |
422 FOR_EACH_OBSERVER(Observer, observers_, LockScreen()); | |
423 } | |
424 | |
425 void ScreenUnlockSignalReceived(dbus::Signal* signal) { | |
426 FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen()); | |
427 } | |
428 | |
429 void ScreenUnlockFailedSignalReceived(dbus::Signal* signal) { | |
430 FOR_EACH_OBSERVER(Observer, observers_, UnlockScreenFailed()); | |
431 } | |
432 | |
433 | |
434 void IdleNotifySignalReceived(dbus::Signal* signal) { | |
435 dbus::MessageReader reader(signal); | |
436 int64 threshold = 0; | |
437 if (!reader.PopInt64(&threshold)) { | |
438 LOG(ERROR) << "Idle Notify signal had incorrect parameters: " | |
439 << signal->ToString(); | |
440 return; | |
441 } | |
442 DCHECK_GT(threshold, 0); | |
443 | |
444 VLOG(1) << "Idle Notify: " << threshold; | |
445 FOR_EACH_OBSERVER(Observer, observers_, IdleNotify(threshold)); | |
446 } | |
447 | |
448 void ActiveNotifySignalReceived(dbus::Signal* signal) { | |
449 dbus::MessageReader reader(signal); | |
450 int64 threshold = 0; | |
451 if (!reader.PopInt64(&threshold)) { | |
452 LOG(ERROR) << "Active Notify signal had incorrect parameters: " | |
453 << signal->ToString(); | |
454 return; | |
455 } | |
456 DCHECK_EQ(threshold, 0); | |
457 | |
458 VLOG(1) << "Active Notify."; | |
459 FOR_EACH_OBSERVER(Observer, observers_, ActiveNotify()); | |
460 } | |
461 | |
462 | |
463 dbus::ObjectProxy* power_manager_proxy_; | |
464 dbus::ObjectProxy* session_manager_proxy_; | |
465 ObserverList<Observer> observers_; | |
466 base::WeakPtrFactory<PowerManagerClientImpl> weak_ptr_factory_; | |
467 | |
468 DISALLOW_COPY_AND_ASSIGN(PowerManagerClientImpl); | |
469 }; | |
470 | |
471 // The PowerManagerClient implementation used on Linux desktop, | |
472 // which does nothing. | |
473 class PowerManagerClientStubImpl : public PowerManagerClient { | |
474 public: | |
475 PowerManagerClientStubImpl() | |
476 : discharging_(true), | |
477 battery_percentage_(81), | |
478 pause_count_(0) { | |
479 } | |
480 | |
481 virtual ~PowerManagerClientStubImpl() {} | |
482 | |
483 // PowerManagerClient overrides: | |
484 | |
485 virtual void AddObserver(Observer* observer) OVERRIDE { | |
486 observers_.AddObserver(observer); | |
487 } | |
488 | |
489 virtual void RemoveObserver(Observer* observer) OVERRIDE { | |
490 observers_.RemoveObserver(observer); | |
491 } | |
492 | |
493 virtual bool HasObserver(Observer* observer) OVERRIDE { | |
494 return observers_.HasObserver(observer); | |
495 } | |
496 | |
497 virtual void DecreaseScreenBrightness(bool allow_off) OVERRIDE { | |
498 VLOG(1) << "Requested to descrease screen brightness"; | |
499 } | |
500 | |
501 virtual void IncreaseScreenBrightness() OVERRIDE { | |
502 VLOG(1) << "Requested to increase screen brightness"; | |
503 } | |
504 | |
505 virtual void SetScreenBrightnessPercent(double percent, | |
506 bool gradual) OVERRIDE { | |
507 VLOG(1) << "Requested to set screen brightness to " << percent << "% " | |
508 << (gradual ? "gradually" : "instantaneously"); | |
509 } | |
510 | |
511 virtual void GetScreenBrightnessPercent( | |
512 const GetScreenBrightnessPercentCallback& callback) OVERRIDE { | |
513 callback.Run(100.0); | |
514 } | |
515 | |
516 virtual void RequestStatusUpdate(UpdateRequestType update_type) OVERRIDE { | |
517 if (update_type == UPDATE_INITIAL) { | |
518 Update(); | |
519 return; | |
520 } | |
521 if (!timer_.IsRunning() && update_type == UPDATE_USER) { | |
522 timer_.Start( | |
523 FROM_HERE, | |
524 base::TimeDelta::FromMilliseconds(1000), | |
525 this, | |
526 &PowerManagerClientStubImpl::Update); | |
527 } else { | |
528 timer_.Stop(); | |
529 } | |
530 } | |
531 | |
532 virtual void RequestRestart() OVERRIDE {} | |
533 virtual void RequestShutdown() OVERRIDE {} | |
534 | |
535 virtual void CalculateIdleTime(const CalculateIdleTimeCallback& callback) | |
536 OVERRIDE { | |
537 callback.Run(0); | |
538 } | |
539 | |
540 virtual void RequestIdleNotification(int64 threshold) OVERRIDE {} | |
541 virtual void RequestActiveNotification() OVERRIDE {} | |
542 virtual void RequestPowerStateOverrides( | |
543 uint32 request_id, | |
544 uint32 duration, | |
545 int overrides, | |
546 PowerStateRequestIdCallback callback) OVERRIDE {} | |
547 | |
548 virtual void NotifyScreenLockRequested() OVERRIDE { | |
549 FOR_EACH_OBSERVER(Observer, observers_, LockScreen()); | |
550 } | |
551 virtual void NotifyScreenLockCompleted() OVERRIDE {} | |
552 virtual void NotifyScreenUnlockRequested() OVERRIDE { | |
553 FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen()); | |
554 } | |
555 | |
556 virtual void NotifyScreenUnlockCompleted() OVERRIDE {} | |
557 | |
558 private: | |
559 void Update() { | |
560 // We pause at 0 and 100% so that it's easier to check those conditions. | |
561 if (pause_count_ > 1) { | |
562 pause_count_--; | |
563 return; | |
564 } | |
565 | |
566 if (battery_percentage_ == 0 || battery_percentage_ == 100) { | |
567 if (pause_count_) { | |
568 pause_count_ = 0; | |
569 discharging_ = !discharging_; | |
570 } else { | |
571 // Pause twice (i.e. skip updating the menu), including the current | |
572 // call to this function. | |
573 pause_count_ = 2; | |
574 return; | |
575 } | |
576 } | |
577 battery_percentage_ += (discharging_ ? -1 : 1); | |
578 | |
579 const int kSecondsToEmptyFullBattery(3 * 60 * 60); // 3 hours. | |
580 | |
581 PowerSupplyStatus status; | |
582 status.line_power_on = !discharging_; | |
583 status.battery_is_present = true; | |
584 status.battery_percentage = battery_percentage_; | |
585 status.battery_seconds_to_empty = | |
586 std::max(1, battery_percentage_ * kSecondsToEmptyFullBattery / 100); | |
587 status.battery_seconds_to_full = | |
588 std::max(static_cast<int64>(1), | |
589 kSecondsToEmptyFullBattery - status.battery_seconds_to_empty); | |
590 | |
591 FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(status)); | |
592 } | |
593 | |
594 bool discharging_; | |
595 int battery_percentage_; | |
596 int pause_count_; | |
597 ObserverList<Observer> observers_; | |
598 base::RepeatingTimer<PowerManagerClientStubImpl> timer_; | |
599 }; | |
600 | |
601 PowerManagerClient::PowerManagerClient() { | |
602 } | |
603 | |
604 PowerManagerClient::~PowerManagerClient() { | |
605 } | |
606 | |
607 PowerManagerClient* PowerManagerClient::Create( | |
608 DBusClientImplementationType type, | |
609 dbus::Bus* bus) { | |
610 if (type == REAL_DBUS_CLIENT_IMPLEMENTATION) | |
611 return new PowerManagerClientImpl(bus); | |
612 DCHECK_EQ(STUB_DBUS_CLIENT_IMPLEMENTATION, type); | |
613 return new PowerManagerClientStubImpl(); | |
614 } | |
615 | |
616 } // namespace chromeos | |
OLD | NEW |