[Android] Convert battery utilities to DeviceUtils.
BUG=459712 Review URL: https://codereview.chromium.org/945883003 Cr-Original-Commit-Position: refs/heads/master@{#317843} Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src Cr-Mirrored-Commit: d3f50b0218788376ec29400561e5731754ce1020
This commit is contained in:
Родитель
08721af283
Коммит
3ca7cb2951
|
@ -25,6 +25,7 @@ from pylib.device import device_blacklist
|
|||
from pylib.device import device_errors
|
||||
from pylib.device import device_utils
|
||||
from pylib.utils import run_tests_helper
|
||||
from pylib.utils import timeout_retry
|
||||
|
||||
sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT,
|
||||
'third_party', 'android_testrunner'))
|
||||
|
@ -84,8 +85,9 @@ def PushAndLaunchAdbReboot(device, target):
|
|||
device.PushChangedFiles([(adb_reboot, '/data/local/tmp/')])
|
||||
# Launch adb_reboot
|
||||
logging.info(' Launching adb_reboot ...')
|
||||
device.old_interface.GetAndroidToolStatusAndOutput(
|
||||
'/data/local/tmp/adb_reboot')
|
||||
device.RunShellCommand([
|
||||
device.GetDevicePieWrapper(),
|
||||
'/data/local/tmp/adb_reboot'])
|
||||
|
||||
|
||||
def _ConfigureLocalProperties(device, java_debug=True):
|
||||
|
@ -149,6 +151,20 @@ def WipeDeviceIfPossible(device, timeout):
|
|||
pass
|
||||
|
||||
|
||||
def ChargeDeviceToLevel(device, level):
|
||||
def device_charged():
|
||||
battery_level = device.GetBatteryInfo().get('level')
|
||||
if battery_level is None:
|
||||
logging.warning('Unable to find current battery level.')
|
||||
battery_level = 100
|
||||
else:
|
||||
logging.info('current battery level: %d', battery_level)
|
||||
battery_level = int(battery_level)
|
||||
return battery_level >= level
|
||||
|
||||
timeout_retry.WaitFor(device_charged, wait_period=60)
|
||||
|
||||
|
||||
def ProvisionDevice(device, options):
|
||||
if options.reboot_timeout:
|
||||
reboot_timeout = options.reboot_timeout
|
||||
|
@ -180,23 +196,11 @@ def ProvisionDevice(device, options):
|
|||
device, device_settings.NETWORK_DISABLED_SETTINGS)
|
||||
if options.min_battery_level is not None:
|
||||
try:
|
||||
battery_info = device.old_interface.GetBatteryInfo()
|
||||
except Exception as e:
|
||||
battery_info = {}
|
||||
logging.error('Unable to obtain battery info for %s, %s',
|
||||
str(device), e)
|
||||
device.SetUsbCharging(True)
|
||||
ChargeDeviceToLevel(device, options.min_battery_level)
|
||||
except device_errors.CommandFailedError as e:
|
||||
logging.exception('Unable to charge device to specified level.')
|
||||
|
||||
while int(battery_info.get('level', 100)) < options.min_battery_level:
|
||||
if not device.old_interface.IsDeviceCharging():
|
||||
if device.old_interface.CanControlUsbCharging():
|
||||
device.old_interface.EnableUsbCharging()
|
||||
else:
|
||||
logging.error('Device is not charging')
|
||||
break
|
||||
logging.info('Waiting for device to charge. Current level=%s',
|
||||
battery_info.get('level', 0))
|
||||
time.sleep(60)
|
||||
battery_info = device.old_interface.GetBatteryInfo()
|
||||
if not options.skip_wipe:
|
||||
device.Reboot(True, timeout=reboot_timeout, retries=0)
|
||||
device.RunShellCommand('date -s %s' % time.strftime('%Y%m%d.%H%M%S',
|
||||
|
|
|
@ -44,6 +44,30 @@ _DEFAULT_RETRIES = 3
|
|||
# the timeout_retry decorators.
|
||||
DEFAULT = object()
|
||||
|
||||
_CONTROL_USB_CHARGING_COMMANDS = [
|
||||
{
|
||||
# Nexus 4
|
||||
'witness_file': '/sys/module/pm8921_charger/parameters/disabled',
|
||||
'enable_command': 'echo 0 > /sys/module/pm8921_charger/parameters/disabled',
|
||||
'disable_command':
|
||||
'echo 1 > /sys/module/pm8921_charger/parameters/disabled',
|
||||
},
|
||||
{
|
||||
# Nexus 5
|
||||
# Setting the HIZ bit of the bq24192 causes the charger to actually ignore
|
||||
# energy coming from USB. Setting the power_supply offline just updates the
|
||||
# Android system to reflect that.
|
||||
'witness_file': '/sys/kernel/debug/bq24192/INPUT_SRC_CONT',
|
||||
'enable_command': (
|
||||
'echo 0x4A > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
|
||||
'echo 1 > /sys/class/power_supply/usb/online'),
|
||||
'disable_command': (
|
||||
'echo 0xCA > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
|
||||
'chmod 644 /sys/class/power_supply/usb/online && '
|
||||
'echo 0 > /sys/class/power_supply/usb/online'),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@decorators.WithExplicitTimeoutAndRetries(
|
||||
_DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
|
||||
|
@ -143,6 +167,10 @@ class DeviceUtils(object):
|
|||
assert hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR)
|
||||
assert hasattr(self, decorators.DEFAULT_RETRIES_ATTR)
|
||||
|
||||
def __str__(self):
|
||||
"""Returns the device serial."""
|
||||
return self.adb.GetDeviceSerial()
|
||||
|
||||
@decorators.WithTimeoutAndRetriesFromInstance()
|
||||
def IsOnline(self, timeout=None, retries=None):
|
||||
"""Checks whether the device is online.
|
||||
|
@ -1370,9 +1398,67 @@ class DeviceUtils(object):
|
|||
"""
|
||||
return logcat_monitor.LogcatMonitor(self.adb, *args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
"""Returns the device serial."""
|
||||
return self.adb.GetDeviceSerial()
|
||||
@decorators.WithTimeoutAndRetriesFromInstance()
|
||||
def GetBatteryInfo(self, timeout=None, retries=None):
|
||||
"""Gets battery info for the device.
|
||||
|
||||
Args:
|
||||
timeout: timeout in seconds
|
||||
retries: number of retries
|
||||
Returns:
|
||||
A dict containing various battery information as reported by dumpsys
|
||||
battery.
|
||||
"""
|
||||
result = {}
|
||||
# Skip the first line, which is just a header.
|
||||
for line in self.RunShellCommand(
|
||||
['dumpsys', 'battery'], check_return=True)[1:]:
|
||||
k, v = line.split(': ', 1)
|
||||
result[k.strip()] = v.strip()
|
||||
return result
|
||||
|
||||
@decorators.WithTimeoutAndRetriesFromInstance()
|
||||
def GetUsbCharging(self, timeout=None, retries=None):
|
||||
"""Gets the USB charging state of the device.
|
||||
|
||||
Args:
|
||||
timeout: timeout in seconds
|
||||
retries: number of retries
|
||||
Returns:
|
||||
True if the device is charging via USB, false otherwise.
|
||||
"""
|
||||
return (self.GetBatteryInfo().get('USB powered', '').lower()
|
||||
in ('true', '1', 'yes'))
|
||||
|
||||
@decorators.WithTimeoutAndRetriesFromInstance()
|
||||
def SetUsbCharging(self, enabled, timeout=None, retries=None):
|
||||
"""Enables or disables USB charging on the device.
|
||||
|
||||
Args:
|
||||
enabled: A boolean indicating whether USB charging should be enabled or
|
||||
disabled.
|
||||
timeout: timeout in seconds
|
||||
retries: number of retries
|
||||
"""
|
||||
if 'usb_charging_config' not in self._cache:
|
||||
for c in _CONTROL_USB_CHARGING_COMMANDS:
|
||||
if self.FileExists(c['witness_file']):
|
||||
self._cache['usb_charging_config'] = c
|
||||
break
|
||||
else:
|
||||
raise device_errors.CommandFailedError(
|
||||
'Unable to find charging commands.')
|
||||
|
||||
if enabled:
|
||||
command = self._cache['usb_charging_config']['enable_command']
|
||||
else:
|
||||
command = self._cache['usb_charging_config']['disable_command']
|
||||
|
||||
def set_and_verify_usb_charging():
|
||||
self.RunShellCommand(command)
|
||||
return self.GetUsbCharging() == enabled
|
||||
|
||||
timeout_retry.WaitFor(set_and_verify_usb_charging, wait_period=1)
|
||||
|
||||
@decorators.WithTimeoutAndRetriesFromInstance()
|
||||
def GetDevicePieWrapper(self, timeout=None, retries=None):
|
||||
|
|
|
@ -1382,6 +1382,83 @@ class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsTest):
|
|||
self.device.GetMemoryUsageForPid(4321))
|
||||
|
||||
|
||||
class DeviceUtilsGetBatteryInfoTest(DeviceUtilsTest):
|
||||
def testGetBatteryInfo_normal(self):
|
||||
with self.assertCall(
|
||||
self.call.device.RunShellCommand(
|
||||
['dumpsys', 'battery'], check_return=True),
|
||||
[
|
||||
'Current Battery Service state:',
|
||||
' AC powered: false',
|
||||
' USB powered: true',
|
||||
' level: 100',
|
||||
' temperature: 321',
|
||||
]):
|
||||
self.assertEquals(
|
||||
{
|
||||
'AC powered': 'false',
|
||||
'USB powered': 'true',
|
||||
'level': '100',
|
||||
'temperature': '321',
|
||||
},
|
||||
self.device.GetBatteryInfo())
|
||||
|
||||
|
||||
def testGetBatteryInfo_nothing(self):
|
||||
with self.assertCall(
|
||||
self.call.device.RunShellCommand(
|
||||
['dumpsys', 'battery'], check_return=True), []):
|
||||
self.assertEquals({}, self.device.GetBatteryInfo())
|
||||
|
||||
|
||||
class DeviceUtilsGetUsbChargingTest(DeviceUtilsTest):
|
||||
def testGetUsbCharging_true(self):
|
||||
with self.assertCall(
|
||||
self.call.device.GetBatteryInfo(), {'USB powered': 'true'}):
|
||||
self.assertTrue(self.device.GetUsbCharging())
|
||||
|
||||
def testGetUsbCharging_false(self):
|
||||
with self.assertCall(
|
||||
self.call.device.GetBatteryInfo(), {'USB powered': 'false'}):
|
||||
self.assertFalse(self.device.GetUsbCharging())
|
||||
|
||||
def testGetUsbCharging_unknown(self):
|
||||
with self.assertCall(
|
||||
self.call.device.GetBatteryInfo(), {'AC powered': 'true'}):
|
||||
self.assertFalse(self.device.GetUsbCharging())
|
||||
|
||||
|
||||
class DeviceUtilsSetUsbChargingTest(DeviceUtilsTest):
|
||||
|
||||
@mock.patch('time.sleep', mock.Mock())
|
||||
def testSetUsbCharging_enabled(self):
|
||||
with self.assertCalls(
|
||||
(self.call.device.FileExists(mock.ANY), True),
|
||||
(self.call.device.RunShellCommand(mock.ANY), []),
|
||||
(self.call.device.GetUsbCharging(), False),
|
||||
(self.call.device.RunShellCommand(mock.ANY), []),
|
||||
(self.call.device.GetUsbCharging(), True)):
|
||||
self.device.SetUsbCharging(True)
|
||||
|
||||
def testSetUsbCharging_alreadyEnabled(self):
|
||||
with self.assertCalls(
|
||||
(self.call.device.FileExists(mock.ANY), True),
|
||||
(self.call.device.RunShellCommand(mock.ANY), []),
|
||||
(self.call.device.GetUsbCharging(), True)):
|
||||
self.device.SetUsbCharging(True)
|
||||
|
||||
@mock.patch('time.sleep', mock.Mock())
|
||||
def testSetUsbCharging_disabled(self):
|
||||
with self.assertCalls(
|
||||
(self.call.device.FileExists(mock.ANY), True),
|
||||
(self.call.device.RunShellCommand(mock.ANY), []),
|
||||
(self.call.device.GetUsbCharging(), True),
|
||||
(self.call.device.RunShellCommand(mock.ANY), []),
|
||||
(self.call.device.GetUsbCharging(), False)):
|
||||
self.device.SetUsbCharging(False)
|
||||
|
||||
|
||||
|
||||
class DeviceUtilsStrTest(DeviceUtilsTest):
|
||||
|
||||
def testStr_returnsSerial(self):
|
||||
|
|
Загрузка…
Ссылка в новой задаче