| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/battery_status/battery_status_manager_linux.h" | 5 #include "device/battery/battery_status_manager_linux.h" |
| 6 | 6 |
| 7 #include "base/macros.h" | 7 #include "base/macros.h" |
| 8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
| 9 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| 11 #include "content/browser/battery_status/battery_status_manager.h" | |
| 12 #include "content/public/browser/browser_thread.h" | |
| 13 #include "dbus/bus.h" | 11 #include "dbus/bus.h" |
| 14 #include "dbus/message.h" | 12 #include "dbus/message.h" |
| 15 #include "dbus/object_path.h" | 13 #include "dbus/object_path.h" |
| 16 #include "dbus/object_proxy.h" | 14 #include "dbus/object_proxy.h" |
| 17 #include "dbus/property.h" | 15 #include "dbus/property.h" |
| 18 #include "dbus/values_util.h" | 16 #include "dbus/values_util.h" |
| 17 #include "device/battery/battery_status_manager.h" |
| 19 | 18 |
| 20 namespace content { | 19 namespace device { |
| 21 | 20 |
| 22 namespace { | 21 namespace { |
| 23 | 22 |
| 24 const char kUPowerServiceName[] = "org.freedesktop.UPower"; | 23 const char kUPowerServiceName[] = "org.freedesktop.UPower"; |
| 25 const char kUPowerDeviceName[] = "org.freedesktop.UPower.Device"; | 24 const char kUPowerDeviceName[] = "org.freedesktop.UPower.Device"; |
| 26 const char kUPowerPath[] = "/org/freedesktop/UPower"; | 25 const char kUPowerPath[] = "/org/freedesktop/UPower"; |
| 27 const char kUPowerDeviceSignalChanged[] = "Changed"; | 26 const char kUPowerDeviceSignalChanged[] = "Changed"; |
| 28 const char kUPowerEnumerateDevices[] = "EnumerateDevices"; | 27 const char kUPowerEnumerateDevices[] = "EnumerateDevices"; |
| 29 const char kBatteryNotifierThreadName[] = "BatteryStatusNotifier"; | 28 const char kBatteryNotifierThreadName[] = "BatteryStatusNotifier"; |
| 30 | 29 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 // obtain battery information and receives battery change notifications. | 105 // obtain battery information and receives battery change notifications. |
| 107 class BatteryStatusNotificationThread : public base::Thread { | 106 class BatteryStatusNotificationThread : public base::Thread { |
| 108 public: | 107 public: |
| 109 BatteryStatusNotificationThread( | 108 BatteryStatusNotificationThread( |
| 110 const BatteryStatusService::BatteryUpdateCallback& callback) | 109 const BatteryStatusService::BatteryUpdateCallback& callback) |
| 111 : base::Thread(kBatteryNotifierThreadName), | 110 : base::Thread(kBatteryNotifierThreadName), |
| 112 callback_(callback), | 111 callback_(callback), |
| 113 battery_proxy_(NULL) {} | 112 battery_proxy_(NULL) {} |
| 114 | 113 |
| 115 virtual ~BatteryStatusNotificationThread() { | 114 virtual ~BatteryStatusNotificationThread() { |
| 116 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 117 | |
| 118 // Make sure to shutdown the dbus connection if it is still open in the very | 115 // Make sure to shutdown the dbus connection if it is still open in the very |
| 119 // end. It needs to happen on the BatteryStatusNotificationThread. | 116 // end. It needs to happen on the BatteryStatusNotificationThread. |
| 120 message_loop()->PostTask( | 117 message_loop()->PostTask( |
| 121 FROM_HERE, | 118 FROM_HERE, |
| 122 base::Bind(&BatteryStatusNotificationThread::ShutdownDBusConnection, | 119 base::Bind(&BatteryStatusNotificationThread::ShutdownDBusConnection, |
| 123 base::Unretained(this))); | 120 base::Unretained(this))); |
| 124 | 121 |
| 125 // Drain the message queue of the BatteryStatusNotificationThread and stop. | 122 // Drain the message queue of the BatteryStatusNotificationThread and stop. |
| 126 Stop(); | 123 Stop(); |
| 127 } | 124 } |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 << "using status data of the first battery only."; | 165 << "using status data of the first battery only."; |
| 169 } else { | 166 } else { |
| 170 battery_proxy_ = device_proxy; | 167 battery_proxy_ = device_proxy; |
| 171 } | 168 } |
| 172 num_batteries++; | 169 num_batteries++; |
| 173 } | 170 } |
| 174 | 171 |
| 175 UpdateNumberBatteriesHistogram(num_batteries); | 172 UpdateNumberBatteriesHistogram(num_batteries); |
| 176 | 173 |
| 177 if (!battery_proxy_) { | 174 if (!battery_proxy_) { |
| 178 callback_.Run(blink::WebBatteryStatus()); | 175 callback_.Run(BatteryStatus()); |
| 179 return; | 176 return; |
| 180 } | 177 } |
| 181 | 178 |
| 182 battery_proxy_->ConnectToSignal( | 179 battery_proxy_->ConnectToSignal( |
| 183 kUPowerDeviceName, | 180 kUPowerDeviceName, |
| 184 kUPowerDeviceSignalChanged, | 181 kUPowerDeviceSignalChanged, |
| 185 base::Bind(&BatteryStatusNotificationThread::BatteryChanged, | 182 base::Bind(&BatteryStatusNotificationThread::BatteryChanged, |
| 186 base::Unretained(this)), | 183 base::Unretained(this)), |
| 187 base::Bind(&BatteryStatusNotificationThread::OnSignalConnected, | 184 base::Bind(&BatteryStatusNotificationThread::OnSignalConnected, |
| 188 base::Unretained(this))); | 185 base::Unretained(this))); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 } | 230 } |
| 234 | 231 |
| 235 if (!system_bus_.get()) | 232 if (!system_bus_.get()) |
| 236 return; | 233 return; |
| 237 | 234 |
| 238 if (success) { | 235 if (success) { |
| 239 BatteryChanged(NULL); | 236 BatteryChanged(NULL); |
| 240 } else { | 237 } else { |
| 241 // Failed to register for "Changed" signal, execute callback with the | 238 // Failed to register for "Changed" signal, execute callback with the |
| 242 // default values. | 239 // default values. |
| 243 callback_.Run(blink::WebBatteryStatus()); | 240 callback_.Run(BatteryStatus()); |
| 244 } | 241 } |
| 245 } | 242 } |
| 246 | 243 |
| 247 void BatteryChanged(dbus::Signal* signal /* unsused */) { | 244 void BatteryChanged(dbus::Signal* signal /* unsused */) { |
| 248 DCHECK(OnWatcherThread()); | 245 DCHECK(OnWatcherThread()); |
| 249 | 246 |
| 250 if (!system_bus_.get()) | 247 if (!system_bus_.get()) |
| 251 return; | 248 return; |
| 252 | 249 |
| 253 scoped_ptr<base::DictionaryValue> dictionary = | 250 scoped_ptr<base::DictionaryValue> dictionary = |
| 254 GetPropertiesAsDictionary(battery_proxy_); | 251 GetPropertiesAsDictionary(battery_proxy_); |
| 255 if (dictionary) | 252 if (dictionary) |
| 256 callback_.Run(ComputeWebBatteryStatus(*dictionary)); | 253 callback_.Run(ComputeWebBatteryStatus(*dictionary)); |
| 257 else | 254 else |
| 258 callback_.Run(blink::WebBatteryStatus()); | 255 callback_.Run(BatteryStatus()); |
| 259 } | 256 } |
| 260 | 257 |
| 261 BatteryStatusService::BatteryUpdateCallback callback_; | 258 BatteryStatusService::BatteryUpdateCallback callback_; |
| 262 scoped_refptr<dbus::Bus> system_bus_; | 259 scoped_refptr<dbus::Bus> system_bus_; |
| 263 dbus::ObjectProxy* battery_proxy_; // owned by the bus | 260 dbus::ObjectProxy* battery_proxy_; // owned by the bus |
| 264 | 261 |
| 265 DISALLOW_COPY_AND_ASSIGN(BatteryStatusNotificationThread); | 262 DISALLOW_COPY_AND_ASSIGN(BatteryStatusNotificationThread); |
| 266 }; | 263 }; |
| 267 | 264 |
| 268 // Runs on IO thread and creates a notification thread and delegates Start/Stop | 265 // Creates a notification thread and delegates Start/Stop calls to it. |
| 269 // calls to it. | |
| 270 class BatteryStatusManagerLinux : public BatteryStatusManager { | 266 class BatteryStatusManagerLinux : public BatteryStatusManager { |
| 271 public: | 267 public: |
| 272 explicit BatteryStatusManagerLinux( | 268 explicit BatteryStatusManagerLinux( |
| 273 const BatteryStatusService::BatteryUpdateCallback& callback) | 269 const BatteryStatusService::BatteryUpdateCallback& callback) |
| 274 : callback_(callback) {} | 270 : callback_(callback) {} |
| 275 | 271 |
| 276 virtual ~BatteryStatusManagerLinux() {} | 272 virtual ~BatteryStatusManagerLinux() {} |
| 277 | 273 |
| 278 private: | 274 private: |
| 279 // BatteryStatusManager: | 275 // BatteryStatusManager: |
| 280 virtual bool StartListeningBatteryChange() override { | 276 virtual bool StartListeningBatteryChange() override { |
| 281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 282 | |
| 283 if (!StartNotifierThreadIfNecessary()) | |
| 284 return false; | 277 return false; |
| 285 | 278 |
| 286 notifier_thread_->message_loop()->PostTask( | 279 notifier_thread_->message_loop()->PostTask( |
| 287 FROM_HERE, | 280 FROM_HERE, |
| 288 base::Bind(&BatteryStatusNotificationThread::StartListening, | 281 base::Bind(&BatteryStatusNotificationThread::StartListening, |
| 289 base::Unretained(notifier_thread_.get()))); | 282 base::Unretained(notifier_thread_.get()))); |
| 290 return true; | 283 return true; |
| 291 } | 284 } |
| 292 | 285 |
| 293 virtual void StopListeningBatteryChange() override { | 286 virtual void StopListeningBatteryChange() override { |
| 294 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 295 | |
| 296 if (!notifier_thread_) | 287 if (!notifier_thread_) |
| 297 return; | 288 return; |
| 298 | 289 |
| 299 notifier_thread_->message_loop()->PostTask( | 290 notifier_thread_->message_loop()->PostTask( |
| 300 FROM_HERE, | 291 FROM_HERE, |
| 301 base::Bind(&BatteryStatusNotificationThread::StopListening, | 292 base::Bind(&BatteryStatusNotificationThread::StopListening, |
| 302 base::Unretained(notifier_thread_.get()))); | 293 base::Unretained(notifier_thread_.get()))); |
| 303 } | 294 } |
| 304 | 295 |
| 305 // Starts the notifier thread if not already started and returns true on | 296 // Starts the notifier thread if not already started and returns true on |
| (...skipping 14 matching lines...) Expand all Loading... |
| 320 } | 311 } |
| 321 | 312 |
| 322 BatteryStatusService::BatteryUpdateCallback callback_; | 313 BatteryStatusService::BatteryUpdateCallback callback_; |
| 323 scoped_ptr<BatteryStatusNotificationThread> notifier_thread_; | 314 scoped_ptr<BatteryStatusNotificationThread> notifier_thread_; |
| 324 | 315 |
| 325 DISALLOW_COPY_AND_ASSIGN(BatteryStatusManagerLinux); | 316 DISALLOW_COPY_AND_ASSIGN(BatteryStatusManagerLinux); |
| 326 }; | 317 }; |
| 327 | 318 |
| 328 } // namespace | 319 } // namespace |
| 329 | 320 |
| 330 blink::WebBatteryStatus ComputeWebBatteryStatus( | 321 BatteryStatus ComputeWebBatteryStatus(const base::DictionaryValue& dictionary) { |
| 331 const base::DictionaryValue& dictionary) { | 322 BatteryStatus status; |
| 332 blink::WebBatteryStatus status; | |
| 333 if (!dictionary.HasKey("State")) | 323 if (!dictionary.HasKey("State")) |
| 334 return status; | 324 return status; |
| 335 | 325 |
| 336 uint32 state = static_cast<uint32>( | 326 uint32 state = static_cast<uint32>( |
| 337 GetPropertyAsDouble(dictionary, "State", UPOWER_DEVICE_STATE_UNKNOWN)); | 327 GetPropertyAsDouble(dictionary, "State", UPOWER_DEVICE_STATE_UNKNOWN)); |
| 338 status.charging = state != UPOWER_DEVICE_STATE_DISCHARGING && | 328 status.charging = state != UPOWER_DEVICE_STATE_DISCHARGING && |
| 339 state != UPOWER_DEVICE_STATE_EMPTY; | 329 state != UPOWER_DEVICE_STATE_EMPTY; |
| 340 double percentage = GetPropertyAsDouble(dictionary, "Percentage", 100); | 330 double percentage = GetPropertyAsDouble(dictionary, "Percentage", 100); |
| 341 // Convert percentage to a value between 0 and 1 with 2 digits of precision. | 331 // Convert percentage to a value between 0 and 1 with 2 digits of precision. |
| 342 // This is to bring it in line with other platforms like Mac and Android where | 332 // This is to bring it in line with other platforms like Mac and Android where |
| 343 // we report level with 1% granularity. It also serves the purpose of reducing | 333 // we report level with 1% granularity. It also serves the purpose of reducing |
| 344 // the possibility of fingerprinting and triggers less level change events on | 334 // the possibility of fingerprinting and triggers less level change events on |
| 345 // the blink side. | 335 // the blink side. |
| 346 // TODO(timvolodine): consider moving this rounding to the blink side. | 336 // TODO(timvolodine): consider moving this rounding to the blink side. |
| 347 status.level = round(percentage) / 100.f; | 337 status.level = round(percentage) / 100.f; |
| 348 | 338 |
| 349 switch (state) { | 339 switch (state) { |
| 350 case UPOWER_DEVICE_STATE_CHARGING : { | 340 case UPOWER_DEVICE_STATE_CHARGING : { |
| 351 double time_to_full = GetPropertyAsDouble(dictionary, "TimeToFull", 0); | 341 double time_to_full = GetPropertyAsDouble(dictionary, "TimeToFull", 0); |
| 352 status.chargingTime = | 342 status.charging_time = |
| 353 (time_to_full > 0) ? time_to_full | 343 (time_to_full > 0) ? time_to_full |
| 354 : std::numeric_limits<double>::infinity(); | 344 : std::numeric_limits<double>::infinity(); |
| 355 break; | 345 break; |
| 356 } | 346 } |
| 357 case UPOWER_DEVICE_STATE_DISCHARGING : { | 347 case UPOWER_DEVICE_STATE_DISCHARGING : { |
| 358 double time_to_empty = GetPropertyAsDouble(dictionary, "TimeToEmpty", 0); | 348 double time_to_empty = GetPropertyAsDouble(dictionary, "TimeToEmpty", 0); |
| 359 // Set dischargingTime if it's available. Otherwise leave the default | 349 // Set dischargingTime if it's available. Otherwise leave the default |
| 360 // value which is +infinity. | 350 // value which is +infinity. |
| 361 if (time_to_empty > 0) | 351 if (time_to_empty > 0) |
| 362 status.dischargingTime = time_to_empty; | 352 status.discharging_time = time_to_empty; |
| 363 status.chargingTime = std::numeric_limits<double>::infinity(); | 353 status.charging_time = std::numeric_limits<double>::infinity(); |
| 364 break; | 354 break; |
| 365 } | 355 } |
| 366 case UPOWER_DEVICE_STATE_FULL : { | 356 case UPOWER_DEVICE_STATE_FULL : { |
| 367 break; | 357 break; |
| 368 } | 358 } |
| 369 default: { | 359 default: { |
| 370 status.chargingTime = std::numeric_limits<double>::infinity(); | 360 status.charging_time = std::numeric_limits<double>::infinity(); |
| 371 } | 361 } |
| 372 } | 362 } |
| 373 return status; | 363 return status; |
| 374 } | 364 } |
| 375 | 365 |
| 376 // static | 366 // static |
| 377 scoped_ptr<BatteryStatusManager> BatteryStatusManager::Create( | 367 scoped_ptr<BatteryStatusManager> BatteryStatusManager::Create( |
| 378 const BatteryStatusService::BatteryUpdateCallback& callback) { | 368 const BatteryStatusService::BatteryUpdateCallback& callback) { |
| 379 return scoped_ptr<BatteryStatusManager>( | 369 return scoped_ptr<BatteryStatusManager>( |
| 380 new BatteryStatusManagerLinux(callback)); | 370 new BatteryStatusManagerLinux(callback)); |
| 381 } | 371 } |
| 382 | 372 |
| 383 } // namespace content | 373 } // namespace device |
| OLD | NEW |