| 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 """Provides a variety of device interactions based on adb. | 5 """Provides a variety of device interactions based on adb. |
| 6 | 6 |
| 7 Eventually, this will be based on adb_wrapper. | 7 Eventually, this will be based on adb_wrapper. |
| 8 """ | 8 """ |
| 9 # pylint: disable=unused-argument | 9 # pylint: disable=unused-argument |
| 10 | 10 |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 161 self.old_interface = pylib.android_commands.AndroidCommands(str(device)) | 161 self.old_interface = pylib.android_commands.AndroidCommands(str(device)) |
| 162 elif isinstance(device, pylib.android_commands.AndroidCommands): | 162 elif isinstance(device, pylib.android_commands.AndroidCommands): |
| 163 self.adb = adb_wrapper.AdbWrapper(device.GetDevice()) | 163 self.adb = adb_wrapper.AdbWrapper(device.GetDevice()) |
| 164 self.old_interface = device | 164 self.old_interface = device |
| 165 else: | 165 else: |
| 166 raise ValueError('Unsupported device value: %r' % device) | 166 raise ValueError('Unsupported device value: %r' % device) |
| 167 self._commands_installed = None | 167 self._commands_installed = None |
| 168 self._default_timeout = default_timeout | 168 self._default_timeout = default_timeout |
| 169 self._default_retries = default_retries | 169 self._default_retries = default_retries |
| 170 self._cache = {} | 170 self._cache = {} |
| 171 self._client_caches = {} |
| 171 assert hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR) | 172 assert hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR) |
| 172 assert hasattr(self, decorators.DEFAULT_RETRIES_ATTR) | 173 assert hasattr(self, decorators.DEFAULT_RETRIES_ATTR) |
| 173 | 174 |
| 174 def __str__(self): | 175 def __str__(self): |
| 175 """Returns the device serial.""" | 176 """Returns the device serial.""" |
| 176 return self.adb.GetDeviceSerial() | 177 return self.adb.GetDeviceSerial() |
| 177 | 178 |
| 178 @decorators.WithTimeoutAndRetriesFromInstance() | 179 @decorators.WithTimeoutAndRetriesFromInstance() |
| 179 def IsOnline(self, timeout=None, retries=None): | 180 def IsOnline(self, timeout=None, retries=None): |
| 180 """Checks whether the device is online. | 181 """Checks whether the device is online. |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 retries: number of retries | 400 retries: number of retries |
| 400 | 401 |
| 401 Raises: | 402 Raises: |
| 402 CommandTimeoutError on timeout. | 403 CommandTimeoutError on timeout. |
| 403 DeviceUnreachableError on missing device. | 404 DeviceUnreachableError on missing device. |
| 404 """ | 405 """ |
| 405 def device_offline(): | 406 def device_offline(): |
| 406 return not self.IsOnline() | 407 return not self.IsOnline() |
| 407 | 408 |
| 408 self.adb.Reboot() | 409 self.adb.Reboot() |
| 409 self._cache = {} | 410 self._ClearCache() |
| 410 timeout_retry.WaitFor(device_offline, wait_period=1) | 411 timeout_retry.WaitFor(device_offline, wait_period=1) |
| 411 if block: | 412 if block: |
| 412 self.WaitUntilFullyBooted(wifi=wifi) | 413 self.WaitUntilFullyBooted(wifi=wifi) |
| 413 | 414 |
| 414 INSTALL_DEFAULT_TIMEOUT = 4 * _DEFAULT_TIMEOUT | 415 INSTALL_DEFAULT_TIMEOUT = 4 * _DEFAULT_TIMEOUT |
| 415 INSTALL_DEFAULT_RETRIES = _DEFAULT_RETRIES | 416 INSTALL_DEFAULT_RETRIES = _DEFAULT_RETRIES |
| 416 | 417 |
| 417 @decorators.WithTimeoutAndRetriesDefaults( | 418 @decorators.WithTimeoutAndRetriesDefaults( |
| 418 INSTALL_DEFAULT_TIMEOUT, | 419 INSTALL_DEFAULT_TIMEOUT, |
| 419 INSTALL_DEFAULT_RETRIES) | 420 INSTALL_DEFAULT_RETRIES) |
| (...skipping 1011 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1431 | 1432 |
| 1432 Parameters passed to this function are passed directly to | 1433 Parameters passed to this function are passed directly to |
| 1433 |logcat_monitor.LogcatMonitor| and are documented there. | 1434 |logcat_monitor.LogcatMonitor| and are documented there. |
| 1434 | 1435 |
| 1435 Args: | 1436 Args: |
| 1436 timeout: timeout in seconds | 1437 timeout: timeout in seconds |
| 1437 retries: number of retries | 1438 retries: number of retries |
| 1438 """ | 1439 """ |
| 1439 return logcat_monitor.LogcatMonitor(self.adb, *args, **kwargs) | 1440 return logcat_monitor.LogcatMonitor(self.adb, *args, **kwargs) |
| 1440 | 1441 |
| 1442 # TODO(rnephew): Remove when battery_utils is switched to. |
| 1441 @decorators.WithTimeoutAndRetriesFromInstance() | 1443 @decorators.WithTimeoutAndRetriesFromInstance() |
| 1442 def GetBatteryInfo(self, timeout=None, retries=None): | 1444 def GetBatteryInfo(self, timeout=None, retries=None): |
| 1443 """Gets battery info for the device. | 1445 """Gets battery info for the device. |
| 1444 | 1446 |
| 1445 Args: | 1447 Args: |
| 1446 timeout: timeout in seconds | 1448 timeout: timeout in seconds |
| 1447 retries: number of retries | 1449 retries: number of retries |
| 1448 Returns: | 1450 Returns: |
| 1449 A dict containing various battery information as reported by dumpsys | 1451 A dict containing various battery information as reported by dumpsys |
| 1450 battery. | 1452 battery. |
| 1451 """ | 1453 """ |
| 1452 result = {} | 1454 result = {} |
| 1453 # Skip the first line, which is just a header. | 1455 # Skip the first line, which is just a header. |
| 1454 for line in self.RunShellCommand( | 1456 for line in self.RunShellCommand( |
| 1455 ['dumpsys', 'battery'], check_return=True)[1:]: | 1457 ['dumpsys', 'battery'], check_return=True)[1:]: |
| 1456 # If usb charging has been disabled, an extra line of header exists. | 1458 # If usb charging has been disabled, an extra line of header exists. |
| 1457 if 'UPDATES STOPPED' in line: | 1459 if 'UPDATES STOPPED' in line: |
| 1458 logging.warning('Dumpsys battery not receiving updates. ' | 1460 logging.warning('Dumpsys battery not receiving updates. ' |
| 1459 'Run dumpsys battery reset if this is in error.') | 1461 'Run dumpsys battery reset if this is in error.') |
| 1460 elif ':' not in line: | 1462 elif ':' not in line: |
| 1461 logging.warning('Unknown line found in dumpsys battery.') | 1463 logging.warning('Unknown line found in dumpsys battery.') |
| 1462 logging.warning(line) | 1464 logging.warning(line) |
| 1463 else: | 1465 else: |
| 1464 k, v = line.split(': ', 1) | 1466 k, v = line.split(': ', 1) |
| 1465 result[k.strip()] = v.strip() | 1467 result[k.strip()] = v.strip() |
| 1466 return result | 1468 return result |
| 1467 | 1469 |
| 1470 # TODO(rnephew): Remove when battery_utils is switched to. |
| 1468 @decorators.WithTimeoutAndRetriesFromInstance() | 1471 @decorators.WithTimeoutAndRetriesFromInstance() |
| 1469 def GetCharging(self, timeout=None, retries=None): | 1472 def GetCharging(self, timeout=None, retries=None): |
| 1470 """Gets the charging state of the device. | 1473 """Gets the charging state of the device. |
| 1471 | 1474 |
| 1472 Args: | 1475 Args: |
| 1473 timeout: timeout in seconds | 1476 timeout: timeout in seconds |
| 1474 retries: number of retries | 1477 retries: number of retries |
| 1475 Returns: | 1478 Returns: |
| 1476 True if the device is charging, false otherwise. | 1479 True if the device is charging, false otherwise. |
| 1477 """ | 1480 """ |
| 1478 battery_info = self.GetBatteryInfo() | 1481 battery_info = self.GetBatteryInfo() |
| 1479 for k in ('AC powered', 'USB powered', 'Wireless powered'): | 1482 for k in ('AC powered', 'USB powered', 'Wireless powered'): |
| 1480 if (k in battery_info and | 1483 if (k in battery_info and |
| 1481 battery_info[k].lower() in ('true', '1', 'yes')): | 1484 battery_info[k].lower() in ('true', '1', 'yes')): |
| 1482 return True | 1485 return True |
| 1483 return False | 1486 return False |
| 1484 | 1487 |
| 1488 # TODO(rnephew): Remove when battery_utils is switched to. |
| 1485 @decorators.WithTimeoutAndRetriesFromInstance() | 1489 @decorators.WithTimeoutAndRetriesFromInstance() |
| 1486 def SetCharging(self, enabled, timeout=None, retries=None): | 1490 def SetCharging(self, enabled, timeout=None, retries=None): |
| 1487 """Enables or disables charging on the device. | 1491 """Enables or disables charging on the device. |
| 1488 | 1492 |
| 1489 Args: | 1493 Args: |
| 1490 enabled: A boolean indicating whether charging should be enabled or | 1494 enabled: A boolean indicating whether charging should be enabled or |
| 1491 disabled. | 1495 disabled. |
| 1492 timeout: timeout in seconds | 1496 timeout: timeout in seconds |
| 1493 retries: number of retries | 1497 retries: number of retries |
| 1494 """ | 1498 """ |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1505 command = self._cache['charging_config']['enable_command'] | 1509 command = self._cache['charging_config']['enable_command'] |
| 1506 else: | 1510 else: |
| 1507 command = self._cache['charging_config']['disable_command'] | 1511 command = self._cache['charging_config']['disable_command'] |
| 1508 | 1512 |
| 1509 def set_and_verify_charging(): | 1513 def set_and_verify_charging(): |
| 1510 self.RunShellCommand(command, check_return=True) | 1514 self.RunShellCommand(command, check_return=True) |
| 1511 return self.GetCharging() == enabled | 1515 return self.GetCharging() == enabled |
| 1512 | 1516 |
| 1513 timeout_retry.WaitFor(set_and_verify_charging, wait_period=1) | 1517 timeout_retry.WaitFor(set_and_verify_charging, wait_period=1) |
| 1514 | 1518 |
| 1515 # TODO(rnephew): Make private when all use cases can use the context manager. | 1519 # TODO(rnephew): Remove when battery_utils is switched to. |
| 1516 @decorators.WithTimeoutAndRetriesFromInstance() | 1520 @decorators.WithTimeoutAndRetriesFromInstance() |
| 1517 def DisableBatteryUpdates(self, timeout=None, retries=None): | 1521 def DisableBatteryUpdates(self, timeout=None, retries=None): |
| 1518 """ Resets battery data and makes device appear like it is not | 1522 """ Resets battery data and makes device appear like it is not |
| 1519 charging so that it will collect power data since last charge. | 1523 charging so that it will collect power data since last charge. |
| 1520 | 1524 |
| 1521 Args: | 1525 Args: |
| 1522 timeout: timeout in seconds | 1526 timeout: timeout in seconds |
| 1523 retries: number of retries | 1527 retries: number of retries |
| 1524 """ | 1528 """ |
| 1525 def battery_updates_disabled(): | 1529 def battery_updates_disabled(): |
| 1526 return self.GetCharging() is False | 1530 return self.GetCharging() is False |
| 1527 | 1531 |
| 1528 self.RunShellCommand( | 1532 self.RunShellCommand( |
| 1529 ['dumpsys', 'batterystats', '--reset'], check_return=True) | 1533 ['dumpsys', 'batterystats', '--reset'], check_return=True) |
| 1530 battery_data = self.RunShellCommand( | 1534 battery_data = self.RunShellCommand( |
| 1531 ['dumpsys', 'batterystats', '--charged', '--checkin'], | 1535 ['dumpsys', 'batterystats', '--charged', '--checkin'], |
| 1532 check_return=True) | 1536 check_return=True) |
| 1533 ROW_TYPE_INDEX = 3 | 1537 ROW_TYPE_INDEX = 3 |
| 1534 PWI_POWER_INDEX = 5 | 1538 PWI_POWER_INDEX = 5 |
| 1535 for line in battery_data: | 1539 for line in battery_data: |
| 1536 l = line.split(',') | 1540 l = line.split(',') |
| 1537 if (len(l) > PWI_POWER_INDEX and l[ROW_TYPE_INDEX] == 'pwi' | 1541 if (len(l) > PWI_POWER_INDEX and l[ROW_TYPE_INDEX] == 'pwi' |
| 1538 and l[PWI_POWER_INDEX] != 0): | 1542 and l[PWI_POWER_INDEX] != 0): |
| 1539 raise device_errors.CommandFailedError( | 1543 raise device_errors.CommandFailedError( |
| 1540 'Non-zero pmi value found after reset.') | 1544 'Non-zero pmi value found after reset.') |
| 1541 self.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '0'], | 1545 self.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '0'], |
| 1542 check_return=True) | 1546 check_return=True) |
| 1543 timeout_retry.WaitFor(battery_updates_disabled, wait_period=1) | 1547 timeout_retry.WaitFor(battery_updates_disabled, wait_period=1) |
| 1544 | 1548 |
| 1545 # TODO(rnephew): Make private when all use cases can use the context manager. | 1549 # TODO(rnephew): Remove when battery_utils is switched to. |
| 1546 @decorators.WithTimeoutAndRetriesFromInstance() | 1550 @decorators.WithTimeoutAndRetriesFromInstance() |
| 1547 def EnableBatteryUpdates(self, timeout=None, retries=None): | 1551 def EnableBatteryUpdates(self, timeout=None, retries=None): |
| 1548 """ Restarts device charging so that dumpsys no longer collects power data. | 1552 """ Restarts device charging so that dumpsys no longer collects power data. |
| 1549 | 1553 |
| 1550 Args: | 1554 Args: |
| 1551 timeout: timeout in seconds | 1555 timeout: timeout in seconds |
| 1552 retries: number of retries | 1556 retries: number of retries |
| 1553 """ | 1557 """ |
| 1554 def battery_updates_enabled(): | 1558 def battery_updates_enabled(): |
| 1555 return self.GetCharging() is True | 1559 return self.GetCharging() is True |
| 1556 | 1560 |
| 1557 self.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '1'], | 1561 self.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '1'], |
| 1558 check_return=True) | 1562 check_return=True) |
| 1559 self.RunShellCommand(['dumpsys', 'battery', 'reset'], check_return=True) | 1563 self.RunShellCommand(['dumpsys', 'battery', 'reset'], check_return=True) |
| 1560 timeout_retry.WaitFor(battery_updates_enabled, wait_period=1) | 1564 timeout_retry.WaitFor(battery_updates_enabled, wait_period=1) |
| 1561 | 1565 |
| 1566 # TODO(rnephew): Remove when battery_utils is switched to. |
| 1562 @contextlib.contextmanager | 1567 @contextlib.contextmanager |
| 1563 def BatteryMeasurement(self, timeout=None, retries=None): | 1568 def BatteryMeasurement(self, timeout=None, retries=None): |
| 1564 """Context manager that enables battery data collection. It makes | 1569 """Context manager that enables battery data collection. It makes |
| 1565 the device appear to stop charging so that dumpsys will start collecting | 1570 the device appear to stop charging so that dumpsys will start collecting |
| 1566 power data since last charge. Once the with block is exited, charging is | 1571 power data since last charge. Once the with block is exited, charging is |
| 1567 resumed and power data since last charge is no longer collected. | 1572 resumed and power data since last charge is no longer collected. |
| 1568 | 1573 |
| 1569 Only for devices L and higher. | 1574 Only for devices L and higher. |
| 1570 | 1575 |
| 1571 Example usage: | 1576 Example usage: |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1641 """ | 1646 """ |
| 1642 if not devices: | 1647 if not devices: |
| 1643 devices = adb_wrapper.AdbWrapper.GetDevices() | 1648 devices = adb_wrapper.AdbWrapper.GetDevices() |
| 1644 if not devices: | 1649 if not devices: |
| 1645 raise device_errors.NoDevicesError() | 1650 raise device_errors.NoDevicesError() |
| 1646 devices = [d if isinstance(d, cls) else cls(d) for d in devices] | 1651 devices = [d if isinstance(d, cls) else cls(d) for d in devices] |
| 1647 if async: | 1652 if async: |
| 1648 return parallelizer.Parallelizer(devices) | 1653 return parallelizer.Parallelizer(devices) |
| 1649 else: | 1654 else: |
| 1650 return parallelizer.SyncParallelizer(devices) | 1655 return parallelizer.SyncParallelizer(devices) |
| 1656 |
| 1657 def GetClientCache(self, client_name): |
| 1658 """Returns client cache.""" |
| 1659 if client_name not in self._client_caches: |
| 1660 self._client_caches[client_name] = {} |
| 1661 return self._client_caches[client_name] |
| 1662 |
| 1663 def _ClearCache(self): |
| 1664 """Clears all caches.""" |
| 1665 for client in self._client_caches: |
| 1666 self._client_caches[client].clear() |
| 1667 self._cache.clear() |
| OLD | NEW |