1# Lint as: python2, python3 2# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import logging 7import os 8 9from autotest_lib.client.bin import utils 10from autotest_lib.client.common_lib import error 11from autotest_lib.client.common_lib.cros import cros_config 12from autotest_lib.client.cros import touch_playback_test_base 13 14 15class touch_WakeupSource(touch_playback_test_base.touch_playback_test_base): 16 """Check that touchpad/touchscreen are set/not set as wake sources.""" 17 version = 1 18 19 # Devices whose touchpads should not be a wake source. 20 # 21 # Note, starting with octopus platform, convertibles should enable touchpad 22 # wake. If you wish to enable on previous devices, see furquan@ doc 23 # go/cros-trackpad-wake and/or consult chromeos-platform-power@ for more 24 # details. 25 _NO_TOUCHPAD_WAKE = [ 26 'caroline', 'clapper', 'elm', 'glimmer', 'hana', 'kevin', 'kukui', 27 'pyro', 'veyron_minnie' 28 ] 29 _TOUCHPAD_WAKE_SET_BY_CROS_CONFIG = ['coral', 'nami'] 30 31 # Devices with Synaptics touchpads that do not report wake source, 32 # or reference platforms like Rambi which are broken but do not ship, 33 # or devices like Cyan which don't report this way: crosbug.com/p/46019. 34 _INVALID_TOUCHPADS = ['x86-alex', 'x86-alex_he', 'x86-zgb', 'x86-zgb_he', 35 'x86-mario', 'stout', 'rambi', 'cyan'] 36 _INVALID_TOUCHSCREENS = ['cyan', 'nocturne', 'sumo', 'ultima'] 37 38 def _touchpad_should_be_wake_source(self): 39 base_platform = self._platform.replace('-kernelnext', '') 40 if base_platform in self._NO_TOUCHPAD_WAKE: 41 return False 42 if (base_platform in self._TOUCHPAD_WAKE_SET_BY_CROS_CONFIG 43 and cros_config.call_cros_config_get_output( 44 '/power touchpad-wakeup', utils.run) == '0'): 45 return False 46 return True 47 48 def _find_wakeup_file(self, input_type): 49 """Return path to wakeup file or None. 50 51 If the file does not exist, check the parent bus for wakeup rules 52 as well, as is the setup for some devices. 53 54 @param input_type: e.g. 'touchpad' or 'mouse'. See parent class for 55 all options. 56 57 @raises: TestError if input_type lacks required information. 58 59 """ 60 device_dir = self.player.devices[input_type].device_dir 61 if not device_dir: 62 raise error.TestError('No device directory for %s!' % input_type) 63 64 filename = os.path.join(device_dir, 'power', 'wakeup') 65 if not os.path.isfile(filename): 66 logging.info('%s not found for %s', filename, input_type) 67 68 # Look for wakeup file on parent bus instead. 69 event = self.player.devices[input_type].node.split('/')[-1] 70 71 parent = None 72 i2c_devices_dir = os.path.join('/', 'sys', 'bus', 'i2c', 'devices') 73 for device_dir in os.listdir(i2c_devices_dir): 74 event_search = os.path.join(i2c_devices_dir, device_dir, '*', 75 'input', 'input*', event) 76 match_count = utils.run('ls %s 2>/dev/null | wc -l' % ( 77 event_search)).stdout.strip() 78 if int(match_count) > 0: 79 parent = os.path.join(i2c_devices_dir, device_dir) 80 break 81 if parent is None: 82 logging.info('Could not find parent bus for %s.', input_type) 83 return None 84 85 logging.info('Parent bus of %s is %s.', input_type, parent) 86 filename = os.path.join(parent, 'power', 'wakeup') 87 if not os.path.isfile(filename): 88 logging.info('%s not found either.', filename) 89 return None 90 91 return filename 92 93 def _is_wake_source(self, input_type): 94 """Return True if the given device is a wake source, else False. 95 96 If the file does not exist, return False. 97 98 @param input_type: e.g. 'touchpad' or 'mouse'. See parent class for 99 all options. 100 101 @raises: TestError if test cannot interpret the file contents. 102 103 """ 104 filename = self._find_wakeup_file(input_type) 105 if filename is None: 106 return False 107 108 result = utils.run('cat %s' % filename).stdout.strip() 109 if result == 'enabled': 110 logging.info('Found that %s is a wake source.', input_type) 111 return True 112 elif result == 'disabled': 113 logging.info('Found that %s is not a wake source.', input_type) 114 return False 115 raise error.TestError('Wakeup file for %s said "%s".' % 116 (input_type, result)) 117 118 def run_once(self, source): 119 """Entry point of this test.""" 120 121 # Check that touchpad is a wake source for all but the excepted boards. 122 if source == 'touchpad': 123 if (self._has_touchpad and 124 self._platform not in self._INVALID_TOUCHPADS): 125 if self._touchpad_should_be_wake_source(): 126 if not self._is_wake_source('touchpad'): 127 raise error.TestFail('Touchpad is not a wake source!') 128 else: 129 if self._is_wake_source('touchpad'): 130 raise error.TestFail('Touchpad is a wake source!') 131 132 # Check that touchscreen is not a wake source (if present). 133 # Devices without a touchpad should have touchscreen as wake source. 134 if source == 'touchscreen': 135 if (self._has_touchscreen and 136 self._platform not in self._INVALID_TOUCHSCREENS): 137 touchscreen_wake = self._is_wake_source('touchscreen') 138 if self._has_touchpad and touchscreen_wake: 139 raise error.TestFail('Touchscreen is a wake source!') 140 if not self._has_touchpad and not touchscreen_wake: 141 raise error.TestFail('Touchscreen is not a wake source!') 142