blob: 42e591918f0c5d32bb5402f98fdf3ccf80eef635 [file] [log] [blame]
# 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 re
from mtlib.util import RequiredRegex, SafeExecute, Execute, Path
# locate required folders in chroot enviornment
src_dir = Path("/mnt/host/source/src/")
scripts_dir = src_dir / "scripts"
autotest_dir = src_dir / "third_party/autotest/files"
pressure_calib_dir = autotest_dir / "client/site_tests/firmware_TouchMTB"
xorg_conf_template = """\
Section "InputClass"
Identifier "touchpad {board} {vendor_lower}"
MatchIsTouchpad "on"
MatchDevicePath "/dev/input/event*"
MatchProduct "{vendor}"
Option "Integrated Touchpad" "1"
Option "Touchpad Stack Version" "2"
Option "Pressure Calibration Offset" "{intercept}"
Option "Pressure Calibration Slope" "{slope}"
EndSection\
"""
class XorgConfBuilder(object):
def __init__(self, info, conf_file, touchpad):
self.board_variant = info.board_variant
self.xorg_conf = conf_file
self.touchpad = touchpad
self.sheet_name = self.board_variant + " " + self.touchpad.fw_version
def GetCalibrationResults(self):
cmd = "python spreadsheet.py --print-info -n \"{}\""
cmd = cmd.format(self.sheet_name)
res = Execute(cmd, cwd=pressure_calib_dir, verbose=True)
if not res:
return False
slope_regex = RequiredRegex("slope=([0-9.\\-]+)")
slope = slope_regex.Search(res).group(1)
intercept_regex = RequiredRegex("intercept=([0-9.\\-]+)")
intercept = intercept_regex.Search(res).group(1)
return (float(slope), float(intercept))
def RunCalibration(self, remote, use_existing=True):
if use_existing:
existing = remote.Execute("readlink /var/tmp/touch_firmware_test/latest")
else:
existing = False
if not existing:
print "Installing firmware_TouchMTB on device"
cmd = ("sh run_remote_tests.sh --autotest_dir {} " +
"--remote={} firmware_TouchMTBSetup")
cmd = cmd.format(autotest_dir, remote.ip)
SafeExecute(cmd, cwd=scripts_dir, verbose=True)
print "Executing Pressure Calibration."
print "Follow instructions on device"
remote.SafeExecute("XAUTHORITY=\"/home/chronos/.Xauthority\" DISPLAY=:0" +
" python main.py -m calibration",
cwd="/usr/local/autotest/tests/firmware_TouchMTB",
verbose=True)
print "Uploading data to spreadsheet. This can take a minute."
cmd = ["python", "spreadsheet.py", "-v", "-d", remote.ip,
"--result-dir=latest", "-n", self.sheet_name]
SafeExecute(cmd, cwd=pressure_calib_dir, verbose=True, interactive=True)
def UpdateXorgConf(self, calib):
conf = xorg_conf_template.format(
board=self.board_variant,
vendor=self.touchpad.vendor,
vendor_lower=self.touchpad.vendor.lower(),
slope=calib[0],
intercept=calib[1])
if self.xorg_conf.exists:
current = self.xorg_conf.Read()
match_regex = RequiredRegex("MatchProduct\s+\"{}\"".format(
self.touchpad.vendor))
match = match_regex.Search(current, safe=False)
if match:
begin = current.rindex("Section", 0, match.start())
end = current.index("EndSection", match.end()) + len("EndSection")
new = current[:begin] + conf + current[end:]
else:
new = current + "\n" + conf
else:
new = conf
self.xorg_conf.Write(new)
class XorgInputClassParser(object):
""" Parser for xorg input config files.
This class is used to parse xorg config files for input class options.
Only input class sections with a valid Identifier line are parsed.
"""
def Parse(self, file=None, string=None):
""" Parse xorg file and return dictionary of input classes.
Provide either a filename or file-like object to the file parameters
or a string containing the configuration to the string parameter.
The return value is a dictionary of all InputClasses, with the
Identifier as a key. The value is another dictionary containing
all options set for this input class.
"""
if file:
if isinstance(file, basestring):
return self._ParseString(open(file).read())
elif hasattr(file, 'read'):
return self._ParseString(file.read())
else:
raise ValueError
elif string:
return self._ParseString(string)
else:
raise ValueError
def _ParseString(self, string):
lines = string.splitlines()
lines = map(lambda l: l.strip(), lines)
section_regex = re.compile('Section\\s+\"([^\"]+)\"')
id_regex = re.compile('Identifier\\s+\"([^\"]+)\"')
option_regex = re.compile('Option\\s+\"([^\"]+)\"\\s+\"([^\"]+)\"')
classes = {}
current_options = None
current_id = None
for line in lines:
if current_options is None:
# Outside of sections
section_match = section_regex.match(line)
if section_match and section_match.group(1) == 'InputClass':
current_options = {}
continue
else:
# Inside of a section
if line == 'EndSection':
if current_id:
# if class had an id, save in results
classes[current_id] = current_options
current_options = None
continue
# look for identifier line
id_match = id_regex.match(line)
if id_match:
current_id = id_match.group(1)
continue
# store options in current_options
option_match = option_regex.match(line)
if option_match:
key = option_match.group(1)
value = option_match.group(2)
current_options[key] = value
return classes