1010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// found in the LICENSE file.
4010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
5010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#ifndef UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
6010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#define UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
7010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "base/time/tick_clock.h"
9f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/timer/timer.h"
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/values.h"
11010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/chromeos/ui_chromeos_export.h"
12f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/events/event.h"
13010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/events/event_rewriter.h"
14f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/events/gesture_detection/gesture_detector.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/events/gestures/gesture_provider_aura.h"
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/gfx/geometry/point.h"
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace aura {
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class Window;
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace ui {
23010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
24010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class Event;
25f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class EventHandler;
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass GestureEvent;
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass GestureProviderAura;
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class TouchEvent;
29010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// A delegate to handle commands in response to detected accessibility gesture
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// events.
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class TouchExplorationControllerDelegate {
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) public:
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual ~TouchExplorationControllerDelegate() {}
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Takes an int from 0.0 to 100.0 that indicates the percent the volume
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // should be set to.
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void SetOutputLevel(int volume) = 0;
396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Silences spoken feedback.
416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void SilenceSpokenFeedback() = 0;
426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // This function should be called when the volume adjust earcon should be
446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // played
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void PlayVolumeAdjustEarcon() = 0;
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // This function should be called when the passthrough earcon should be
486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // played.
496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void PlayPassthroughEarcon() = 0;
506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // This function should be called when the exit screen earcon should be
526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // played.
536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void PlayExitScreenEarcon() = 0;
546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // This function should be called when the enter screen earcon should be
566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // played.
576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual void PlayEnterScreenEarcon() = 0;
585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)};
595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// TouchExplorationController is used in tandem with "Spoken Feedback" to
615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// make the touch UI accessible. Gestures performed in the middle of the screen
626e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// are mapped to accessibility key shortcuts while gestures performed on the
636e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// edge of the screen can change settings.
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ** Short version **
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// At a high-level, single-finger events are used for accessibility -
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// exploring the screen gets turned into mouse moves (which can then be
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// spoken by an accessibility service running), a single tap while the user
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// is in touch exploration or a double-tap simulates a click, and gestures
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// can be used to send high-level accessibility commands. For example, a swipe
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// right would correspond to the keyboard short cut shift+search+right.
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Swipes with up to four fingers are also mapped to commands. Slide
745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// gestures performed on the edge of the screen can change settings
755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// continuously. For example, sliding a finger along the right side of the
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// screen will change the volume. When a user double taps and holds with one
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// finger, the finger is passed through as if accessibility was turned off. If
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// the user taps the screen with two fingers, the user can silence spoken
796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// feedback if it is playing.
80f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
81f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ** Long version **
82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
83f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Here are the details of the implementation:
84f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
85f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// When the first touch is pressed, a 300 ms grace period timer starts.
86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If the user keeps their finger down for more than 300 ms and doesn't
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// perform a supported accessibility gesture in that time (e.g. swipe right),
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// they enter touch exploration mode, and all movements are translated into
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// synthesized mouse move events.
91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Also, if the user moves their single finger outside a certain slop region
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// (without performing a gesture), they enter touch exploration mode earlier
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// than 300 ms.
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If the user taps and releases their finger, after 300 ms from the initial
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// touch, a single mouse move is fired.
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// While in touch exploration mode, the user can perform a single tap
100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// if the user releases their finger and taps before 300 ms passes.
101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// This will result in a click on the last successful touch exploration
102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// location. This allows the user to perform a single tap
103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// anywhere to activate it.
104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//
105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch// The user can perform swipe gestures in one of the four cardinal directions
1066e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// which will be interpreted and used to control the UI. All gestures will only
1076e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// be registered if the fingers move outside the slop, and all fingers will only
1086e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// be registered if they are completed within the grace period. If a single
1096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// finger gesture fails to be completed within the grace period, the state
1106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// changes to touch exploration mode. If a multi finger gesture fails to be
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// completed within the grace period, the user must lift all fingers before
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// completing any more actions.
113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If the user double-taps, the second tap is passed through, allowing the
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// user to click - however, the double-tap location is changed to the location
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// of the last successful touch exploration - that allows the user to explore
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// anywhere on the screen, hear its description, then double-tap anywhere
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// to activate it.
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// If the user double taps and holds, any event from that finger is passed
1215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// through. These events are passed through with an offset such that the first
1225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// touch is offset to be at the location of the last touch exploration
1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// location, and every following event is offset by the same amount.
1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//
1255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// If any other fingers are added or removed, they are ignored. Once the
1265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// passthrough finger is released, passthrough stops and the user is reset
1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// to no fingers down state.
1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If the user enters touch exploration mode, they can click without lifting
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// their touch exploration finger by tapping anywhere else on the screen with
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// a second finger, while the touch exploration finger is still pressed.
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Once touch exploration mode has been activated, it remains in that mode until
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// all fingers have been released.
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// If the user places a finger on the edge of the screen and moves their finger
1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// past slop, a slide gesture is performed. The user can then slide one finger
1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// along an edge of the screen and continuously control a setting. Once the user
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// enters this state, the boundaries that define an edge expand so that the user
1405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// can now adjust the setting within a slightly bigger width along the screen.
1415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// If the user exits this area without lifting their finger, they will not be
1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// able to perform any actions, however if they keep their finger down and
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// return to the "hot edge," then they can still adjust the setting. In order to
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// perform other touch accessibility movements, the user must lift their finger.
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// If additional fingers are added while in this state, the user will transition
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// to passthrough.
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)//
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// Currently, only the right edge is mapped to control the volume. Volume
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// control along the edge of the screen is directly proportional to where the
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// user's finger is located on the screen. The top right corner of the screen
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// automatically sets the volume to 100% and the bottome right corner of the
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)// screen automatically sets the volume to 0% once the user has moved past slop.
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// If the user taps the screen with two fingers and lifts both fingers before
1556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// the grace period has passed, spoken feedback is silenced.
1566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)//
1576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// The user can also enter passthrough by placing a finger on one of the bottom
1586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// corners of the screen until an earcon sounds. After the earcon sounds, the
1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// user is in passthrough so all subsequent fingers placed on the screen will be
1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// passed through. Once the finger in the corner has been released, the state
1616e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// will switch to wait for no fingers.
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
163010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// The caller is expected to retain ownership of instances of this class and
164010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// destroy them before |root_window| is destroyed.
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass UI_CHROMEOS_EXPORT TouchExplorationController
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : public ui::EventRewriter,
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      public ui::GestureProviderAuraClient {
168010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public:
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  explicit TouchExplorationController(
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      aura::Window* root_window,
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      ui::TouchExplorationControllerDelegate* delegate);
172010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual ~TouchExplorationController();
173010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
174010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private:
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  friend class TouchExplorationControllerTestApi;
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from ui::EventRewriter
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ui::EventRewriteStatus RewriteEvent(
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::Event& event,
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<ui::Event>* rewritten_event) OVERRIDE;
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ui::EventRewriteStatus NextDispatchEvent(
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE;
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Event handlers based on the current state - see State, below.
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InNoFingersDown(
186f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
187f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InSingleTapPressed(
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ui::EventRewriteStatus InSingleTapOrTouchExploreReleased(
190f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::EventRewriteStatus InDoubleTapPending(
1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
1935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::EventRewriteStatus InTouchReleasePending(
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InTouchExploration(
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
1976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ui::EventRewriteStatus InCornerPassthrough(
198116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
1995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::EventRewriteStatus InOneFingerPassthrough(
200116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
201116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  ui::EventRewriteStatus InGestureInProgress(
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InTouchExploreSecondPress(
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ui::EventRewriteStatus InWaitForNoFingers(
2065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
2075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::EventRewriteStatus InSlideGesture(
208116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
2096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  ui::EventRewriteStatus InTwoFingerTap(
2106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
211116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Returns the current time of the tick clock.
2135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::TimeDelta Now();
2145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // This timer is started every time we get the first press event, and
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // it fires after the double-click timeout elapses (300 ms by default).
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If the user taps and releases within 300 ms and doesn't press again,
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // we treat that as a single mouse move (touch exploration) event.
2195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void StartTapTimer();
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void OnTapTimerFired();
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
2226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // This timer is started every timer we get the first press event and the
2236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // finger is in the corner of the screen.
2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // It fires after the corner passthrough delay elapses. If the
2256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // user is still in the corner by the time this timer fires, all subsequent
2266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // fingers added on the screen will be passed through.
2276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void OnPassthroughTimerFired();
2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
229f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Dispatch a new event outside of the event rewriting flow.
230f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void DispatchEvent(ui::Event* event);
231f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Overridden from GestureProviderAuraClient.
233116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  //
234116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The gesture provider keeps track of all the touch events after
235116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // the user moves fast enough to trigger a gesture. After the user
236116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // completes their gesture, this method will decide what keyboard
237116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // input their gesture corresponded to.
238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE;
239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Process the gesture events that have been created.
241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void ProcessGestureEvents();
242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
243116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnSwipeEvent(ui::GestureEvent* swipe_gesture);
244116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void SideSlideControl(ui::GestureEvent* gesture);
2465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
247116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Dispatches the keyboard short cut Shift+Search+<arrow key>
248116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // outside the event rewritting flow.
2496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void DispatchShiftSearchKeyEvent(const ui::KeyboardCode third_key);
2506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Binds DispatchShiftSearchKeyEvent to a specific third key.
2526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::Closure BindShiftSearchKeyEvent(const ui::KeyboardCode third_key);
2536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Dispatches a single key with the given flags.
2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void DispatchKeyWithFlags(const ui::KeyboardCode key, int flags);
2566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Binds DispatchKeyWithFlags to a specific key and flags.
2586e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::Closure BindKeyEventWithFlags(const ui::KeyboardCode key, int flags);
259116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
260010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location,
261010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                             int flags);
262010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
263010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void EnterTouchToMouseMode();
264010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
2655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void PlaySoundForTimer();
2665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Some constants used in touch_exploration_controller:
2685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Within this many dips of the screen edge, the release event generated will
2705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // reset the state to NoFingersDown.
2715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const float kLeavingScreenEdge = 6;
2725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Swipe/scroll gestures within these bounds (in DIPs) will change preset
2745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // settings.
2755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const float kMaxDistanceFromEdge = 75;
2765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // After a slide gesture has been triggered, if the finger is still within
2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // these bounds (in DIPs), the preset settings will still change.
2795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  const float kSlopDistanceFromEdge = kMaxDistanceFromEdge + 40;
2805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
2816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // The split tap slop  is a bit more generous since keeping two
2826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // fingers in place is a bit harder.
2836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const float GetSplitTapTouchSlop();
2846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  enum State {
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // No fingers are down and no events are pending.
287f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    NO_FINGERS_DOWN,
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
289f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // A single finger is down, but we're not yet sure if this is going
290f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // to be touch exploration or something else.
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SINGLE_TAP_PRESSED,
292f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
293f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The user pressed and released a single finger - a tap - but we have
294f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // to wait until the end of the grace period to allow the user to tap the
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // second time. If the second tap doesn't occurs within the grace period,
296f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // we dispatch a mouse move at the location of the first tap.
297f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SINGLE_TAP_RELEASED,
298f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
299116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // The user was in touch explore mode and released the finger.
300116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // If another touch press occurs within the grace period, a single
301116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // tap click occurs. This state differs from SINGLE_TAP_RELEASED
3026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // in that if a second tap doesn't occur within the grace period,
303116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // there is no mouse move dispatched.
304116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    TOUCH_EXPLORE_RELEASED,
305116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
306f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The user tapped once, and before the grace period expired, pressed
307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // one finger down to begin a double-tap, but has not released it yet.
3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // This could become passthrough, so no touch press is dispatched yet.
3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    DOUBLE_TAP_PENDING,
3105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3115f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // The user was doing touch exploration, started split tap, but lifted the
3125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // touch exploration finger. Once they remove all fingers, a touch release
3135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // will go through.
3145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    TOUCH_RELEASE_PENDING,
315f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
316f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // We're in touch exploration mode. Anything other than the first finger
317f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // is ignored, and movements of the first finger are rewritten as mouse
318f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // move events. This mode is entered if a single finger is pressed and
319f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // after the grace period the user hasn't added a second finger or
320f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // moved the finger outside of the slop region. We'll stay in this
321f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // mode until all fingers are lifted.
322f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    TOUCH_EXPLORATION,
323f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // If the user moves their finger faster than the threshold velocity after a
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // single tap, the touch events that follow will be translated into gesture
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // events. If the user successfully completes a gesture within the grace
327116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // period, the gesture will be interpreted and used to control the UI via
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // discrete actions - currently by synthesizing key events corresponding to
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // each gesture Otherwise, the collected gestures are discarded and the
330116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // state changes to touch_exploration.
331116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    GESTURE_IN_PROGRESS,
332f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
333f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The user was in touch exploration, but has placed down another finger.
334f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // If the user releases the second finger, a touch press and release
335f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // will go through at the last touch explore location. If the user
3366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // releases the touch explore finger, the touch press and release will
3376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // still go through once the split tap finger is also lifted. If any
3386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // fingers pressed past the first two, the touch press is cancelled and
3396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // the user enters the wait state for the fingers to be removed.
340f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    TOUCH_EXPLORE_SECOND_PRESS,
341116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // After the user double taps and holds with a single finger, all events
3435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // for that finger are passed through, displaced by an offset. Adding
3445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // extra fingers has no effect. This state is left when the user removes
3455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // all fingers.
3465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    ONE_FINGER_PASSTHROUGH,
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // If the user has pressed and held down the left corner past long press,
3496e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // then as long as they are holding the corner, all subsequent fingers
3506e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // registered will be in passthrough.
3516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    CORNER_PASSTHROUGH,
3526e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // If the user added another finger in SINGLE_TAP_PRESSED, or if the user
3545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // has multiple fingers fingers down in any other state between
3555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // passthrough, touch exploration, and gestures, they must release
3566e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // all fingers before completing any more actions. This state is
357116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // generally useful for developing new features, because it creates a
358116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // simple way to handle a dead end in user flow.
3596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    WAIT_FOR_NO_FINGERS,
3605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // If the user is within the given bounds from an edge of the screen, not
3625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // including corners, then the resulting movements will be interpreted as
3635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // slide gestures.
3645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    SLIDE_GESTURE,
3656e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
3666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // If the user taps the screen with two fingers and releases both fingers
3676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // before the grace period has passed, spoken feedback will be silenced.
3686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    TWO_FINGER_TAP,
369f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  };
370f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  enum ScreenLocation {
3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    // Hot "edges" of the screen are each represented by a respective bit.
3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    NO_EDGE = 0,
3745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RIGHT_EDGE = 1 << 0,
3755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    TOP_EDGE = 1 << 1,
3765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    LEFT_EDGE = 1 << 2,
3775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    BOTTOM_EDGE = 1 << 3,
3786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    BOTTOM_LEFT_CORNER = LEFT_EDGE | BOTTOM_EDGE,
3796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    BOTTOM_RIGHT_CORNER = RIGHT_EDGE | BOTTOM_EDGE,
3805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  };
3815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Given a point, if it is within the given bounds of an edge, returns the
3835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // edge. If it is within the given bounds of two edges, returns an int with
3845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // both bits that represent the respective edges turned on. Otherwise returns
3855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // SCREEN_CENTER.
3865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  int FindEdgesWithinBounds(gfx::Point point, float bounds);
3875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
3886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Set the state and modifies any variables related to the state change.
3896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // (e.g. resetting the gesture provider).
3906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void SetState(State new_state, const char* function_name);
3916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
392f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void VlogState(const char* function_name);
393f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
394f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void VlogEvent(const ui::TouchEvent& event, const char* function_name);
395f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
396f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Gets enum name from integer value.
397f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const char* EnumStateToString(State state);
398f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
3996e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Maps each single/multi finger swipe to the function that dispatches
4006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // the corresponding key events.
4016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  void InitializeSwipeGestureMaps();
4026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
403f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  aura::Window* root_window_;
404010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
4055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // Handles volume control. Not owned.
4065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::TouchExplorationControllerDelegate* delegate_;
4075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
408010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // A set of touch ids for fingers currently touching the screen.
409f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<int> current_touch_ids_;
410010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
411010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Map of touch ids to their last known location.
412010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::map<int, gfx::PointF> touch_locations_;
413010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
414f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The current state.
415f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  State state_;
416f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
417f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A copy of the event from the initial touch press.
418f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<ui::TouchEvent> initial_press_;
419f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Map of touch ids to where its initial press occurred relative to the
4216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // screen.
4226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::map<int, gfx::Point> initial_presses_;
4236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // In one finger passthrough, the touch is displaced relative to the
4255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // last touch exploration location.
4265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  gfx::Vector2d passthrough_offset_;
4275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
428116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Stores the most recent event from a finger that is currently not
4295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // sending events through, but might in the future (e.g. before a finger
4305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // enters double-tap-hold passthrough, we need to update its location.)
431116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ui::TouchEvent> last_unused_finger_event_;
432116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
433f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The last synthesized mouse move event. When the user double-taps,
434f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // we send the passed-through tap to the location of this event.
435f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<ui::TouchEvent> last_touch_exploration_;
436f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // A timer that fires after the double-tap delay.
438f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::OneShotTimer<TouchExplorationController> tap_timer_;
439f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
4406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // A timer that fires to enter passthrough.
4416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::OneShotTimer<TouchExplorationController> passthrough_timer_;
4426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
4435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // A timer to fire an indicating sound when sliding to change volume.
4445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::RepeatingTimer<TouchExplorationController> sound_timer_;
445f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
446f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A default gesture detector config, so we can share the same
447f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // timeout and pixel slop constants.
448f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::GestureDetector::Config gesture_detector_config_;
449f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
450116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Gesture Handler to interpret the touch events.
4516e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  scoped_ptr<ui::GestureProviderAura> gesture_provider_;
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
453f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The previous state entered.
454f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  State prev_state_;
455f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
456f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A copy of the previous event passed.
457f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<ui::TouchEvent> prev_event_;
458010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
459116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // This toggles whether VLOGS are turned on or not.
460116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool VLOG_on_;
461116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
4625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // When touch_exploration_controller gets time relative to real time during
4635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  // testing, this clock is set to the simulated clock and used.
4645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  base::TickClock* tick_clock_;
4655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
4666e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Maps the number of fingers in a swipe to the resulting functions that
4676e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // dispatch key events.
4686e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::map<int, base::Closure> left_swipe_gestures_;
4696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::map<int, base::Closure> right_swipe_gestures_;
4706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::map<int, base::Closure> up_swipe_gestures_;
4716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::map<int, base::Closure> down_swipe_gestures_;
4726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
473010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TouchExplorationController);
474010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
475010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
476010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace ui
477010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
478010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif  // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
479