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/time/tick_clock.h" | 8 #include "base/time/tick_clock.h" |
9 #include "base/timer/timer.h" | 9 #include "base/timer/timer.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 // edge of the screen can change settings. | 51 // edge of the screen can change settings. |
52 // | 52 // |
53 // ** Short version ** | 53 // ** Short version ** |
54 // | 54 // |
55 // At a high-level, single-finger events are used for accessibility - | 55 // At a high-level, single-finger events are used for accessibility - |
56 // exploring the screen gets turned into mouse moves (which can then be | 56 // exploring the screen gets turned into mouse moves (which can then be |
57 // spoken by an accessibility service running), a single tap while the user | 57 // spoken by an accessibility service running), a single tap while the user |
58 // is in touch exploration or a double-tap simulates a click, and gestures | 58 // is in touch exploration or a double-tap simulates a click, and gestures |
59 // can be used to send high-level accessibility commands. For example, a swipe | 59 // can be used to send high-level accessibility commands. For example, a swipe |
60 // right would correspond to the keyboard short cut shift+search+right. | 60 // right would correspond to the keyboard short cut shift+search+right. |
61 // When two or more fingers are pressed initially, from then on the events | 61 // Swipes with up to four fingers are also mapped to commands. Slide |
62 // are passed through, but with the initial finger removed - so if you swipe | |
63 // down with two fingers, the running app will see a one-finger swipe. Slide | |
64 // gestures performed on the edge of the screen can change settings | 62 // gestures performed on the edge of the screen can change settings |
65 // continuously. For example, sliding a finger along the right side of the | 63 // continuously. For example, sliding a finger along the right side of the |
66 // screen will change the volume. When a user double taps and holds with one | 64 // screen will change the volume. When a user double taps and holds with one |
67 // finger, the finger is passed through as if accessibility was turned off. If | 65 // finger, the finger is passed through as if accessibility was turned off. If |
68 // the user taps the screen with two fingers, the user can silence spoken | 66 // the user taps the screen with two fingers, the user can silence spoken |
69 // feedback if it is playing. | 67 // feedback if it is playing. |
70 // | 68 // |
71 // ** Long version ** | 69 // ** Long version ** |
72 // | 70 // |
73 // Here are the details of the implementation: | 71 // Here are the details of the implementation: |
(...skipping 12 matching lines...) Expand all Loading... |
86 // If the user taps and releases their finger, after 300 ms from the initial | 84 // If the user taps and releases their finger, after 300 ms from the initial |
87 // touch, a single mouse move is fired. | 85 // touch, a single mouse move is fired. |
88 // | 86 // |
89 // While in touch exploration mode, the user can perform a single tap | 87 // While in touch exploration mode, the user can perform a single tap |
90 // if the user releases their finger and taps before 300 ms passes. | 88 // if the user releases their finger and taps before 300 ms passes. |
91 // This will result in a click on the last successful touch exploration | 89 // This will result in a click on the last successful touch exploration |
92 // location. This allows the user to perform a single tap | 90 // location. This allows the user to perform a single tap |
93 // anywhere to activate it. | 91 // anywhere to activate it. |
94 // | 92 // |
95 // The user can perform swipe gestures in one of the four cardinal directions | 93 // The user can perform swipe gestures in one of the four cardinal directions |
96 // which will be interpreted and used to control the UI. The gesture will only | 94 // which will be interpreted and used to control the UI. All gestures will only |
97 // be registered if the finger moves outside the slop and completed within the | 95 // be registered if the fingers move outside the slop, and all fingers will only |
98 // grace period. If additional fingers are added during the grace period, the | 96 // be registered if they are completed within the grace period. If a single |
99 // state changes to wait for those fingers to be released, and then goes to | 97 // finger gesture fails to be completed within the grace period, the state |
100 // touch exploration mode. If the gesture fails to be completed within the | 98 // changes to touch exploration mode. If a multi finger gesture fails to be |
101 // grace period, the state changes to touch exploration mode. Once the state has | 99 // completed within the grace period, the user must lift all fingers before |
102 // changed, any gestures made during the grace period are discarded. | 100 // completing any more actions. |
103 // | 101 // |
104 // If the user double-taps, the second tap is passed through, allowing the | 102 // If the user double-taps, the second tap is passed through, allowing the |
105 // user to click - however, the double-tap location is changed to the location | 103 // user to click - however, the double-tap location is changed to the location |
106 // of the last successful touch exploration - that allows the user to explore | 104 // of the last successful touch exploration - that allows the user to explore |
107 // anywhere on the screen, hear its description, then double-tap anywhere | 105 // anywhere on the screen, hear its description, then double-tap anywhere |
108 // to activate it. | 106 // to activate it. |
109 // | 107 // |
110 // If the user double taps and holds, any event from that finger is passed | 108 // If the user double taps and holds, any event from that finger is passed |
111 // through. These events are passed through with an offset such that the first | 109 // through. These events are passed through with an offset such that the first |
112 // touch is offset to be at the location of the last touch exploration | 110 // touch is offset to be at the location of the last touch exploration |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 ui::EventRewriteStatus InSingleTapPressed( | 169 ui::EventRewriteStatus InSingleTapPressed( |
172 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 170 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
173 ui::EventRewriteStatus InSingleTapOrTouchExploreReleased( | 171 ui::EventRewriteStatus InSingleTapOrTouchExploreReleased( |
174 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 172 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
175 ui::EventRewriteStatus InDoubleTapPending( | 173 ui::EventRewriteStatus InDoubleTapPending( |
176 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 174 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
177 ui::EventRewriteStatus InTouchReleasePending( | 175 ui::EventRewriteStatus InTouchReleasePending( |
178 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 176 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
179 ui::EventRewriteStatus InTouchExploration( | 177 ui::EventRewriteStatus InTouchExploration( |
180 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 178 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
181 ui::EventRewriteStatus InTwoToOneFinger( | |
182 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | |
183 ui::EventRewriteStatus InOneFingerPassthrough( | 179 ui::EventRewriteStatus InOneFingerPassthrough( |
184 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 180 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
185 ui::EventRewriteStatus InGestureInProgress( | 181 ui::EventRewriteStatus InGestureInProgress( |
186 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 182 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
187 ui::EventRewriteStatus InTouchExploreSecondPress( | 183 ui::EventRewriteStatus InTouchExploreSecondPress( |
188 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 184 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
189 ui::EventRewriteStatus InWaitForOneFinger( | 185 ui::EventRewriteStatus InWaitForNoFingers( |
190 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 186 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
191 ui::EventRewriteStatus InSlideGesture( | 187 ui::EventRewriteStatus InSlideGesture( |
192 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 188 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
193 ui::EventRewriteStatus InTwoFingerTap( | 189 ui::EventRewriteStatus InTwoFingerTap( |
194 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 190 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
195 | 191 |
196 // Returns the current time of the tick clock. | 192 // Returns the current time of the tick clock. |
197 base::TimeDelta Now(); | 193 base::TimeDelta Now(); |
198 | 194 |
199 // This timer is started every time we get the first press event, and | 195 // This timer is started every time we get the first press event, and |
(...skipping 16 matching lines...) Expand all Loading... |
216 | 212 |
217 // Process the gesture events that have been created. | 213 // Process the gesture events that have been created. |
218 void ProcessGestureEvents(); | 214 void ProcessGestureEvents(); |
219 | 215 |
220 void OnSwipeEvent(ui::GestureEvent* swipe_gesture); | 216 void OnSwipeEvent(ui::GestureEvent* swipe_gesture); |
221 | 217 |
222 void SideSlideControl(ui::GestureEvent* gesture); | 218 void SideSlideControl(ui::GestureEvent* gesture); |
223 | 219 |
224 // Dispatches the keyboard short cut Shift+Search+<arrow key> | 220 // Dispatches the keyboard short cut Shift+Search+<arrow key> |
225 // outside the event rewritting flow. | 221 // outside the event rewritting flow. |
226 void DispatchShiftSearchKeyEvent(const ui::KeyboardCode direction); | 222 void DispatchShiftSearchKeyEvent(const ui::KeyboardCode third_key); |
| 223 |
| 224 // Binds DispatchShiftSearchKeyEvent to a specific third key. |
| 225 base::Closure BindShiftSearchKeyEvent(const ui::KeyboardCode third_key); |
| 226 |
| 227 // Dispatches a single key with the given flags. |
| 228 void DispatchKeyWithFlags(const ui::KeyboardCode key, int flags); |
| 229 |
| 230 // Binds DispatchKeyWithFlags to a specific key and flags. |
| 231 base::Closure BindKeyEventWithFlags(const ui::KeyboardCode key, int flags); |
227 | 232 |
228 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location, | 233 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location, |
229 int flags); | 234 int flags); |
230 | 235 |
231 void EnterTouchToMouseMode(); | 236 void EnterTouchToMouseMode(); |
232 | 237 |
233 // Set the state to NO_FINGERS_DOWN and reset any other fields to their | |
234 // default value. | |
235 void ResetToNoFingersDown(); | |
236 | |
237 void PlaySoundForTimer(); | 238 void PlaySoundForTimer(); |
238 | 239 |
239 // Some constants used in touch_exploration_controller: | 240 // Some constants used in touch_exploration_controller: |
240 | 241 |
241 // Within this many dips of the screen edge, the release event generated will | 242 // Within this many dips of the screen edge, the release event generated will |
242 // reset the state to NoFingersDown. | 243 // reset the state to NoFingersDown. |
243 const float kLeavingScreenEdge = 6; | 244 const float kLeavingScreenEdge = 6; |
244 | 245 |
245 // Swipe/scroll gestures within these bounds (in DIPs) will change preset | 246 // Swipe/scroll gestures within these bounds (in DIPs) will change preset |
246 // settings. | 247 // settings. |
(...skipping 13 matching lines...) Expand all Loading... |
260 | 261 |
261 // The user pressed and released a single finger - a tap - but we have | 262 // The user pressed and released a single finger - a tap - but we have |
262 // to wait until the end of the grace period to allow the user to tap the | 263 // to wait until the end of the grace period to allow the user to tap the |
263 // second time. If the second tap doesn't occurs within the grace period, | 264 // second time. If the second tap doesn't occurs within the grace period, |
264 // we dispatch a mouse move at the location of the first tap. | 265 // we dispatch a mouse move at the location of the first tap. |
265 SINGLE_TAP_RELEASED, | 266 SINGLE_TAP_RELEASED, |
266 | 267 |
267 // The user was in touch explore mode and released the finger. | 268 // The user was in touch explore mode and released the finger. |
268 // If another touch press occurs within the grace period, a single | 269 // If another touch press occurs within the grace period, a single |
269 // tap click occurs. This state differs from SINGLE_TAP_RELEASED | 270 // tap click occurs. This state differs from SINGLE_TAP_RELEASED |
270 // In that if a second tap doesn't occur within the grace period, | 271 // in that if a second tap doesn't occur within the grace period, |
271 // there is no mouse move dispatched. | 272 // there is no mouse move dispatched. |
272 TOUCH_EXPLORE_RELEASED, | 273 TOUCH_EXPLORE_RELEASED, |
273 | 274 |
274 // The user tapped once, and before the grace period expired, pressed | 275 // The user tapped once, and before the grace period expired, pressed |
275 // one finger down to begin a double-tap, but has not released it yet. | 276 // one finger down to begin a double-tap, but has not released it yet. |
276 // This could become passthrough, so no touch press is dispatched yet. | 277 // This could become passthrough, so no touch press is dispatched yet. |
277 DOUBLE_TAP_PENDING, | 278 DOUBLE_TAP_PENDING, |
278 | 279 |
279 // The user was doing touch exploration, started split tap, but lifted the | 280 // The user was doing touch exploration, started split tap, but lifted the |
280 // touch exploration finger. Once they remove all fingers, a touch release | 281 // touch exploration finger. Once they remove all fingers, a touch release |
(...skipping 26 matching lines...) Expand all Loading... |
307 | 308 |
308 // After the user double taps and holds with a single finger, all events | 309 // After the user double taps and holds with a single finger, all events |
309 // for that finger are passed through, displaced by an offset. Adding | 310 // for that finger are passed through, displaced by an offset. Adding |
310 // extra fingers has no effect. This state is left when the user removes | 311 // extra fingers has no effect. This state is left when the user removes |
311 // all fingers. | 312 // all fingers. |
312 ONE_FINGER_PASSTHROUGH, | 313 ONE_FINGER_PASSTHROUGH, |
313 | 314 |
314 // If the user added another finger in SINGLE_TAP_PRESSED, or if the user | 315 // If the user added another finger in SINGLE_TAP_PRESSED, or if the user |
315 // has multiple fingers fingers down in any other state between | 316 // has multiple fingers fingers down in any other state between |
316 // passthrough, touch exploration, and gestures, they must release | 317 // passthrough, touch exploration, and gestures, they must release |
317 // all fingers except before completing any more actions. This state is | 318 // all fingers before completing any more actions. This state is |
318 // generally useful for developing new features, because it creates a | 319 // generally useful for developing new features, because it creates a |
319 // simple way to handle a dead end in user flow. | 320 // simple way to handle a dead end in user flow. |
320 WAIT_FOR_ONE_FINGER, | 321 WAIT_FOR_NO_FINGERS, |
321 | 322 |
322 // If the user is within the given bounds from an edge of the screen, not | 323 // If the user is within the given bounds from an edge of the screen, not |
323 // including corners, then the resulting movements will be interpreted as | 324 // including corners, then the resulting movements will be interpreted as |
324 // slide gestures. | 325 // slide gestures. |
325 SLIDE_GESTURE, | 326 SLIDE_GESTURE, |
326 | 327 |
327 // If the user taps the screen with two fingers and releases both fingers | 328 // If the user taps the screen with two fingers and releases both fingers |
328 // before the grace period has passed, spoken feedback will be silenced. | 329 // before the grace period has passed, spoken feedback will be silenced. |
329 TWO_FINGER_TAP, | 330 TWO_FINGER_TAP, |
330 }; | 331 }; |
331 | 332 |
332 enum ScreenLocation { | 333 enum ScreenLocation { |
333 // Hot "edges" of the screen are each represented by a respective bit. | 334 // Hot "edges" of the screen are each represented by a respective bit. |
334 NO_EDGE = 0, | 335 NO_EDGE = 0, |
335 RIGHT_EDGE = 1 << 0, | 336 RIGHT_EDGE = 1 << 0, |
336 TOP_EDGE = 1 << 1, | 337 TOP_EDGE = 1 << 1, |
337 LEFT_EDGE = 1 << 2, | 338 LEFT_EDGE = 1 << 2, |
338 BOTTOM_EDGE = 1 << 3, | 339 BOTTOM_EDGE = 1 << 3, |
339 }; | 340 }; |
340 | 341 |
341 // Given a point, if it is within the given bounds of an edge, returns the | 342 // Given a point, if it is within the given bounds of an edge, returns the |
342 // edge. If it is within the given bounds of two edges, returns an int with | 343 // edge. If it is within the given bounds of two edges, returns an int with |
343 // both bits that represent the respective edges turned on. Otherwise returns | 344 // both bits that represent the respective edges turned on. Otherwise returns |
344 // SCREEN_CENTER. | 345 // SCREEN_CENTER. |
345 int FindEdgesWithinBounds(gfx::Point point, float bounds); | 346 int FindEdgesWithinBounds(gfx::Point point, float bounds); |
346 | 347 |
| 348 // Set the state and modifies any variables related to the state change. |
| 349 // (e.g. resetting the gesture provider). |
| 350 void SetState(State new_state, const char* function_name); |
| 351 |
347 void VlogState(const char* function_name); | 352 void VlogState(const char* function_name); |
348 | 353 |
349 void VlogEvent(const ui::TouchEvent& event, const char* function_name); | 354 void VlogEvent(const ui::TouchEvent& event, const char* function_name); |
350 | 355 |
351 // Gets enum name from integer value. | 356 // Gets enum name from integer value. |
352 const char* EnumStateToString(State state); | 357 const char* EnumStateToString(State state); |
353 | 358 |
| 359 // Maps each single/multi finger swipe to the function that dispatches |
| 360 // the corresponding key events. |
| 361 void InitializeSwipeGestureMaps(); |
| 362 |
354 aura::Window* root_window_; | 363 aura::Window* root_window_; |
355 | 364 |
356 // Handles volume control. Not owned. | 365 // Handles volume control. Not owned. |
357 ui::TouchExplorationControllerDelegate* delegate_; | 366 ui::TouchExplorationControllerDelegate* delegate_; |
358 | 367 |
359 // A set of touch ids for fingers currently touching the screen. | 368 // A set of touch ids for fingers currently touching the screen. |
360 std::vector<int> current_touch_ids_; | 369 std::vector<int> current_touch_ids_; |
361 | 370 |
362 // Map of touch ids to their last known location. | 371 // Map of touch ids to their last known location. |
363 std::map<int, gfx::PointF> touch_locations_; | 372 std::map<int, gfx::PointF> touch_locations_; |
(...skipping 14 matching lines...) Expand all Loading... |
378 | 387 |
379 // Stores the most recent event from a finger that is currently not | 388 // Stores the most recent event from a finger that is currently not |
380 // sending events through, but might in the future (e.g. before a finger | 389 // sending events through, but might in the future (e.g. before a finger |
381 // enters double-tap-hold passthrough, we need to update its location.) | 390 // enters double-tap-hold passthrough, we need to update its location.) |
382 scoped_ptr<ui::TouchEvent> last_unused_finger_event_; | 391 scoped_ptr<ui::TouchEvent> last_unused_finger_event_; |
383 | 392 |
384 // The last synthesized mouse move event. When the user double-taps, | 393 // The last synthesized mouse move event. When the user double-taps, |
385 // we send the passed-through tap to the location of this event. | 394 // we send the passed-through tap to the location of this event. |
386 scoped_ptr<ui::TouchEvent> last_touch_exploration_; | 395 scoped_ptr<ui::TouchEvent> last_touch_exploration_; |
387 | 396 |
388 // A timer to fire the mouse move event after the double-tap delay. | 397 // A timer that fires after the double-tap delay. |
389 base::OneShotTimer<TouchExplorationController> tap_timer_; | 398 base::OneShotTimer<TouchExplorationController> tap_timer_; |
390 | 399 |
391 // A timer to fire an indicating sound when sliding to change volume. | 400 // A timer to fire an indicating sound when sliding to change volume. |
392 base::RepeatingTimer<TouchExplorationController> sound_timer_; | 401 base::RepeatingTimer<TouchExplorationController> sound_timer_; |
393 | 402 |
394 // A default gesture detector config, so we can share the same | 403 // A default gesture detector config, so we can share the same |
395 // timeout and pixel slop constants. | 404 // timeout and pixel slop constants. |
396 ui::GestureDetector::Config gesture_detector_config_; | 405 ui::GestureDetector::Config gesture_detector_config_; |
397 | 406 |
398 // Gesture Handler to interpret the touch events. | 407 // Gesture Handler to interpret the touch events. |
399 ui::GestureProviderAura gesture_provider_; | 408 scoped_ptr<ui::GestureProviderAura> gesture_provider_; |
400 | 409 |
401 // The previous state entered. | 410 // The previous state entered. |
402 State prev_state_; | 411 State prev_state_; |
403 | 412 |
404 // A copy of the previous event passed. | 413 // A copy of the previous event passed. |
405 scoped_ptr<ui::TouchEvent> prev_event_; | 414 scoped_ptr<ui::TouchEvent> prev_event_; |
406 | 415 |
407 // This toggles whether VLOGS are turned on or not. | 416 // This toggles whether VLOGS are turned on or not. |
408 bool VLOG_on_; | 417 bool VLOG_on_; |
409 | 418 |
410 // When touch_exploration_controller gets time relative to real time during | 419 // When touch_exploration_controller gets time relative to real time during |
411 // testing, this clock is set to the simulated clock and used. | 420 // testing, this clock is set to the simulated clock and used. |
412 base::TickClock* tick_clock_; | 421 base::TickClock* tick_clock_; |
413 | 422 |
| 423 // Maps the number of fingers in a swipe to the resulting functions that |
| 424 // dispatch key events. |
| 425 std::map<int, base::Closure> left_swipe_gestures_; |
| 426 std::map<int, base::Closure> right_swipe_gestures_; |
| 427 std::map<int, base::Closure> up_swipe_gestures_; |
| 428 std::map<int, base::Closure> down_swipe_gestures_; |
| 429 |
414 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); | 430 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); |
415 }; | 431 }; |
416 | 432 |
417 } // namespace ui | 433 } // namespace ui |
418 | 434 |
419 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ | 435 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ |
OLD | NEW |