blob: 90ca1e8e0ae906174144f9fa32d0e4d1c780f29d [file] [log] [blame]
# Lint as: python2, python3
# Copyright 2021 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Helper class for power autotests that force DUT to discharge with EC."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import logging
import time
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import ec
from autotest_lib.client.cros.power import power_utils
from six.moves import range
_FORCE_DISCHARGE_SETTINGS = ['false', 'true', 'optional']
def _parse(force_discharge):
"""
Parse and return force discharge setting.
@param force_discharge: string of whether to tell ec to discharge battery
even when the charger is plugged in. 'false' means no forcing
discharge; 'true' means forcing discharge and raising an error when
it fails; 'optional' means forcing discharge when possible but not
raising an error when it fails, which is more friendly to devices
without a battery.
@return: string representing valid force discharge setting.
@raise error.TestError: for invalid force discharge setting.
"""
setting = str(force_discharge).lower()
if setting not in _FORCE_DISCHARGE_SETTINGS:
raise error.TestError(
'Force discharge setting \'%s\' need to be one of %s.' %
(str(force_discharge), _FORCE_DISCHARGE_SETTINGS))
return setting
def _wait_for_battery_discharge(status):
"""
Polling every 100ms for 2 seconds until battery is discharging. This
normally would take about 350ms.
@param status: DUT power status object.
@return: boolean indicating force discharge success.
"""
for _ in range(20):
status.refresh()
if status.battery_discharging():
return True
time.sleep(0.1)
return False
def process(force_discharge, status):
"""
Perform force discharge steps.
@param force_discharge: string of whether to tell ec to discharge battery
even when the charger is plugged in. 'false' means no forcing
discharge; 'true' means forcing discharge and raising an error when
it fails; 'optional' means forcing discharge when possible but not
raising an error when it fails, which is more friendly to devices
without a battery.
@param status: DUT power status object.
@return: bool to indicate whether force discharge steps are successful. Note
that DUT cannot force discharge if DUT is not connected to AC.
@raise error.TestError: for invalid force discharge setting.
@raise error.TestNAError: when force_discharge is 'true' and the DUT is
incapable of forcing discharge.
@raise error.TestError: when force_discharge is 'true' and the DUT command
to force discharge fails.
"""
force_discharge = _parse(force_discharge)
if force_discharge == 'true':
if not status.battery:
raise error.TestNAError('DUT does not have battery. '
'Could not force discharge.')
if not ec.has_cros_ec():
raise error.TestNAError('DUT does not have CrOS EC. '
'Could not force discharge.')
if not power_utils.charge_control_by_ectool(False):
raise error.TestError('Could not run battery force discharge.')
if not _wait_for_battery_discharge(status):
logging.warning('Battery does not report discharging state.')
return True
elif force_discharge == 'optional':
if not status.battery:
logging.warning('DUT does not have battery. '
'Do not force discharge.')
return False
if not ec.has_cros_ec():
logging.warning('DUT does not have CrOS EC. '
'Do not force discharge.')
return False
if not power_utils.charge_control_by_ectool(False):
logging.warning('Could not run battery force discharge. '
'Do not force discharge.')
return False
if not _wait_for_battery_discharge(status):
logging.warning('Battery does not report discharging state.')
return True
elif force_discharge == 'false':
return False
def restore(force_discharge_success):
"""
Set DUT back to charging.
@param force_discharge_success: if DUT previously forced discharge
successfully, set DUT back to charging.
"""
if force_discharge_success:
if not power_utils.charge_control_by_ectool(True):
logging.warning('Can not restore from force discharge.')