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