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

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: Removed line that Evy was working on Created 6 years, 6 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 accessible key
tdresser 2014/06/26 13:31:49 Should "accessible" be "accessibility"?
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 the gesture fails to be completed within the grace period,
73 // the state changes to touch exploration mode and any gestures made during the
74 // grace period are discarded.
75 //
64 // If the user double-taps, the second tap is passed through, allowing the 76 // 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 77 // 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 78 // of the last successful touch exploration - that allows the user to explore
67 // anywhere on the screen, hear its description, then double-tap anywhere 79 // anywhere on the screen, hear its description, then double-tap anywhere
68 // to activate it. 80 // to activate it.
69 // 81 //
70 // If the user enters touch exploration mode, they can click without lifting 82 // 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 83 // their touch exploration finger by tapping anywhere else on the screen with
72 // a second finger, while the touch exploration finger is still pressed. 84 // a second finger, while the touch exploration finger is still pressed.
73 // 85 //
74 // If the user adds a second finger during the grace period, they enter 86 // If the user adds a second finger during the grace period, they enter
75 // passthrough mode. In this mode, the first finger is ignored but all 87 // passthrough mode. In this mode, the first finger is ignored but all
76 // additional touch events are mostly passed through unmodified. So a 88 // additional touch events are mostly passed through unmodified. So a
77 // two-finger scroll gets passed through as a one-finger scroll. However, 89 // two-finger scroll gets passed through as a one-finger scroll. However,
78 // once in passthrough mode, if one finger is released, the remaining fingers 90 // once in passthrough mode, if one finger is released, the remaining fingers
79 // continue to pass through events, allowing the user to start a scroll 91 // continue to pass through events, allowing the user to start a scroll
80 // with two fingers but finish it with one. Sometimes this requires rewriting 92 // with two fingers but finish it with one. Sometimes this requires rewriting
81 // the touch ids. 93 // the touch ids.
82 // 94 //
83 // Once either touch exploration or passthrough mode has been activated, 95 // Once either touch exploration or passthrough mode has been activated,
84 // it remains in that mode until all fingers have been released. 96 // it remains in that mode until all fingers have been released.
85 // 97 //
86 // The caller is expected to retain ownership of instances of this class and 98 // The caller is expected to retain ownership of instances of this class and
87 // destroy them before |root_window| is destroyed. 99 // destroy them before |root_window| is destroyed.
88 class UI_CHROMEOS_EXPORT TouchExplorationController : 100 class UI_CHROMEOS_EXPORT TouchExplorationController
89 public ui::EventRewriter { 101 : public ui::EventRewriter,
102 public ui::GestureProviderAuraClient {
90 public: 103 public:
91 explicit TouchExplorationController(aura::Window* root_window); 104 explicit TouchExplorationController(aura::Window* root_window);
92 virtual ~TouchExplorationController(); 105 virtual ~TouchExplorationController();
93 106
94 void CallTapTimerNowForTesting(); 107 void CallTapTimerNowForTesting();
95 void SetEventHandlerForTesting(ui::EventHandler* event_handler_for_testing); 108 void SetEventHandlerForTesting(ui::EventHandler* event_handler_for_testing);
96 bool IsInNoFingersDownStateForTesting() const; 109 bool IsInNoFingersDownStateForTesting() const;
110 bool IsInGestureInProgressStateForTesting() const;
97 111
98 private: 112 private:
99 // Overridden from ui::EventRewriter 113 // Overridden from ui::EventRewriter
100 virtual ui::EventRewriteStatus RewriteEvent( 114 virtual ui::EventRewriteStatus RewriteEvent(
101 const ui::Event& event, 115 const ui::Event& event,
102 scoped_ptr<ui::Event>* rewritten_event) OVERRIDE; 116 scoped_ptr<ui::Event>* rewritten_event) OVERRIDE;
103 virtual ui::EventRewriteStatus NextDispatchEvent( 117 virtual ui::EventRewriteStatus NextDispatchEvent(
104 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE; 118 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE;
105 119
106 // Event handlers based on the current state - see State, below. 120 // Event handlers based on the current state - see State, below.
107 ui::EventRewriteStatus InNoFingersDown( 121 ui::EventRewriteStatus InNoFingersDown(
108 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 122 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
109 ui::EventRewriteStatus InSingleTapPressed( 123 ui::EventRewriteStatus InSingleTapPressed(
110 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 124 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
111 ui::EventRewriteStatus InSingleTapOrTouchExploreReleased( 125 ui::EventRewriteStatus InSingleTapOrTouchExploreReleased(
112 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 126 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
113 ui::EventRewriteStatus InDoubleTapPressed( 127 ui::EventRewriteStatus InDoubleTapPressed(
114 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 128 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
115 ui::EventRewriteStatus InTouchExploration( 129 ui::EventRewriteStatus InTouchExploration(
116 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 130 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
131 ui::EventRewriteStatus InGestureInProgress(
132 const ui::TouchEvent& event,
133 scoped_ptr<ui::Event>* rewritten_event);
117 ui::EventRewriteStatus InPassthroughMinusOne( 134 ui::EventRewriteStatus InPassthroughMinusOne(
118 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); 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);
138
121 // This timer is started every time we get the first press event, and 139 // This timer is started every time we get the first press event, and
122 // it fires after the double-click timeout elapses (300 ms by default). 140 // it fires after the double-click timeout elapses (300 ms by default).
123 // If the user taps and releases within 300 ms and doesn't press again, 141 // If the user taps and releases within 300 ms and doesn't press again,
124 // we treat that as a single mouse move (touch exploration) event. 142 // we treat that as a single mouse move (touch exploration) event.
125 void OnTapTimerFired(); 143 void OnTapTimerFired();
126 144
127 // Dispatch a new event outside of the event rewriting flow. 145 // Dispatch a new event outside of the event rewriting flow.
128 void DispatchEvent(ui::Event* event); 146 void DispatchEvent(ui::Event* event);
129 147
148 // Overridden from GestureProviderAuraClient.
149 //
150 // The gesture provider keeps track of all the touch events after
151 // the user moves fast enough to trigger a gesture. After the user
152 // completes their gesture, this method will decide what keyboard
153 // input their gesture corresponded to.
154 void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE;
155
156 void OnSwipeEvent(ui::GestureEvent* swipe_gesture);
157
158 // Dispatches the keyboard short cut Shift+Search+<arrow key>
159 // outside the event rewritting flow.
160 void DispatchShiftSearchKeyEvent(const ui::KeyboardCode direction);
161
130 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location, 162 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location,
131 int flags); 163 int flags);
132 164
133 void EnterTouchToMouseMode(); 165 void EnterTouchToMouseMode();
134 166
135 // Set the state to NO_FINGERS_DOWN and reset any other fields to their 167 // Set the state to NO_FINGERS_DOWN and reset any other fields to their
136 // default value. 168 // default value.
137 void ResetToNoFingersDown(); 169 void ResetToNoFingersDown();
138 170
139 enum State { 171 enum State {
(...skipping 22 matching lines...) Expand all
162 DOUBLE_TAP_PRESSED, 194 DOUBLE_TAP_PRESSED,
163 195
164 // We're in touch exploration mode. Anything other than the first finger 196 // We're in touch exploration mode. Anything other than the first finger
165 // is ignored, and movements of the first finger are rewritten as mouse 197 // is ignored, and movements of the first finger are rewritten as mouse
166 // move events. This mode is entered if a single finger is pressed and 198 // move events. This mode is entered if a single finger is pressed and
167 // after the grace period the user hasn't added a second finger or 199 // after the grace period the user hasn't added a second finger or
168 // moved the finger outside of the slop region. We'll stay in this 200 // moved the finger outside of the slop region. We'll stay in this
169 // mode until all fingers are lifted. 201 // mode until all fingers are lifted.
170 TOUCH_EXPLORATION, 202 TOUCH_EXPLORATION,
171 203
204 // If the user moves their finger faster than the threshold velocity after a
205 // single tap, the touch events that follow will be translated into gesture
206 // events. If the user successfully completes a gesture within the grace
207 // period, the gesture will be interpreted and used to control the UI via
208 // discrete actions - currently by synthesizing key events corresponding to
209 // each gesture Otherwise, the collected gestures are discarded and the
210 // state changes to touch_exploration.
211 GESTURE_IN_PROGRESS,
212
172 // The user placed two or more fingers down within the grace period. 213 // The user placed two or more fingers down within the grace period.
173 // We're now in passthrough mode until all fingers are lifted. Initially 214 // We're now in passthrough mode until all fingers are lifted. Initially
174 // the first finger is ignored and other fingers are passed through 215 // the first finger is ignored and other fingers are passed through
175 // as-is. If a finger other than the initial one is the first to be 216 // as-is. If a finger other than the initial one is the first to be
176 // released, we rewrite the first finger with the touch id of the finger 217 // released, we rewrite the first finger with the touch id of the finger
177 // that was released, from now on. The motivation for this is that if 218 // that was released, from now on. The motivation for this is that if
178 // the user starts a scroll with 2 fingers, they can release either one 219 // the user starts a scroll with 2 fingers, they can release either one
179 // and continue the scrolling. 220 // and continue the scrolling.
180 PASSTHROUGH_MINUS_ONE, 221 PASSTHROUGH_MINUS_ONE,
181 222
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 base::OneShotTimer<TouchExplorationController> tap_timer_; 265 base::OneShotTimer<TouchExplorationController> tap_timer_;
225 266
226 // For testing only, an event handler to use for generated events 267 // For testing only, an event handler to use for generated events
227 // outside of the normal event rewriting flow. 268 // outside of the normal event rewriting flow.
228 ui::EventHandler* event_handler_for_testing_; 269 ui::EventHandler* event_handler_for_testing_;
229 270
230 // A default gesture detector config, so we can share the same 271 // A default gesture detector config, so we can share the same
231 // timeout and pixel slop constants. 272 // timeout and pixel slop constants.
232 ui::GestureDetector::Config gesture_detector_config_; 273 ui::GestureDetector::Config gesture_detector_config_;
233 274
275 // Gesture Handler to interpret the touch events.
276 ui::GestureProviderAura gesture_provider_;
277
234 // The previous state entered. 278 // The previous state entered.
235 State prev_state_; 279 State prev_state_;
236 280
237 // A copy of the previous event passed. 281 // A copy of the previous event passed.
238 scoped_ptr<ui::TouchEvent> prev_event_; 282 scoped_ptr<ui::TouchEvent> prev_event_;
239 283
240 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); 284 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController);
241 }; 285 };
242 286
243 } // namespace ui 287 } // namespace ui
244 288
245 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ 289 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
OLDNEW
« no previous file with comments | « no previous file | ui/chromeos/touch_exploration_controller.cc » ('j') | ui/chromeos/touch_exploration_controller_unittest.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698