Fixes flakey test
[chromium-blink-merge.git] / device / battery / battery_status_manager_chromeos.cc
blobb2ca0d4697e4e557b2f7be40c9135e89a69217b2
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
3 // found in the LICENSE file.
5 #include "device/battery/battery_status_manager.h"
7 #include "base/memory/ref_counted.h"
8 #include "chromeos/dbus/dbus_thread_manager.h"
9 #include "chromeos/dbus/power_manager/power_supply_properties.pb.h"
10 #include "chromeos/dbus/power_manager_client.h"
12 namespace device {
14 namespace {
16 class PowerManagerObserver
17 : public chromeos::PowerManagerClient::Observer,
18 public base::RefCountedThreadSafe<PowerManagerObserver> {
19 public:
20 explicit PowerManagerObserver(
21 const BatteryStatusService::BatteryUpdateCallback& callback)
22 : callback_(callback), currently_listening_(false) {}
24 // Starts listening for updates.
25 void Start() {
26 if (currently_listening_)
27 return;
28 chromeos::PowerManagerClient* power_client =
29 chromeos::DBusThreadManager::Get()->GetPowerManagerClient();
30 power_client->AddObserver(this);
31 power_client->RequestStatusUpdate();
32 currently_listening_ = true;
35 // Stops listening for updates.
36 void Stop() {
37 if (!currently_listening_)
38 return;
39 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
40 this);
41 currently_listening_ = false;
44 private:
45 friend class base::RefCountedThreadSafe<PowerManagerObserver>;
47 ~PowerManagerObserver() override {}
49 bool IsBatteryPresent(
50 const power_manager::PowerSupplyProperties& proto) const {
51 return proto.battery_state() !=
52 power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT;
55 bool IsUsbChargerConnected(
56 const power_manager::PowerSupplyProperties& proto) const {
57 return proto.external_power() ==
58 power_manager::PowerSupplyProperties_ExternalPower_USB;
61 bool IsBatteryCharging(
62 const power_manager::PowerSupplyProperties& proto) const {
63 return proto.battery_state() !=
64 power_manager::PowerSupplyProperties_BatteryState_DISCHARGING;
67 bool IsBatteryFull(const power_manager::PowerSupplyProperties& proto) const {
68 return proto.battery_state() ==
69 power_manager::PowerSupplyProperties_BatteryState_FULL;
72 double GetBatteryLevel(
73 const power_manager::PowerSupplyProperties& proto) const {
74 const double kMaxBatteryLevelProto = 100.f;
75 return proto.battery_percent() / kMaxBatteryLevelProto;
78 // chromeos::PowerManagerClient::Observer:
79 void PowerChanged(
80 const power_manager::PowerSupplyProperties& proto) override {
81 BatteryStatus status;
83 // Use the default values if there is no battery in the system.
84 if (IsBatteryPresent(proto)) {
85 // The charging status is unreliable if a low power charger is connected
86 // (i.e. usb).
87 bool status_unreliable = IsUsbChargerConnected(proto);
88 // Battery time is unreliable if it is still being computed.
89 bool time_unreliable =
90 status_unreliable || proto.is_calculating_battery_time();
92 // Set |charging| only if the status is reliable. Otherwise, keep the
93 // default (which is |true|).
94 if (!status_unreliable)
95 status.charging = IsBatteryCharging(proto);
97 // Set |chargingTime| to +infinity if the battery is discharging, or if
98 // the time is unreliable. Keep the default value (which is 0) if the
99 // battery is full.
100 if (time_unreliable || !status.charging)
101 status.charging_time = std::numeric_limits<double>::infinity();
102 else if (!IsBatteryFull(proto))
103 status.charging_time = proto.battery_time_to_full_sec();
105 // Keep the default value for |dischargingTime| (which is +infinity) if
106 // the time is unreliable, or if the battery is charging.
107 if (!time_unreliable && !status.charging)
108 status.discharging_time = proto.battery_time_to_empty_sec();
110 status.level = GetBatteryLevel(proto);
112 callback_.Run(status);
115 BatteryStatusService::BatteryUpdateCallback callback_;
116 bool currently_listening_;
118 DISALLOW_COPY_AND_ASSIGN(PowerManagerObserver);
121 class BatteryStatusManagerChromeOS
122 : public BatteryStatusManager,
123 public chromeos::PowerManagerClient::Observer {
124 public:
125 explicit BatteryStatusManagerChromeOS(
126 const BatteryStatusService::BatteryUpdateCallback& callback)
127 : observer_(new PowerManagerObserver(callback)) {}
129 ~BatteryStatusManagerChromeOS() override { observer_->Stop(); }
131 private:
132 // BatteryStatusManager:
133 bool StartListeningBatteryChange() override {
134 observer_->Start();
135 return true;
138 void StopListeningBatteryChange() override { observer_->Stop(); }
140 scoped_refptr<PowerManagerObserver> observer_;
142 DISALLOW_COPY_AND_ASSIGN(BatteryStatusManagerChromeOS);
145 } // namespace
147 // static
148 scoped_ptr<BatteryStatusManager> BatteryStatusManager::Create(
149 const BatteryStatusService::BatteryUpdateCallback& callback) {
150 return scoped_ptr<BatteryStatusManager>(
151 new BatteryStatusManagerChromeOS(callback));
154 } // namespace device