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"
16 class PowerManagerObserver
17 : public chromeos::PowerManagerClient::Observer
,
18 public base::RefCountedThreadSafe
<PowerManagerObserver
> {
20 explicit PowerManagerObserver(
21 const BatteryStatusService::BatteryUpdateCallback
& callback
)
22 : callback_(callback
), currently_listening_(false) {}
24 // Starts listening for updates.
26 if (currently_listening_
)
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.
37 if (!currently_listening_
)
39 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
41 currently_listening_
= false;
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:
80 const power_manager::PowerSupplyProperties
& proto
) override
{
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
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
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
{
125 explicit BatteryStatusManagerChromeOS(
126 const BatteryStatusService::BatteryUpdateCallback
& callback
)
127 : observer_(new PowerManagerObserver(callback
)) {}
129 ~BatteryStatusManagerChromeOS() override
{ observer_
->Stop(); }
132 // BatteryStatusManager:
133 bool StartListeningBatteryChange() override
{
138 void StopListeningBatteryChange() override
{ observer_
->Stop(); }
140 scoped_refptr
<PowerManagerObserver
> observer_
;
142 DISALLOW_COPY_AND_ASSIGN(BatteryStatusManagerChromeOS
);
148 scoped_ptr
<BatteryStatusManager
> BatteryStatusManager::Create(
149 const BatteryStatusService::BatteryUpdateCallback
& callback
) {
150 return scoped_ptr
<BatteryStatusManager
>(
151 new BatteryStatusManagerChromeOS(callback
));
154 } // namespace device