| 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/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(×tamp_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 | |
| OLD | NEW |