blob: 2a83c6ac5754d7347ec7653e81655cce9b685237 [file] [log] [blame]
# Copyright (c) 2012 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.
"""Touchpad device module provides some touchpad related attributes."""
import glob
import os
import re
import common_util
class TouchpadDevice:
"""A class about touchpad device properties."""
def __init__(self, device_node=None):
self.device_info_file = '/proc/bus/input/devices'
self.device_node = (device_node if device_node
else self.get_device_node())
def _re_str(self):
"""Get the regular expression search string for a touchpad device."""
pattern_str = ('touchpad', 'trackpad', 'cyapa')
return '(?:%s)' % '|'.join(pattern_str)
def get_device_node(self):
"""Get the touchpad device node through tpcontrol.
tpcontrol returns a string like
Device Node (244): "/dev/input/event8"
"""
cmd = '/opt/google/touchpad/tpcontrol status | grep -i "device node"'
device_node_str = common_util.simple_system_output(cmd)
device_node = device_node_str.split(':')[-1].strip().strip('"')
return device_node
def get_dimensions_in_mm(self):
"""Get the width and height in mm of the device."""
(left, right, top, bottom,
resolution_x, resolution_y) = self.get_resolutions()
width = float((right - left)) / resolution_x
height = float((bottom - top)) / resolution_y
return (width, height)
def get_resolutions(self, device_description=None):
"""Get the resolutions in x and y axis of the device."""
_, _, _, _, resolution_x, resolution_y = self.get_abs_axes(
device_description)
return (resolution_x, resolution_y)
def get_edges(self, device_description=None):
"""Get the left, right, top, and bottom edges of the device."""
left, right, top, bottom, _, _ = self.get_abs_axes(
device_description)
return (left, right, top, bottom)
def get_abs_axes(self, device_description=None):
"""Get information about min, max, and resolution from ABS_X and ABS_Y
Example of ABS_X:
A: 00 0 1280 0 0 12
Example of ABS_y:
A: 01 0 1280 0 0 12
"""
pattern = 'A:\s*%s\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)'
pattern_x = pattern % '00'
pattern_y = pattern % '01'
cmd = 'evemu-describe %s' % self.device_node
if device_description is None:
device_description = common_util.simple_system_output(cmd)
found_x = found_y = False
left = right = top = bottom = None
resolution_x = resolution_y = None
if device_description:
for line in device_description.splitlines():
if not found_x:
result = re.search(pattern_x, line, re.I)
if result:
left = int(result.group(1))
right = int(result.group(2))
resolution_x = int(result.group(5))
found_x = True
if not found_y:
result = re.search(pattern_y, line, re.I)
if result:
top = int(result.group(1))
bottom = int(result.group(2))
resolution_y = int(result.group(5))
found_y = True
return (left, right, top, bottom, resolution_x, resolution_y)
def get_dimensions(self, device_description=None):
"""Get the dimensions of the touchpad reported size."""
left, right, top, bottom = self.get_edges(device_description)
return (right - left, bottom - top)
def get_display_geometry(self, screen_size, display_ratio):
"""Get a preferred display geometry when running the test."""
display_ratio = 0.8
dev_width, dev_height = self.get_dimensions()
screen_width, screen_height = screen_size
if 1.0 * screen_width / screen_height <= 1.0 * dev_width / dev_height:
disp_width = int(screen_width * display_ratio)
disp_height = int(disp_width * dev_height / dev_width)
disp_offset_x = 0
disp_offset_y = screen_height - disp_height
else:
disp_height = int(screen_height * display_ratio)
disp_width = int(disp_height * dev_width / dev_height)
disp_offset_x = 0
disp_offset_y = screen_height - disp_height
return (disp_width, disp_height, disp_offset_x, disp_offset_y)
def _touchpad_input_name_re_str(self):
pattern_str = ('touchpad', 'trackpad')
return '(?:%s)' % '|'.join(pattern_str)
def get_touchpad_input_dir(self):
"""Get touchpad input directory."""
input_root_dir = '/sys/class/input'
input_dirs = glob.glob(os.path.join(input_root_dir, 'input*'))
re_pattern = re.compile(self._touchpad_input_name_re_str(), re.I)
for input_dir in input_dirs:
filename = os.path.join(input_dir, 'name')
if os.path.isfile(filename):
with open(filename) as f:
for line in f:
if re_pattern.search(line) is not None:
return input_dir
return None
def get_firmware_version(self):
"""Probe the firmware version."""
input_dir = self.get_touchpad_input_dir()
device_dir = 'device'
# Get the re search pattern for firmware_version file name
fw_list = ('firmware', 'fw')
ver_list = ('version', 'id')
sep_list = ('_', '-')
re_str = '%s%s%s' % ('(?:%s)' % '|'.join(fw_list),
'(?:%s)' % '|'.join(sep_list),
'(?:%s)' % '|'.join(ver_list))
re_pattern = re.compile(re_str, re.I)
if input_dir is not None:
device_dir = os.path.join(input_dir, 'device', '*')
for f in glob.glob(device_dir):
if os.path.isfile(f) and re_pattern.search(f):
with open (f) as f:
for line in f:
return line.strip('\n')
return 'unknown'