OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ | 5 #ifndef UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ |
6 #define UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ | 6 #define UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ |
7 | 7 |
8 #include "base/timer/timer.h" | 8 #include "base/timer/timer.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "ui/chromeos/ui_chromeos_export.h" | 10 #include "ui/chromeos/ui_chromeos_export.h" |
11 #include "ui/events/event.h" | 11 #include "ui/events/event.h" |
12 #include "ui/events/event_rewriter.h" | 12 #include "ui/events/event_rewriter.h" |
13 #include "ui/events/gesture_detection/gesture_detector.h" | 13 #include "ui/events/gesture_detection/gesture_detector.h" |
| 14 #include "ui/events/gestures/gesture_provider_aura.h" |
14 #include "ui/gfx/geometry/point.h" | 15 #include "ui/gfx/geometry/point.h" |
15 | 16 |
16 namespace aura { | 17 namespace aura { |
17 class Window; | 18 class Window; |
18 } | 19 } |
19 | 20 |
20 namespace ui { | 21 namespace ui { |
21 | 22 |
22 class Event; | 23 class Event; |
23 class EventHandler; | 24 class EventHandler; |
| 25 class GestureEvent; |
| 26 class GestureProviderAura; |
24 class TouchEvent; | 27 class TouchEvent; |
25 | 28 |
26 // TouchExplorationController is used in tandem with "Spoken Feedback" to | 29 // TouchExplorationController is used in tandem with "Spoken Feedback" to |
27 // make the touch UI accessible. | 30 // make the touch UI accessible. Gestures are mapped to accessiblity key |
| 31 // shortcuts. |
28 // | 32 // |
29 // ** Short version ** | 33 // ** Short version ** |
30 // | 34 // |
31 // At a high-level, single-finger events are used for accessibility - | 35 // At a high-level, single-finger events are used for accessibility - |
32 // exploring the screen gets turned into mouse moves (which can then be | 36 // exploring the screen gets turned into mouse moves (which can then be |
33 // spoken by an accessibility service running), a single tap while the user | 37 // spoken by an accessibility service running), a single tap while the user |
34 // is in touch exploration or a double-tap simulates a click, and gestures | 38 // is in touch exploration or a double-tap simulates a click, and gestures |
35 // can be used to send high-level accessibility commands. | 39 // can be used to send high-level accessibility commands. For example, a swipe |
| 40 // right would correspond to the keyboard short cut shift+search+right. |
36 // When two or more fingers are pressed initially, from then on the events | 41 // When two or more fingers are pressed initially, from then on the events |
37 // are passed through, but with the initial finger removed - so if you swipe | 42 // are passed through, but with the initial finger removed - so if you swipe |
38 // down with two fingers, the running app will see a one-finger swipe. | 43 // down with two fingers, the running app will see a one-finger swipe. |
39 // | 44 // |
40 // ** Long version ** | 45 // ** Long version ** |
41 // | 46 // |
42 // Here are the details of the implementation: | 47 // Here are the details of the implementation: |
43 // | 48 // |
44 // When the first touch is pressed, a 300 ms grace period timer starts. | 49 // When the first touch is pressed, a 300 ms grace period timer starts. |
45 // | 50 // |
46 // If the user keeps their finger down for more than 300 ms and doesn't | 51 // If the user keeps their finger down for more than 300 ms and doesn't |
47 // perform a supported accessibility gesture in that time (e.g. swipe right), | 52 // perform a supported accessibility gesture in that time (e.g. swipe right), |
48 // they enter touch exploration mode, and all movements are translated into | 53 // they enter touch exploration mode, and all movements are translated into |
49 // synthesized mouse move events. | 54 // synthesized mouse move events. |
50 // | 55 // |
51 // Also, if the user moves their single finger outside a certain slop region | 56 // Also, if the user moves their single finger outside a certain slop region |
52 // (without performing a gesture), they enter touch exploration mode earlier | 57 // (without performing a gesture), they enter touch exploration mode earlier |
53 // than 300 ms. | 58 // than 300 ms. |
54 // | 59 // |
55 // If the user taps and releases their finger, after 300 ms from the initial | 60 // If the user taps and releases their finger, after 300 ms from the initial |
56 // touch, a single mouse move is fired. | 61 // touch, a single mouse move is fired. |
57 // | 62 // |
58 // While in touch exploration mode, the user can perform a single tap | 63 // While in touch exploration mode, the user can perform a single tap |
59 // if the user releases their finger and taps before 300 ms passes. | 64 // if the user releases their finger and taps before 300 ms passes. |
60 // This will result in a click on the last successful touch exploration | 65 // This will result in a click on the last successful touch exploration |
61 // location. This allows the user to perform a single tap | 66 // location. This allows the user to perform a single tap |
62 // anywhere to activate it. | 67 // anywhere to activate it. |
63 // | 68 // |
| 69 // The user can perform swipe gestures in one of the four cardinal directions |
| 70 // which will be interpreted and used to control the UI. The gesture will only |
| 71 // be registered if the finger moves outside the slop and completed within the |
| 72 // grace period. If additional fingers are added during the grace period, the |
| 73 // state changes to passthrough. If the gesture fails to be completed within the |
| 74 // grace period, the state changes to touch exploration mode. Once the state has |
| 75 // changed, any gestures made during the grace period are discarded. |
| 76 // |
64 // If the user double-taps, the second tap is passed through, allowing the | 77 // If the user double-taps, the second tap is passed through, allowing the |
65 // user to click - however, the double-tap location is changed to the location | 78 // user to click - however, the double-tap location is changed to the location |
66 // of the last successful touch exploration - that allows the user to explore | 79 // of the last successful touch exploration - that allows the user to explore |
67 // anywhere on the screen, hear its description, then double-tap anywhere | 80 // anywhere on the screen, hear its description, then double-tap anywhere |
68 // to activate it. | 81 // to activate it. |
69 // | 82 // |
70 // If the user enters touch exploration mode, they can click without lifting | 83 // If the user enters touch exploration mode, they can click without lifting |
71 // their touch exploration finger by tapping anywhere else on the screen with | 84 // their touch exploration finger by tapping anywhere else on the screen with |
72 // a second finger, while the touch exploration finger is still pressed. | 85 // a second finger, while the touch exploration finger is still pressed. |
73 // | 86 // |
74 // If the user adds a second finger during the grace period, they enter | 87 // If the user adds a second finger during the grace period, they enter |
75 // two to one finger passthrough mode. In this mode, the first finger is | 88 // two to one finger passthrough mode. In this mode, the first finger is |
76 // ignored and the user can scroll or drag with the second finger. If either | 89 // ignored and the user can scroll or drag with the second finger. If either |
77 // finger is released, nothing happens until all fingers are up. If the user | 90 // finger is released, nothing happens until all fingers are up. If the user |
78 // adds a third finger while in two to one finger mode, all fingers and touch | 91 // adds a third finger while in two to one finger mode, all fingers and touch |
79 // events are passed through from then on. | 92 // events are passed through from then on. |
80 // | 93 // |
81 // Once touch exploration mode has been activated, | 94 // Once touch exploration mode has been activated, |
82 // it remains in that mode until all fingers have been released. | 95 // it remains in that mode until all fingers have been released. |
83 // | 96 // |
84 // The caller is expected to retain ownership of instances of this class and | 97 // The caller is expected to retain ownership of instances of this class and |
85 // destroy them before |root_window| is destroyed. | 98 // destroy them before |root_window| is destroyed. |
86 class UI_CHROMEOS_EXPORT TouchExplorationController | 99 class UI_CHROMEOS_EXPORT TouchExplorationController |
87 : public ui::EventRewriter { | 100 : public ui::EventRewriter, |
| 101 public ui::GestureProviderAuraClient { |
88 public: | 102 public: |
89 explicit TouchExplorationController(aura::Window* root_window); | 103 explicit TouchExplorationController(aura::Window* root_window); |
90 virtual ~TouchExplorationController(); | 104 virtual ~TouchExplorationController(); |
91 | 105 |
92 void CallTapTimerNowForTesting(); | 106 void CallTapTimerNowForTesting(); |
93 void SetEventHandlerForTesting(ui::EventHandler* event_handler_for_testing); | 107 void SetEventHandlerForTesting(ui::EventHandler* event_handler_for_testing); |
94 bool IsInNoFingersDownStateForTesting() const; | 108 bool IsInNoFingersDownStateForTesting() const; |
| 109 bool IsInGestureInProgressStateForTesting() const; |
95 | 110 |
96 private: | 111 private: |
97 // Overridden from ui::EventRewriter | 112 // Overridden from ui::EventRewriter |
98 virtual ui::EventRewriteStatus RewriteEvent( | 113 virtual ui::EventRewriteStatus RewriteEvent( |
99 const ui::Event& event, | 114 const ui::Event& event, |
100 scoped_ptr<ui::Event>* rewritten_event) OVERRIDE; | 115 scoped_ptr<ui::Event>* rewritten_event) OVERRIDE; |
101 virtual ui::EventRewriteStatus NextDispatchEvent( | 116 virtual ui::EventRewriteStatus NextDispatchEvent( |
102 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE; | 117 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE; |
103 | 118 |
104 // Event handlers based on the current state - see State, below. | 119 // Event handlers based on the current state - see State, below. |
105 ui::EventRewriteStatus InNoFingersDown( | 120 ui::EventRewriteStatus InNoFingersDown( |
106 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 121 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
107 ui::EventRewriteStatus InSingleTapPressed( | 122 ui::EventRewriteStatus InSingleTapPressed( |
108 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 123 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
109 ui::EventRewriteStatus InSingleTapOrTouchExploreReleased( | 124 ui::EventRewriteStatus InSingleTapOrTouchExploreReleased( |
110 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 125 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
111 ui::EventRewriteStatus InDoubleTapPressed( | 126 ui::EventRewriteStatus InDoubleTapPressed( |
112 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 127 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
113 ui::EventRewriteStatus InTouchExploration( | 128 ui::EventRewriteStatus InTouchExploration( |
114 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 129 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
115 ui::EventRewriteStatus InTwoToOneFinger( | 130 ui::EventRewriteStatus InTwoToOneFinger( |
116 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 131 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
117 ui::EventRewriteStatus InPassthrough( | 132 ui::EventRewriteStatus InPassthrough( |
118 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 133 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
| 134 ui::EventRewriteStatus InGestureInProgress( |
| 135 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
119 ui::EventRewriteStatus InTouchExploreSecondPress( | 136 ui::EventRewriteStatus InTouchExploreSecondPress( |
120 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 137 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
121 ui::EventRewriteStatus InWaitForRelease( | 138 ui::EventRewriteStatus InWaitForRelease( |
122 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 139 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
123 | 140 |
124 // This timer is started every time we get the first press event, and | 141 // This timer is started every time we get the first press event, and |
125 // it fires after the double-click timeout elapses (300 ms by default). | 142 // it fires after the double-click timeout elapses (300 ms by default). |
126 // If the user taps and releases within 300 ms and doesn't press again, | 143 // If the user taps and releases within 300 ms and doesn't press again, |
127 // we treat that as a single mouse move (touch exploration) event. | 144 // we treat that as a single mouse move (touch exploration) event. |
128 void OnTapTimerFired(); | 145 void OnTapTimerFired(); |
129 | 146 |
130 // Dispatch a new event outside of the event rewriting flow. | 147 // Dispatch a new event outside of the event rewriting flow. |
131 void DispatchEvent(ui::Event* event); | 148 void DispatchEvent(ui::Event* event); |
132 | 149 |
| 150 // Overridden from GestureProviderAuraClient. |
| 151 // |
| 152 // The gesture provider keeps track of all the touch events after |
| 153 // the user moves fast enough to trigger a gesture. After the user |
| 154 // completes their gesture, this method will decide what keyboard |
| 155 // input their gesture corresponded to. |
| 156 virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE; |
| 157 |
| 158 // Process the gesture events that have been created. |
| 159 void ProcessGestureEvents(); |
| 160 |
| 161 void OnSwipeEvent(ui::GestureEvent* swipe_gesture); |
| 162 |
| 163 // Dispatches the keyboard short cut Shift+Search+<arrow key> |
| 164 // outside the event rewritting flow. |
| 165 void DispatchShiftSearchKeyEvent(const ui::KeyboardCode direction); |
| 166 |
133 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location, | 167 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location, |
134 int flags); | 168 int flags); |
135 | 169 |
136 void EnterTouchToMouseMode(); | 170 void EnterTouchToMouseMode(); |
137 | 171 |
138 // Set the state to NO_FINGERS_DOWN and reset any other fields to their | 172 // Set the state to NO_FINGERS_DOWN and reset any other fields to their |
139 // default value. | 173 // default value. |
140 void ResetToNoFingersDown(); | 174 void ResetToNoFingersDown(); |
141 | 175 |
142 enum State { | 176 enum State { |
(...skipping 22 matching lines...) Expand all Loading... |
165 DOUBLE_TAP_PRESSED, | 199 DOUBLE_TAP_PRESSED, |
166 | 200 |
167 // We're in touch exploration mode. Anything other than the first finger | 201 // We're in touch exploration mode. Anything other than the first finger |
168 // is ignored, and movements of the first finger are rewritten as mouse | 202 // is ignored, and movements of the first finger are rewritten as mouse |
169 // move events. This mode is entered if a single finger is pressed and | 203 // move events. This mode is entered if a single finger is pressed and |
170 // after the grace period the user hasn't added a second finger or | 204 // after the grace period the user hasn't added a second finger or |
171 // moved the finger outside of the slop region. We'll stay in this | 205 // moved the finger outside of the slop region. We'll stay in this |
172 // mode until all fingers are lifted. | 206 // mode until all fingers are lifted. |
173 TOUCH_EXPLORATION, | 207 TOUCH_EXPLORATION, |
174 | 208 |
| 209 // If the user moves their finger faster than the threshold velocity after a |
| 210 // single tap, the touch events that follow will be translated into gesture |
| 211 // events. If the user successfully completes a gesture within the grace |
| 212 // period, the gesture will be interpreted and used to control the UI via |
| 213 // discrete actions - currently by synthesizing key events corresponding to |
| 214 // each gesture Otherwise, the collected gestures are discarded and the |
| 215 // state changes to touch_exploration. |
| 216 GESTURE_IN_PROGRESS, |
| 217 |
175 // The user was in touch exploration, but has placed down another finger. | 218 // The user was in touch exploration, but has placed down another finger. |
176 // If the user releases the second finger, a touch press and release | 219 // If the user releases the second finger, a touch press and release |
177 // will go through at the last touch explore location. If the user | 220 // will go through at the last touch explore location. If the user |
178 // releases the touch explore finger, the other finger will continue with | 221 // releases the touch explore finger, the other finger will continue with |
179 // touch explore. Any fingers pressed past the first two are ignored. | 222 // touch explore. Any fingers pressed past the first two are ignored. |
180 TOUCH_EXPLORE_SECOND_PRESS, | 223 TOUCH_EXPLORE_SECOND_PRESS, |
181 | 224 |
182 // The user placed two fingers down within the grace period. | 225 // The user placed two fingers down within the grace period. |
183 // We're now in two to one finger mode until one of the fingers is | 226 // We're now in two to one finger mode until one of the fingers is |
184 // lifted. The first finger is ignored and the events for the second | 227 // lifted. The first finger is ignored and the events for the second |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
237 base::OneShotTimer<TouchExplorationController> tap_timer_; | 280 base::OneShotTimer<TouchExplorationController> tap_timer_; |
238 | 281 |
239 // For testing only, an event handler to use for generated events | 282 // For testing only, an event handler to use for generated events |
240 // outside of the normal event rewriting flow. | 283 // outside of the normal event rewriting flow. |
241 ui::EventHandler* event_handler_for_testing_; | 284 ui::EventHandler* event_handler_for_testing_; |
242 | 285 |
243 // A default gesture detector config, so we can share the same | 286 // A default gesture detector config, so we can share the same |
244 // timeout and pixel slop constants. | 287 // timeout and pixel slop constants. |
245 ui::GestureDetector::Config gesture_detector_config_; | 288 ui::GestureDetector::Config gesture_detector_config_; |
246 | 289 |
| 290 // Gesture Handler to interpret the touch events. |
| 291 ui::GestureProviderAura gesture_provider_; |
| 292 |
247 // The previous state entered. | 293 // The previous state entered. |
248 State prev_state_; | 294 State prev_state_; |
249 | 295 |
250 // A copy of the previous event passed. | 296 // A copy of the previous event passed. |
251 scoped_ptr<ui::TouchEvent> prev_event_; | 297 scoped_ptr<ui::TouchEvent> prev_event_; |
252 | 298 |
253 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); | 299 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); |
254 }; | 300 }; |
255 | 301 |
256 } // namespace ui | 302 } // namespace ui |
257 | 303 |
258 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ | 304 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ |
OLD | NEW |