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