1# Lint as: python2, python3 2# Copyright (c) 2014 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import itertools 7import logging 8import re 9import time 10 11from autotest_lib.client.common_lib import error 12from autotest_lib.client.common_lib.cros import chrome 13from autotest_lib.client.cros import touch_playback_test_base 14 15 16class touch_TapSettings(touch_playback_test_base.touch_playback_test_base): 17 """Toggles tap-to-click and tap dragging settings to ensure correctness.""" 18 version = 1 19 20 _TEST_TIMEOUT = 1 # Number of seconds the test will wait for a click. 21 _MOUSE_DESCRIPTION = 'apple_mouse.prop' 22 _CLICK_NAME = 'tap' 23 _DRAG_NAME = 'tap-drag-right' 24 25 26 def _check_for_click(self, expected): 27 """Playback and check whether tap-to-click occurred. Fail if needed. 28 29 @param expected: True if clicking should happen, else False. 30 @raises: TestFail if actual value does not match expected. 31 32 """ 33 expected_count = 1 if expected else 0 34 self._events.clear_previous_events() 35 self._playback(self._filepaths[self._CLICK_NAME]) 36 time.sleep(self._TEST_TIMEOUT) 37 actual_count = self._events.get_click_count() 38 if actual_count is not expected_count: 39 self._events.log_events() 40 raise error.TestFail('Expected clicks=%s, actual=%s.' 41 % (expected_count, actual_count)) 42 43 44 def _check_for_drag(self, expected): 45 """Playback and check whether tap dragging occurred. Fail if needed. 46 47 @param expected: True if dragging should happen, else False. 48 @raises: TestFail if actual value does not match expected. 49 50 """ 51 self._events.clear_previous_events() 52 self._blocking_playback(self._filepaths[self._DRAG_NAME]) 53 self._events.wait_for_events_to_complete() 54 55 # Find a drag in the reported input events. 56 events_log = self._events.get_events_log() 57 log_search = re.search('mousedown.*\n(mousemove.*\n)+mouseup', 58 events_log, re.MULTILINE) 59 actual_dragging = log_search != None 60 actual_click_count = self._events.get_click_count() 61 actual = actual_dragging and actual_click_count == 1 62 63 if actual is not expected: 64 self._events.log_events() 65 raise error.TestFail('Tap dragging movement was %s; expected %s. ' 66 'Saw %s clicks.' 67 % (actual, expected, actual_click_count)) 68 69 70 def _is_testable(self): 71 """Return True if test can run on this device, else False. 72 73 @raises: TestError if host has no touchpad when it should. 74 75 """ 76 # Raise error if no touchpad detected. 77 if not self._has_touchpad: 78 raise error.TestError('No touchpad found on this device!') 79 80 # Check if playback files are available on DUT to run test. 81 self._filepaths = self._find_test_files( 82 'touchpad', [self._CLICK_NAME, self._DRAG_NAME]) 83 if not self._filepaths: 84 logging.info('Missing gesture files, Aborting test.') 85 return False 86 87 return True 88 89 90 def run_once(self): 91 """Entry point of this test.""" 92 if not self._is_testable(): 93 raise error.TestNAError('Missing input data for this board name.') 94 95 # Log in and start test. 96 with chrome.Chrome(autotest_ext=True, 97 init_network_controller=True) as cr: 98 # Setup. 99 self._set_autotest_ext(cr.autotest_ext) 100 self._open_events_page(cr) 101 self._emulate_mouse() 102 self._center_cursor() 103 104 # Check default setting values. 105 logging.info('Checking for default setting values.') 106 self._check_for_click(True) 107 self._check_for_drag(False) 108 109 # Toggle settings in all combinations and check. 110 options = [True, False] 111 option_pairs = itertools.product(options, options) 112 for (click_value, drag_value) in option_pairs: 113 self._center_cursor() 114 self._set_tap_to_click(click_value) 115 self._set_tap_dragging(drag_value) 116 self._check_for_click(click_value) 117 self._check_for_drag(click_value and drag_value) 118