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