blob: 76f971128e9791eb37518f35f273184c8fd0363a [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
Charlie Mooney2107d6b2015-08-07 11:16:59 -0700158 elif test.name == tests.NOISE_LINE:
159 fn = lambda: _PerformLineNoiseTest(variation, robot, device_spec)
160
Charlie Mooney1777b372015-05-21 10:40:43 -0700161 elif test.name in ONE_FINGERTIP_TAP_TESTS:
162 fingertip = robot.fingertips[TAP_TEST_FINGERTIPS[test.name]]
Charlie Mooney587197f2015-06-05 15:35:02 -0700163 num_taps = 20 if test.name == tests.REPEATED_TAPS else 1
Charlie Mooney1777b372015-05-21 10:40:43 -0700164 vertical_offset = 0
165 if test.name != tests.ONE_FINGER_TAP:
166 vertical_offset = robot.LARGE_FINGERTIP_VERTICAL_OFFSET
Charlie Mooney587197f2015-06-05 15:35:02 -0700167 fn = lambda: _PerformOneFingertipTapTest(
168 variation, robot, device_spec, fingertip,
169 vertical_offset, num_taps)
170
Charlie Mooney4198adb2015-05-04 13:55:20 -0700171 elif test.name == tests.TWO_FINGER_TAP:
172 fn = lambda: _PerformTwoFingerTapTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700173
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700174 elif test.name in PHYSICAL_CLICK_TESTS:
175 fingertips = [robot.fingertips[STANDARD_FINGERTIP]]
176 if test.name == tests.TWO_FINGER_PHYSICAL_CLICK:
177 fingertips.append(robot.fingertips[STANDARD_SECONDARY_FINGERTIP])
178 fn = lambda: _PerformPhysicalClickTest(variation, robot, device_spec,
179 fingertips)
180
Charlie Mooney9426d0c2015-07-01 15:03:45 -0700181 elif test.name == tests.DRUMROLL:
182 fn = lambda: _PerformDrumroll(variation, robot, device_spec)
183
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700184 elif test.name in SINGLE_FINGER_LINE_TESTS:
185 pause = 1 if test.name == tests.ONE_FINGER_TRACKING_FROM_CENTER else 0
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700186 is_swipe = (test.name == tests.ONE_FINGER_SWIPE)
187 fn = lambda: _PerformOneFingerLineTest(variation, robot, device_spec,
188 pause, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700189
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700190 elif test.name in TWO_FINGER_LINE_TESTS:
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700191 spacing = 5
192 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
193 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700194 is_swipe = (test.name == tests.TWO_FINGER_SWIPE)
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700195 if test.name == tests.TWO_CLOSE_FINGERS_TRACKING:
196 spacing = 0
197 elif test.name == tests.TWO_FAT_FINGERS_TRACKING:
198 spacing = 10
199 fingertips = [robot.fingertips[FAT_FINGERTIP],
200 robot.fingertips[FAT_SECONDARY_FINGERTIP]]
Charlie Mooneycfb4a642015-05-07 15:33:37 -0700201 fn = lambda: _PerformTwoFingerLineTest(variation, robot, device_spec,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700202 fingertips, spacing, is_swipe)
Charlie Mooney1777b372015-05-21 10:40:43 -0700203
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700204 elif test.name == tests.RESTING_FINGER_PLUS_2ND_FINGER_MOVE:
Charlie Mooney9a177682015-06-16 15:24:36 -0700205 moving_fingertip = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
206 stationary_location = LOCATION_COORDINATES[tests.GV.BL]
207 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec,
208 moving_fingertip,
209 stationary_location)
210
211 elif test.name == tests.FAT_FINGER_MOVE_WITH_RESTING_FINGER:
212 moving_fingertip = robot.fingertips[FAT_SECONDARY_FINGERTIP]
213 direction, speed = variation
214 stationary_location = STATIONARY_FINGER_LOCATION[direction]
215 fn = lambda: _PerformRestingFingerTest(variation, robot, device_spec,
216 moving_fingertip,
217 stationary_location)
Charlie Mooney1777b372015-05-21 10:40:43 -0700218
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700219 elif test.name == tests.PINCH_TO_ZOOM:
220 fn = lambda: _PerformPinchTest(variation, robot, device_spec)
Charlie Mooney1777b372015-05-21 10:40:43 -0700221
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700222 elif test.name == tests.DRAG_THUMB_EDGE:
223 fn = lambda: _PerformThumbEdgeTest(variation, robot, device_spec)
Charlie Mooney08661912015-04-16 09:20:34 -0700224
225 if fn is None:
Charlie Mooneyca3fc202015-05-21 11:16:53 -0700226 print color.Fore.RED + 'Robot unable to perform gesture! Skipping...'
Charlie Mooney08661912015-04-16 09:20:34 -0700227 return None
228
229 return Thread(target=fn)
230
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700231
Charlie Mooney08661912015-04-16 09:20:34 -0700232def _PerformStationaryNoiseTest(variation, robot, device_spec):
233 frequency, amplitude, waveform, location = variation
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700234 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700235 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
Charlie Mooney4198adb2015-05-04 13:55:20 -0700236 robot.Tap(device_spec, [fingertip], tap_position, touch_time_s=4)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700237
Charlie Mooney2107d6b2015-08-07 11:16:59 -0700238def _PerformLineNoiseTest(variation, robot, device_spec):
239 frequency, amplitude, waveform, direction = variation
240 start, end = LINE_DIRECTION_COORDINATES[direction]
241 fingertip = robot.fingertips[NOISE_TESTING_FINGERTIP]
242 robot.Line(device_spec, [fingertip], start, end, pause_s=1, swipe=False)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700243
Charlie Mooney1777b372015-05-21 10:40:43 -0700244def _PerformOneFingertipTapTest(variation, robot, device_spec, fingertip,
Charlie Mooney587197f2015-06-05 15:35:02 -0700245 vertical_offset, num_taps):
Charlie Mooney1b708112015-04-28 14:46:21 -0700246 location, = variation
247 tap_position = LOCATION_COORDINATES[location]
Charlie Mooney1777b372015-05-21 10:40:43 -0700248 robot.Tap(device_spec, [fingertip], tap_position,
Charlie Mooney587197f2015-06-05 15:35:02 -0700249 vertical_offset=vertical_offset, num_taps=num_taps)
Charlie Mooney4198adb2015-05-04 13:55:20 -0700250
251
252def _PerformTwoFingerTapTest(variation, robot, device_spec):
253 angle, = variation
254
255 fingertip1 = robot.fingertips[STANDARD_FINGERTIP]
256 fingertip2 = robot.fingertips[STANDARD_SECONDARY_FINGERTIP]
257 fingertips = [fingertip1, fingertip2]
258
259 robot.Tap(device_spec, fingertips, (CENTER, CENTER), angle=ANGLES[angle])
Charlie Mooney1b708112015-04-28 14:46:21 -0700260
261
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700262def _PerformOneFingerLineTest(variation, robot, device_spec, pause_time_s,
263 is_swipe):
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700264 direction, speed = variation
265 start, end = LINE_DIRECTION_COORDINATES[direction]
266 fingertip = robot.fingertips[STANDARD_FINGERTIP]
267
268 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700269 robot.Line(device_spec, [fingertip], start, end, pause_s=pause_time_s,
270 swipe=is_swipe)
Charlie Mooneya337d582015-04-29 10:37:45 -0700271 robot.PopSpeed()
272
273
Charlie Mooney7b1fdb92015-05-08 09:22:55 -0700274def _PerformTwoFingerLineTest(variation, robot, device_spec, fingertips,
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700275 spacing_mm, is_swipe):
Charlie Mooneya337d582015-04-29 10:37:45 -0700276 direction, speed = variation
277 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700278 angle = _ComputePerpendicularAngle(start, end)
Charlie Mooneya337d582015-04-29 10:37:45 -0700279
Charlie Mooneya337d582015-04-29 10:37:45 -0700280 robot.PushSpeed(SPEEDS[speed])
Charlie Mooneybe4661e2015-05-20 11:46:43 -0700281 robot.Line(device_spec, fingertips, start, end, fingertip_spacing=spacing_mm,
282 fingertip_angle=angle, swipe=is_swipe)
Charlie Mooney61b4fbb2015-04-22 15:22:02 -0700283 robot.PopSpeed()
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700284
285
Charlie Mooney9a177682015-06-16 15:24:36 -0700286def _PerformRestingFingerTest(variation, robot, device_spec, moving_fingertip,
287 stationary_location):
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700288 direction, speed = variation
289 start, end = LINE_DIRECTION_COORDINATES[direction]
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700290
291 stationary_fingertip = robot.fingertips[STANDARD_FINGERTIP]
Charlie Mooneye9fd6562015-04-30 13:45:19 -0700292
293 robot.PushSpeed(SPEEDS[speed])
294 robot.LineWithStationaryFinger(device_spec, stationary_fingertip,
295 moving_fingertip, start, end,
296 stationary_location)
297 robot.PopSpeed()
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700298
299def _PerformPinchTest(variation, robot, device_spec):
300 direction, angle = variation
301
302 min_spread = 15
303 max_spread = min(device_spec.Height(), device_spec.Width(),
304 robot.MAX_FINGER_DISTANCE)
305 if direction == tests.GV.ZOOM_OUT:
306 start_distance, end_distance = max_spread, min_spread
307 else:
308 start_distance, end_distance = min_spread, max_spread
309
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700310 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
311 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
312
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700313 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
Charlie Mooney058aa5f2015-05-06 12:55:48 -0700314 robot.Pinch(device_spec, fingertips, (CENTER, CENTER), ANGLES[angle],
Charlie Mooney5065bcb2015-05-04 13:18:09 -0700315 start_distance, end_distance)
316 robot.PopSpeed()
Charlie Mooneyc56c8602015-05-07 15:15:40 -0700317
318def _PerformThumbEdgeTest(variation, robot, device_spec):
319 fingertip_type, direction = variation
320 start, end = LINE_DIRECTION_COORDINATES[direction]
321 angle = _ComputePerpendicularAngle(start, end)
322
323 fingertip = robot.fingertips[fingertip_type]
324
325 robot.PushSpeed(SPEEDS[tests.GV.NORMAL])
326 robot.Line(device_spec, [fingertip], start, end, fingertip_angle=angle)
327 robot.PopSpeed()
Charlie Mooneya5a5d3e2015-06-11 13:48:01 -0700328
329def _PerformPhysicalClickTest(variation, robot, device_spec, fingertips):
330 location, = variation
331 click_position = LOCATION_COORDINATES[location]
332 robot.Click(device_spec, fingertips, click_position)
Charlie Mooney9426d0c2015-07-01 15:03:45 -0700333
334def _PerformDrumroll(variation, robot, device_spec):
335 fingertips = [robot.fingertips[STANDARD_FINGERTIP],
336 robot.fingertips[STANDARD_SECONDARY_FINGERTIP]]
337 location = LOCATION_COORDINATES[tests.GV.CENTER]
338 robot.Drumroll(device_spec, fingertips, location)