blob: d9bedf6ed65d97c1c31719685a1826ce7147271a [file] [log] [blame]
Charlie Mooney08661912015-04-16 09:20:34 -07001# Copyright 2015 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
5""" This is a module containing functions that allow the test suite to
6determine the specifics of the gesture and execute them on the touchbot.
7In essence, you use this class to go from a Test object to the robot
8actually performing the correct gesture on the pad.
9"""
10
Charlie Mooneya337d582015-04-29 10:37:45 -070011import math
Charlie Mooney08661912015-04-16 09:20:34 -070012from threading import Thread
13
14import colorama as color
15
16import tests
17from touchbot import Touchbot
18
19
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070020STANDARD_FINGERTIP = '1round_9mm'
Charlie Mooneya337d582015-04-29 10:37:45 -070021STANDARD_SECONDARY_FINGERTIP = '2round_9mm'
Charlie Mooney7b1fdb92015-05-08 09:22:55 -070022FAT_FINGERTIP = '1round_14mm'
23FAT_SECONDARY_FINGERTIP = '2round_14mm'
24NOISE_TESTING_FINGERTIP = '1round_12mm'
Charlie Mooney1777b372015-05-21 10:40:43 -070025THREE_FINGER_FINGERTIP = 'three_fingers'
26FOUR_FINGER_FINGERTIP = 'four_fingers'
27FIVE_FINGER_FINGERTIP = 'five_fingers'
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070028
Charlie Mooney08661912015-04-16 09:20:34 -070029BUFFER_SIZE = 0.1
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070030OVERSHOOT_DISTANCE = 0.05
Charlie Mooney08661912015-04-16 09:20:34 -070031LEFT = BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070032OVER_LEFT = -OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070033RIGHT = 1.0 - BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070034OVER_RIGHT = 1.0 + OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070035TOP = BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070036OVER_TOP = -OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070037BOTTOM = 1.0 - BUFFER_SIZE
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070038OVER_BOTTOM = 1.0 + OVERSHOOT_DISTANCE
Charlie Mooney08661912015-04-16 09:20:34 -070039CENTER = 0.5
40
41LOCATION_COORDINATES = {
42 tests.GV.TL: (LEFT, TOP),
43 tests.GV.TR: (RIGHT, TOP),
44 tests.GV.BL: (LEFT, BOTTOM),
45 tests.GV.BR: (RIGHT, BOTTOM),
46 tests.GV.TS: (CENTER, TOP),
47 tests.GV.BS: (CENTER, BOTTOM),
48 tests.GV.LS: (LEFT, CENTER),
49 tests.GV.RS: (RIGHT, CENTER),
50 tests.GV.CENTER: (CENTER, CENTER),
51}
52
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070053LINE_DIRECTION_COORDINATES = {
54 tests.GV.LR: ((LEFT, CENTER), (RIGHT, CENTER)),
55 tests.GV.RL: ((RIGHT, CENTER), (LEFT, CENTER)),
56 tests.GV.TB: ((CENTER, TOP), (CENTER, BOTTOM)),
57 tests.GV.BT: ((CENTER, BOTTOM), (CENTER, TOP)),
58 tests.GV.BLTR: ((LEFT, BOTTOM), (RIGHT, TOP)),
59 tests.GV.BRTL: ((RIGHT, BOTTOM), (LEFT, TOP)),
60 tests.GV.TRBL: ((RIGHT, TOP), (LEFT, BOTTOM)),
61 tests.GV.TLBR: ((LEFT, TOP), (RIGHT, BOTTOM)),
62 tests.GV.CL: ((CENTER, CENTER), (OVER_LEFT, CENTER)),
63 tests.GV.CR: ((CENTER, CENTER), (OVER_RIGHT, CENTER)),
64 tests.GV.CT: ((CENTER, CENTER), (CENTER, OVER_TOP)),
65 tests.GV.CB: ((CENTER, CENTER), (CENTER, OVER_BOTTOM)),
66 tests.GV.CUL: ((CENTER, CENTER), (OVER_LEFT, OVER_TOP)),
67 tests.GV.CLL: ((CENTER, CENTER), (OVER_LEFT, OVER_BOTTOM)),
68 tests.GV.CLR: ((CENTER, CENTER), (OVER_RIGHT, OVER_BOTTOM)),
69}
70
Charlie Mooney9a177682015-06-16 15:24:36 -070071STATIONARY_FINGER_LOCATION = {
72 tests.GV.LR: LOCATION_COORDINATES[tests.GV.TS],
73 tests.GV.RL: LOCATION_COORDINATES[tests.GV.BS],
74 tests.GV.TB: LOCATION_COORDINATES[tests.GV.LS],
75 tests.GV.BT: LOCATION_COORDINATES[tests.GV.RS],
76}
77
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070078SPEEDS = {
79 tests.GV.NORMAL: Touchbot.SPEED_MEDIUM,
80 tests.GV.SLOW: Touchbot.SPEED_SLOW,
Charlie Mooneybe4661e2015-05-20 11:46:43 -070081 tests.GV.FAST: Touchbot.SPEED_FAST,
Charlie Mooney61b4fbb2015-04-22 15:22:02 -070082}
83
Charlie Mooney4198adb2015-05-04 13:55:20 -070084ANGLES = {
Charlie Mooney5065bcb2015-05-04 13:18:09 -070085 tests.GV.HORIZONTAL: 0,
86 tests.GV.VERTICAL: 90,
87 tests.GV.DIAGONAL: 45,
88}
89
Charlie Mooney1777b372015-05-21 10:40:43 -070090ONE_FINGERTIP_TAP_TESTS = [
91 tests.ONE_FINGER_TAP,
Charlie Mooney587197f2015-06-05 15:35:02 -070092 tests.REPEATED_TAPS,
Charlie Mooney1777b372015-05-21 10:40:43 -070093 tests.THREE_FINGER_TAP,
94 tests.FOUR_FINGER_TAP,
95 tests.FIVE_FINGER_TAP,
96]
97
98TAP_TEST_FINGERTIPS = {
99 tests.ONE_FINGER_TAP: STANDARD_FINGERTIP,
Charlie Mooney587197f2015-06-05 15:35:02 -0700100 tests.REPEATED_TAPS: STANDARD_FINGERTIP,
Charlie Mooney1777b372015-05-21 10:40:43 -0700101 tests.THREE_FINGER_TAP: THREE_FINGER_FINGERTIP,
102 tests.FOUR_FINGER_TAP: FOUR_FINGER_FINGERTIP,
103 tests.FIVE_FINGER_TAP: FIVE_FINGER_FINGERTIP,
104}
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700105
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700106SINGLE_FINGER_LINE_TESTS = [
107 tests.ONE_FINGER_TO_EDGE,
108 tests.ONE_FINGER_TRACKING,
109 tests.ONE_FINGER_TRACKING_FROM_CENTER,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700110 tests.ONE_FINGER_SWIPE,
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700111]
112
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700113TWO_FINGER_LINE_TESTS = [
114 tests.TWO_FINGER_TRACKING,
115 tests.TWO_CLOSE_FINGERS_TRACKING,
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700116 tests.TWO_FAT_FINGERS_TRACKING,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700117 tests.TWO_FINGER_SWIPE,
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700118]
119
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700120PHYSICAL_CLICK_TESTS = [
121 tests.ONE_FINGER_PHYSICAL_CLICK,
122 tests.TWO_FINGER_PHYSICAL_CLICK,
123]
124
Charlie Mooney08661912015-04-16 09:20:34 -0700125
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700126def _ComputePerpendicularAngle(start, end):
127 """ Compute the fingertip angle to be perpendicular to the
128 movement direction.
129
130 The robot's X/Y axes are not in the same direction as the touch device's,
131 they are flipped.
132
133 DUT x ----> Robot y ---->
134 y x
135 | |
136 | |
137 \/ \/
138
139 As a result the angle is computed in the DUT space, but then must have
140 its sign flipped before being used in any commands to the robot or
141 everything will be wrong since it's a clockwise angle instead of counter-
142 clockwise.
143 """
144 x1, y1 = start
145 x2, y2 = end
146 dy = y2 - y1
147 dx = x2 - x1
148 return -1 * (math.degrees(math.atan2(y2 - y1, x2 - x1)) + 90)
149
150
Charlie Mooney08661912015-04-16 09:20:34 -0700151def PerformCorrespondingGesture(test, variation_number, robot, device_spec):
152 variation = test.variations[variation_number]
153 fn = None
Charlie Mooney1777b372015-05-21 10:40:43 -0700154
Charlie Mooney08661912015-04-16 09:20:34 -0700155 if test.name == tests.NOISE_STATIONARY:
156 fn = lambda: _PerformStationaryNoiseTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700157
158 elif test.name in ONE_FINGERTIP_TAP_TESTS:
159 fingertip = robot.fingertips[TAP_TEST_FINGERTIPS[test.name]]
Charlie Mooney587197f2015-06-05 15:35:02 -0700160 num_taps = 20 if test.name == tests.REPEATED_TAPS else 1
Charlie Mooney1777b372015-05-21 10:40:43 -0700161 vertical_offset = 0
162 if test.name != tests.ONE_FINGER_TAP:
163 vertical_offset = robot.LARGE_FINGERTIP_VERTICAL_OFFSET
Charlie Mooney587197f2015-06-05 15:35:02 -0700164 fn = lambda: _PerformOneFingertipTapTest(
165 variation, robot, device_spec, fingertip,
166 vertical_offset, num_taps)
167
Charlie Mooney4198adb2015-05-04 13:55:20 -0700168 elif test.name == tests.TWO_FINGER_TAP:
169 fn = lambda: _PerformTwoFingerTapTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700170
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700171 elif test.name in PHYSICAL_CLICK_TESTS:
172 fingertips = [robot.fingertips[STANDARD_FINGERTIP]]
173 if test.name == tests.TWO_FINGER_PHYSICAL_CLICK:
174 fingertips.append(robot.fingertips[STANDARD_SECONDARY_FINGERTIP])
175 fn = lambda: _PerformPhysicalClickTest(variation, robot, device_spec,
176 fingertips)
177
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700178 elif test.name in SINGLE_FINGER_LINE_TESTS:
179 pause = 1 if test.name == tests.ONE_FINGER_TRACKING_FROM_CENTER else 0
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700180 is_swipe = (test.name == tests.ONE_FINGER_SWIPE)
181 fn = lambda: _PerformOneFingerLineTest(variation, robot, device_spec,
182 pause, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700183
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700184 elif test.name in TWO_FINGER_LINE_TESTS:
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700185 spacing = 5
186 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
187 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700188 is_swipe = (test.name == tests.TWO_FINGER_SWIPE)
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700189 if test.name == tests.TWO_CLOSE_FINGERS_TRACKING:
190 spacing = 0
191 elif test.name == tests.TWO_FAT_FINGERS_TRACKING:
192 spacing = 10
193 fingertips = [robot.fingertips[FAT_FINGERTIP],
194 robot.fingertips[FAT_SECONDARY_FINGERTIP]]
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700195 fn = lambda: _PerformTwoFingerLineTest(variation, robot, device_spec,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700196 fingertips, spacing, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700197
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700198 elif test.name == tests.RESTING_FINGER_PLUS_2ND_FINGER_MOVE:
Charlie Mooney9a177682015-06-16 15:24:36 -0700199 moving_fingertip = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
200 stationary_location = LOCATION_COORDINATES[tests.GV.BL]
201 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec,
202 moving_fingertip,
203 stationary_location)
204
205 elif test.name == tests.FAT_FINGER_MOVE_WITH_RESTING_FINGER:
206 moving_fingertip = robot.fingertips[FAT_SECONDARY_FINGERTIP]
207 direction, speed = variation
208 stationary_location = STATIONARY_FINGER_LOCATION[direction]
209 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec,
210 moving_fingertip,
211 stationary_location)
Charlie Mooney1777b372015-05-21 10:40:43 -0700212
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700213 elif test.name == tests.PINCH_TO_ZOOM:
214 fn = lambda: _PerformPinchTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700215
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700216 elif test.name == tests.DRAG_THUMB_EDGE:
217 fn = lambda: _PerformThumbEdgeTest(variation, robot, device_spec)
Charlie Mooney08661912015-04-16 09:20:34 -0700218
219 if fn is None:
Charlie Mooneyca3fc202015-05-21 11:16:53 -0700220 print color.Fore.RED + 'Robot unable to perform gesture! Skipping...'
Charlie Mooney08661912015-04-16 09:20:34 -0700221 return None
222
223 return Thread(target=fn)
224
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700225
Charlie Mooney08661912015-04-16 09:20:34 -0700226def _PerformStationaryNoiseTest(variation, robot, device_spec):
227 frequency, amplitude, waveform, location = variation
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700228 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700229 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
Charlie Mooney4198adb2015-05-04 13:55:20 -0700230 robot.Tap(device_spec, [fingertip], tap_position, touch_time_s=4)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700231
232
Charlie Mooney1777b372015-05-21 10:40:43 -0700233def _PerformOneFingertipTapTest(variation, robot, device_spec, fingertip,
Charlie Mooney587197f2015-06-05 15:35:02 -0700234 vertical_offset, num_taps):
Charlie Mooney1b708112015-04-28 14:46:21 -0700235 location, = variation
236 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney1777b372015-05-21 10:40:43 -0700237 robot.Tap(device_spec, [fingertip], tap_position,
Charlie Mooney587197f2015-06-05 15:35:02 -0700238 vertical_offset=vertical_offset, num_taps=num_taps)
Charlie Mooney4198adb2015-05-04 13:55:20 -0700239
240
241def _PerformTwoFingerTapTest(variation, robot, device_spec):
242 angle, = variation
243
244 fingertip1 = robot.fingertips[STANDARD_FINGERTIP]
245 fingertip2 = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
246 fingertips = [fingertip1, fingertip2]
247
248 robot.Tap(device_spec, fingertips, (CENTER, CENTER), angle=ANGLES[angle])
Charlie Mooney1b708112015-04-28 14:46:21 -0700249
250
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700251def _PerformOneFingerLineTest(variation, robot, device_spec, pause_time_s,
252 is_swipe):
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700253 direction, speed = variation
254 start, end = LINE_DIRECTION_COORDINATES[direction]
255 fingertip = robot.fingertips[STANDARD_FINGERTIP]
256
257 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700258 robot.Line(device_spec, [fingertip], start, end, pause_s=pause_time_s,
259 swipe=is_swipe)
Charlie Mooneya337d582015-04-29 10:37:45 -0700260 robot.PopSpeed()
261
262
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700263def _PerformTwoFingerLineTest(variation, robot, device_spec, fingertips,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700264 spacing_mm, is_swipe):
Charlie Mooneya337d582015-04-29 10:37:45 -0700265 direction, speed = variation
266 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700267 angle = _ComputePerpendicularAngle(start, end)
Charlie Mooneya337d582015-04-29 10:37:45 -0700268
Charlie Mooneya337d582015-04-29 10:37:45 -0700269 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700270 robot.Line(device_spec, fingertips, start, end, fingertip_spacing=spacing_mm,
271 fingertip_angle=angle, swipe=is_swipe)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700272 robot.PopSpeed()
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700273
274
Charlie Mooney9a177682015-06-16 15:24:36 -0700275def _PerformRestingFingerTest(variation, robot, device_spec, moving_fingertip,
276 stationary_location):
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700277 direction, speed = variation
278 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700279
280 stationary_fingertip = robot.fingertips[STANDARD_FINGERTIP]
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700281
282 robot.PushSpeed(SPEEDS[speed])
283 robot.LineWithStationaryFinger(device_spec, stationary_fingertip,
284 moving_fingertip, start, end,
285 stationary_location)
286 robot.PopSpeed()
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700287
288def _PerformPinchTest(variation, robot, device_spec):
289 direction, angle = variation
290
291 min_spread = 15
292 max_spread = min(device_spec.Height(), device_spec.Width(),
293 robot.MAX_FINGER_DISTANCE)
294 if direction == tests.GV.ZOOM_OUT:
295 start_distance, end_distance = max_spread, min_spread
296 else:
297 start_distance, end_distance = min_spread, max_spread
298
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700299 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
300 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
301
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700302 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700303 robot.Pinch(device_spec, fingertips, (CENTER, CENTER), ANGLES[angle],
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700304 start_distance, end_distance)
305 robot.PopSpeed()
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700306
307def _PerformThumbEdgeTest(variation, robot, device_spec):
308 fingertip_type, direction = variation
309 start, end = LINE_DIRECTION_COORDINATES[direction]
310 angle = _ComputePerpendicularAngle(start, end)
311
312 fingertip = robot.fingertips[fingertip_type]
313
314 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
315 robot.Line(device_spec, [fingertip], start, end, fingertip_angle=angle)
316 robot.PopSpeed()
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700317
318def _PerformPhysicalClickTest(variation, robot, device_spec, fingertips):
319 location, = variation
320 click_position = LOCATION_COORDINATES[location]
321 robot.Click(device_spec, fingertips, click_position)