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