Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(87)

Side by Side Diff: ui/chromeos/touch_exploration_controller.h

Issue 330763007: Swipe Gestures for Accessibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gesture-vlogs
Patch Set: Fixed Memory Leak Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698