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

Side by Side Diff: content/browser/battery_status/battery_status_manager_chromeos.cc

Issue 356873002: battery-status: Implement the battery-status API for chromeos. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: scoped_ptr Created 6 years, 5 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 | Annotate | Revision Log
OLDNEW
(Empty)
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.
4
5 #include "content/browser/battery_status/battery_status_manager.h"
6
7 #include "base/memory/weak_ptr.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"
11 #include "content/public/browser/browser_thread.h"
12 #include "third_party/WebKit/public/platform/WebBatteryStatus.h"
13
14 namespace content {
15
16 namespace {
17
18 void RemoveObserverOnUI(chromeos::PowerManagerClient::Observer* observer) {
19 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
20 observer);
21 }
22
23 class BatteryStatusManagerChromeOS
24 : public BatteryStatusManager,
25 public chromeos::PowerManagerClient::Observer {
26 public:
27 explicit BatteryStatusManagerChromeOS(
28 const BatteryStatusService::BatteryUpdateCallback& callback)
29 : callback_(callback), currently_listening_(false), weak_factory_(this) {}
30
31 virtual ~BatteryStatusManagerChromeOS() {
32 if (!currently_listening_)
timvolodine 2014/07/09 11:35:01 This looks like there is a potential race conditio
sadrul 2014/07/13 09:04:54 I have moved the main code out of this into a RefC
33 return;
34
35 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
36 StopOnUI();
37 } else {
38 BrowserThread::PostTask(
39 BrowserThread::UI,
40 FROM_HERE,
41 base::Bind(&RemoveObserverOnUI, base::Unretained(this)));
42 }
43 }
44
45 private:
46 bool IsBatteryPresent(
47 const power_manager::PowerSupplyProperties& proto) const {
48 return proto.battery_state() !=
49 power_manager::PowerSupplyProperties_BatteryState_NOT_PRESENT;
50 }
51
52 bool IsUsbChargerConnected(
53 const power_manager::PowerSupplyProperties& proto) const {
54 return proto.external_power() ==
55 power_manager::PowerSupplyProperties_ExternalPower_USB;
56 }
57
58 bool IsBatteryCharging(
59 const power_manager::PowerSupplyProperties& proto) const {
60 return proto.battery_state() !=
61 power_manager::PowerSupplyProperties_BatteryState_DISCHARGING;
62 }
63
64 bool IsBatteryFull(const power_manager::PowerSupplyProperties& proto) const {
65 return proto.battery_state() ==
66 power_manager::PowerSupplyProperties_BatteryState_FULL;
67 }
68
69 double GetBatteryLevel(
70 const power_manager::PowerSupplyProperties& proto) const {
71 const double kMaxBatteryLevelProto = 100.f;
72 return proto.battery_percent() / kMaxBatteryLevelProto;
73 }
74
75 void StartOnUI() {
timvolodine 2014/07/09 11:35:01 not sure if this is relevant for chromeOS, but alt
sadrul 2014/07/13 09:04:54 In the case of Chrome OS, the interaction with the
timvolodine 2014/07/14 17:38:56 fyi: on macOS it is sufficient to have a thread wi
76 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
77 if (currently_listening_)
78 return;
79 chromeos::PowerManagerClient* power_client =
80 chromeos::DBusThreadManager::Get()->GetPowerManagerClient();
81 power_client->AddObserver(this);
82 power_client->RequestStatusUpdate();
83 currently_listening_ = true;
84 }
85
86 void StopOnUI() {
87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
88 if (!currently_listening_)
89 return;
90 chromeos::DBusThreadManager::Get()->GetPowerManagerClient()->RemoveObserver(
91 this);
92 currently_listening_ = false;
93 }
94
95 // BatteryStatusManager:
96 virtual bool StartListeningBatteryChange() OVERRIDE {
97 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
98 weak_factory_.InvalidateWeakPtrs();
99 BrowserThread::PostTask(BrowserThread::UI,
100 FROM_HERE,
101 base::Bind(&BatteryStatusManagerChromeOS::StartOnUI,
102 weak_factory_.GetWeakPtr()));
timvolodine 2014/07/09 11:35:01 Probably false alarm, but I was curious whether We
sadrul 2014/07/13 09:04:54 Good catch! It looks like WeakPtr indeed is not th
103 return true;
104 }
105
106 virtual void StopListeningBatteryChange() OVERRIDE {
107 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
108 weak_factory_.InvalidateWeakPtrs();
109 BrowserThread::PostTask(BrowserThread::UI,
110 FROM_HERE,
111 base::Bind(&BatteryStatusManagerChromeOS::StopOnUI,
112 weak_factory_.GetWeakPtr()));
113 }
114
115 // chromeos::PowerManagerClient::Observer:
116 virtual void PowerChanged(
117 const power_manager::PowerSupplyProperties& proto) OVERRIDE {
118 blink::WebBatteryStatus status;
119 // Use the default values if there is no battery in the system.
120 if (IsBatteryPresent(proto)) {
121 // The charging status is unreliable if a low power charger is connected
122 // (i.e. usb).
123 bool status_unreliable = IsUsbChargerConnected(proto);
124 // Battery time is unreliable if it is still being computed.
125 bool time_unreliable =
126 status_unreliable || proto.is_calculating_battery_time();
127
128 // Set |charging| only if the status is reliable. Otherwise, keep the
129 // default (which is |true|).
130 if (!status_unreliable)
131 status.charging = IsBatteryCharging(proto);
132
133 // Set |chargingTime| to +infinity if the battery is discharging, or if
134 // the time is unreliable. Keep the default value (which is 0) if the
135 // battery is full.
136 if (time_unreliable || !status.charging)
137 status.chargingTime = std::numeric_limits<double>::infinity();
138 else if (!IsBatteryFull(proto))
139 status.chargingTime = proto.battery_time_to_full_sec();
140
141 // Keep the default value for |dischargingTime| (which is +infinity) if
142 // the time is unreliable, or if the battery is charging.
143 if (!time_unreliable && !status.charging)
144 status.dischargingTime = proto.battery_time_to_empty_sec();
145
146 status.level = GetBatteryLevel(proto);
147 }
148 callback_.Run(status);
149 }
150
151 BatteryStatusService::BatteryUpdateCallback callback_;
152 bool currently_listening_;
153 base::WeakPtrFactory<BatteryStatusManagerChromeOS> weak_factory_;
154
155 DISALLOW_COPY_AND_ASSIGN(BatteryStatusManagerChromeOS);
156 };
157
158 } // namespace
159
160 // static
161 scoped_ptr<BatteryStatusManager> BatteryStatusManager::Create(
162 const BatteryStatusService::BatteryUpdateCallback& callback) {
163 return scoped_ptr<BatteryStatusManager>(
164 new BatteryStatusManagerChromeOS(callback));
165 }
166
167 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698