Chromium Code Reviews| 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/timer/timer.h" | 8 #include "base/timer/timer.h" |
| 9 #include "base/values.h" | 9 #include "base/values.h" |
| 10 #include "ui/chromeos/ui_chromeos_export.h" | 10 #include "ui/chromeos/ui_chromeos_export.h" |
| 11 #include "ui/events/event.h" | 11 #include "ui/events/event.h" |
| 12 #include "ui/events/event_rewriter.h" | 12 #include "ui/events/event_rewriter.h" |
| 13 #include "ui/events/gesture_detection/gesture_detector.h" | 13 #include "ui/events/gesture_detection/gesture_detector.h" |
| 14 #include "ui/events/gestures/gesture_provider_aura.h" | 14 #include "ui/events/gestures/gesture_provider_aura.h" |
| 15 #include "ui/gfx/geometry/point.h" | 15 #include "ui/gfx/geometry/point.h" |
| 16 | 16 |
| 17 namespace aura { | 17 namespace aura { |
| 18 class Window; | 18 class Window; |
| 19 } | 19 } |
| 20 | 20 |
| 21 namespace ui { | 21 namespace ui { |
| 22 | 22 |
| 23 class Event; | 23 class Event; |
| 24 class EventHandler; | 24 class EventHandler; |
| 25 class GestureEvent; | 25 class GestureEvent; |
| 26 class GestureProviderAura; | 26 class GestureProviderAura; |
| 27 class TouchEvent; | 27 class TouchEvent; |
| 28 | 28 |
| 29 // A delegate to handle commands in response to detected accessibility gesture | |
| 30 // events. | |
| 31 class TouchExplorationControllerDelegate { | |
| 32 public: | |
| 33 virtual ~TouchExplorationControllerDelegate() {} | |
| 34 | |
| 35 // This function should be called whenever the delegate wants to play a sound | |
| 36 // when the volume adjusts. | |
| 37 virtual void PlayVolumeAdjustSound() = 0; | |
| 38 // Takes a float from 1 to 100 that indicates the percent the volume should be | |
|
James Cook
2014/07/15 22:40:37
nit: blank line above
And nice comment, it explai
lisayin
2014/07/15 23:54:46
Done.
| |
| 39 // set to. | |
| 40 virtual void SetOutputLevel(float volume) = 0; | |
| 41 }; | |
| 42 | |
| 29 // TouchExplorationController is used in tandem with "Spoken Feedback" to | 43 // TouchExplorationController is used in tandem with "Spoken Feedback" to |
| 30 // make the touch UI accessible. Gestures are mapped to accessiblity key | 44 // make the touch UI accessible. Gestures performed in the middle of the screen |
| 31 // shortcuts. | 45 // are mapped to accessiblity key shortcuts while gestures performed on the edge |
| 46 // of the screen can change settings. | |
| 32 // | 47 // |
| 33 // ** Short version ** | 48 // ** Short version ** |
| 34 // | 49 // |
| 35 // At a high-level, single-finger events are used for accessibility - | 50 // At a high-level, single-finger events are used for accessibility - |
| 36 // exploring the screen gets turned into mouse moves (which can then be | 51 // exploring the screen gets turned into mouse moves (which can then be |
| 37 // spoken by an accessibility service running), a single tap while the user | 52 // spoken by an accessibility service running), a single tap while the user |
| 38 // is in touch exploration or a double-tap simulates a click, and gestures | 53 // is in touch exploration or a double-tap simulates a click, and gestures |
| 39 // can be used to send high-level accessibility commands. For example, a swipe | 54 // can be used to send high-level accessibility commands. For example, a swipe |
| 40 // right would correspond to the keyboard short cut shift+search+right. | 55 // right would correspond to the keyboard short cut shift+search+right. |
| 41 // When two or more fingers are pressed initially, from then on the events | 56 // When two or more fingers are pressed initially, from then on the events |
| 42 // are passed through, but with the initial finger removed - so if you swipe | 57 // are passed through, but with the initial finger removed - so if you swipe |
| 43 // down with two fingers, the running app will see a one-finger swipe. | 58 // down with two fingers, the running app will see a one-finger swipe. Slide |
| 59 // gestures performed on the edge of the screen can change settings | |
| 60 // continuously. For example, sliding a finger along the right side of the | |
| 61 // screen will change the volume. | |
| 44 // | 62 // |
| 45 // ** Long version ** | 63 // ** Long version ** |
| 46 // | 64 // |
| 47 // Here are the details of the implementation: | 65 // Here are the details of the implementation: |
| 48 // | 66 // |
| 49 // When the first touch is pressed, a 300 ms grace period timer starts. | 67 // When the first touch is pressed, a 300 ms grace period timer starts. |
| 50 // | 68 // |
| 51 // If the user keeps their finger down for more than 300 ms and doesn't | 69 // If the user keeps their finger down for more than 300 ms and doesn't |
| 52 // perform a supported accessibility gesture in that time (e.g. swipe right), | 70 // perform a supported accessibility gesture in that time (e.g. swipe right), |
| 53 // they enter touch exploration mode, and all movements are translated into | 71 // they enter touch exploration mode, and all movements are translated into |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 84 // their touch exploration finger by tapping anywhere else on the screen with | 102 // their touch exploration finger by tapping anywhere else on the screen with |
| 85 // a second finger, while the touch exploration finger is still pressed. | 103 // a second finger, while the touch exploration finger is still pressed. |
| 86 // | 104 // |
| 87 // If the user adds a second finger during the grace period, they enter | 105 // If the user adds a second finger during the grace period, they enter |
| 88 // two to one finger passthrough mode. In this mode, the first finger is | 106 // two to one finger passthrough mode. In this mode, the first finger is |
| 89 // ignored and the user can scroll or drag with the second finger. If either | 107 // ignored and the user can scroll or drag with the second finger. If either |
| 90 // finger is released, nothing happens until all fingers are up. If the user | 108 // finger is released, nothing happens until all fingers are up. If the user |
| 91 // adds a third finger while in two to one finger mode, all fingers and touch | 109 // adds a third finger while in two to one finger mode, all fingers and touch |
| 92 // events are passed through from then on. | 110 // events are passed through from then on. |
| 93 // | 111 // |
| 112 // If the user places a finger on the edge of the screen and moves their finger | |
| 113 // past slop, a slide gesture is performed. The user can then slide one finger | |
| 114 // along an edge of the screen and continuously control a setting. Once the user | |
| 115 // enters this state, the boundaries that define an edge expand so that the user | |
| 116 // can now adjust the setting within a slightly bigger width along the screen. | |
| 117 // If the user exits this area without lifting their finger, they will not be | |
| 118 // able to perform any actions, however if they keep their finger down and | |
| 119 // return to the "hot edge," then they can still adjust the setting. In order to | |
| 120 // perform other touch accessibility movements, the user must lift their finger. | |
| 121 // If additional fingers are added while in this state, the user will transition | |
| 122 // to passthrough. | |
| 123 // | |
| 124 // Currently, only the right edge is mapped to control the volume. Volume | |
| 125 // control along the edge of the screen is directly proportional to where the | |
| 126 // user's finger is located on the screen. The top right corner of the screen | |
| 127 // automatically sets the volume to 100% and the bottome right corner of the | |
| 128 // screen automatically sets the volume to 0% once the user has moved past slop. | |
| 129 // | |
| 94 // Once touch exploration mode has been activated, | 130 // Once touch exploration mode has been activated, |
| 95 // it remains in that mode until all fingers have been released. | 131 // it remains in that mode until all fingers have been released. |
| 96 // | 132 // |
| 97 // The caller is expected to retain ownership of instances of this class and | 133 // The caller is expected to retain ownership of instances of this class and |
| 98 // destroy them before |root_window| is destroyed. | 134 // destroy them before |root_window| is destroyed. |
| 99 class UI_CHROMEOS_EXPORT TouchExplorationController | 135 class UI_CHROMEOS_EXPORT TouchExplorationController |
| 100 : public ui::EventRewriter, | 136 : public ui::EventRewriter, |
| 101 public ui::GestureProviderAuraClient { | 137 public ui::GestureProviderAuraClient { |
| 102 public: | 138 public: |
| 103 explicit TouchExplorationController(aura::Window* root_window); | 139 explicit TouchExplorationController( |
| 140 aura::Window* root_window, | |
| 141 ui::TouchExplorationControllerDelegate* delegate); | |
| 104 virtual ~TouchExplorationController(); | 142 virtual ~TouchExplorationController(); |
| 105 | 143 |
| 106 void CallTapTimerNowForTesting(); | 144 void CallTapTimerNowForTesting(); |
| 107 void CallTapTimerNowIfRunningForTesting(); | 145 void CallTapTimerNowIfRunningForTesting(); |
| 108 void SetEventHandlerForTesting(ui::EventHandler* event_handler_for_testing); | 146 void SetEventHandlerForTesting(ui::EventHandler* event_handler_for_testing); |
| 109 bool IsInNoFingersDownStateForTesting() const; | 147 bool IsInNoFingersDownStateForTesting() const; |
| 110 bool IsInGestureInProgressStateForTesting() const; | 148 bool IsInGestureInProgressStateForTesting() const; |
| 149 bool IsInSlideGestureStateForTesting() const; | |
| 111 // VLOGs should be suppressed in tests that generate a lot of logs, | 150 // VLOGs should be suppressed in tests that generate a lot of logs, |
| 112 // for example permutations of nine touch events. | 151 // for example permutations of nine touch events. |
| 113 void SuppressVLOGsForTesting(bool suppress); | 152 void SuppressVLOGsForTesting(bool suppress); |
| 153 gfx::Rect BoundsOfRootWindowInDIPForTesting(); | |
| 114 | 154 |
| 115 private: | 155 private: |
| 116 // Overridden from ui::EventRewriter | 156 // Overridden from ui::EventRewriter |
| 117 virtual ui::EventRewriteStatus RewriteEvent( | 157 virtual ui::EventRewriteStatus RewriteEvent( |
| 118 const ui::Event& event, | 158 const ui::Event& event, |
| 119 scoped_ptr<ui::Event>* rewritten_event) OVERRIDE; | 159 scoped_ptr<ui::Event>* rewritten_event) OVERRIDE; |
| 120 virtual ui::EventRewriteStatus NextDispatchEvent( | 160 virtual ui::EventRewriteStatus NextDispatchEvent( |
| 121 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE; | 161 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) OVERRIDE; |
| 122 | 162 |
| 123 // Event handlers based on the current state - see State, below. | 163 // Event handlers based on the current state - see State, below. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 134 ui::EventRewriteStatus InTwoToOneFinger( | 174 ui::EventRewriteStatus InTwoToOneFinger( |
| 135 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 175 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
| 136 ui::EventRewriteStatus InPassthrough( | 176 ui::EventRewriteStatus InPassthrough( |
| 137 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 177 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
| 138 ui::EventRewriteStatus InGestureInProgress( | 178 ui::EventRewriteStatus InGestureInProgress( |
| 139 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 179 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
| 140 ui::EventRewriteStatus InTouchExploreSecondPress( | 180 ui::EventRewriteStatus InTouchExploreSecondPress( |
| 141 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 181 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
| 142 ui::EventRewriteStatus InWaitForRelease( | 182 ui::EventRewriteStatus InWaitForRelease( |
| 143 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | 183 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); |
| 184 ui::EventRewriteStatus InSlideGesture( | |
| 185 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event); | |
| 144 | 186 |
| 145 // This timer is started every time we get the first press event, and | 187 // This timer is started every time we get the first press event, and |
| 146 // it fires after the double-click timeout elapses (300 ms by default). | 188 // it fires after the double-click timeout elapses (300 ms by default). |
| 147 // If the user taps and releases within 300 ms and doesn't press again, | 189 // If the user taps and releases within 300 ms and doesn't press again, |
| 148 // we treat that as a single mouse move (touch exploration) event. | 190 // we treat that as a single mouse move (touch exploration) event. |
| 149 void OnTapTimerFired(); | 191 void OnTapTimerFired(); |
| 150 | 192 |
| 151 // Dispatch a new event outside of the event rewriting flow. | 193 // Dispatch a new event outside of the event rewriting flow. |
| 152 void DispatchEvent(ui::Event* event); | 194 void DispatchEvent(ui::Event* event); |
| 153 | 195 |
| 154 // Overridden from GestureProviderAuraClient. | 196 // Overridden from GestureProviderAuraClient. |
| 155 // | 197 // |
| 156 // The gesture provider keeps track of all the touch events after | 198 // The gesture provider keeps track of all the touch events after |
| 157 // the user moves fast enough to trigger a gesture. After the user | 199 // the user moves fast enough to trigger a gesture. After the user |
| 158 // completes their gesture, this method will decide what keyboard | 200 // completes their gesture, this method will decide what keyboard |
| 159 // input their gesture corresponded to. | 201 // input their gesture corresponded to. |
| 160 virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE; | 202 virtual void OnGestureEvent(ui::GestureEvent* gesture) OVERRIDE; |
| 161 | 203 |
| 162 // Process the gesture events that have been created. | 204 // Process the gesture events that have been created. |
| 163 void ProcessGestureEvents(); | 205 void ProcessGestureEvents(); |
| 164 | 206 |
| 165 void OnSwipeEvent(ui::GestureEvent* swipe_gesture); | 207 void OnSwipeEvent(ui::GestureEvent* swipe_gesture); |
| 166 | 208 |
| 209 void SideSlideControl(ui::GestureEvent* gesture); | |
| 210 | |
| 167 // Dispatches the keyboard short cut Shift+Search+<arrow key> | 211 // Dispatches the keyboard short cut Shift+Search+<arrow key> |
| 168 // outside the event rewritting flow. | 212 // outside the event rewritting flow. |
| 169 void DispatchShiftSearchKeyEvent(const ui::KeyboardCode direction); | 213 void DispatchShiftSearchKeyEvent(const ui::KeyboardCode direction); |
| 170 | 214 |
| 171 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location, | 215 scoped_ptr<ui::Event> CreateMouseMoveEvent(const gfx::PointF& location, |
| 172 int flags); | 216 int flags); |
| 173 | 217 |
| 174 void EnterTouchToMouseMode(); | 218 void EnterTouchToMouseMode(); |
| 175 | 219 |
| 176 // Set the state to NO_FINGERS_DOWN and reset any other fields to their | 220 // Set the state to NO_FINGERS_DOWN and reset any other fields to their |
| 177 // default value. | 221 // default value. |
| 178 void ResetToNoFingersDown(); | 222 void ResetToNoFingersDown(); |
| 179 | 223 |
| 224 void PlaySoundForTimer(); | |
| 225 | |
| 180 enum State { | 226 enum State { |
| 181 // No fingers are down and no events are pending. | 227 // No fingers are down and no events are pending. |
| 182 NO_FINGERS_DOWN, | 228 NO_FINGERS_DOWN, |
| 183 | 229 |
| 184 // A single finger is down, but we're not yet sure if this is going | 230 // A single finger is down, but we're not yet sure if this is going |
| 185 // to be touch exploration or something else. | 231 // to be touch exploration or something else. |
| 186 SINGLE_TAP_PRESSED, | 232 SINGLE_TAP_PRESSED, |
| 187 | 233 |
| 188 // The user pressed and released a single finger - a tap - but we have | 234 // The user pressed and released a single finger - a tap - but we have |
| 189 // to wait until the end of the grace period to allow the user to tap the | 235 // to wait until the end of the grace period to allow the user to tap the |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 // If the user is in TWO_TO_ONE_FINGER with two fingers down and presses | 282 // If the user is in TWO_TO_ONE_FINGER with two fingers down and presses |
| 237 // a third finger, every finger and touch event is passed through until | 283 // a third finger, every finger and touch event is passed through until |
| 238 // all fingers are released. | 284 // all fingers are released. |
| 239 PASSTHROUGH, | 285 PASSTHROUGH, |
| 240 | 286 |
| 241 // If the user lifted a finger in TWO_TO_ONE_FINGER, they must release | 287 // If the user lifted a finger in TWO_TO_ONE_FINGER, they must release |
| 242 // all fingers before completing any more actions. This state is | 288 // all fingers before completing any more actions. This state is |
| 243 // generally useful for developing new features, because it creates a | 289 // generally useful for developing new features, because it creates a |
| 244 // simple way to handle a dead end in user flow. | 290 // simple way to handle a dead end in user flow. |
| 245 WAIT_FOR_RELEASE, | 291 WAIT_FOR_RELEASE, |
| 292 | |
| 293 // If the user is within the given bounds from an edge of the screen, not | |
| 294 // including corners, then the resulting movements will be interpreted as | |
| 295 // slide gestures. | |
| 296 SLIDE_GESTURE, | |
| 246 }; | 297 }; |
| 247 | 298 |
| 299 enum ScreenLocation { | |
| 300 // Hot "edges" of the screen are each represented by a respective bit. | |
| 301 RIGHT_EDGE = 0x1, | |
| 302 TOP_EDGE = 0x2, | |
| 303 LEFT_EDGE = 0x4, | |
| 304 BOTTOM_EDGE = 0x8, | |
| 305 SCREEN_CENTER = 0x0, | |
| 306 }; | |
| 307 | |
| 308 // Given a point, if it is within the given bounds of an edge, returns the | |
| 309 // edge. If it is within the given bounds of two edges, returns an int with | |
| 310 // both bits that represent the respective edges turned on. Otherwise returns | |
| 311 // SCREEN_CENTER. | |
| 312 int WithinBoundsOfEdge(gfx::Point point, float bounds); | |
| 313 | |
| 248 void VlogState(const char* function_name); | 314 void VlogState(const char* function_name); |
| 249 | 315 |
| 250 void VlogEvent(const ui::TouchEvent& event, const char* function_name); | 316 void VlogEvent(const ui::TouchEvent& event, const char* function_name); |
| 251 | 317 |
| 252 // Gets enum name from integer value. | 318 // Gets enum name from integer value. |
| 253 const char* EnumStateToString(State state); | 319 const char* EnumStateToString(State state); |
| 254 | 320 |
| 255 aura::Window* root_window_; | 321 aura::Window* root_window_; |
| 256 | 322 |
| 323 // Volume control. | |
| 324 scoped_ptr<ui::TouchExplorationControllerDelegate> delegate_; | |
| 325 | |
| 257 // A set of touch ids for fingers currently touching the screen. | 326 // A set of touch ids for fingers currently touching the screen. |
| 258 std::vector<int> current_touch_ids_; | 327 std::vector<int> current_touch_ids_; |
| 259 | 328 |
| 260 // Map of touch ids to their last known location. | 329 // Map of touch ids to their last known location. |
| 261 std::map<int, gfx::PointF> touch_locations_; | 330 std::map<int, gfx::PointF> touch_locations_; |
| 262 | 331 |
| 263 // The current state. | 332 // The current state. |
| 264 State state_; | 333 State state_; |
| 265 | 334 |
| 266 // A copy of the event from the initial touch press. | 335 // A copy of the event from the initial touch press. |
| 267 scoped_ptr<ui::TouchEvent> initial_press_; | 336 scoped_ptr<ui::TouchEvent> initial_press_; |
| 268 | 337 |
| 269 // Stores the most recent event from a finger that is currently not | 338 // Stores the most recent event from a finger that is currently not |
| 270 // sending events through, but might in the future (e.g. TwoToOneFinger | 339 // sending events through, but might in the future (e.g. TwoToOneFinger |
| 271 // to Passthrough state). | 340 // to Passthrough state). |
| 272 scoped_ptr<ui::TouchEvent> last_unused_finger_event_; | 341 scoped_ptr<ui::TouchEvent> last_unused_finger_event_; |
| 273 | 342 |
| 274 // The last synthesized mouse move event. When the user double-taps, | 343 // The last synthesized mouse move event. When the user double-taps, |
| 275 // we send the passed-through tap to the location of this event. | 344 // we send the passed-through tap to the location of this event. |
| 276 scoped_ptr<ui::TouchEvent> last_touch_exploration_; | 345 scoped_ptr<ui::TouchEvent> last_touch_exploration_; |
| 277 | 346 |
| 278 // The last event from the finger that is being passed through in | 347 // The last event from the finger that is being passed through in |
| 279 // TWO_TO_ONE_FINGER. When the user lifts a finger during two to one, | 348 // TWO_TO_ONE_FINGER. When the user lifts a finger during two to one, |
| 280 // the location and id of the touch release is from here. | 349 // the location and id of the touch release is from here. |
| 281 scoped_ptr<ui::TouchEvent> last_two_to_one_; | 350 scoped_ptr<ui::TouchEvent> last_two_to_one_; |
| 282 | 351 |
| 283 // A timer to fire the mouse move event after the double-tap delay. | 352 // A timer to fire the mouse move event after the double-tap delay. |
| 284 base::OneShotTimer<TouchExplorationController> tap_timer_; | 353 base::OneShotTimer<TouchExplorationController> tap_timer_; |
| 285 | 354 |
| 355 // A timer to fire a indicating sound when sliding to change volume. | |
| 356 base::RepeatingTimer<TouchExplorationController> sound_timer_; | |
| 357 | |
| 286 // For testing only, an event handler to use for generated events | 358 // For testing only, an event handler to use for generated events |
| 287 // outside of the normal event rewriting flow. | 359 // outside of the normal event rewriting flow. |
| 288 ui::EventHandler* event_handler_for_testing_; | 360 ui::EventHandler* event_handler_for_testing_; |
| 289 | 361 |
| 290 // A default gesture detector config, so we can share the same | 362 // A default gesture detector config, so we can share the same |
| 291 // timeout and pixel slop constants. | 363 // timeout and pixel slop constants. |
| 292 ui::GestureDetector::Config gesture_detector_config_; | 364 ui::GestureDetector::Config gesture_detector_config_; |
| 293 | 365 |
| 294 // Gesture Handler to interpret the touch events. | 366 // Gesture Handler to interpret the touch events. |
| 295 ui::GestureProviderAura gesture_provider_; | 367 ui::GestureProviderAura gesture_provider_; |
| 296 | 368 |
| 297 // The previous state entered. | 369 // The previous state entered. |
| 298 State prev_state_; | 370 State prev_state_; |
| 299 | 371 |
| 300 // A copy of the previous event passed. | 372 // A copy of the previous event passed. |
| 301 scoped_ptr<ui::TouchEvent> prev_event_; | 373 scoped_ptr<ui::TouchEvent> prev_event_; |
| 302 | 374 |
| 303 // This toggles whether VLOGS are turned on or not. | 375 // This toggles whether VLOGS are turned on or not. |
| 304 bool VLOG_on_; | 376 bool VLOG_on_; |
| 305 | 377 |
| 306 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); | 378 DISALLOW_COPY_AND_ASSIGN(TouchExplorationController); |
| 307 }; | 379 }; |
| 308 | 380 |
| 309 } // namespace ui | 381 } // namespace ui |
| 310 | 382 |
| 311 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ | 383 #endif // UI_CHROMEOS_TOUCH_EXPLORATION_CONTROLLER_H_ |
| OLD | NEW |