1# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import time 6import logging 7from threading import Timer 8 9from autotest_lib.client.common_lib import error 10from autotest_lib.server.cros.faft.firmware_test import FirmwareTest 11 12 13class firmware_ECPowerButton(FirmwareTest): 14 """ 15 Servo based EC power button test. 16 """ 17 version = 1 18 19 # Delay between recovery screen and shutdown by power button 20 RECOVERY_SCREEN_SHUTDOWN_DELAY = 3 21 22 # Duration of holding down power button to test ignoring power button press 23 POWER_BUTTON_IGNORE_PRESS_DURATION = 0.2 24 25 # Delay after pressing power button to check power state 26 POWER_BUTTON_IGNORE_PRESS_DELAY = 10 27 28 # Number of tries when checking power state 29 POWER_STATE_CHECK_TRIES = 20 30 31 # After the device has reached the wanted shutdown power states (S5 or G3), 32 # wait for a short time before executing a power button wakeup. 33 SHUTDOWN_STABLE_DELAY = 1 34 35 def initialize(self, host, cmdline_args): 36 super(firmware_ECPowerButton, self).initialize(host, cmdline_args) 37 38 # Duration of holding down power button to shut down with powerd 39 self.POWER_BUTTON_POWERD_DURATION = ( 40 self.faft_config.hold_pwr_button_poweroff) 41 # Duration of holding down power button to shut down without powerd 42 self.POWER_BUTTON_NO_POWERD_DURATION = max( 43 self.faft_config.hold_pwr_button_nopowerd_shutdown, 11) 44 # Short duration of holding down power button to power on 45 self.POWER_BUTTON_SHORT_POWER_ON_DURATION = max( 46 self.faft_config.hold_pwr_button_poweron, 0.05) 47 # Long duration of holding down power button to power on 48 self.POWER_BUTTON_LONG_POWER_ON_DURATION = max( 49 self.faft_config.hold_pwr_button_poweron, 1) 50 # Only run in normal mode 51 self.switcher.setup_mode('normal') 52 self.has_display = host.has_internal_display() or \ 53 host.has_external_display() 54 55 def kill_powerd(self): 56 """Stop powerd on client.""" 57 self.faft_client.system.run_shell_command("stop powerd") 58 59 def debounce_power_button(self): 60 """Check if power button debouncing works. 61 62 Press power button for a very short period and checks for power 63 button keycode. 64 """ 65 # Delay 3 seconds to ensure client machine is waiting for key press. 66 # Press power button for only 10ms. Should be debounced. 67 logging.info('ECPowerButton: debounce_power_button') 68 Timer(3, self.servo.power_key, [0.001]).start() 69 return self.faft_client.system.check_keys([116]) 70 71 def shutdown_and_wake(self, shutdown_powerkey_duration, power_state, 72 wake_powerkey_duration): 73 """ 74 Shutdown the system by power button, delay, wait for requested power 75 states and then power on by power button again. 76 """ 77 78 # Shutdown the system by pressing the power button 79 self.servo.power_key(shutdown_powerkey_duration) 80 81 # Wait for the system to enter the requested power mode 82 if not self.wait_power_state(power_state, 83 self.POWER_STATE_CHECK_TRIES): 84 raise error.TestFail('The device failed to reach %s.' % 85 power_state) 86 87 # Add a delay to confirm the system is stabily shut down 88 time.sleep(self.SHUTDOWN_STABLE_DELAY) 89 90 # Send a new line to wakeup EC from deepsleep, 91 # it can happen if the EC console is not used for some time. 92 self.ec.send_command("") 93 94 # Power on the system by pressing the power button 95 self.servo.power_key(wake_powerkey_duration) 96 97 # Some platforms undergo extra power state transitions during power-on. 98 # We need to wait for longer time for the power state to be stable. 99 time.sleep(self.faft_config.delay_powerinfo_stable) 100 101 def run_once(self): 102 """Runs a single iteration of the test.""" 103 if not self.check_ec_capability(): 104 raise error.TestNAError("Nothing needs to be tested on this device") 105 106 # Ensure that detachable is in OFF State for following test 107 if self.faft_config.is_detachable: 108 # Skip this test step for detachable 109 # Setting Power State to off for entry to next step 110 logging.info("Setting Power Off") 111 self.servo.get_power_state_controller().power_off() 112 else: 113 # Run these test steps for non detachable devices 114 logging.info("Boot to recovery screen.") 115 self.switcher.enable_rec_mode_and_reboot(usb_state='host') 116 time.sleep(self.faft_config.firmware_screen) 117 if self.get_power_state() != self.POWER_STATE_S0: 118 raise error.TestFail("DUT didn't boot to recovery screen") 119 120 logging.info("Shutdown by short power button press.") 121 self.servo.power_key(self.faft_config.hold_pwr_button_poweron) 122 time.sleep(self.RECOVERY_SCREEN_SHUTDOWN_DELAY) 123 power_state = self.get_power_state() 124 if (power_state != self.POWER_STATE_S5 125 and power_state != self.POWER_STATE_G3): 126 raise error.TestFail("DUT didn't shutdown by " 127 "short power button press") 128 if self.ec.check_feature('EC_FEATURE_EFS2'): 129 logging.info("Check if EC jumped to RW.") 130 if not self.ec.check_ro_rw('RW'): 131 raise error.TestFail("EC didn't jump to RW") 132 133 logging.info("Boot by short power button press.") 134 self.servo.power_key(self.faft_config.hold_pwr_button_poweron) 135 self.switcher.wait_for_client() 136 if self.get_power_state() != self.POWER_STATE_S0: 137 raise error.TestFail("DUT didn't boot by short power button press") 138 139 if self.has_display: 140 logging.info("Display connected, check system ignores short 200ms " 141 "power button press.") 142 old_boot_id = self.get_bootid(retry=1) 143 self.servo.power_key(self.POWER_BUTTON_IGNORE_PRESS_DURATION) 144 time.sleep(self.POWER_BUTTON_IGNORE_PRESS_DELAY) 145 power_state = self.get_power_state() 146 new_boot_id = self.get_bootid(retry=1) 147 if power_state != self.POWER_STATE_S0 or new_boot_id != old_boot_id: 148 self._reset_client() 149 raise error.TestFail("DUT shutdown from short 200ms power " 150 "button press") 151 else: 152 logging.info("No display connected, check system shuts down from " 153 "short 200ms power button check.") 154 self.servo.power_key(self.POWER_BUTTON_IGNORE_PRESS_DURATION) 155 time.sleep(self.POWER_BUTTON_IGNORE_PRESS_DELAY) 156 power_state = self.get_power_state() 157 logging.info("Power state = %s", power_state) 158 if (power_state != self.POWER_STATE_S5 and 159 power_state != self.POWER_STATE_G3): 160 self._reset_client() 161 raise error.TestFail("DUT didn't shutdown by " 162 "short power button press") 163 self.servo.power_key(self.faft_config.hold_pwr_button_poweron) 164 self.switcher.wait_for_client() 165 if self.get_power_state() != self.POWER_STATE_S0: 166 self._reset_client() 167 raise error.TestFail("DUT didn't boot by short power button press") 168 169 logging.info( 170 "Shutdown when powerd is still running and wake from S5/G3 " 171 "with short power button press.") 172 if self.servo.is_localhost() and self.has_display: 173 self.check_state(self.debounce_power_button) 174 self.switcher.mode_aware_reboot( 175 'custom', lambda: self.shutdown_and_wake( 176 self.POWER_BUTTON_POWERD_DURATION, 177 self.POWER_STATE_S5 + '|' + self.POWER_STATE_G3, 178 self.POWER_BUTTON_SHORT_POWER_ON_DURATION)) 179 180 logging.info("Shutdown when powerd is stopped and wake from G3 " 181 "with short power button press.") 182 self.kill_powerd() 183 self.switcher.mode_aware_reboot( 184 'custom', lambda: self.shutdown_and_wake( 185 self.POWER_BUTTON_NO_POWERD_DURATION, self. 186 POWER_STATE_G3, 187 self.POWER_BUTTON_SHORT_POWER_ON_DURATION)) 188 189 logging.info("Shutdown when powerd is still running and wake from G3 " 190 "with long power button press.") 191 self.switcher.mode_aware_reboot( 192 'custom', lambda: self.shutdown_and_wake( 193 self.POWER_BUTTON_POWERD_DURATION, 194 self.POWER_STATE_G3, 195 self.POWER_BUTTON_LONG_POWER_ON_DURATION)) 196 197 logging.info("Shutdown when powerd is stopped and wake from S5/G3 " 198 "with long power button press.") 199 self.kill_powerd() 200 self.switcher.mode_aware_reboot( 201 'custom', lambda: self.shutdown_and_wake( 202 self.POWER_BUTTON_NO_POWERD_DURATION, 203 self.POWER_STATE_S5 + '|' + self.POWER_STATE_G3, 204 self.POWER_BUTTON_LONG_POWER_ON_DURATION)) 205