Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(131)

Side by Side Diff: chrome/browser/chromeos/dbus/power_manager_client.cc

Issue 9838085: Move files inside chrome/browser/chromeos/dbus to chromeos/dbus (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: _ Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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/chromeos/chromeos_version.h"
12 #include "base/format_macros.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/observer_list.h"
15 #include "base/stringprintf.h"
16 #include "base/time.h"
17 #include "base/timer.h"
18 #include "chrome/browser/chromeos/dbus/power_supply_properties.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 #if !defined(USE_ASH)
28 PowerSupplyStatus::PowerSupplyStatus()
29 : line_power_on(false),
30 battery_is_present(false),
31 battery_is_full(false),
32 battery_seconds_to_empty(0),
33 battery_seconds_to_full(0),
34 battery_percentage(0) {
35 }
36
37 std::string PowerSupplyStatus::ToString() const {
38 std::string result;
39 base::StringAppendF(&result,
40 "line_power_on = %s ",
41 line_power_on ? "true" : "false");
42 base::StringAppendF(&result,
43 "battery_is_present = %s ",
44 battery_is_present ? "true" : "false");
45 base::StringAppendF(&result,
46 "battery_is_full = %s ",
47 battery_is_full ? "true" : "false");
48 base::StringAppendF(&result,
49 "battery_percentage = %f ",
50 battery_percentage);
51 base::StringAppendF(&result,
52 "battery_seconds_to_empty = %"PRId64" ",
53 battery_seconds_to_empty);
54 base::StringAppendF(&result,
55 "battery_seconds_to_full = %"PRId64" ",
56 battery_seconds_to_full);
57 return result;
58 }
59 #endif // !defined(USE_ASH)
60
61 // The PowerManagerClient implementation used in production.
62 class PowerManagerClientImpl : public PowerManagerClient {
63 public:
64 explicit PowerManagerClientImpl(dbus::Bus* bus)
65 : power_manager_proxy_(NULL),
66 weak_ptr_factory_(this) {
67 power_manager_proxy_ = bus->GetObjectProxy(
68 power_manager::kPowerManagerServiceName,
69 dbus::ObjectPath(power_manager::kPowerManagerServicePath));
70
71 session_manager_proxy_ = bus->GetObjectProxy(
72 login_manager::kSessionManagerServiceName,
73 dbus::ObjectPath(login_manager::kSessionManagerServicePath));
74
75 // Monitor the D-Bus signal for brightness changes. Only the power
76 // manager knows the actual brightness level. We don't cache the
77 // brightness level in Chrome as it'll make things less reliable.
78 power_manager_proxy_->ConnectToSignal(
79 power_manager::kPowerManagerInterface,
80 power_manager::kBrightnessChangedSignal,
81 base::Bind(&PowerManagerClientImpl::BrightnessChangedReceived,
82 weak_ptr_factory_.GetWeakPtr()),
83 base::Bind(&PowerManagerClientImpl::SignalConnected,
84 weak_ptr_factory_.GetWeakPtr()));
85
86 power_manager_proxy_->ConnectToSignal(
87 power_manager::kPowerManagerInterface,
88 power_manager::kPowerSupplyPollSignal,
89 base::Bind(&PowerManagerClientImpl::PowerSupplyPollReceived,
90 weak_ptr_factory_.GetWeakPtr()),
91 base::Bind(&PowerManagerClientImpl::SignalConnected,
92 weak_ptr_factory_.GetWeakPtr()));
93
94 power_manager_proxy_->ConnectToSignal(
95 power_manager::kPowerManagerInterface,
96 power_manager::kPowerStateChangedSignal,
97 base::Bind(&PowerManagerClientImpl::PowerStateChangedSignalReceived,
98 weak_ptr_factory_.GetWeakPtr()),
99 base::Bind(&PowerManagerClientImpl::SignalConnected,
100 weak_ptr_factory_.GetWeakPtr()));
101
102 power_manager_proxy_->ConnectToSignal(
103 power_manager::kPowerManagerInterface,
104 power_manager::kButtonEventSignal,
105 base::Bind(&PowerManagerClientImpl::ButtonEventSignalReceived,
106 weak_ptr_factory_.GetWeakPtr()),
107 base::Bind(&PowerManagerClientImpl::SignalConnected,
108 weak_ptr_factory_.GetWeakPtr()));
109
110 session_manager_proxy_->ConnectToSignal(
111 chromium::kChromiumInterface,
112 chromium::kLockScreenSignal,
113 base::Bind(&PowerManagerClientImpl::ScreenLockSignalReceived,
114 weak_ptr_factory_.GetWeakPtr()),
115 base::Bind(&PowerManagerClientImpl::SignalConnected,
116 weak_ptr_factory_.GetWeakPtr()));
117
118 session_manager_proxy_->ConnectToSignal(
119 chromium::kChromiumInterface,
120 chromium::kUnlockScreenSignal,
121 base::Bind(&PowerManagerClientImpl::ScreenUnlockSignalReceived,
122 weak_ptr_factory_.GetWeakPtr()),
123 base::Bind(&PowerManagerClientImpl::SignalConnected,
124 weak_ptr_factory_.GetWeakPtr()));
125 session_manager_proxy_->ConnectToSignal(
126 chromium::kChromiumInterface,
127 chromium::kUnlockScreenFailedSignal,
128 base::Bind(&PowerManagerClientImpl::ScreenUnlockFailedSignalReceived,
129 weak_ptr_factory_.GetWeakPtr()),
130 base::Bind(&PowerManagerClientImpl::SignalConnected,
131 weak_ptr_factory_.GetWeakPtr()));
132
133 power_manager_proxy_->ConnectToSignal(
134 power_manager::kPowerManagerInterface,
135 power_manager::kIdleNotifySignal,
136 base::Bind(&PowerManagerClientImpl::IdleNotifySignalReceived,
137 weak_ptr_factory_.GetWeakPtr()),
138 base::Bind(&PowerManagerClientImpl::SignalConnected,
139 weak_ptr_factory_.GetWeakPtr()));
140
141 power_manager_proxy_->ConnectToSignal(
142 power_manager::kPowerManagerInterface,
143 power_manager::kActiveNotifySignal,
144 base::Bind(&PowerManagerClientImpl::ActiveNotifySignalReceived,
145 weak_ptr_factory_.GetWeakPtr()),
146 base::Bind(&PowerManagerClientImpl::SignalConnected,
147 weak_ptr_factory_.GetWeakPtr()));
148 }
149
150 virtual ~PowerManagerClientImpl() {
151 }
152
153 // PowerManagerClient overrides:
154
155 virtual void AddObserver(Observer* observer) OVERRIDE {
156 observers_.AddObserver(observer);
157 }
158
159 virtual void RemoveObserver(Observer* observer) OVERRIDE {
160 observers_.RemoveObserver(observer);
161 }
162
163 virtual bool HasObserver(Observer* observer) OVERRIDE {
164 return observers_.HasObserver(observer);
165 }
166
167 virtual void DecreaseScreenBrightness(bool allow_off) OVERRIDE {
168 dbus::MethodCall method_call(
169 power_manager::kPowerManagerInterface,
170 power_manager::kDecreaseScreenBrightness);
171 dbus::MessageWriter writer(&method_call);
172 writer.AppendBool(allow_off);
173 power_manager_proxy_->CallMethod(
174 &method_call,
175 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
176 dbus::ObjectProxy::EmptyResponseCallback());
177 }
178
179 virtual void IncreaseScreenBrightness() OVERRIDE {
180 SimpleMethodCallToPowerManager(power_manager::kIncreaseScreenBrightness);
181 }
182
183 virtual void RequestStatusUpdate(UpdateRequestType update_type) OVERRIDE {
184 dbus::MethodCall method_call(
185 power_manager::kPowerManagerInterface,
186 power_manager::kGetPowerSupplyPropertiesMethod);
187 power_manager_proxy_->CallMethod(
188 &method_call,
189 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
190 base::Bind(&PowerManagerClientImpl::OnGetPowerSupplyPropertiesMethod,
191 weak_ptr_factory_.GetWeakPtr()));
192 }
193
194 virtual void RequestRestart() OVERRIDE {
195 SimpleMethodCallToPowerManager(power_manager::kRequestRestartMethod);
196 };
197
198 virtual void RequestShutdown() OVERRIDE {
199 SimpleMethodCallToPowerManager(power_manager::kRequestShutdownMethod);
200 }
201
202 virtual void CalculateIdleTime(const CalculateIdleTimeCallback& callback)
203 OVERRIDE {
204 dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
205 power_manager::kGetIdleTime);
206 power_manager_proxy_->CallMethod(
207 &method_call,
208 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
209 base::Bind(&PowerManagerClientImpl::OnGetIdleTime,
210 weak_ptr_factory_.GetWeakPtr(), callback));
211 }
212
213 virtual void RequestIdleNotification(int64 threshold) OVERRIDE {
214 dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
215 power_manager::kRequestIdleNotification);
216 dbus::MessageWriter writer(&method_call);
217 writer.AppendInt64(threshold);
218
219 power_manager_proxy_->CallMethod(
220 &method_call,
221 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
222 dbus::ObjectProxy::EmptyResponseCallback());
223 }
224
225 virtual void RequestActiveNotification() OVERRIDE {
226 RequestIdleNotification(0);
227 }
228
229
230 virtual void NotifyScreenLockRequested() OVERRIDE {
231 SimpleMethodCallToPowerManager(power_manager::kRequestLockScreenMethod);
232 }
233
234 virtual void NotifyScreenLockCompleted() OVERRIDE {
235 SimpleMethodCallToPowerManager(power_manager::kScreenIsLockedMethod);
236 }
237
238 virtual void NotifyScreenUnlockRequested() OVERRIDE {
239 SimpleMethodCallToPowerManager(power_manager::kRequestUnlockScreenMethod);
240 }
241
242 virtual void NotifyScreenUnlockCompleted() OVERRIDE {
243 SimpleMethodCallToPowerManager(power_manager::kScreenIsUnlockedMethod);
244 }
245
246 private:
247 // Called when a dbus signal is initially connected.
248 void SignalConnected(const std::string& interface_name,
249 const std::string& signal_name,
250 bool success) {
251 LOG_IF(WARNING, !success) << "Failed to connect to signal "
252 << signal_name << ".";
253 }
254
255 // Make a method call to power manager with no arguments and no response.
256 void SimpleMethodCallToPowerManager(const std::string& method_name) {
257 dbus::MethodCall method_call(power_manager::kPowerManagerInterface,
258 method_name);
259 power_manager_proxy_->CallMethod(
260 &method_call,
261 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
262 dbus::ObjectProxy::EmptyResponseCallback());
263 }
264
265 void BrightnessChangedReceived(dbus::Signal* signal) {
266 dbus::MessageReader reader(signal);
267 int32 brightness_level = 0;
268 bool user_initiated = 0;
269 if (!(reader.PopInt32(&brightness_level) &&
270 reader.PopBool(&user_initiated))) {
271 LOG(ERROR) << "Brightness changed signal had incorrect parameters: "
272 << signal->ToString();
273 return;
274 }
275 VLOG(1) << "Brightness changed to " << brightness_level
276 << ": user initiated " << user_initiated;
277 FOR_EACH_OBSERVER(Observer, observers_,
278 BrightnessChanged(brightness_level, user_initiated));
279 }
280
281 void PowerStateChangedSignalReceived(dbus::Signal* signal) {
282 VLOG(1) << "Received power state changed signal.";
283 dbus::MessageReader reader(signal);
284 std::string power_state_string;
285 if (!reader.PopString(&power_state_string)) {
286 LOG(ERROR) << "Error reading signal args: " << signal->ToString();
287 return;
288 }
289 if (power_state_string != "on")
290 return;
291 FOR_EACH_OBSERVER(Observer, observers_, SystemResumed());
292 }
293
294 void ButtonEventSignalReceived(dbus::Signal* signal) {
295 dbus::MessageReader reader(signal);
296 std::string button_name;
297 bool down = false;
298 int64 timestamp_internal = 0;
299 if (!reader.PopString(&button_name) ||
300 !reader.PopBool(&down) ||
301 !reader.PopInt64(&timestamp_internal)) {
302 LOG(ERROR) << "Button signal had incorrect parameters: "
303 << signal->ToString();
304 return;
305 }
306 base::TimeTicks timestamp =
307 base::TimeTicks::FromInternalValue(timestamp_internal);
308
309 if (button_name == power_manager::kPowerButtonName) {
310 FOR_EACH_OBSERVER(
311 Observer, observers_, PowerButtonStateChanged(down, timestamp));
312 } else if (button_name == power_manager::kLockButtonName) {
313 FOR_EACH_OBSERVER(
314 Observer, observers_, LockButtonStateChanged(down, timestamp));
315 }
316 }
317
318 void PowerSupplyPollReceived(dbus::Signal* unused_signal) {
319 VLOG(1) << "Received power supply poll signal.";
320 RequestStatusUpdate(UPDATE_POLL);
321 }
322
323 void OnGetPowerSupplyPropertiesMethod(dbus::Response* response) {
324 if (!response) {
325 LOG(ERROR) << "Error calling "
326 << power_manager::kGetPowerSupplyPropertiesMethod;
327 return;
328 }
329
330 dbus::MessageReader reader(response);
331 PowerSupplyProperties protobuf;
332 reader.PopArrayOfBytesAsProto(&protobuf);
333
334 PowerSupplyStatus status;
335 status.line_power_on = protobuf.line_power_on();
336 status.battery_seconds_to_empty = protobuf.battery_time_to_empty();
337 status.battery_seconds_to_full = protobuf.battery_time_to_full();
338 status.battery_percentage = protobuf.battery_percentage();
339 status.battery_is_present = protobuf.battery_is_present();
340 status.battery_is_full = protobuf.battery_is_charged();
341
342 VLOG(1) << "Power status: " << status.ToString();
343 FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(status));
344 }
345
346 void OnGetIdleTime(const CalculateIdleTimeCallback& callback,
347 dbus::Response* response) {
348 if (!response) {
349 LOG(ERROR) << "Error calling " << power_manager::kGetIdleTime;
350 return;
351 }
352 dbus::MessageReader reader(response);
353 int64 idle_time_ms = 0;
354 if (!reader.PopInt64(&idle_time_ms)) {
355 LOG(ERROR) << "Error reading response from powerd: "
356 << response->ToString();
357 callback.Run(-1);
358 return;
359 }
360 if (idle_time_ms < 0) {
361 LOG(ERROR) << "Power manager failed to calculate idle time.";
362 callback.Run(-1);
363 return;
364 }
365 callback.Run(idle_time_ms/1000);
366 }
367
368 void ScreenLockSignalReceived(dbus::Signal* signal) {
369 FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
370 }
371
372 void ScreenUnlockSignalReceived(dbus::Signal* signal) {
373 FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen());
374 }
375
376 void ScreenUnlockFailedSignalReceived(dbus::Signal* signal) {
377 FOR_EACH_OBSERVER(Observer, observers_, UnlockScreenFailed());
378 }
379
380
381 void IdleNotifySignalReceived(dbus::Signal* signal) {
382 dbus::MessageReader reader(signal);
383 int64 threshold = 0;
384 if (!reader.PopInt64(&threshold)) {
385 LOG(ERROR) << "Idle Notify signal had incorrect parameters: "
386 << signal->ToString();
387 return;
388 }
389 DCHECK_GT(threshold, 0);
390
391 VLOG(1) << "Idle Notify: " << threshold;
392 FOR_EACH_OBSERVER(Observer, observers_, IdleNotify(threshold));
393 }
394
395 void ActiveNotifySignalReceived(dbus::Signal* signal) {
396 dbus::MessageReader reader(signal);
397 int64 threshold = 0;
398 if (!reader.PopInt64(&threshold)) {
399 LOG(ERROR) << "Active Notify signal had incorrect parameters: "
400 << signal->ToString();
401 return;
402 }
403 DCHECK_EQ(threshold, 0);
404
405 VLOG(1) << "Active Notify.";
406 FOR_EACH_OBSERVER(Observer, observers_, ActiveNotify());
407 }
408
409
410 dbus::ObjectProxy* power_manager_proxy_;
411 dbus::ObjectProxy* session_manager_proxy_;
412 ObserverList<Observer> observers_;
413 base::WeakPtrFactory<PowerManagerClientImpl> weak_ptr_factory_;
414
415 DISALLOW_COPY_AND_ASSIGN(PowerManagerClientImpl);
416 };
417
418 // The PowerManagerClient implementation used on Linux desktop,
419 // which does nothing.
420 class PowerManagerClientStubImpl : public PowerManagerClient {
421 public:
422 PowerManagerClientStubImpl()
423 : discharging_(true),
424 battery_percentage_(81),
425 pause_count_(0) {
426 }
427
428 virtual ~PowerManagerClientStubImpl() {}
429
430 // PowerManagerClient overrides:
431
432 virtual void AddObserver(Observer* observer) OVERRIDE {
433 observers_.AddObserver(observer);
434 }
435
436 virtual void RemoveObserver(Observer* observer) OVERRIDE {
437 observers_.RemoveObserver(observer);
438 }
439
440 virtual bool HasObserver(Observer* observer) OVERRIDE {
441 return observers_.HasObserver(observer);
442 }
443
444 virtual void DecreaseScreenBrightness(bool allow_off) OVERRIDE {
445 VLOG(1) << "Requested to descrease screen brightness";
446 }
447
448 virtual void IncreaseScreenBrightness() OVERRIDE {
449 VLOG(1) << "Requested to increase screen brightness";
450 }
451
452 virtual void RequestStatusUpdate(UpdateRequestType update_type) OVERRIDE {
453 if (update_type == UPDATE_INITIAL) {
454 Update();
455 return;
456 }
457 if (!timer_.IsRunning() && update_type == UPDATE_USER) {
458 timer_.Start(
459 FROM_HERE,
460 base::TimeDelta::FromMilliseconds(1000),
461 this,
462 &PowerManagerClientStubImpl::Update);
463 } else {
464 timer_.Stop();
465 }
466 }
467
468 virtual void RequestRestart() OVERRIDE {}
469 virtual void RequestShutdown() OVERRIDE {}
470
471 virtual void CalculateIdleTime(const CalculateIdleTimeCallback& callback)
472 OVERRIDE {
473 callback.Run(0);
474 }
475
476 virtual void RequestIdleNotification(int64 threshold) OVERRIDE {}
477 virtual void RequestActiveNotification() OVERRIDE {}
478
479 virtual void NotifyScreenLockRequested() OVERRIDE {
480 FOR_EACH_OBSERVER(Observer, observers_, LockScreen());
481 }
482 virtual void NotifyScreenLockCompleted() OVERRIDE {}
483 virtual void NotifyScreenUnlockRequested() OVERRIDE {
484 FOR_EACH_OBSERVER(Observer, observers_, UnlockScreen());
485 }
486
487 virtual void NotifyScreenUnlockCompleted() OVERRIDE {}
488
489 private:
490 void Update() {
491 // We pause at 0 and 100% so that it's easier to check those conditions.
492 if (pause_count_ > 1) {
493 pause_count_--;
494 return;
495 }
496
497 if (battery_percentage_ == 0 || battery_percentage_ == 100) {
498 if (pause_count_) {
499 pause_count_ = 0;
500 discharging_ = !discharging_;
501 } else {
502 // Pause twice (i.e. skip updating the menu), including the current
503 // call to this function.
504 pause_count_ = 2;
505 return;
506 }
507 }
508 battery_percentage_ += (discharging_ ? -1 : 1);
509
510 const int kSecondsToEmptyFullBattery(3 * 60 * 60); // 3 hours.
511
512 PowerSupplyStatus status;
513 status.line_power_on = !discharging_;
514 status.battery_is_present = true;
515 status.battery_percentage = battery_percentage_;
516 status.battery_seconds_to_empty =
517 std::max(1, battery_percentage_ * kSecondsToEmptyFullBattery / 100);
518 status.battery_seconds_to_full =
519 std::max(static_cast<int64>(1),
520 kSecondsToEmptyFullBattery - status.battery_seconds_to_empty);
521
522 FOR_EACH_OBSERVER(Observer, observers_, PowerChanged(status));
523 }
524
525 bool discharging_;
526 int battery_percentage_;
527 int pause_count_;
528 ObserverList<Observer> observers_;
529 base::RepeatingTimer<PowerManagerClientStubImpl> timer_;
530 };
531
532 PowerManagerClient::PowerManagerClient() {
533 }
534
535 PowerManagerClient::~PowerManagerClient() {
536 }
537
538 PowerManagerClient* PowerManagerClient::Create(dbus::Bus* bus) {
539 if (base::chromeos::IsRunningOnChromeOS()) {
540 return new PowerManagerClientImpl(bus);
541 } else {
542 return new PowerManagerClientStubImpl();
543 }
544 }
545
546 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698