OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 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 """Provides a variety of device interactions with power. | 5 """Provides a variety of device interactions with power. |
6 """ | 6 """ |
7 # pylint: disable=unused-argument | 7 # pylint: disable=unused-argument |
8 | 8 |
9 import collections | 9 import collections |
10 import contextlib | 10 import contextlib |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 returns: | 140 returns: |
141 Dict of UID and power data. | 141 Dict of UID and power data. |
142 { | 142 { |
143 'uid': uid, | 143 'uid': uid, |
144 'data': [1,2,3] | 144 'data': [1,2,3] |
145 } | 145 } |
146 None if the package is not found in the power data. | 146 None if the package is not found in the power data. |
147 """ | 147 """ |
148 return self.GetPowerData().get(package) | 148 return self.GetPowerData().get(package) |
149 | 149 |
150 # TODO(rnephew): Move implementation from device_utils when this is used. | |
151 def GetBatteryInfo(self, timeout=None, retries=None): | 150 def GetBatteryInfo(self, timeout=None, retries=None): |
152 """Gets battery info for the device. | 151 """Gets battery info for the device. |
153 | 152 |
154 Args: | 153 Args: |
155 timeout: timeout in seconds | 154 timeout: timeout in seconds |
156 retries: number of retries | 155 retries: number of retries |
157 Returns: | 156 Returns: |
158 A dict containing various battery information as reported by dumpsys | 157 A dict containing various battery information as reported by dumpsys |
159 battery. | 158 battery. |
160 """ | 159 """ |
161 return self._device.GetBatteryInfo(timeout=None, retries=None) | 160 result = {} |
| 161 # Skip the first line, which is just a header. |
| 162 for line in self._device.RunShellCommand( |
| 163 ['dumpsys', 'battery'], check_return=True)[1:]: |
| 164 # If usb charging has been disabled, an extra line of header exists. |
| 165 if 'UPDATES STOPPED' in line: |
| 166 logging.warning('Dumpsys battery not receiving updates. ' |
| 167 'Run dumpsys battery reset if this is in error.') |
| 168 elif ':' not in line: |
| 169 logging.warning('Unknown line found in dumpsys battery: "%s"', line) |
| 170 else: |
| 171 k, v = line.split(':', 1) |
| 172 result[k.strip()] = v.strip() |
| 173 return result |
162 | 174 |
163 # TODO(rnephew): Move implementation from device_utils when this is used. | |
164 def GetCharging(self, timeout=None, retries=None): | 175 def GetCharging(self, timeout=None, retries=None): |
165 """Gets the charging state of the device. | 176 """Gets the charging state of the device. |
166 | 177 |
167 Args: | 178 Args: |
168 timeout: timeout in seconds | 179 timeout: timeout in seconds |
169 retries: number of retries | 180 retries: number of retries |
170 Returns: | 181 Returns: |
171 True if the device is charging, false otherwise. | 182 True if the device is charging, false otherwise. |
172 """ | 183 """ |
173 return self._device.GetCharging(timeout=None, retries=None) | 184 battery_info = self.GetBatteryInfo() |
| 185 for k in ('AC powered', 'USB powered', 'Wireless powered'): |
| 186 if (k in battery_info and |
| 187 battery_info[k].lower() in ('true', '1', 'yes')): |
| 188 return True |
| 189 return False |
174 | 190 |
175 # TODO(rnephew): Move implementation from device_utils when this is used. | |
176 def SetCharging(self, enabled, timeout=None, retries=None): | 191 def SetCharging(self, enabled, timeout=None, retries=None): |
177 """Enables or disables charging on the device. | 192 """Enables or disables charging on the device. |
178 | 193 |
179 Args: | 194 Args: |
180 enabled: A boolean indicating whether charging should be enabled or | 195 enabled: A boolean indicating whether charging should be enabled or |
181 disabled. | 196 disabled. |
182 timeout: timeout in seconds | 197 timeout: timeout in seconds |
183 retries: number of retries | 198 retries: number of retries |
184 | 199 |
185 Raises: | 200 Raises: |
186 device_errors.CommandFailedError: If method of disabling charging cannot | 201 device_errors.CommandFailedError: If method of disabling charging cannot |
187 be determined. | 202 be determined. |
188 """ | 203 """ |
189 self._device.SetCharging(enabled, timeout=None, retries=None) | 204 if 'charging_config' not in self._cache: |
| 205 for c in _CONTROL_CHARGING_COMMANDS: |
| 206 if self._device.FileExists(c['witness_file']): |
| 207 self._cache['charging_config'] = c |
| 208 break |
| 209 else: |
| 210 raise device_errors.CommandFailedError( |
| 211 'Unable to find charging commands.') |
190 | 212 |
191 # TODO(rnephew): Move implementation from device_utils when this is used. | 213 if enabled: |
| 214 command = self._cache['charging_config']['enable_command'] |
| 215 else: |
| 216 command = self._cache['charging_config']['disable_command'] |
| 217 |
| 218 def set_and_verify_charging(): |
| 219 self._device.RunShellCommand(command, check_return=True) |
| 220 return self.GetCharging() == enabled |
| 221 |
| 222 timeout_retry.WaitFor(set_and_verify_charging, wait_period=1) |
| 223 |
192 # TODO(rnephew): Make private when all use cases can use the context manager. | 224 # TODO(rnephew): Make private when all use cases can use the context manager. |
193 def DisableBatteryUpdates(self, timeout=None, retries=None): | 225 def DisableBatteryUpdates(self, timeout=None, retries=None): |
194 """ Resets battery data and makes device appear like it is not | 226 """ Resets battery data and makes device appear like it is not |
195 charging so that it will collect power data since last charge. | 227 charging so that it will collect power data since last charge. |
196 | 228 |
197 Args: | 229 Args: |
198 timeout: timeout in seconds | 230 timeout: timeout in seconds |
199 retries: number of retries | 231 retries: number of retries |
200 | 232 |
201 Raises: | 233 Raises: |
202 device_errors.CommandFailedError: When resetting batterystats fails to | 234 device_errors.CommandFailedError: When resetting batterystats fails to |
203 reset power values. | 235 reset power values. |
204 """ | 236 """ |
205 self._device.DisableBatteryUpdates(timeout=None, retries=None) | 237 def battery_updates_disabled(): |
| 238 return self.GetCharging() is False |
206 | 239 |
207 # TODO(rnephew): Move implementation from device_utils when this is used. | 240 self._device.RunShellCommand( |
| 241 ['dumpsys', 'battery', 'set', 'usb', '1'], check_return=True) |
| 242 self._device.RunShellCommand( |
| 243 ['dumpsys', 'batterystats', '--reset'], check_return=True) |
| 244 battery_data = self._device.RunShellCommand( |
| 245 ['dumpsys', 'batterystats', '--charged', '--checkin'], |
| 246 check_return=True) |
| 247 ROW_TYPE_INDEX = 3 |
| 248 PWI_POWER_INDEX = 5 |
| 249 for line in battery_data: |
| 250 l = line.split(',') |
| 251 if (len(l) > PWI_POWER_INDEX and l[ROW_TYPE_INDEX] == 'pwi' |
| 252 and l[PWI_POWER_INDEX] != 0): |
| 253 raise device_errors.CommandFailedError( |
| 254 'Non-zero pmi value found after reset.') |
| 255 self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '0'], |
| 256 check_return=True) |
| 257 timeout_retry.WaitFor(battery_updates_disabled, wait_period=1) |
| 258 |
208 # TODO(rnephew): Make private when all use cases can use the context manager. | 259 # TODO(rnephew): Make private when all use cases can use the context manager. |
209 def EnableBatteryUpdates(self, timeout=None, retries=None): | 260 def EnableBatteryUpdates(self, timeout=None, retries=None): |
210 """ Restarts device charging so that dumpsys no longer collects power data. | 261 """ Restarts device charging so that dumpsys no longer collects power data. |
211 | 262 |
212 Args: | 263 Args: |
213 timeout: timeout in seconds | 264 timeout: timeout in seconds |
214 retries: number of retries | 265 retries: number of retries |
215 """ | 266 """ |
216 self._device.EnableBatteryUpdates(timeout=None, retries=None) | 267 def battery_updates_enabled(): |
| 268 return self.GetCharging() is True |
| 269 |
| 270 self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '1'], |
| 271 check_return=True) |
| 272 self._device.RunShellCommand(['dumpsys', 'battery', 'reset'], |
| 273 check_return=True) |
| 274 timeout_retry.WaitFor(battery_updates_enabled, wait_period=1) |
217 | 275 |
218 @contextlib.contextmanager | 276 @contextlib.contextmanager |
219 def BatteryMeasurement(self, timeout=None, retries=None): | 277 def BatteryMeasurement(self, timeout=None, retries=None): |
220 """Context manager that enables battery data collection. It makes | 278 """Context manager that enables battery data collection. It makes |
221 the device appear to stop charging so that dumpsys will start collecting | 279 the device appear to stop charging so that dumpsys will start collecting |
222 power data since last charge. Once the with block is exited, charging is | 280 power data since last charge. Once the with block is exited, charging is |
223 resumed and power data since last charge is no longer collected. | 281 resumed and power data since last charge is no longer collected. |
224 | 282 |
225 Only for devices L and higher. | 283 Only for devices L and higher. |
226 | 284 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 battery_level = self.GetBatteryInfo().get('level') | 318 battery_level = self.GetBatteryInfo().get('level') |
261 if battery_level is None: | 319 if battery_level is None: |
262 logging.warning('Unable to find current battery level.') | 320 logging.warning('Unable to find current battery level.') |
263 battery_level = 100 | 321 battery_level = 100 |
264 else: | 322 else: |
265 logging.info('current battery level: %s', battery_level) | 323 logging.info('current battery level: %s', battery_level) |
266 battery_level = int(battery_level) | 324 battery_level = int(battery_level) |
267 return battery_level >= level | 325 return battery_level >= level |
268 | 326 |
269 timeout_retry.WaitFor(device_charged, wait_period=wait_period) | 327 timeout_retry.WaitFor(device_charged, wait_period=wait_period) |
OLD | NEW |