test_conf.py revision 3355dcdfdac4cdea9f3cc4953409a8607d0f6e5b
1# -*- coding: utf-8 -*-
2#
3# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""This configuration file defines the gestures to perform."""
8
9from firmware_constants import DEV, GV, VAL
10from validators import (CountPacketsValidator,
11                        CountTrackingIDNormalFingerValidator,
12                        CountTrackingIDFatFingerValidator,
13                        DrumrollValidator,
14                        HysteresisValidator,
15                        LinearityValidator,
16                        NoGapValidator,
17                        NoReversedMotionValidator,
18                        PhysicalClickValidator,
19                        PinchValidator,
20                        RangeValidator,
21                        ReportRateValidator,
22                        StationaryFingerValidator,
23                        StationaryTapValidator,
24)
25
26
27# Define which score aggregator is to be used. A score aggregator collects
28# the scores from every tests and calculates the final score for the touch
29# firmware test suite.
30score_aggregator = 'fuzzy.average'
31
32
33# Define some common criteria
34count_packets_criteria = '>= 3, ~ -3'
35drumroll_criteria = '<= 2.0'
36# linearity_criteria is used for strictly straight line drawn with a ruler.
37linearity_criteria = '<= 0.8, ~ +2.4'
38# relaxed_linearity_criteria is used for lines drawn with thumb edge or
39# fat fingers which are allowed to be curvy to some extent.
40relaxed_linearity_criteria = '<= 1.5, ~ +3.0'
41no_gap_criteria = '<= 1.8, ~ +1.0'
42no_level_jump_criteria = '<= 10, ~ +30'
43no_reversed_motion_criteria = '<= 5, ~ +30'
44pinch_criteria = '>= 200, ~ -100'
45range_criteria = '<= 0.01, ~ +0.07'
46min_report_rate = 60
47max_report_interval = 1.0 / min_report_rate * 1000
48report_rate_criteria = '>= %d' % min_report_rate
49stationary_finger_criteria = '<= 1.0'
50stationary_tap_criteria = '<= 1.0'
51hysteresis_criteria = '<= 2.0'
52
53MIN_MOVING_DISTANCE = 20
54
55
56# Define filenames and paths
57docroot = '/tmp'
58report_basename = 'touch_firmware_report'
59html_ext = '.html'
60ENVIRONMENT_REPORT_HTML_NAME = 'REPORT_HTML_NAME'
61log_root_dir = '/var/tmp/touch_firmware_test'
62fw_prefix = 'fw_'
63device_description_dir = 'tests/device'
64
65
66# Define parameters for GUI
67score_colors = ((0.9, 'blue'), (0.8, 'orange'), (0.0, 'red'))
68num_chars_per_row = 28
69
70
71# Define the validators that are shown only when there are failures.
72validators_hidden_when_no_failures = ['PinchValidator',
73                                      'CountTrackingIDNormalFingerValidator',
74                                      'CountTrackingIDFatFingerValidator',
75                                      'CountPacketsValidator']
76
77
78# Define the path to find the robot gestures library path
79robot_lib_path = '/usr/lib*'
80python_package = 'python*'
81gestures_sub_path = 'site-packages/touchbotII'
82
83
84# Define the gesture names
85ONE_FINGER_TRACKING = 'one_finger_tracking'
86ONE_FINGER_TO_EDGE = 'one_finger_to_edge'
87TWO_FINGER_TRACKING = 'two_finger_tracking'
88FINGER_CROSSING = 'finger_crossing'
89ONE_FINGER_SWIPE = 'one_finger_swipe'
90TWO_FINGER_SWIPE = 'two_finger_swipe'
91PINCH_TO_ZOOM = 'pinch_to_zoom'
92ONE_FINGER_TAP = 'one_finger_tap'
93TWO_FINGER_TAP = 'two_finger_tap'
94ONE_FINGER_PHYSICAL_CLICK = 'one_finger_physical_click'
95TWO_FINGER_PHYSICAL_CLICK = 'two_fingers_physical_click'
96THREE_FINGER_PHYSICAL_CLICK = 'three_fingers_physical_click'
97FOUR_FINGER_PHYSICAL_CLICK = 'four_fingers_physical_click'
98FIVE_FINGER_PHYSICAL_CLICK = 'five_fingers_physical_click'
99STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS = \
100        'stationary_finger_not_affected_by_2nd_finger_taps'
101FAT_FINGER_MOVE_WITH_RESTING_FINGER = 'fat_finger_move_with_resting_finger'
102DRAG_EDGE_THUMB = 'drag_edge_thumb'
103TWO_CLOSE_FINGERS_TRACKING = 'two_close_fingers_tracking'
104RESTING_FINGER_PLUS_2ND_FINGER_MOVE = 'resting_finger_plus_2nd_finger_move'
105TWO_FAT_FINGERS_TRACKING = 'two_fat_fingers_tracking'
106FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS = \
107        'first_finger_tracking_and_second_finger_taps'
108DRUMROLL = 'drumroll'
109RAPID_TAPS = 'rapid_taps_20'
110ONE_FINGER_TRACKING_FROM_CENTER = 'one_finger_tracking_from_center'
111# This following gesture is for pressure calibration.
112PRESSURE_CALIBRATION = 'pressure_calibration'
113
114# This denotes the list of the numbers of fingers for physical click tests.
115# It corresponds to ONE/TWO/THREE/FOUR/FIVE_FINGER_PHYSICAL_CLICK defined above.
116fingers_physical_click = [1, 2, 3, 4, 5]
117
118
119# Define the complete list
120gesture_names_complete = {
121    DEV.TOUCHPAD: [
122        ONE_FINGER_TRACKING,
123        ONE_FINGER_TO_EDGE,
124        TWO_FINGER_TRACKING,
125        FINGER_CROSSING,
126        ONE_FINGER_SWIPE,
127        ONE_FINGER_TRACKING_FROM_CENTER,
128        TWO_FINGER_SWIPE,
129        PINCH_TO_ZOOM,
130        ONE_FINGER_TAP,
131        TWO_FINGER_TAP,
132        ONE_FINGER_PHYSICAL_CLICK,
133        TWO_FINGER_PHYSICAL_CLICK,
134        THREE_FINGER_PHYSICAL_CLICK,
135        FOUR_FINGER_PHYSICAL_CLICK,
136        FIVE_FINGER_PHYSICAL_CLICK,
137        STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS,
138        FAT_FINGER_MOVE_WITH_RESTING_FINGER,
139        DRAG_EDGE_THUMB,
140        TWO_CLOSE_FINGERS_TRACKING,
141        RESTING_FINGER_PLUS_2ND_FINGER_MOVE,
142        TWO_FAT_FINGERS_TRACKING,
143        FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS,
144        DRUMROLL,
145        RAPID_TAPS,
146    ],
147    DEV.TOUCHSCREEN: [
148        ONE_FINGER_TRACKING,
149        ONE_FINGER_TO_EDGE,
150        TWO_FINGER_TRACKING,
151        FINGER_CROSSING,
152        ONE_FINGER_SWIPE,
153        ONE_FINGER_TRACKING_FROM_CENTER,
154        TWO_FINGER_SWIPE,
155        PINCH_TO_ZOOM,
156        ONE_FINGER_TAP,
157        TWO_FINGER_TAP,
158        STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS,
159        FAT_FINGER_MOVE_WITH_RESTING_FINGER,
160        DRAG_EDGE_THUMB,
161        TWO_CLOSE_FINGERS_TRACKING,
162        RESTING_FINGER_PLUS_2ND_FINGER_MOVE,
163        TWO_FAT_FINGERS_TRACKING,
164        FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS,
165        DRUMROLL,
166        RAPID_TAPS,
167    ],
168}
169
170
171# Define what gestures the robot can perform.
172# This also defines the order for the robot to perform the gestures.
173# Basically, two-fingers gestures follow one-finger gestures.
174robot_capability_list = [
175    ONE_FINGER_TRACKING,
176    ONE_FINGER_TO_EDGE,
177    ONE_FINGER_SWIPE,
178    ONE_FINGER_TRACKING_FROM_CENTER,
179    ONE_FINGER_TAP,
180    RAPID_TAPS,
181    TWO_FINGER_TRACKING,
182    TWO_FINGER_SWIPE,
183    TWO_FINGER_TAP,
184    RESTING_FINGER_PLUS_2ND_FINGER_MOVE,
185    PINCH_TO_ZOOM,
186    ONE_FINGER_PHYSICAL_CLICK,
187    TWO_FINGER_PHYSICAL_CLICK,
188    THREE_FINGER_PHYSICAL_CLICK,
189    FOUR_FINGER_PHYSICAL_CLICK,
190]
191
192robot_must_start_without_fingertips = [
193    ONE_FINGER_PHYSICAL_CLICK,
194    TWO_FINGER_PHYSICAL_CLICK,
195    THREE_FINGER_PHYSICAL_CLICK,
196    FOUR_FINGER_PHYSICAL_CLICK,
197]
198
199def get_gesture_names_for_robot(device):
200    """Get the gesture names that a robot can do for a specified device."""
201    return [gesture for gesture in robot_capability_list
202                    if gesture in gesture_names_complete[device]]
203
204
205# Define the list of one-finger and two-finger gestures to test using the robot.
206gesture_names_robot = {
207    DEV.TOUCHPAD: get_gesture_names_for_robot(DEV.TOUCHPAD),
208    DEV.TOUCHSCREEN: get_gesture_names_for_robot(DEV.TOUCHSCREEN),
209}
210
211
212# Define the manual list which is gesture_names_complete - gesture_names_robot
213gesture_names_manual = {}
214for dev in DEV.DEVICE_TYPE_LIST:
215    complete_gesture_list = gesture_names_complete[dev]
216    manual_set = set(complete_gesture_list) - set(gesture_names_robot[dev])
217    gesture_names_manual[dev] = [gesture for gesture in complete_gesture_list
218                                 if gesture in manual_set]
219
220
221# Define the gesture for pressure calibration
222gesture_names_calibration = [PRESSURE_CALIBRATION,]
223
224# Define the relative segment weights of a validator.
225# For example, LinearityMiddleValidator : LinearityBothEndsValidator = 7 : 3
226segment_weights = {VAL.BEGIN: 0.15,
227                   VAL.MIDDLE: 0.7,
228                   VAL.END: 0.15,
229                   VAL.BOTH_ENDS: 0.15 + 0.15,
230                   VAL.WHOLE: 0.15 + 0.7 + 0.15,
231}
232
233
234# Define the validator score weights
235weight_rare = 1
236weight_common = 2
237weight_critical = 3
238validator_weights = {'CountPacketsValidator': weight_common,
239                     'CountTrackingIDNormalFingerValidator': weight_critical,
240                     'CountTrackingIDFatFingerValidator': weight_rare,
241                     'DrumrollValidator': weight_rare,
242                     'LinearityValidator': weight_common,
243                     'NoGapValidator': weight_common,
244                     'NoReversedMotionValidator': weight_common,
245                     'PhysicalClickValidator': weight_critical,
246                     'PinchValidator': weight_common,
247                     'RangeValidator': weight_common,
248                     'ReportRateValidator': weight_common,
249                     'HysteresisValidator': weight_common,
250                     'StationaryFingerValidator': weight_common,
251                     'StationaryTapValidator': weight_common,
252}
253
254
255# Define the gesture list that the user needs to perform in the test suite.
256def get_gesture_dict():
257    """Define the dictionary for all gestures."""
258    gesture_dict = {
259        ONE_FINGER_TRACKING:
260        Gesture(
261            name=ONE_FINGER_TRACKING,
262            variations=((GV.LR, GV.RL, GV.TB, GV.BT, GV.BLTR, GV.TRBL),
263                        (GV.SLOW, GV.NORMAL),
264            ),
265            prompt='Take {2} to draw a straight, {0} line {1} using a ruler.',
266            subprompt={
267                GV.LR: ('horizontal', 'from left to right',),
268                GV.RL: ('horizontal', 'from right to left',),
269                GV.TB: ('vertical', 'from top to bottom',),
270                GV.BT: ('vertical', 'from bottom to top',),
271                GV.BLTR: ('diagonal', 'from bottom left to top right',),
272                GV.TRBL: ('diagonal', 'from top right to bottom left',),
273                GV.SLOW: ('3 seconds',),
274                GV.NORMAL: ('1 second',),
275            },
276            validators=(
277                CountTrackingIDNormalFingerValidator('== 1'),
278                LinearityValidator(linearity_criteria, finger=0,
279                                   segments=VAL.MIDDLE),
280                NoGapValidator(no_gap_criteria, slot=0),
281                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0,
282                                          segments=VAL.MIDDLE),
283                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0,
284                                          segments=VAL.BOTH_ENDS),
285                ReportRateValidator(report_rate_criteria),
286            ),
287        ),
288
289        ONE_FINGER_TO_EDGE:
290        Gesture(
291            name=ONE_FINGER_TO_EDGE,
292            variations=((GV.CL, GV.CR, GV.CT, GV.CB),
293                        (GV.SLOW,),
294            ),
295            prompt='Take {2} to draw a striaght {0} line {1}.',
296            subprompt={
297                GV.CL: ('horizontal', 'from the center off left edge',),
298                GV.CR: ('horizontal', 'from the center off right edge',),
299                GV.CT: ('vertical', 'from the center  off top edge',),
300                GV.CB: ('vertical', 'from the center off bottom edge',),
301                GV.SLOW: ('2 seconds',),
302            },
303            validators=(
304                CountTrackingIDNormalFingerValidator('== 1'),
305                LinearityValidator(linearity_criteria, finger=0,
306                                   segments=VAL.MIDDLE),
307                NoGapValidator(no_gap_criteria, slot=0),
308                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0),
309                RangeValidator(range_criteria),
310                ReportRateValidator(report_rate_criteria),
311            ),
312        ),
313
314        TWO_FINGER_TRACKING:
315        Gesture(
316            name=TWO_FINGER_TRACKING,
317            variations=((GV.LR, GV.RL, GV.TB, GV.BT, GV.BLTR, GV.TRBL),
318                        (GV.SLOW, GV.NORMAL),
319            ),
320            prompt='Take {2} to draw a {0} line {1} using a ruler '
321                   'with TWO fingers at the same time.',
322            subprompt={
323                GV.LR: ('horizontal', 'from left to right',),
324                GV.RL: ('horizontal', 'from right to left',),
325                GV.TB: ('vertical', 'from top to bottom',),
326                GV.BT: ('vertical', 'from bottom to top',),
327                GV.BLTR: ('diagonal', 'from bottom left to top right',),
328                GV.TRBL: ('diagonal', 'from top right to bottom left',),
329                GV.SLOW: ('3 seconds',),
330                GV.NORMAL: ('1 second',),
331            },
332            validators=(
333                CountTrackingIDNormalFingerValidator('== 2'),
334                LinearityValidator(linearity_criteria, finger=0,
335                                   segments=VAL.MIDDLE),
336                LinearityValidator(linearity_criteria, finger=1,
337                                   segments=VAL.MIDDLE),
338                NoGapValidator(no_gap_criteria, slot=0),
339                NoGapValidator(no_gap_criteria, slot=1),
340                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0),
341                NoReversedMotionValidator(no_reversed_motion_criteria, slots=1),
342                ReportRateValidator(report_rate_criteria),
343            ),
344        ),
345
346        FINGER_CROSSING:
347        Gesture(
348            # also covers stationary_finger_not_affected_by_2nd_moving_finger
349            name=FINGER_CROSSING,
350            variations=((GV.LR, GV.RL, GV.TB, GV.BT, GV.BLTR, GV.TRBL),
351                        (GV.SLOW, GV.NORMAL),
352            ),
353            prompt='Place one stationary finger near the center of the '
354                   'touch surface, then take {2} to draw a straight line '
355                   '{0} {1} with a second finger',
356            subprompt={
357                GV.LR: ('from left to right', 'above the stationary finger'),
358                GV.RL: ('from right to left', 'below the stationary finger'),
359                GV.TB: ('from top to bottom',
360                        'on the right to the stationary finger'),
361                GV.BT: ('from bottom to top',
362                        'on the left to the stationary finger'),
363                GV.BLTR: ('from the bottom left to the top right',
364                          'above the stationary finger',),
365                GV.TRBL: ('from the top right to the bottom left',
366                          'below the stationary finger'),
367                GV.SLOW: ('3 seconds',),
368                GV.NORMAL: ('1 second',),
369            },
370            validators=(
371                CountTrackingIDNormalFingerValidator('== 2'),
372                NoGapValidator(no_gap_criteria, slot=1),
373                NoReversedMotionValidator(no_reversed_motion_criteria, slots=1),
374                ReportRateValidator(report_rate_criteria, finger=1),
375                StationaryFingerValidator(stationary_finger_criteria, slot=0),
376            ),
377        ),
378
379        ONE_FINGER_SWIPE:
380        Gesture(
381            name=ONE_FINGER_SWIPE,
382            variations=(GV.BLTR, GV.TRBL),
383            prompt='Use ONE finger to quickly swipe {0}.',
384            subprompt={
385                GV.BLTR: ('from the bottom left to the top right',),
386                GV.TRBL: ('from the top right to the bottom left',),
387            },
388            validators=(
389                CountPacketsValidator(count_packets_criteria, slot=0),
390                CountTrackingIDNormalFingerValidator('== 1'),
391                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0),
392                ReportRateValidator(report_rate_criteria),
393            ),
394        ),
395
396        TWO_FINGER_SWIPE:
397        Gesture(
398            name=TWO_FINGER_SWIPE,
399            variations=(GV.TB, GV.BT),
400            prompt='Use TWO fingers to quickly swipe {0}.',
401            subprompt={
402                GV.TB: ('from top to bottom',),
403                GV.BT: ('from bottom to top',),
404            },
405            validators=(
406                CountPacketsValidator(count_packets_criteria, slot=0),
407                CountPacketsValidator(count_packets_criteria, slot=1),
408                CountTrackingIDNormalFingerValidator('== 2'),
409                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0),
410                NoReversedMotionValidator(no_reversed_motion_criteria, slots=1),
411                ReportRateValidator(report_rate_criteria),
412            ),
413        ),
414
415        PINCH_TO_ZOOM:
416        Gesture(
417            name=PINCH_TO_ZOOM,
418            variations=(GV.ZOOM_IN, GV.ZOOM_OUT),
419            prompt='Using two fingers, preform a "{0}" pinch by bringing'
420                   'your fingers {1}.',
421            subprompt={
422                GV.ZOOM_IN: ('zoom in', 'farther apart'),
423                GV.ZOOM_OUT: ('zoom out', 'closer together'),
424            },
425            validators=(
426                CountTrackingIDNormalFingerValidator('== 2'),
427                PinchValidator(pinch_criteria),
428                ReportRateValidator(report_rate_criteria),
429            ),
430        ),
431
432        ONE_FINGER_TAP:
433        Gesture(
434            name=ONE_FINGER_TAP,
435            variations=(GV.TL, GV.TR, GV.BL, GV.BR, GV.TS, GV.BS, GV.LS, GV.RS,
436                        GV.CENTER),
437            prompt='Use one finger to tap on the {0} of the touch surface.',
438            subprompt={
439                GV.TL: ('top left corner',),
440                GV.TR: ('top right corner',),
441                GV.BL: ('bottom left corner',),
442                GV.BR: ('bottom right corner',),
443                GV.TS: ('top edge',),
444                GV.BS: ('bottom side',),
445                GV.LS: ('left hand side',),
446                GV.RS: ('right hand side',),
447                GV.CENTER: ('center',),
448            },
449            validators=(
450                CountTrackingIDNormalFingerValidator('== 1'),
451                StationaryTapValidator(stationary_tap_criteria, slot=0),
452            ),
453        ),
454
455        TWO_FINGER_TAP:
456        Gesture(
457            name=TWO_FINGER_TAP,
458            variations=(GV.HORIZONTAL, GV.VERTICAL, GV.DIAGONAL),
459            prompt='Use two fingers aligned {0} to tap the center of the '
460                   'touch surface.',
461            subprompt={
462                GV.HORIZONTAL: ('horizontally',),
463                GV.VERTICAL: ('vertically',),
464                GV.DIAGONAL: ('diagonally',),
465            },
466            validators=(
467                CountTrackingIDNormalFingerValidator('== 2'),
468                StationaryTapValidator(stationary_tap_criteria, slot=0),
469                StationaryTapValidator(stationary_tap_criteria, slot=1),
470            ),
471        ),
472
473        ONE_FINGER_PHYSICAL_CLICK:
474        Gesture(
475            name=ONE_FINGER_PHYSICAL_CLICK,
476            variations=(GV.CENTER, GV.BL, GV.BS, GV.BR),
477            prompt='Use one finger to physically click the {0} of the '
478                   'touch surface.',
479            subprompt={
480                GV.CENTER: ('center',),
481                GV.BL: ('bottom left corner',),
482                GV.BS: ('bottom side',),
483                GV.BR: ('bottom right corner',),
484            },
485            validators=(
486                CountTrackingIDNormalFingerValidator('== 1'),
487                PhysicalClickValidator('== 1', fingers=1),
488                StationaryTapValidator(stationary_tap_criteria, slot=0),
489            ),
490        ),
491
492        TWO_FINGER_PHYSICAL_CLICK:
493        Gesture(
494            name=TWO_FINGER_PHYSICAL_CLICK,
495            variations=None,
496            prompt='Use two fingers physically click the center of the '
497                   'touch surface.',
498            subprompt=None,
499            validators=(
500                CountTrackingIDNormalFingerValidator('== 2'),
501                PhysicalClickValidator('== 1', fingers=2),
502                StationaryTapValidator(stationary_tap_criteria, slot=0),
503                StationaryTapValidator(stationary_tap_criteria, slot=1),
504            ),
505        ),
506
507        THREE_FINGER_PHYSICAL_CLICK:
508        Gesture(
509            name=THREE_FINGER_PHYSICAL_CLICK,
510            variations=None,
511            prompt='Use three fingers to physically click '
512                   'the center of the touch surface.',
513            subprompt=None,
514            validators=(
515                CountTrackingIDNormalFingerValidator('== 3'),
516                PhysicalClickValidator('== 1', fingers=3),
517            ),
518        ),
519
520        FOUR_FINGER_PHYSICAL_CLICK:
521        Gesture(
522            name=FOUR_FINGER_PHYSICAL_CLICK,
523            variations=None,
524            prompt='Use four fingers to physically click '
525                   'the center of the touch surface.',
526            subprompt=None,
527            validators=(
528                CountTrackingIDNormalFingerValidator('== 4'),
529                PhysicalClickValidator('== 1', fingers=4),
530            ),
531        ),
532
533        FIVE_FINGER_PHYSICAL_CLICK:
534        Gesture(
535            name=FIVE_FINGER_PHYSICAL_CLICK,
536            variations=None,
537            prompt='Use five fingers to physically click '
538                   'the center of the touch surface.',
539            subprompt=None,
540            validators=(
541                CountTrackingIDNormalFingerValidator('== 5'),
542                PhysicalClickValidator('== 1', fingers=5),
543            ),
544        ),
545
546        STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS:
547        Gesture(
548            name=STATIONARY_FINGER_NOT_AFFECTED_BY_2ND_FINGER_TAPS,
549            variations=(GV.AROUND,),
550            prompt='Place your one stationary finger in the middle of the '
551                   'touch surface, and use a second finger to tap '
552                   'all around it',
553            subprompt=None,
554            validators=(
555                CountTrackingIDNormalFingerValidator('>= 2'),
556                StationaryFingerValidator(stationary_finger_criteria, slot=0),
557            ),
558        ),
559
560        FAT_FINGER_MOVE_WITH_RESTING_FINGER:
561        Gesture(
562            name=FAT_FINGER_MOVE_WITH_RESTING_FINGER,
563            variations=(GV.LR, GV.RL, GV.TB, GV.BT),
564            prompt='With a stationary finger on the {0} of the touch surface, '
565                   'draw a straight line with a FAT finger {1} {2} it.',
566            subprompt={
567                GV.LR: ('center', 'from left to right', 'below'),
568                GV.RL: ('bottom edge', 'from right to left', 'above'),
569                GV.TB: ('center', 'from top to bottom', 'on the right to'),
570                GV.BT: ('center', 'from bottom to top', 'on the left to'),
571            },
572            validators=(
573                CountTrackingIDFatFingerValidator('== 2'),
574                LinearityValidator(relaxed_linearity_criteria, finger=1,
575                                   segments=VAL.MIDDLE),
576                NoGapValidator(no_gap_criteria, slot=1),
577                NoReversedMotionValidator(no_reversed_motion_criteria, slots=1),
578                ReportRateValidator(report_rate_criteria, finger=1),
579                StationaryFingerValidator(stationary_finger_criteria, slot=0),
580            ),
581        ),
582
583        DRAG_EDGE_THUMB:
584        Gesture(
585            name=DRAG_EDGE_THUMB,
586            variations=(GV.LR, GV.RL, GV.TB, GV.BT),
587            prompt='Drag the edge of your thumb {0} in a straight line '
588                   'across the touch surface',
589            subprompt={
590                GV.LR: ('horizontally from left to right',),
591                GV.RL: ('horizontally from right to left',),
592                GV.TB: ('vertically from top to bottom',),
593                GV.BT: ('vertically from bottom to top',),
594            },
595            validators=(
596                CountTrackingIDFatFingerValidator('== 1'),
597                LinearityValidator(relaxed_linearity_criteria, finger=0,
598                                   segments=VAL.MIDDLE),
599                NoGapValidator(no_gap_criteria, slot=0),
600                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0),
601                ReportRateValidator(report_rate_criteria),
602            ),
603        ),
604
605        TWO_CLOSE_FINGERS_TRACKING:
606        Gesture(
607            # TODO(josephsih): make a special two-finger pen to perform this
608            # gesture so that the finger distance remains the same every time
609            # this test is conducted.
610            name=TWO_CLOSE_FINGERS_TRACKING,
611            variations=(GV.LR, GV.TB, GV.TLBR),
612            prompt='With two fingers close together (lightly touching each '
613                   'other) in a two finger scrolling gesture, draw a {0} '
614                   'line {1}.',
615            subprompt={
616                GV.LR: ('horizontal', 'from left to right',),
617                GV.TB: ('vertical', 'from top to bottom',),
618                GV.TLBR: ('diagonal', 'from the top left to the bottom right',),
619            },
620            validators=(
621                CountTrackingIDFatFingerValidator('== 2'),
622                LinearityValidator(relaxed_linearity_criteria, finger=0,
623                                   segments=VAL.MIDDLE),
624                LinearityValidator(relaxed_linearity_criteria, finger=1,
625                                   segments=VAL.MIDDLE),
626                NoGapValidator(no_gap_criteria, slot=0),
627                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0),
628                ReportRateValidator(report_rate_criteria),
629            ),
630        ),
631
632        RESTING_FINGER_PLUS_2ND_FINGER_MOVE:
633        Gesture(
634            name=RESTING_FINGER_PLUS_2ND_FINGER_MOVE,
635            variations=((GV.TLBR, GV.BRTL),
636                        (GV.SLOW,),
637            ),
638            prompt='With a stationary finger in the bottom left corner, take '
639                   '{1} to draw a straight line {0} with a second finger.',
640            subprompt={
641                GV.TLBR: ('from the top left to the bottom right',),
642                GV.BRTL: ('from the bottom right to the top left',),
643                GV.SLOW: ('3 seconds',),
644            },
645            validators=(
646                CountTrackingIDNormalFingerValidator('== 2'),
647                LinearityValidator(relaxed_linearity_criteria, finger=1,
648                                   segments=VAL.MIDDLE),
649                NoGapValidator(no_gap_criteria, slot=1),
650                NoReversedMotionValidator(no_reversed_motion_criteria, slots=1),
651                ReportRateValidator(report_rate_criteria, finger=1),
652                StationaryFingerValidator(stationary_finger_criteria, slot=0),
653            ),
654        ),
655
656        TWO_FAT_FINGERS_TRACKING:
657        Gesture(
658            name=TWO_FAT_FINGERS_TRACKING,
659            variations=(GV.LR, GV.RL),
660            prompt='Use two FAT fingers separated by about 1cm to draw '
661                   'a straight line {0}.',
662            subprompt={
663                GV.LR: ('from left to right',),
664                GV.RL: ('from right to left',),
665            },
666            validators=(
667                CountTrackingIDFatFingerValidator('== 2'),
668                LinearityValidator(relaxed_linearity_criteria, finger=0,
669                                   segments=VAL.MIDDLE),
670                LinearityValidator(relaxed_linearity_criteria, finger=1,
671                                   segments=VAL.MIDDLE),
672                NoGapValidator(no_gap_criteria, slot=0),
673                NoGapValidator(no_gap_criteria, slot=1),
674                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0),
675                NoReversedMotionValidator(no_reversed_motion_criteria, slots=1),
676                ReportRateValidator(report_rate_criteria),
677            ),
678        ),
679
680        FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS:
681        Gesture(
682            name=FIRST_FINGER_TRACKING_AND_SECOND_FINGER_TAPS,
683            variations=(GV.TLBR, GV.BRTL),
684            prompt='While drawing a straight line {0} slowly (~3 seconds), '
685                   'tap the bottom left corner with a second finger '
686                   'gently 3 times.',
687            subprompt={
688                GV.TLBR: ('from top left to bottom right',),
689                GV.BRTL: ('from bottom right to top left',),
690            },
691            validators=(
692                CountTrackingIDNormalFingerValidator('== 4'),
693                LinearityValidator(relaxed_linearity_criteria, finger=0,
694                                   segments=VAL.MIDDLE),
695                NoGapValidator(no_gap_criteria, slot=0),
696                NoReversedMotionValidator(no_reversed_motion_criteria, slots=0),
697                ReportRateValidator(report_rate_criteria),
698            ),
699        ),
700
701        DRUMROLL:
702        Gesture(
703            name=DRUMROLL,
704            variations=(GV.FAST, ),
705            prompt='Use the index and middle finger of one hand to make a '
706                   '"drum roll" {0} by alternately tapping each finger '
707                   'for 5 seconds.',
708            subprompt={
709                GV.FAST: ('as fast as possible',),
710            },
711            validators=(
712                CountTrackingIDNormalFingerValidator('>= 5'),
713                DrumrollValidator(drumroll_criteria),
714            ),
715            timeout = 2000,
716        ),
717
718        RAPID_TAPS:
719        Gesture(
720            name=RAPID_TAPS,
721            variations=(GV.TL, GV.BR, GV.CENTER),
722            prompt='Tap the {0} of the touch surface 20 times quickly',
723            subprompt={
724                GV.TL: ('top left corner',),
725                GV.TS: ('top edge',),
726                GV.TR: ('top right corner',),
727                GV.LS: ('left edge',),
728                GV.CENTER: ('center',),
729                GV.RS: ('right edge',),
730                GV.BL: ('bottom left corner',),
731                GV.BS: ('bottom edge',),
732                GV.BR: ('bottom right corner',),
733            },
734            validators=(
735                CountTrackingIDNormalFingerValidator('== 20'),
736            ),
737            timeout = 2000,
738        ),
739
740        ONE_FINGER_TRACKING_FROM_CENTER:
741        Gesture(
742            name=ONE_FINGER_TRACKING_FROM_CENTER,
743            variations=((GV.CR, GV.CT, GV.CUL, GV.CLL),
744                        (GV.SLOW, GV.NORMAL),
745            ),
746            prompt='Place a stationary finger on the center of the touch '
747                   'surface for about 1 second, and then take {2} to draw a '
748                   '{0} line {1}.',
749            subprompt={
750                GV.CR: ('horizontal', 'to the right',),
751                GV.CT: ('vertical', 'to the top',),
752                GV.CUL: ('diagonal', 'to the upper left',),
753                GV.CLL: ('diagonal', 'to the lower left',),
754                GV.SLOW: ('2 seconds',),
755                GV.NORMAL: ('1 second',),
756            },
757            validators=(
758                HysteresisValidator(hysteresis_criteria, finger=0),
759            ),
760        ),
761
762        PRESSURE_CALIBRATION:
763        Gesture(
764            name=PRESSURE_CALIBRATION,
765            variations=(GV.SIZE0, GV.SIZE1, GV.SIZE2, GV.SIZE3, GV.SIZE4,
766                        GV.SIZE5, GV.SIZE6, ),
767            prompt='Draw circles continuously for 5 seconds '
768                   'using the metal finger of size {0}.',
769            subprompt={
770                GV.SIZE0: ('0 (the smallest size)',),
771                GV.SIZE1: ('1',),
772                GV.SIZE2: ('2',),
773                GV.SIZE3: ('3',),
774                GV.SIZE4: ('4',),
775                GV.SIZE5: ('5',),
776                GV.SIZE6: ('6 (the largest size)',),
777            },
778            validators=(
779                CountTrackingIDNormalFingerValidator('== 1'),
780            ),
781        ),
782    }
783    return gesture_dict
784
785
786class FileName:
787    """A dummy class to hold the attributes in a test file name."""
788    pass
789filename = FileName()
790filename.sep = '-'
791filename.ext = 'dat'
792
793
794class Gesture:
795    """A class defines the structure of Gesture."""
796    # define the default timeout (in milli-seconds) when performing a gesture.
797    # A gesture is considered done when finger is lifted for this time interval.
798    TIMEOUT = int(1000/80*10)
799
800    def __init__(self, name=None, variations=None, prompt=None, subprompt=None,
801                 validators=None, timeout=TIMEOUT):
802        self.name = name
803        self.variations = variations
804        self.prompt = prompt
805        self.subprompt = subprompt
806        self.validators = validators
807        self.timeout = timeout
808