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