# 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]))