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 "content/browser/battery_status/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/threading/thread.h" | 9 #include "base/threading/thread.h" |
9 #include "base/values.h" | 10 #include "base/values.h" |
10 #include "content/browser/battery_status/battery_status_manager.h" | 11 #include "content/browser/battery_status/battery_status_manager.h" |
11 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
12 #include "dbus/bus.h" | 13 #include "dbus/bus.h" |
13 #include "dbus/message.h" | 14 #include "dbus/message.h" |
14 #include "dbus/object_path.h" | 15 #include "dbus/object_path.h" |
15 #include "dbus/object_proxy.h" | 16 #include "dbus/object_proxy.h" |
16 #include "dbus/property.h" | 17 #include "dbus/property.h" |
17 #include "dbus/values_util.h" | 18 #include "dbus/values_util.h" |
(...skipping 16 matching lines...) Expand all Loading... | |
34 UPOWER_DEVICE_TYPE_LINE_POWER = 1, | 35 UPOWER_DEVICE_TYPE_LINE_POWER = 1, |
35 UPOWER_DEVICE_TYPE_BATTERY = 2, | 36 UPOWER_DEVICE_TYPE_BATTERY = 2, |
36 UPOWER_DEVICE_TYPE_UPS = 3, | 37 UPOWER_DEVICE_TYPE_UPS = 3, |
37 UPOWER_DEVICE_TYPE_MONITOR = 4, | 38 UPOWER_DEVICE_TYPE_MONITOR = 4, |
38 UPOWER_DEVICE_TYPE_MOUSE = 5, | 39 UPOWER_DEVICE_TYPE_MOUSE = 5, |
39 UPOWER_DEVICE_TYPE_KEYBOARD = 6, | 40 UPOWER_DEVICE_TYPE_KEYBOARD = 6, |
40 UPOWER_DEVICE_TYPE_PDA = 7, | 41 UPOWER_DEVICE_TYPE_PDA = 7, |
41 UPOWER_DEVICE_TYPE_PHONE = 8, | 42 UPOWER_DEVICE_TYPE_PHONE = 8, |
42 }; | 43 }; |
43 | 44 |
45 // This enum is used for histogram. Don't change the order of the existing | |
46 // values. | |
47 enum NumberBatteriesType { | |
Michael van Ouwerkerk
2014/08/21 09:28:18
This seems kind of over-engineered. Can't we use a
timvolodine
2014/08/21 14:52:18
sure, the CUSTOM_COUNTS are a bit difficult to use
| |
48 NO_BATTERY = 0, | |
49 ONE_BATTERY = 1, | |
50 TWO_BATTERIES = 2, | |
51 THREE_BATTERIES = 3, | |
52 FOUR_BATTERIES = 4, | |
53 FIVE_OR_MORE_BATTERIES = 5, | |
54 NUMBER_BATTERIES_COUNT = 6, | |
55 }; | |
56 | |
44 typedef std::vector<dbus::ObjectPath> PathsVector; | 57 typedef std::vector<dbus::ObjectPath> PathsVector; |
45 | 58 |
46 double GetPropertyAsDouble(const base::DictionaryValue& dictionary, | 59 double GetPropertyAsDouble(const base::DictionaryValue& dictionary, |
47 const std::string& property_name, | 60 const std::string& property_name, |
48 double default_value) { | 61 double default_value) { |
49 double value = default_value; | 62 double value = default_value; |
50 return dictionary.GetDouble(property_name, &value) ? value : default_value; | 63 return dictionary.GetDouble(property_name, &value) ? value : default_value; |
51 } | 64 } |
52 | 65 |
53 bool GetPropertyAsBoolean(const base::DictionaryValue& dictionary, | 66 bool GetPropertyAsBoolean(const base::DictionaryValue& dictionary, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 proxy->CallMethodAndBlock(&method_call, | 102 proxy->CallMethodAndBlock(&method_call, |
90 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | 103 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
91 | 104 |
92 if (response) { | 105 if (response) { |
93 dbus::MessageReader reader(response.get()); | 106 dbus::MessageReader reader(response.get()); |
94 reader.PopArrayOfObjectPaths(paths.get()); | 107 reader.PopArrayOfObjectPaths(paths.get()); |
95 } | 108 } |
96 return paths.Pass();; | 109 return paths.Pass();; |
97 } | 110 } |
98 | 111 |
112 void UpdateNumberBatteriesHistogram(int count) { | |
113 UMA_HISTOGRAM_ENUMERATION( | |
114 "BatteryStatus.NumberBatteriesLinux", | |
115 count < NUMBER_BATTERIES_COUNT ? count : FIVE_OR_MORE_BATTERIES, | |
116 NUMBER_BATTERIES_COUNT); | |
117 } | |
118 | |
99 // Class that represents a dedicated thread which communicates with DBus to | 119 // Class that represents a dedicated thread which communicates with DBus to |
100 // obtain battery information and receives battery change notifications. | 120 // obtain battery information and receives battery change notifications. |
101 class BatteryStatusNotificationThread : public base::Thread { | 121 class BatteryStatusNotificationThread : public base::Thread { |
102 public: | 122 public: |
103 BatteryStatusNotificationThread( | 123 BatteryStatusNotificationThread( |
104 const BatteryStatusService::BatteryUpdateCallback& callback) | 124 const BatteryStatusService::BatteryUpdateCallback& callback) |
105 : base::Thread(kBatteryNotifierThreadName), | 125 : base::Thread(kBatteryNotifierThreadName), |
106 callback_(callback), | 126 callback_(callback), |
107 battery_proxy_(NULL) {} | 127 battery_proxy_(NULL) {} |
108 | 128 |
(...skipping 15 matching lines...) Expand all Loading... | |
124 DCHECK(OnWatcherThread()); | 144 DCHECK(OnWatcherThread()); |
125 | 145 |
126 if (system_bus_) | 146 if (system_bus_) |
127 return; | 147 return; |
128 | 148 |
129 InitDBus(); | 149 InitDBus(); |
130 dbus::ObjectProxy* power_proxy = | 150 dbus::ObjectProxy* power_proxy = |
131 system_bus_->GetObjectProxy(kUPowerServiceName, | 151 system_bus_->GetObjectProxy(kUPowerServiceName, |
132 dbus::ObjectPath(kUPowerPath)); | 152 dbus::ObjectPath(kUPowerPath)); |
133 scoped_ptr<PathsVector> device_paths = GetPowerSourcesPaths(power_proxy); | 153 scoped_ptr<PathsVector> device_paths = GetPowerSourcesPaths(power_proxy); |
154 int num_batteries = 0; | |
134 | 155 |
135 for (size_t i = 0; i < device_paths->size(); ++i) { | 156 for (size_t i = 0; i < device_paths->size(); ++i) { |
136 const dbus::ObjectPath& device_path = device_paths->at(i); | 157 const dbus::ObjectPath& device_path = device_paths->at(i); |
137 dbus::ObjectProxy* device_proxy = system_bus_->GetObjectProxy( | 158 dbus::ObjectProxy* device_proxy = system_bus_->GetObjectProxy( |
138 kUPowerServiceName, device_path); | 159 kUPowerServiceName, device_path); |
139 scoped_ptr<base::DictionaryValue> dictionary = | 160 scoped_ptr<base::DictionaryValue> dictionary = |
140 GetPropertiesAsDictionary(device_proxy); | 161 GetPropertiesAsDictionary(device_proxy); |
141 | 162 |
142 if (!dictionary) | 163 if (!dictionary) |
143 continue; | 164 continue; |
144 | 165 |
145 bool is_present = GetPropertyAsBoolean(*dictionary, "IsPresent", false); | 166 bool is_present = GetPropertyAsBoolean(*dictionary, "IsPresent", false); |
146 uint32 type = static_cast<uint32>( | 167 uint32 type = static_cast<uint32>( |
147 GetPropertyAsDouble(*dictionary, "Type", UPOWER_DEVICE_TYPE_UNKNOWN)); | 168 GetPropertyAsDouble(*dictionary, "Type", UPOWER_DEVICE_TYPE_UNKNOWN)); |
148 | 169 |
149 if (!is_present || type != UPOWER_DEVICE_TYPE_BATTERY) { | 170 if (!is_present || type != UPOWER_DEVICE_TYPE_BATTERY) { |
150 system_bus_->RemoveObjectProxy(kUPowerServiceName, | 171 system_bus_->RemoveObjectProxy(kUPowerServiceName, |
151 device_path, | 172 device_path, |
152 base::Bind(&base::DoNothing)); | 173 base::Bind(&base::DoNothing)); |
153 continue; | 174 continue; |
154 } | 175 } |
155 | 176 |
156 if (battery_proxy_) { | 177 if (battery_proxy_) { |
157 // TODO(timvolodine): add support for multiple batteries. Currently we | 178 // TODO(timvolodine): add support for multiple batteries. Currently we |
158 // only collect information from the first battery we encounter | 179 // only collect information from the first battery we encounter |
159 // (crbug.com/400780). | 180 // (crbug.com/400780). |
160 // TODO(timvolodine): add UMA logging for this case. | |
161 LOG(WARNING) << "multiple batteries found, " | 181 LOG(WARNING) << "multiple batteries found, " |
162 << "using status data of the first battery only."; | 182 << "using status data of the first battery only."; |
163 } else { | 183 } else { |
164 battery_proxy_ = device_proxy; | 184 battery_proxy_ = device_proxy; |
165 } | 185 } |
186 num_batteries++; | |
166 } | 187 } |
167 | 188 |
189 UpdateNumberBatteriesHistogram(num_batteries); | |
190 | |
168 if (!battery_proxy_) { | 191 if (!battery_proxy_) { |
169 callback_.Run(blink::WebBatteryStatus()); | 192 callback_.Run(blink::WebBatteryStatus()); |
170 return; | 193 return; |
171 } | 194 } |
172 | 195 |
173 battery_proxy_->ConnectToSignal( | 196 battery_proxy_->ConnectToSignal( |
174 kUPowerDeviceName, | 197 kUPowerDeviceName, |
175 kUPowerDeviceSignalChanged, | 198 kUPowerDeviceSignalChanged, |
176 base::Bind(&BatteryStatusNotificationThread::BatteryChanged, | 199 base::Bind(&BatteryStatusNotificationThread::BatteryChanged, |
177 base::Unretained(this)), | 200 base::Unretained(this)), |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
365 } | 388 } |
366 | 389 |
367 // static | 390 // static |
368 scoped_ptr<BatteryStatusManager> BatteryStatusManager::Create( | 391 scoped_ptr<BatteryStatusManager> BatteryStatusManager::Create( |
369 const BatteryStatusService::BatteryUpdateCallback& callback) { | 392 const BatteryStatusService::BatteryUpdateCallback& callback) { |
370 return scoped_ptr<BatteryStatusManager>( | 393 return scoped_ptr<BatteryStatusManager>( |
371 new BatteryStatusManagerLinux(callback)); | 394 new BatteryStatusManagerLinux(callback)); |
372 } | 395 } |
373 | 396 |
374 } // namespace content | 397 } // namespace content |
OLD | NEW |