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