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)
8f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "base/timer/timer.h"
9010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "base/values.h"
10010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/chromeos/ui_chromeos_export.h"
11f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/events/event.h"
12010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/events/event_rewriter.h"
13f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "ui/events/gesture_detection/gesture_detector.h"
14010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/gfx/geometry/point.h"
15010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
16010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace aura {
17010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class Window;
18010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
19010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace ui {
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
22010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class Event;
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class EventHandler;
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class TouchEvent;
25010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
26010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// TouchExplorationController is used in tandem with "Spoken Feedback" to
27f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// make the touch UI accessible.
28f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
29f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ** Short version **
30f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
31f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// At a high-level, single-finger events are used for accessibility -
32f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// exploring the screen gets turned into mouse moves (which can then be
33f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// spoken by an accessibility service running), a double-tap simulates a
34f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// click, and gestures can be used to send high-level accessibility commands.
35f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// When two or more fingers are pressed initially, from then on the events
36f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// are passed through, but with the initial finger removed - so if you swipe
37f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// down with two fingers, the running app will see a one-finger swipe.
38f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
39f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// ** Long version **
40f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
41f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Here are the details of the implementation:
42f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
43f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// When the first touch is pressed, a 300 ms grace period timer starts.
44f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
45f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If the user keeps their finger down for more than 300 ms and doesn't
46f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// perform a supported accessibility gesture in that time (e.g. swipe right),
47f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// they enter touch exploration mode, and all movements are translated into
48f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// synthesized mouse move events.
49f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
50f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Also, if the user moves their single finger outside a certain slop region
51f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// (without performing a gesture), they enter touch exploration mode earlier
52f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// than 300 ms.
53f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
54f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If the user taps and releases their finger, after 300 ms from the initial
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// touch, a single mouse move is fired.
56f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If the user double-taps, the second tap is passed through, allowing the
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// user to click - however, the double-tap location is changed to the location
59f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// of the last successful touch exploration - that allows the user to explore
60f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// anywhere on the screen, hear its description, then double-tap anywhere
61f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// to activate it.
62f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
63f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If the user enters touch exploration mode, they can click without lifting
64f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// their touch exploration finger by tapping anywhere else on the screen with
65f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// a second finger, while the touch exploration finger is still pressed.
66f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
67f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// If the user adds a second finger during the grace period, they enter
68f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// passthrough mode. In this mode, the first finger is ignored but all
69f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// additional touch events are mostly passed through unmodified. So a
70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// two-finger scroll gets passed through as a one-finger scroll. However,
71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// once in passthrough mode, if one finger is released, the remaining fingers
72f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// continue to pass through events, allowing the user to start a scroll
73f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// with two fingers but finish it with one. Sometimes this requires rewriting
74f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// the touch ids.
75f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
76f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Once either touch exploration or passthrough mode has been activated,
77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// it remains in that mode until all fingers have been released.
78f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)//
79010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// The caller is expected to retain ownership of instances of this class and
80010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// destroy them before |root_window| is destroyed.
81010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)class UI_CHROMEOS_EXPORT TouchExplorationController :
82010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    public ui::EventRewriter {
83010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) public:
84010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  explicit TouchExplorationController(aura::Window* root_window);
85010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual ~TouchExplorationController();
86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void CallTapTimerNowForTesting();
88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void SetEventHandlerForTesting(ui::EventHandler* event_handler_for_testing);
89f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  bool IsInNoFingersDownStateForTesting() const;
90f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
91010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) private:
92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Overridden from ui::EventRewriter
93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ui::EventRewriteStatus RewriteEvent(
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::Event& event,
95f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      scoped_ptr<ui::Event>* rewritten_event) OVERRIDE;
96f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ui::EventRewriteStatus NextDispatchEvent(
97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE;
98f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Event handlers based on the current state - see State, below.
100f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InNoFingersDown(
101f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
102f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InSingleTapPressed(
103f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
104f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InSingleTapReleased(
105f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
106f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InDoubleTapPressed(
107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InTouchExploration(
109f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
110f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InPassthroughMinusOne(
111f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
112f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventRewriteStatus InTouchExploreSecondPress(
113f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event);
114f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // This timer is started every time we get the first press event, and
115f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // it fires after the double-click timeout elapses (300 ms by default).
116f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // If the user taps and releases within 300 ms and doesn't press again,
117f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // we treat that as a single mouse move (touch exploration) event.
118f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void OnTapTimerFired();
119f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
120f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Dispatch a new event outside of the event rewriting flow.
121f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void DispatchEvent(ui::Event* event);
122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
123010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location,
124010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                                             int flags);
125010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
126010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  void EnterTouchToMouseMode();
127010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
128f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Set the state to NO_FINGERS_DOWN and reset any other fields to their
129f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // default value.
130f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void ResetToNoFingersDown();
131f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
132f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  enum State {
133f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // No fingers are down and no events are pending.
134f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    NO_FINGERS_DOWN,
135f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
136f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // A single finger is down, but we're not yet sure if this is going
137f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // to be touch exploration or something else.
138f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SINGLE_TAP_PRESSED,
139f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
140f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The user pressed and released a single finger - a tap - but we have
141f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // to wait until the end of the grace period to allow the user to tap the
142f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // second time. If the second tap doesn't occurs within the grace period,
143f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // we dispatch a mouse move at the location of the first tap.
144f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    SINGLE_TAP_RELEASED,
145f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
146f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The user tapped once, and before the grace period expired, pressed
147f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // one finger down to begin a double-tap, but has not released it yet.
148f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    DOUBLE_TAP_PRESSED,
149f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
150f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // We're in touch exploration mode. Anything other than the first finger
151f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // is ignored, and movements of the first finger are rewritten as mouse
152f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // move events. This mode is entered if a single finger is pressed and
153f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // after the grace period the user hasn't added a second finger or
154f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // moved the finger outside of the slop region. We'll stay in this
155f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // mode until all fingers are lifted.
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    TOUCH_EXPLORATION,
157f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
158f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The user placed two or more fingers down within the grace period.
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // We're now in passthrough mode until all fingers are lifted. Initially
160f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // the first finger is ignored and other fingers are passed through
161f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // as-is. If a finger other than the initial one is the first to be
162f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // released, we rewrite the first finger with the touch id of the finger
163f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // that was released, from now on. The motivation for this is that if
164f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // the user starts a scroll with 2 fingers, they can release either one
165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // and continue the scrolling.
166f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    PASSTHROUGH_MINUS_ONE,
167f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
168f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // The user was in touch exploration, but has placed down another finger.
169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // If the user releases the second finger, a touch press and release
170f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // will go through at the last touch explore location. If the user
171f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // releases the touch explore finger, the other finger will continue with
172f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    // touch explore. Any fingers pressed past the first two are ignored.
173f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    TOUCH_EXPLORE_SECOND_PRESS,
174f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  };
175f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
176f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void VlogState(const char* function_name);
177f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
178f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void VlogEvent(const ui::TouchEvent& event, const char* function_name);
179f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
180f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // Gets enum name from integer value.
181f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  const char* EnumStateToString(State state);
182f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
183f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::string EnumEventTypeToString(ui::EventType type);
184f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
185f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  aura::Window* root_window_;
186010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
187010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // A set of touch ids for fingers currently touching the screen.
188f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  std::vector<int> current_touch_ids_;
189010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
190010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // Map of touch ids to their last known location.
191010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  std::map<int, gfx::PointF> touch_locations_;
192010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
193f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The touch id that any events on the initial finger should be rewritten
194f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // as in passthrough-minus-one mode. If kTouchIdUnassigned, events on the
195f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // initial finger are discarded. If kTouchIdNone, the initial finger
196f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // has been released and no more rewriting will be done.
197f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  int initial_touch_id_passthrough_mapping_;
198010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
199f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The current state.
200f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  State state_;
201f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
202f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A copy of the event from the initial touch press.
203f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<ui::TouchEvent> initial_press_;
204f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The last synthesized mouse move event. When the user double-taps,
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // we send the passed-through tap to the location of this event.
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<ui::TouchEvent> last_touch_exploration_;
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
209f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A timer to fire the mouse move event after the double-tap delay.
210f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  base::OneShotTimer<TouchExplorationController> tap_timer_;
211f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
212f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // For testing only, an event handler to use for generated events
213f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // outside of the normal event rewriting flow.
214f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::EventHandler* event_handler_for_testing_;
215f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
216f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A default gesture detector config, so we can share the same
217f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // timeout and pixel slop constants.
218f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ui::GestureDetector::Config gesture_detector_config_;
219f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
220f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // The previous state entered.
221f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  State prev_state_;
222f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
223f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  // A copy of the previous event passed.
224f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  scoped_ptr<ui::TouchEvent> prev_event_;
225010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
226010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TouchExplorationController);
227010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)};
228010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
229010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace ui
230010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
231010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif  // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_
232