Home | History | Annotate | Download | only in hardware_TouchScreenPowerCycles
      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