| 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 1421 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1432  |  1432  | 
|  1433     Parameters passed to this function are passed directly to |  1433     Parameters passed to this function are passed directly to | 
|  1434     |logcat_monitor.LogcatMonitor| and are documented there. |  1434     |logcat_monitor.LogcatMonitor| and are documented there. | 
|  1435  |  1435  | 
|  1436     Args: |  1436     Args: | 
|  1437       timeout: timeout in seconds |  1437       timeout: timeout in seconds | 
|  1438       retries: number of retries |  1438       retries: number of retries | 
|  1439     """ |  1439     """ | 
|  1440     return logcat_monitor.LogcatMonitor(self.adb, *args, **kwargs) |  1440     return logcat_monitor.LogcatMonitor(self.adb, *args, **kwargs) | 
|  1441  |  1441  | 
|  1442   # TODO(rnephew): Remove when battery_utils is switched to. |  | 
|  1443   @decorators.WithTimeoutAndRetriesFromInstance() |  | 
|  1444   def GetBatteryInfo(self, timeout=None, retries=None): |  | 
|  1445     """Gets battery info for the device. |  | 
|  1446  |  | 
|  1447     Args: |  | 
|  1448       timeout: timeout in seconds |  | 
|  1449       retries: number of retries |  | 
|  1450     Returns: |  | 
|  1451       A dict containing various battery information as reported by dumpsys |  | 
|  1452       battery. |  | 
|  1453     """ |  | 
|  1454     result = {} |  | 
|  1455     # Skip the first line, which is just a header. |  | 
|  1456     for line in self.RunShellCommand( |  | 
|  1457         ['dumpsys', 'battery'], check_return=True)[1:]: |  | 
|  1458       # If usb charging has been disabled, an extra line of header exists. |  | 
|  1459       if 'UPDATES STOPPED' in line: |  | 
|  1460         logging.warning('Dumpsys battery not receiving updates. ' |  | 
|  1461                         'Run dumpsys battery reset if this is in error.') |  | 
|  1462       elif ':' not in line: |  | 
|  1463         logging.warning('Unknown line found in dumpsys battery.') |  | 
|  1464         logging.warning(line) |  | 
|  1465       else: |  | 
|  1466         k, v = line.split(': ', 1) |  | 
|  1467         result[k.strip()] = v.strip() |  | 
|  1468     return result |  | 
|  1469  |  | 
|  1470   # TODO(rnephew): Remove when battery_utils is switched to. |  | 
|  1471   @decorators.WithTimeoutAndRetriesFromInstance() |  | 
|  1472   def GetCharging(self, timeout=None, retries=None): |  | 
|  1473     """Gets the charging state of the device. |  | 
|  1474  |  | 
|  1475     Args: |  | 
|  1476       timeout: timeout in seconds |  | 
|  1477       retries: number of retries |  | 
|  1478     Returns: |  | 
|  1479       True if the device is charging, false otherwise. |  | 
|  1480     """ |  | 
|  1481     battery_info = self.GetBatteryInfo() |  | 
|  1482     for k in ('AC powered', 'USB powered', 'Wireless powered'): |  | 
|  1483       if (k in battery_info and |  | 
|  1484           battery_info[k].lower() in ('true', '1', 'yes')): |  | 
|  1485         return True |  | 
|  1486     return False |  | 
|  1487  |  | 
|  1488   # TODO(rnephew): Remove when battery_utils is switched to. |  | 
|  1489   @decorators.WithTimeoutAndRetriesFromInstance() |  | 
|  1490   def SetCharging(self, enabled, timeout=None, retries=None): |  | 
|  1491     """Enables or disables charging on the device. |  | 
|  1492  |  | 
|  1493     Args: |  | 
|  1494       enabled: A boolean indicating whether charging should be enabled or |  | 
|  1495         disabled. |  | 
|  1496       timeout: timeout in seconds |  | 
|  1497       retries: number of retries |  | 
|  1498     """ |  | 
|  1499     if 'charging_config' not in self._cache: |  | 
|  1500       for c in _CONTROL_CHARGING_COMMANDS: |  | 
|  1501         if self.FileExists(c['witness_file']): |  | 
|  1502           self._cache['charging_config'] = c |  | 
|  1503           break |  | 
|  1504       else: |  | 
|  1505         raise device_errors.CommandFailedError( |  | 
|  1506             'Unable to find charging commands.') |  | 
|  1507  |  | 
|  1508     if enabled: |  | 
|  1509       command = self._cache['charging_config']['enable_command'] |  | 
|  1510     else: |  | 
|  1511       command = self._cache['charging_config']['disable_command'] |  | 
|  1512  |  | 
|  1513     def set_and_verify_charging(): |  | 
|  1514       self.RunShellCommand(command, check_return=True) |  | 
|  1515       return self.GetCharging() == enabled |  | 
|  1516  |  | 
|  1517     timeout_retry.WaitFor(set_and_verify_charging, wait_period=1) |  | 
|  1518  |  | 
|  1519   # TODO(rnephew): Remove when battery_utils is switched to. |  | 
|  1520   @decorators.WithTimeoutAndRetriesFromInstance() |  | 
|  1521   def DisableBatteryUpdates(self, timeout=None, retries=None): |  | 
|  1522     """ Resets battery data and makes device appear like it is not |  | 
|  1523     charging so that it will collect power data since last charge. |  | 
|  1524  |  | 
|  1525     Args: |  | 
|  1526       timeout: timeout in seconds |  | 
|  1527       retries: number of retries |  | 
|  1528     """ |  | 
|  1529     def battery_updates_disabled(): |  | 
|  1530       return self.GetCharging() is False |  | 
|  1531  |  | 
|  1532     self.RunShellCommand( |  | 
|  1533         ['dumpsys', 'batterystats', '--reset'], check_return=True) |  | 
|  1534     battery_data = self.RunShellCommand( |  | 
|  1535         ['dumpsys', 'batterystats', '--charged', '--checkin'], |  | 
|  1536         check_return=True) |  | 
|  1537     ROW_TYPE_INDEX = 3 |  | 
|  1538     PWI_POWER_INDEX = 5 |  | 
|  1539     for line in battery_data: |  | 
|  1540       l = line.split(',') |  | 
|  1541       if (len(l) > PWI_POWER_INDEX and l[ROW_TYPE_INDEX] == 'pwi' |  | 
|  1542           and l[PWI_POWER_INDEX] != 0): |  | 
|  1543         raise device_errors.CommandFailedError( |  | 
|  1544             'Non-zero pmi value found after reset.') |  | 
|  1545     self.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '0'], |  | 
|  1546                          check_return=True) |  | 
|  1547     timeout_retry.WaitFor(battery_updates_disabled, wait_period=1) |  | 
|  1548  |  | 
|  1549   # TODO(rnephew): Remove when battery_utils is switched to. |  | 
|  1550   @decorators.WithTimeoutAndRetriesFromInstance() |  | 
|  1551   def EnableBatteryUpdates(self, timeout=None, retries=None): |  | 
|  1552     """ Restarts device charging so that dumpsys no longer collects power data. |  | 
|  1553  |  | 
|  1554     Args: |  | 
|  1555       timeout: timeout in seconds |  | 
|  1556       retries: number of retries |  | 
|  1557     """ |  | 
|  1558     def battery_updates_enabled(): |  | 
|  1559       return self.GetCharging() is True |  | 
|  1560  |  | 
|  1561     self.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '1'], |  | 
|  1562                          check_return=True) |  | 
|  1563     self.RunShellCommand(['dumpsys', 'battery', 'reset'], check_return=True) |  | 
|  1564     timeout_retry.WaitFor(battery_updates_enabled, wait_period=1) |  | 
|  1565  |  | 
|  1566   # TODO(rnephew): Remove when battery_utils is switched to. |  | 
|  1567   @contextlib.contextmanager |  | 
|  1568   def BatteryMeasurement(self, timeout=None, retries=None): |  | 
|  1569     """Context manager that enables battery data collection. It makes |  | 
|  1570     the device appear to stop charging so that dumpsys will start collecting |  | 
|  1571     power data since last charge. Once the with block is exited, charging is |  | 
|  1572     resumed and power data since last charge is no longer collected. |  | 
|  1573  |  | 
|  1574     Only for devices L and higher. |  | 
|  1575  |  | 
|  1576     Example usage: |  | 
|  1577       with BatteryMeasurement(): |  | 
|  1578         browser_actions() |  | 
|  1579         get_power_data() # report usage within this block |  | 
|  1580       after_measurements() # Anything that runs after power |  | 
|  1581                            # measurements are collected |  | 
|  1582  |  | 
|  1583     Args: |  | 
|  1584       timeout: timeout in seconds |  | 
|  1585       retries: number of retries |  | 
|  1586     """ |  | 
|  1587     if self.build_version_sdk < constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP: |  | 
|  1588       raise device_errors.CommandFailedError('Device must be L or higher.') |  | 
|  1589     try: |  | 
|  1590       self.DisableBatteryUpdates(timeout=timeout, retries=retries) |  | 
|  1591       yield |  | 
|  1592     finally: |  | 
|  1593       self.EnableBatteryUpdates(timeout=timeout, retries=retries) |  | 
|  1594  |  | 
|  1595   @decorators.WithTimeoutAndRetriesFromInstance() |  1442   @decorators.WithTimeoutAndRetriesFromInstance() | 
|  1596   def GetDevicePieWrapper(self, timeout=None, retries=None): |  1443   def GetDevicePieWrapper(self, timeout=None, retries=None): | 
|  1597     """Gets the absolute path to the run_pie wrapper on the device. |  1444     """Gets the absolute path to the run_pie wrapper on the device. | 
|  1598  |  1445  | 
|  1599     We have to build our device executables to be PIE, but they need to be able |  1446     We have to build our device executables to be PIE, but they need to be able | 
|  1600     to run on versions of android that don't support PIE (i.e. ICS and below). |  1447     to run on versions of android that don't support PIE (i.e. ICS and below). | 
|  1601     To do so, we push a wrapper to the device that lets older android versions |  1448     To do so, we push a wrapper to the device that lets older android versions | 
|  1602     run PIE executables. This method pushes that wrapper to the device if |  1449     run PIE executables. This method pushes that wrapper to the device if | 
|  1603     necessary and returns the path to it. |  1450     necessary and returns the path to it. | 
|  1604  |  1451  | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1658     """Returns client cache.""" |  1505     """Returns client cache.""" | 
|  1659     if client_name not in self._client_caches: |  1506     if client_name not in self._client_caches: | 
|  1660       self._client_caches[client_name] = {} |  1507       self._client_caches[client_name] = {} | 
|  1661     return self._client_caches[client_name] |  1508     return self._client_caches[client_name] | 
|  1662  |  1509  | 
|  1663   def _ClearCache(self): |  1510   def _ClearCache(self): | 
|  1664     """Clears all caches.""" |  1511     """Clears all caches.""" | 
|  1665     for client in self._client_caches: |  1512     for client in self._client_caches: | 
|  1666       self._client_caches[client].clear() |  1513       self._client_caches[client].clear() | 
|  1667     self._cache.clear() |  1514     self._cache.clear() | 
| OLD | NEW |