# Copyright (c) 2013 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. import logging import os import re import subprocess import tempfile import time from autotest_lib.client.bin import test from autotest_lib.client.common_lib import error from autotest_lib.client.cros.graphics import graphics_utils class hardware_TouchScreenPowerCycles(test.test): """Check if there are any spurious contacts when power is cycled.""" version = 1 SCREEN_ON = 1 SCREEN_OFF = 0 def initialize(self): self.touch_screen_device = self._probe_touch_screen_device() logging.info('Touchscreen device: %s', self.touch_screen_device) if self.touch_screen_device is None: raise error.TestError('No touch screen device is found.') # Make sure that the screen is turned on before conducting the test. self._wakeup_screen() self.touch_screen_status = self.SCREEN_ON def _wakeup_screen(self): """Wake up the screen if it is dark.""" graphics_utils.screen_wakeup() time.sleep(2) def _touch_screen_on(self, interval): """Turn the touch screen on.""" graphics_utils.switch_screen_on(on=1) self.touch_screen_status = self.SCREEN_ON logging.info('Touchscreen is turned on') time.sleep(interval) def _touch_screen_off(self, interval): """Turn the touch screen off.""" graphics_utils.switch_screen_on(on=0) self.touch_screen_status = self.SCREEN_OFF logging.info('Touchscreen is turned off') time.sleep(interval) def _probe_touch_screen_device(self): """Probe the touch screen device file.""" device_info_file = '/proc/bus/input/devices' if not os.path.exists(device_info_file): return None with open(device_info_file) as f: device_info = f.read() touch_screen_pattern = re.compile('name=.+%s' % 'Touchscreen', re.I) event_pattern = re.compile('handlers=.*event(\d+)', re.I) found_touch_screen = False touch_screen_device_file = None for line in device_info.splitlines(): if (not found_touch_screen and touch_screen_pattern.search(line) is not None): found_touch_screen = True elif found_touch_screen: result = event_pattern.search(line) if result is not None: event_no = int(result.group(1)) device_file = '/dev/input/event%d' % event_no if os.path.exists(device_file): touch_screen_device_file = device_file break return touch_screen_device_file def _begin_recording(self): """Begin a recording process.""" record_program = 'evemu-record' record_cmd = '%s %s -1' % (record_program, self.touch_screen_device) self.event_file = tempfile.TemporaryFile() self.rec_proc = subprocess.Popen(record_cmd.split(), stdout=self.event_file) def _end_recording(self): """Terminate recording process, and read/close the temp event file.""" self.rec_proc.terminate() self.rec_proc.wait() self.event_file.seek(0) self.events = self.event_file.readlines() self.event_file.close() def _get_timestamp(self, event): """Get the timestamp of an event. A device event looks like: "E: 1344225607.043493 0003 0036 202" """ result = re.search('E:\s*(\d+(\.\d*)?|\.\d+)', event) timestamp = float(result.group(1)) if result else None return timestamp def _get_number_touch_contacts(self): """Get the number of touch contacts. Count ABS_MT_TRACKING_ID with a positive ID number but not -1 For example: count this event: "E: 1365999572.107771 0003 0039 405" do not count this event: "E: 1365999572.107771 0003 0039 -1" """ touch_pattern = re.compile('^E:.*\s*0003\s*0039\s*\d+') count_contacts = len(filter(touch_pattern.search, self.events)) return count_contacts def run_once(self, repeated_times=5, interval=30): """Run through power cycles and check spurious contacts. @param repeated_times: the number of power on/off cycles to check. @param interval: the power on/off duration in seconds. Turn the power on for 30 seconds, and then turn it off for another 30 seconds. Repeat it for 5 times. """ count_contacts_list = [] count_rounds = 0 for _ in range(repeated_times): self._begin_recording() self._touch_screen_off(interval) self._touch_screen_on(interval) self._end_recording() count_contacts = self._get_number_touch_contacts() count_contacts_list.append(count_contacts) if count_contacts > 0: count_rounds += 1 if count_rounds > 0: msg1 = ('Spurious contacts detected %d out of %d iterations.' % (count_rounds, repeated_times)) msg2 = 'Count of touch contacts: %s' % str(count_contacts_list) ave = float(sum(count_contacts_list)) / len(count_contacts_list) msg3 = 'Average count of touch contacts: %.2f' % ave raise error.TestFail('\n'.join(['', msg1, msg2, msg3]))