1 # Copyright (c) 2013 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 5 import logging 6 import os 7 import re 8 import subprocess 9 import tempfile 10 import time 11 12 from autotest_lib.client.bin import test 13 from autotest_lib.client.common_lib import error 14 from autotest_lib.client.cros.graphics import graphics_utils 15 16 17 class hardware_TouchScreenPowerCycles(test.test): 18 """Check if there are any spurious contacts when power is cycled.""" 19 version = 1 20 21 SCREEN_ON = 1 22 SCREEN_OFF = 0 23 24 def initialize(self): 25 self.touch_screen_device = self._probe_touch_screen_device() 26 logging.info('Touchscreen device: %s', self.touch_screen_device) 27 if self.touch_screen_device is None: 28 raise error.TestError('No touch screen device is found.') 29 30 # Make sure that the screen is turned on before conducting the test. 31 self._wakeup_screen() 32 self.touch_screen_status = self.SCREEN_ON 33 34 def _wakeup_screen(self): 35 """Wake up the screen if it is dark.""" 36 graphics_utils.screen_wakeup() 37 time.sleep(2) 38 39 def _touch_screen_on(self, interval): 40 """Turn the touch screen on.""" 41 graphics_utils.switch_screen_on(on=1) 42 self.touch_screen_status = self.SCREEN_ON 43 logging.info('Touchscreen is turned on') 44 time.sleep(interval) 45 46 def _touch_screen_off(self, interval): 47 """Turn the touch screen off.""" 48 graphics_utils.switch_screen_on(on=0) 49 self.touch_screen_status = self.SCREEN_OFF 50 logging.info('Touchscreen is turned off') 51 time.sleep(interval) 52 53 def _probe_touch_screen_device(self): 54 """Probe the touch screen device file.""" 55 device_info_file = '/proc/bus/input/devices' 56 if not os.path.exists(device_info_file): 57 return None 58 with open(device_info_file) as f: 59 device_info = f.read() 60 61 touch_screen_pattern = re.compile('name=.+%s' % 'Touchscreen', re.I) 62 event_pattern = re.compile('handlers=.*event(\d+)', re.I) 63 found_touch_screen = False 64 touch_screen_device_file = None 65 for line in device_info.splitlines(): 66 if (not found_touch_screen and 67 touch_screen_pattern.search(line) is not None): 68 found_touch_screen = True 69 elif found_touch_screen: 70 result = event_pattern.search(line) 71 if result is not None: 72 event_no = int(result.group(1)) 73 device_file = '/dev/input/event%d' % event_no 74 if os.path.exists(device_file): 75 touch_screen_device_file = device_file 76 break 77 return touch_screen_device_file 78 79 def _begin_recording(self): 80 """Begin a recording process.""" 81 record_program = 'evemu-record' 82 record_cmd = '%s %s -1' % (record_program, self.touch_screen_device) 83 self.event_file = tempfile.TemporaryFile() 84 self.rec_proc = subprocess.Popen(record_cmd.split(), 85 stdout=self.event_file) 86 87 def _end_recording(self): 88 """Terminate recording process, and read/close the temp event file.""" 89 self.rec_proc.terminate() 90 self.rec_proc.wait() 91 self.event_file.seek(0) 92 self.events = self.event_file.readlines() 93 self.event_file.close() 94 95 def _get_timestamp(self, event): 96 """Get the timestamp of an event. 97 98 A device event looks like: "E: 1344225607.043493 0003 0036 202" 99 """ 100 result = re.search('E:\s*(\d+(\.\d*)?|\.\d+)', event) 101 timestamp = float(result.group(1)) if result else None 102 return timestamp 103 104 def _get_number_touch_contacts(self): 105 """Get the number of touch contacts. 106 107 Count ABS_MT_TRACKING_ID with a positive ID number but not -1 108 For example: 109 count this event: "E: 1365999572.107771 0003 0039 405" 110 do not count this event: "E: 1365999572.107771 0003 0039 -1" 111 """ 112 touch_pattern = re.compile('^E:.*\s*0003\s*0039\s*\d+') 113 count_contacts = len(filter(touch_pattern.search, self.events)) 114 return count_contacts 115 116 def run_once(self, repeated_times=5, interval=30): 117 """Run through power cycles and check spurious contacts. 118 119 @param repeated_times: the number of power on/off cycles to check. 120 @param interval: the power on/off duration in seconds. 121 122 Turn the power on for 30 seconds, and then turn it off for another 123 30 seconds. Repeat it for 5 times. 124 """ 125 count_contacts_list = [] 126 count_rounds = 0 127 for _ in range(repeated_times): 128 self._begin_recording() 129 self._touch_screen_off(interval) 130 self._touch_screen_on(interval) 131 self._end_recording() 132 count_contacts = self._get_number_touch_contacts() 133 count_contacts_list.append(count_contacts) 134 if count_contacts > 0: 135 count_rounds += 1 136 137 if count_rounds > 0: 138 msg1 = ('Spurious contacts detected %d out of %d iterations.' % 139 (count_rounds, repeated_times)) 140 msg2 = 'Count of touch contacts: %s' % str(count_contacts_list) 141 ave = float(sum(count_contacts_list)) / len(count_contacts_list) 142 msg3 = 'Average count of touch contacts: %.2f' % ave 143 raise error.TestFail('\n'.join(['', msg1, msg2, msg3])) 144