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

Side by Side Diff: ui/chromeos/touch_exploration_controller.cc

Issue 410783002: Corner Passthrough for Accessibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@side-gestures
Patch Set: Fixed some rebase quirks Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/chromeos/touch_exploration_controller.h" 5 #include "ui/chromeos/touch_exploration_controller.h"
6 6
7 #include "base/strings/string_number_conversions.h" 7 #include "base/strings/string_number_conversions.h"
8 #include "ui/aura/client/cursor_client.h" 8 #include "ui/aura/client/cursor_client.h"
9 #include "ui/aura/window.h" 9 #include "ui/aura/window.h"
10 #include "ui/aura/window_event_dispatcher.h" 10 #include "ui/aura/window_event_dispatcher.h"
11 #include "ui/aura/window_tree_host.h" 11 #include "ui/aura/window_tree_host.h"
12 #include "ui/events/event.h" 12 #include "ui/events/event.h"
13 #include "ui/events/event_processor.h" 13 #include "ui/events/event_processor.h"
14 #include "ui/gfx/geometry/rect.h" 14 #include "ui/gfx/geometry/rect.h"
15 15
16 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) 16 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__)
17 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) 17 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__)
18 18
19 namespace ui { 19 namespace ui {
20 20
21 namespace { 21 namespace {
22 22
23 // Delay between adjustment sounds. 23 // Delay between adjustment sounds.
24 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150); 24 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150);
25 25
26 // Delay before corner passthrough activates.
27 const base::TimeDelta kCornerPassthroughDelay =
28 base::TimeDelta::FromMilliseconds(700);
29
26 // In ChromeOS, VKEY_LWIN is synonymous for the search key. 30 // In ChromeOS, VKEY_LWIN is synonymous for the search key.
27 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; 31 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
28 } // namespace 32 } // namespace
29 33
30 TouchExplorationController::TouchExplorationController( 34 TouchExplorationController::TouchExplorationController(
31 aura::Window* root_window, 35 aura::Window* root_window,
32 TouchExplorationControllerDelegate* delegate) 36 TouchExplorationControllerDelegate* delegate)
33 : root_window_(root_window), 37 : root_window_(root_window),
34 delegate_(delegate), 38 delegate_(delegate),
35 state_(NO_FINGERS_DOWN), 39 state_(NO_FINGERS_DOWN),
36 event_handler_for_testing_(NULL), 40 event_handler_for_testing_(NULL),
37 gesture_provider_(this), 41 gesture_provider_(this),
38 prev_state_(NO_FINGERS_DOWN), 42 prev_state_(NO_FINGERS_DOWN),
39 VLOG_on_(true) { 43 VLOG_on_(true),
44 waiting_for_corner_passthrough_(false) {
40 CHECK(root_window); 45 CHECK(root_window);
41 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 46 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
42 } 47 }
43 48
44 TouchExplorationController::~TouchExplorationController() { 49 TouchExplorationController::~TouchExplorationController() {
45 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); 50 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
46 } 51 }
47 52
48 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 53 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
49 const ui::Event& event, 54 const ui::Event& event,
(...skipping 16 matching lines...) Expand all
66 // the timer. 71 // the timer.
67 if (tap_timer_.IsRunning() && 72 if (tap_timer_.IsRunning() &&
68 touch_event.time_stamp() - initial_press_->time_stamp() > 73 touch_event.time_stamp() - initial_press_->time_stamp() >
69 gesture_detector_config_.double_tap_timeout) { 74 gesture_detector_config_.double_tap_timeout) {
70 tap_timer_.Stop(); 75 tap_timer_.Stop();
71 OnTapTimerFired(); 76 OnTapTimerFired();
72 // Note: this may change the state. We should now continue and process 77 // Note: this may change the state. We should now continue and process
73 // this event under this new state. 78 // this event under this new state.
74 } 79 }
75 80
81 if (long_press_timer_.IsRunning() &&
82 event.time_stamp() - initial_press_->time_stamp() >
83 gesture_detector_config_.longpress_timeout) {
84 long_press_timer_.Stop();
85 OnLongPressTimerFired();
86 }
87
76 const ui::EventType type = touch_event.type(); 88 const ui::EventType type = touch_event.type();
77 const gfx::PointF& location = touch_event.location_f(); 89 const gfx::PointF& location = touch_event.location_f();
78 const int touch_id = touch_event.touch_id(); 90 const int touch_id = touch_event.touch_id();
79 91
80 // Always update touch ids and touch locations, so we can use those 92 // Always update touch ids and touch locations, so we can use those
81 // no matter what state we're in. 93 // no matter what state we're in.
82 if (type == ui::ET_TOUCH_PRESSED) { 94 if (type == ui::ET_TOUCH_PRESSED) {
95 // If the user enters the screen then send an earcon.
96 gfx::Point edges = touch_event.location();
97 if (FindEdgesWithinBounds(edges, kLeavingScreenEdge) != NO_EDGE) {
98 VLOG(0) << "Entering the screen";
99 delegate_->PlayEnterScreenEarcon();
100 }
83 current_touch_ids_.push_back(touch_id); 101 current_touch_ids_.push_back(touch_id);
84 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); 102 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
85 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 103 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
86 // In order to avoid accidentally double tapping when moving off the edge of 104 // In order to avoid accidentally double tapping when moving off the edge of
87 // the screen, the state will be rewritten to NoFingersDown. 105 // the screen, the state will be rewritten to NoFingersDown.
88 TouchEvent touch_event = static_cast<const TouchEvent&>(event); 106 TouchEvent touch_event = static_cast<const TouchEvent&>(event);
89 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != 107 gfx::Point edges = touch_event.location();
90 NO_EDGE) { 108 if (FindEdgesWithinBounds(edges, kLeavingScreenEdge) != NO_EDGE) {
109 VLOG(0) << "Leaving screen";
110 // Indicates to the user that they are leaving the screen.
111 delegate_->PlayExitScreenEarcon();
91 if (current_touch_ids_.size() == 0) 112 if (current_touch_ids_.size() == 0)
92 ResetToNoFingersDown(); 113 ResetToNoFingersDown();
93 } 114 }
94 115
95 std::vector<int>::iterator it = std::find( 116 std::vector<int>::iterator it = std::find(
96 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); 117 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id);
97 118
98 // Can happen if touch exploration is enabled while fingers were down. 119 // Can happen if touch exploration is enabled while fingers were down.
99 if (it == current_touch_ids_.end()) 120 if (it == current_touch_ids_.end())
100 return ui::EVENT_REWRITE_CONTINUE; 121 return ui::EVENT_REWRITE_CONTINUE;
(...skipping 24 matching lines...) Expand all
125 case DOUBLE_TAP_PRESSED: 146 case DOUBLE_TAP_PRESSED:
126 return InDoubleTapPressed(touch_event, rewritten_event); 147 return InDoubleTapPressed(touch_event, rewritten_event);
127 case TOUCH_EXPLORATION: 148 case TOUCH_EXPLORATION:
128 return InTouchExploration(touch_event, rewritten_event); 149 return InTouchExploration(touch_event, rewritten_event);
129 case GESTURE_IN_PROGRESS: 150 case GESTURE_IN_PROGRESS:
130 return InGestureInProgress(touch_event, rewritten_event); 151 return InGestureInProgress(touch_event, rewritten_event);
131 case TOUCH_EXPLORE_SECOND_PRESS: 152 case TOUCH_EXPLORE_SECOND_PRESS:
132 return InTouchExploreSecondPress(touch_event, rewritten_event); 153 return InTouchExploreSecondPress(touch_event, rewritten_event);
133 case TWO_TO_ONE_FINGER: 154 case TWO_TO_ONE_FINGER:
134 return InTwoToOneFinger(touch_event, rewritten_event); 155 return InTwoToOneFinger(touch_event, rewritten_event);
156 case CORNER_PASSTHROUGH:
157 return InCornerPassthrough(touch_event, rewritten_event);
135 case PASSTHROUGH: 158 case PASSTHROUGH:
136 return InPassthrough(touch_event, rewritten_event); 159 return InPassthrough(touch_event, rewritten_event);
137 case WAIT_FOR_RELEASE: 160 case WAIT_FOR_RELEASE:
138 return InWaitForRelease(touch_event, rewritten_event); 161 return InWaitForRelease(touch_event, rewritten_event);
139 case SLIDE_GESTURE: 162 case SLIDE_GESTURE:
140 return InSlideGesture(touch_event, rewritten_event); 163 return InSlideGesture(touch_event, rewritten_event);
141 } 164 }
142 NOTREACHED(); 165 NOTREACHED();
143 return ui::EVENT_REWRITE_CONTINUE; 166 return ui::EVENT_REWRITE_CONTINUE;
144 } 167 }
145 168
146 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 169 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
147 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 170 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
148 NOTREACHED(); 171 NOTREACHED();
149 return ui::EVENT_REWRITE_CONTINUE; 172 return ui::EVENT_REWRITE_CONTINUE;
150 } 173 }
151 174
152 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 175 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
153 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 176 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
154 const ui::EventType type = event.type(); 177 const ui::EventType type = event.type();
155 if (type == ui::ET_TOUCH_PRESSED) { 178 if (type != ui::ET_TOUCH_PRESSED) {
156 initial_press_.reset(new TouchEvent(event)); 179 NOTREACHED() << "Unexpected event type received: " << event.name();
157 last_unused_finger_event_.reset(new TouchEvent(event)); 180 return ui::EVENT_REWRITE_CONTINUE;
158 tap_timer_.Start(FROM_HERE,
159 gesture_detector_config_.double_tap_timeout,
160 this,
161 &TouchExplorationController::OnTapTimerFired);
162 gesture_provider_.OnTouchEvent(event);
163 gesture_provider_.OnTouchEventAck(false);
164 ProcessGestureEvents();
165 state_ = SINGLE_TAP_PRESSED;
166 VLOG_STATE();
167 return ui::EVENT_REWRITE_DISCARD;
168 } 181 }
169 NOTREACHED() << "Unexpected event type received: " << event.name();; 182 int location = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
170 return ui::EVENT_REWRITE_CONTINUE; 183 base::TimeDelta timeout;
184
185 // If the press was at a corner, the user might go into corner passthrough
186 // instead.
187 bool in_a_bottom_corner =
188 (BOTTOM_LEFT_CORNER == location) || (BOTTOM_RIGHT_CORNER == location);
189 if (in_a_bottom_corner) {
190 VLOG(0) << "Location: " << location;
191 long_press_timer_.Start(FROM_HERE,
192 gesture_detector_config_.longpress_timeout,
193 this,
194 &TouchExplorationController::OnLongPressTimerFired);
195 waiting_for_corner_passthrough_ = true;
196 } else {
197 waiting_for_corner_passthrough_ = false;
198 }
199 tap_timer_.Start(FROM_HERE,
200 gesture_detector_config_.double_tap_timeout,
201 this,
202 &TouchExplorationController::OnTapTimerFired);
203 initial_press_.reset(new TouchEvent(event));
204 last_unused_finger_event_.reset(new TouchEvent(event));
205 gesture_provider_.OnTouchEvent(event);
206 gesture_provider_.OnTouchEventAck(false);
207 ProcessGestureEvents();
208 state_ = SINGLE_TAP_PRESSED;
209 VLOG_STATE();
210 return ui::EVENT_REWRITE_DISCARD;
171 } 211 }
172 212
173 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 213 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
174 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 214 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
175 const ui::EventType type = event.type(); 215 const ui::EventType type = event.type();
176 216
217 int location = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
218 bool in_a_bottom_corner =
219 (location == BOTTOM_LEFT_CORNER) || (location == BOTTOM_RIGHT_CORNER);
220 // If the event is from the initial press and the location is no longer in the
221 // corner, then we are not waiting for a corner passthrough anymore.
222 if (event.touch_id() == initial_press_->touch_id() && !in_a_bottom_corner) {
223 waiting_for_corner_passthrough_ = false;
224 if (long_press_timer_.IsRunning()) {
225 long_press_timer_.Stop();
226 if (event.time_stamp() - initial_press_->time_stamp() >
227 gesture_detector_config_.double_tap_timeout) {
228 OnTapTimerFired();
229 }
230 }
231 }
232
177 if (type == ui::ET_TOUCH_PRESSED) { 233 if (type == ui::ET_TOUCH_PRESSED) {
234 waiting_for_corner_passthrough_ = false;
178 // Adding a second finger within the timeout period switches to 235 // Adding a second finger within the timeout period switches to
179 // passing through every event from the second finger and none form the 236 // passing through every event from the second finger and none form the
180 // first. The event from the first finger is still saved in initial_press_. 237 // first. The event from the first finger is still saved in initial_press_.
181 state_ = TWO_TO_ONE_FINGER; 238 state_ = TWO_TO_ONE_FINGER;
182 last_two_to_one_.reset(new TouchEvent(event)); 239 last_two_to_one_.reset(new TouchEvent(event));
183 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 240 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
184 event.location(), 241 event.location(),
185 event.touch_id(), 242 event.touch_id(),
186 event.time_stamp())); 243 event.time_stamp()));
187 (*rewritten_event)->set_flags(event.flags()); 244 (*rewritten_event)->set_flags(event.flags());
188 return EVENT_REWRITE_REWRITTEN; 245 return EVENT_REWRITE_REWRITTEN;
189 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 246 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
247 waiting_for_corner_passthrough_ = false;
190 DCHECK_EQ(0U, current_touch_ids_.size()); 248 DCHECK_EQ(0U, current_touch_ids_.size());
191 state_ = SINGLE_TAP_RELEASED; 249 state_ = SINGLE_TAP_RELEASED;
192 VLOG_STATE(); 250 VLOG_STATE();
193 return EVENT_REWRITE_DISCARD; 251 return EVENT_REWRITE_DISCARD;
194 } else if (type == ui::ET_TOUCH_MOVED) { 252 } else if (type == ui::ET_TOUCH_MOVED) {
195 float distance = (event.location() - initial_press_->location()).Length(); 253 float distance = (event.location() - initial_press_->location()).Length();
196 // If the user does not move far enough from the original position, then the 254 // If the user does not move far enough from the original position, then the
197 // resulting movement should not be considered to be a deliberate gesture or 255 // resulting movement should not be considered to be a deliberate gesture or
198 // touch exploration. 256 // touch exploration.
199 if (distance <= gesture_detector_config_.touch_slop) 257 if (distance <= gesture_detector_config_.touch_slop)
200 return EVENT_REWRITE_DISCARD; 258 return EVENT_REWRITE_DISCARD;
201 259
202 float delta_time = 260 float delta_time =
203 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); 261 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF();
204 float velocity = distance / delta_time; 262 float velocity = distance / delta_time;
205 VLOG(0) << "\n Delta time: " << delta_time 263 VLOG(0) << "\n Delta time: " << delta_time
206 << "\n Distance: " << distance 264 << "\n Distance: " << distance
207 << "\n Velocity of click: " << velocity 265 << "\n Velocity of click: " << velocity
208 << "\n Minimum swipe velocity: " 266 << "\n Minimum swipe velocity: "
209 << gesture_detector_config_.minimum_swipe_velocity; 267 << gesture_detector_config_.minimum_swipe_velocity;
210 268
211 // Change to slide gesture if the slide occurred at the right edge. 269 // Change to slide gesture if the slide occurred at the right edge.
212 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); 270 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
213 if (edge & RIGHT_EDGE) { 271 if (edge & RIGHT_EDGE && edge != BOTTOM_RIGHT_CORNER) {
214 state_ = SLIDE_GESTURE; 272 state_ = SLIDE_GESTURE;
215 VLOG_STATE(); 273 VLOG_STATE();
216 return InSlideGesture(event, rewritten_event); 274 return InSlideGesture(event, rewritten_event);
217 } 275 }
218 276
219 // If the user moves fast enough from the initial touch location, start 277 // If the user moves fast enough from the initial touch location, start
220 // gesture detection. Otherwise, jump to the touch exploration mode early. 278 // gesture detection. Otherwise, jump to the touch exploration mode early.
221 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 279 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
222 state_ = GESTURE_IN_PROGRESS; 280 state_ = GESTURE_IN_PROGRESS;
223 VLOG_STATE(); 281 VLOG_STATE();
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 event.time_stamp())); 450 event.time_stamp()));
393 (*rewritten_event)->set_flags(event.flags()); 451 (*rewritten_event)->set_flags(event.flags());
394 state_ = WAIT_FOR_RELEASE; 452 state_ = WAIT_FOR_RELEASE;
395 return ui::EVENT_REWRITE_REWRITTEN; 453 return ui::EVENT_REWRITE_REWRITTEN;
396 } 454 }
397 } else if (type == ui::ET_TOUCH_PRESSED) { 455 } else if (type == ui::ET_TOUCH_PRESSED) {
398 DCHECK(current_touch_ids_.size() == 3); 456 DCHECK(current_touch_ids_.size() == 3);
399 // If a third finger is pressed, we are now going into passthrough mode 457 // If a third finger is pressed, we are now going into passthrough mode
400 // and now need to dispatch the first finger into a press, as well as the 458 // and now need to dispatch the first finger into a press, as well as the
401 // recent press. 459 // recent press.
402 if (current_touch_ids_.size() == 3){ 460 if (current_touch_ids_.size() == 3) {
403 state_ = PASSTHROUGH; 461 state_ = PASSTHROUGH;
404 scoped_ptr<ui::TouchEvent> first_finger_press; 462 scoped_ptr<ui::TouchEvent> first_finger_press;
405 first_finger_press.reset( 463 first_finger_press.reset(
406 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 464 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
407 last_unused_finger_event_->location(), 465 last_unused_finger_event_->location(),
408 last_unused_finger_event_->touch_id(), 466 last_unused_finger_event_->touch_id(),
409 event.time_stamp())); 467 event.time_stamp()));
410 DispatchEvent(first_finger_press.get()); 468 DispatchEvent(first_finger_press.get());
411 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 469 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
412 event.location(), 470 event.location(),
(...skipping 18 matching lines...) Expand all
431 event.touch_id(), 489 event.touch_id(),
432 event.time_stamp())); 490 event.time_stamp()));
433 (*rewritten_event)->set_flags(event.flags()); 491 (*rewritten_event)->set_flags(event.flags());
434 return ui::EVENT_REWRITE_REWRITTEN; 492 return ui::EVENT_REWRITE_REWRITTEN;
435 } 493 }
436 } 494 }
437 NOTREACHED() << "Unexpected event type received: " << event.name(); 495 NOTREACHED() << "Unexpected event type received: " << event.name();
438 return ui::EVENT_REWRITE_CONTINUE; 496 return ui::EVENT_REWRITE_CONTINUE;
439 } 497 }
440 498
499 ui::EventRewriteStatus TouchExplorationController::InCornerPassthrough(
500 const ui::TouchEvent& event,
501 scoped_ptr<ui::Event>* rewritten_event) {
502 ui::EventType type = event.type();
503
504 // If the first finger has left the corner, then exit passthrough.
505 if (event.touch_id() == initial_press_->touch_id()) {
506 int edges = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
507 bool in_a_bottom_corner = (edges == BOTTOM_LEFT_CORNER) ||
508 (edges == BOTTOM_RIGHT_CORNER);
509 if (type == ui::ET_TOUCH_MOVED && in_a_bottom_corner)
510 return ui::EVENT_REWRITE_DISCARD;
511
512 if (current_touch_ids_.size() == 0) {
513 ResetToNoFingersDown();
514 return ui::EVENT_REWRITE_DISCARD;
515 }
516
517 waiting_for_corner_passthrough_ = false;
518 VLOG(0) << "Waiting for corner passthrough is false";
519 state_ = WAIT_FOR_RELEASE;
520 VLOG_STATE();
521 return ui::EVENT_REWRITE_DISCARD;
522 }
523
524 rewritten_event->reset(new ui::TouchEvent(
525 type, event.location(), event.touch_id(), event.time_stamp()));
526 (*rewritten_event)->set_flags(event.flags());
527
528 if (current_touch_ids_.size() == 0)
529 ResetToNoFingersDown();
530
531 return ui::EVENT_REWRITE_REWRITTEN;
532 }
533
441 ui::EventRewriteStatus TouchExplorationController::InPassthrough( 534 ui::EventRewriteStatus TouchExplorationController::InPassthrough(
442 const ui::TouchEvent& event, 535 const ui::TouchEvent& event,
443 scoped_ptr<ui::Event>* rewritten_event) { 536 scoped_ptr<ui::Event>* rewritten_event) {
444 ui::EventType type = event.type(); 537 ui::EventType type = event.type();
445 538
446 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED || 539 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED ||
447 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) { 540 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) {
448 NOTREACHED() << "Unexpected event type received: " << event.name(); 541 NOTREACHED() << "Unexpected event type received: " << event.name();
449 return ui::EVENT_REWRITE_CONTINUE; 542 return ui::EVENT_REWRITE_CONTINUE;
450 } 543 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 VLOG_STATE(); 591 VLOG_STATE();
499 return ui::EVENT_REWRITE_REWRITTEN; 592 return ui::EVENT_REWRITE_REWRITTEN;
500 } 593 }
501 NOTREACHED() << "Unexpected event type received: " << event.name(); 594 NOTREACHED() << "Unexpected event type received: " << event.name();
502 return ui::EVENT_REWRITE_CONTINUE; 595 return ui::EVENT_REWRITE_CONTINUE;
503 } 596 }
504 597
505 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease( 598 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease(
506 const ui::TouchEvent& event, 599 const ui::TouchEvent& event,
507 scoped_ptr<ui::Event>* rewritten_event) { 600 scoped_ptr<ui::Event>* rewritten_event) {
601 waiting_for_corner_passthrough_ = false;
508 ui::EventType type = event.type(); 602 ui::EventType type = event.type();
509 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || 603 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED ||
510 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { 604 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) {
511 NOTREACHED() << "Unexpected event type received: " << event.name(); 605 NOTREACHED() << "Unexpected event type received: " << event.name();
512 return ui::EVENT_REWRITE_CONTINUE; 606 return ui::EVENT_REWRITE_CONTINUE;
513 } 607 }
514 if (current_touch_ids_.size() == 0) { 608 if (current_touch_ids_.size() == 0) {
515 state_ = NO_FINGERS_DOWN; 609 state_ = NO_FINGERS_DOWN;
516 VLOG_STATE(); 610 VLOG_STATE();
517 ResetToNoFingersDown(); 611 ResetToNoFingersDown();
518 } 612 }
519 return EVENT_REWRITE_DISCARD; 613 return EVENT_REWRITE_DISCARD;
520 } 614 }
521 615
522 void TouchExplorationController::PlaySoundForTimer() { 616 void TouchExplorationController::PlaySoundForTimer() {
523 delegate_->PlayVolumeAdjustSound(); 617 delegate_->PlayVolumeAdjustEarcon();
524 } 618 }
525 619
526 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( 620 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
527 const ui::TouchEvent& event, 621 const ui::TouchEvent& event,
528 scoped_ptr<ui::Event>* rewritten_event) { 622 scoped_ptr<ui::Event>* rewritten_event) {
529 // The timer should not fire when sliding. 623 // The timer should not fire when sliding.
530 if (tap_timer_.IsRunning()) 624 if (tap_timer_.IsRunning())
531 tap_timer_.Stop(); 625 tap_timer_.Stop();
532 626
533 ui::EventType type = event.type(); 627 ui::EventType type = event.type();
(...skipping 19 matching lines...) Expand all
553 return EVENT_REWRITE_DISCARD; 647 return EVENT_REWRITE_DISCARD;
554 } 648 }
555 649
556 // This can occur if the user leaves the screen edge and then returns to it to 650 // This can occur if the user leaves the screen edge and then returns to it to
557 // continue adjusting the sound. 651 // continue adjusting the sound.
558 if (!sound_timer_.IsRunning()) { 652 if (!sound_timer_.IsRunning()) {
559 sound_timer_.Start(FROM_HERE, 653 sound_timer_.Start(FROM_HERE,
560 kSoundDelay, 654 kSoundDelay,
561 this, 655 this,
562 &ui::TouchExplorationController::PlaySoundForTimer); 656 &ui::TouchExplorationController::PlaySoundForTimer);
563 delegate_->PlayVolumeAdjustSound(); 657 delegate_->PlayVolumeAdjustEarcon();
564 } 658 }
565 659
566 // There should not be more than one finger down. 660 // There should not be more than one finger down.
567 DCHECK(current_touch_ids_.size() <= 1); 661 DCHECK(current_touch_ids_.size() <= 1);
568 if (type == ui::ET_TOUCH_MOVED) { 662 if (type == ui::ET_TOUCH_MOVED) {
569 gesture_provider_.OnTouchEvent(event); 663 gesture_provider_.OnTouchEvent(event);
570 gesture_provider_.OnTouchEventAck(false); 664 gesture_provider_.OnTouchEventAck(false);
571 } 665 }
572 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 666 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
573 gesture_provider_.OnTouchEvent(event); 667 gesture_provider_.OnTouchEvent(event);
(...skipping 11 matching lines...) Expand all
585 void TouchExplorationController::OnTapTimerFired() { 679 void TouchExplorationController::OnTapTimerFired() {
586 switch (state_) { 680 switch (state_) {
587 case SINGLE_TAP_RELEASED: 681 case SINGLE_TAP_RELEASED:
588 ResetToNoFingersDown(); 682 ResetToNoFingersDown();
589 break; 683 break;
590 case TOUCH_EXPLORE_RELEASED: 684 case TOUCH_EXPLORE_RELEASED:
591 ResetToNoFingersDown(); 685 ResetToNoFingersDown();
592 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 686 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
593 return; 687 return;
594 case SINGLE_TAP_PRESSED: 688 case SINGLE_TAP_PRESSED:
689 if (waiting_for_corner_passthrough_)
690 return;
595 case GESTURE_IN_PROGRESS: 691 case GESTURE_IN_PROGRESS:
596 // Discard any pending gestures. 692 // Discard any pending gestures.
597 delete gesture_provider_.GetAndResetPendingGestures(); 693 delete gesture_provider_.GetAndResetPendingGestures();
598 EnterTouchToMouseMode(); 694 EnterTouchToMouseMode();
599 state_ = TOUCH_EXPLORATION; 695 state_ = TOUCH_EXPLORATION;
600 VLOG_STATE(); 696 VLOG_STATE();
601 break; 697 break;
602 default: 698 default:
603 return; 699 return;
604 } 700 }
605 scoped_ptr<ui::Event> mouse_move = 701 scoped_ptr<ui::Event> mouse_move =
606 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 702 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
607 DispatchEvent(mouse_move.get()); 703 DispatchEvent(mouse_move.get());
608 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 704 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
609 } 705 }
610 706
707 void TouchExplorationController::OnLongPressTimerFired() {
708 if (waiting_for_corner_passthrough_) {
709 if (sound_timer_.IsRunning())
710 sound_timer_.Stop();
711 delegate_->PlayPassthroughEarcon();
712 delete gesture_provider_.GetAndResetPendingGestures();
713 state_ = CORNER_PASSTHROUGH;
714 VLOG_STATE();
715 return;
716 }
717 }
718
611 void TouchExplorationController::DispatchEvent(ui::Event* event) { 719 void TouchExplorationController::DispatchEvent(ui::Event* event) {
612 if (event_handler_for_testing_) { 720 if (event_handler_for_testing_) {
613 event_handler_for_testing_->OnEvent(event); 721 event_handler_for_testing_->OnEvent(event);
614 return; 722 return;
615 } 723 }
616 ui::EventDispatchDetails result ALLOW_UNUSED = 724 ui::EventDispatchDetails result ALLOW_UNUSED =
617 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 725 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
618 } 726 }
619 727
620 void TouchExplorationController::OnGestureEvent( 728 void TouchExplorationController::OnGestureEvent(
(...skipping 23 matching lines...) Expand all
644 } 752 }
645 } 753 }
646 } 754 }
647 755
648 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { 756 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) {
649 ui::EventType type = gesture->type(); 757 ui::EventType type = gesture->type();
650 if (!gesture->IsScrollGestureEvent()) 758 if (!gesture->IsScrollGestureEvent())
651 return; 759 return;
652 760
653 if (type == ET_GESTURE_SCROLL_BEGIN) { 761 if (type == ET_GESTURE_SCROLL_BEGIN) {
654 delegate_->PlayVolumeAdjustSound(); 762 delegate_->PlayVolumeAdjustEarcon();
655 } 763 }
656 764
657 if (type == ET_GESTURE_SCROLL_END) { 765 if (type == ET_GESTURE_SCROLL_END) {
658 if (sound_timer_.IsRunning()) 766 if (sound_timer_.IsRunning())
659 sound_timer_.Stop(); 767 sound_timer_.Stop();
660 delegate_->PlayVolumeAdjustSound(); 768 delegate_->PlayVolumeAdjustEarcon();
661 } 769 }
662 770
663 // If the user is in the corner of the right side of the screen, the volume 771 // If the user is in the corner of the right side of the screen, the volume
664 // will be automatically set to 100% or muted depending on which corner they 772 // will be automatically set to 100% or muted depending on which corner they
665 // are in. Otherwise, the user will be able to adjust the volume by sliding 773 // are in. Otherwise, the user will be able to adjust the volume by sliding
666 // their finger along the right side of the screen. Volume is relative to 774 // their finger along the right side of the screen. Volume is relative to
667 // where they are on the right side of the screen. 775 // where they are on the right side of the screen.
668 gfx::Point location = gesture->location(); 776 gfx::Point location = gesture->location();
669 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); 777 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge);
670 if (!(edge & RIGHT_EDGE)) 778 if (!(edge & RIGHT_EDGE))
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 void TouchExplorationController::EnterTouchToMouseMode() { 903 void TouchExplorationController::EnterTouchToMouseMode() {
796 aura::client::CursorClient* cursor_client = 904 aura::client::CursorClient* cursor_client =
797 aura::client::GetCursorClient(root_window_); 905 aura::client::GetCursorClient(root_window_);
798 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) 906 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
799 cursor_client->EnableMouseEvents(); 907 cursor_client->EnableMouseEvents();
800 if (cursor_client && cursor_client->IsCursorVisible()) 908 if (cursor_client && cursor_client->IsCursorVisible())
801 cursor_client->HideCursor(); 909 cursor_client->HideCursor();
802 } 910 }
803 911
804 void TouchExplorationController::ResetToNoFingersDown() { 912 void TouchExplorationController::ResetToNoFingersDown() {
913 waiting_for_corner_passthrough_ = false;
805 ProcessGestureEvents(); 914 ProcessGestureEvents();
806 if (sound_timer_.IsRunning()) 915 if (sound_timer_.IsRunning())
807 sound_timer_.Stop(); 916 sound_timer_.Stop();
808 state_ = NO_FINGERS_DOWN; 917 state_ = NO_FINGERS_DOWN;
809 VLOG_STATE(); 918 VLOG_STATE();
810 if (tap_timer_.IsRunning()) 919 if (tap_timer_.IsRunning())
811 tap_timer_.Stop(); 920 tap_timer_.Stop();
812 } 921 }
813 922
814 void TouchExplorationController::VlogState(const char* function_name) { 923 void TouchExplorationController::VlogState(const char* function_name) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 case DOUBLE_TAP_PRESSED: 974 case DOUBLE_TAP_PRESSED:
866 return "DOUBLE_TAP_PRESSED"; 975 return "DOUBLE_TAP_PRESSED";
867 case TOUCH_EXPLORATION: 976 case TOUCH_EXPLORATION:
868 return "TOUCH_EXPLORATION"; 977 return "TOUCH_EXPLORATION";
869 case GESTURE_IN_PROGRESS: 978 case GESTURE_IN_PROGRESS:
870 return "GESTURE_IN_PROGRESS"; 979 return "GESTURE_IN_PROGRESS";
871 case TOUCH_EXPLORE_SECOND_PRESS: 980 case TOUCH_EXPLORE_SECOND_PRESS:
872 return "TOUCH_EXPLORE_SECOND_PRESS"; 981 return "TOUCH_EXPLORE_SECOND_PRESS";
873 case TWO_TO_ONE_FINGER: 982 case TWO_TO_ONE_FINGER:
874 return "TWO_TO_ONE_FINGER"; 983 return "TWO_TO_ONE_FINGER";
984 case CORNER_PASSTHROUGH:
985 return "CORNER_PASSTHROUGH";
875 case PASSTHROUGH: 986 case PASSTHROUGH:
876 return "PASSTHROUGH"; 987 return "PASSTHROUGH";
877 case WAIT_FOR_RELEASE: 988 case WAIT_FOR_RELEASE:
878 return "WAIT_FOR_RELEASE"; 989 return "WAIT_FOR_RELEASE";
879 case SLIDE_GESTURE: 990 case SLIDE_GESTURE:
880 return "SLIDE_GESTURE"; 991 return "SLIDE_GESTURE";
881 } 992 }
882 return "Not a state"; 993 return "Not a state";
883 } 994 }
884 995
885 } // namespace ui 996 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698