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

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: Added Exit and Enter Screen tests 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 if (VLOG_on_)
99 VLOG(0) << "Entering the screen";
100 delegate_->PlayEnterScreenEarcon();
101 }
83 current_touch_ids_.push_back(touch_id); 102 current_touch_ids_.push_back(touch_id);
84 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); 103 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
85 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 104 } 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 105 // In order to avoid accidentally double tapping when moving off the edge of
87 // the screen, the state will be rewritten to NoFingersDown. 106 // the screen, the state will be rewritten to NoFingersDown.
88 TouchEvent touch_event = static_cast<const TouchEvent&>(event); 107 TouchEvent touch_event = static_cast<const TouchEvent&>(event);
89 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != 108 gfx::Point edges = touch_event.location();
90 NO_EDGE) { 109 if (FindEdgesWithinBounds(edges, kLeavingScreenEdge) != NO_EDGE) {
110 if (VLOG_on_)
111 VLOG(0) << "Leaving screen";
112 // Indicates to the user that they are leaving the screen.
113 delegate_->PlayExitScreenEarcon();
91 if (current_touch_ids_.size() == 0) 114 if (current_touch_ids_.size() == 0)
92 ResetToNoFingersDown(); 115 ResetToNoFingersDown();
93 } 116 }
94 117
95 std::vector<int>::iterator it = std::find( 118 std::vector<int>::iterator it = std::find(
96 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); 119 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id);
97 120
98 // Can happen if touch exploration is enabled while fingers were down. 121 // Can happen if touch exploration is enabled while fingers were down.
99 if (it == current_touch_ids_.end()) 122 if (it == current_touch_ids_.end())
100 return ui::EVENT_REWRITE_CONTINUE; 123 return ui::EVENT_REWRITE_CONTINUE;
(...skipping 24 matching lines...) Expand all
125 case DOUBLE_TAP_PRESSED: 148 case DOUBLE_TAP_PRESSED:
126 return InDoubleTapPressed(touch_event, rewritten_event); 149 return InDoubleTapPressed(touch_event, rewritten_event);
127 case TOUCH_EXPLORATION: 150 case TOUCH_EXPLORATION:
128 return InTouchExploration(touch_event, rewritten_event); 151 return InTouchExploration(touch_event, rewritten_event);
129 case GESTURE_IN_PROGRESS: 152 case GESTURE_IN_PROGRESS:
130 return InGestureInProgress(touch_event, rewritten_event); 153 return InGestureInProgress(touch_event, rewritten_event);
131 case TOUCH_EXPLORE_SECOND_PRESS: 154 case TOUCH_EXPLORE_SECOND_PRESS:
132 return InTouchExploreSecondPress(touch_event, rewritten_event); 155 return InTouchExploreSecondPress(touch_event, rewritten_event);
133 case TWO_TO_ONE_FINGER: 156 case TWO_TO_ONE_FINGER:
134 return InTwoToOneFinger(touch_event, rewritten_event); 157 return InTwoToOneFinger(touch_event, rewritten_event);
158 case CORNER_PASSTHROUGH:
159 return InCornerPassthrough(touch_event, rewritten_event);
135 case PASSTHROUGH: 160 case PASSTHROUGH:
136 return InPassthrough(touch_event, rewritten_event); 161 return InPassthrough(touch_event, rewritten_event);
137 case WAIT_FOR_RELEASE: 162 case WAIT_FOR_RELEASE:
138 return InWaitForRelease(touch_event, rewritten_event); 163 return InWaitForRelease(touch_event, rewritten_event);
139 case SLIDE_GESTURE: 164 case SLIDE_GESTURE:
140 return InSlideGesture(touch_event, rewritten_event); 165 return InSlideGesture(touch_event, rewritten_event);
141 } 166 }
142 NOTREACHED(); 167 NOTREACHED();
143 return ui::EVENT_REWRITE_CONTINUE; 168 return ui::EVENT_REWRITE_CONTINUE;
144 } 169 }
145 170
146 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 171 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
147 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 172 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
148 NOTREACHED(); 173 NOTREACHED();
149 return ui::EVENT_REWRITE_CONTINUE; 174 return ui::EVENT_REWRITE_CONTINUE;
150 } 175 }
151 176
152 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 177 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
153 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 178 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
154 const ui::EventType type = event.type(); 179 const ui::EventType type = event.type();
155 if (type == ui::ET_TOUCH_PRESSED) { 180 if (type != ui::ET_TOUCH_PRESSED) {
156 initial_press_.reset(new TouchEvent(event)); 181 NOTREACHED() << "Unexpected event type received: " << event.name();
157 last_unused_finger_event_.reset(new TouchEvent(event)); 182 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 } 183 }
169 NOTREACHED() << "Unexpected event type received: " << event.name();; 184 int location = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
170 return ui::EVENT_REWRITE_CONTINUE; 185 base::TimeDelta timeout;
186
187 // If the press was at a corner, the user might go into corner passthrough
188 // instead.
189 bool in_a_bottom_corner =
190 (BOTTOM_LEFT_CORNER == location) || (BOTTOM_RIGHT_CORNER == location);
191 if (in_a_bottom_corner) {
192 if (VLOG_on_)
193 VLOG(0) << "Location: " << location;
194 long_press_timer_.Start(FROM_HERE,
195 gesture_detector_config_.longpress_timeout,
196 this,
197 &TouchExplorationController::OnLongPressTimerFired);
198 waiting_for_corner_passthrough_ = true;
199 } else {
200 waiting_for_corner_passthrough_ = false;
201 }
202 tap_timer_.Start(FROM_HERE,
203 gesture_detector_config_.double_tap_timeout,
204 this,
205 &TouchExplorationController::OnTapTimerFired);
206 initial_press_.reset(new TouchEvent(event));
207 last_unused_finger_event_.reset(new TouchEvent(event));
208 gesture_provider_.OnTouchEvent(event);
209 gesture_provider_.OnTouchEventAck(false);
210 ProcessGestureEvents();
211 state_ = SINGLE_TAP_PRESSED;
212 VLOG_STATE();
213 return ui::EVENT_REWRITE_DISCARD;
171 } 214 }
172 215
173 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 216 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
174 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 217 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
175 const ui::EventType type = event.type(); 218 const ui::EventType type = event.type();
176 219
220 int location = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
221 bool in_a_bottom_corner =
222 (location == BOTTOM_LEFT_CORNER) || (location == BOTTOM_RIGHT_CORNER);
223 // If the event is from the initial press and the location is no longer in the
224 // corner, then we are not waiting for a corner passthrough anymore.
225 if (event.touch_id() == initial_press_->touch_id() && !in_a_bottom_corner) {
226 waiting_for_corner_passthrough_ = false;
227 if (long_press_timer_.IsRunning()) {
228 long_press_timer_.Stop();
229 if (event.time_stamp() - initial_press_->time_stamp() >
230 gesture_detector_config_.double_tap_timeout) {
231 OnTapTimerFired();
232 }
233 }
234 }
235
177 if (type == ui::ET_TOUCH_PRESSED) { 236 if (type == ui::ET_TOUCH_PRESSED) {
237 waiting_for_corner_passthrough_ = false;
178 // Adding a second finger within the timeout period switches to 238 // Adding a second finger within the timeout period switches to
179 // passing through every event from the second finger and none form the 239 // 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_. 240 // first. The event from the first finger is still saved in initial_press_.
181 state_ = TWO_TO_ONE_FINGER; 241 state_ = TWO_TO_ONE_FINGER;
182 last_two_to_one_.reset(new TouchEvent(event)); 242 last_two_to_one_.reset(new TouchEvent(event));
183 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 243 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
184 event.location(), 244 event.location(),
185 event.touch_id(), 245 event.touch_id(),
186 event.time_stamp())); 246 event.time_stamp()));
187 (*rewritten_event)->set_flags(event.flags()); 247 (*rewritten_event)->set_flags(event.flags());
188 return EVENT_REWRITE_REWRITTEN; 248 return EVENT_REWRITE_REWRITTEN;
189 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 249 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
250 waiting_for_corner_passthrough_ = false;
190 DCHECK_EQ(0U, current_touch_ids_.size()); 251 DCHECK_EQ(0U, current_touch_ids_.size());
191 state_ = SINGLE_TAP_RELEASED; 252 state_ = SINGLE_TAP_RELEASED;
192 VLOG_STATE(); 253 VLOG_STATE();
193 return EVENT_REWRITE_DISCARD; 254 return EVENT_REWRITE_DISCARD;
194 } else if (type == ui::ET_TOUCH_MOVED) { 255 } else if (type == ui::ET_TOUCH_MOVED) {
195 float distance = (event.location() - initial_press_->location()).Length(); 256 float distance = (event.location() - initial_press_->location()).Length();
196 // If the user does not move far enough from the original position, then the 257 // 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 258 // resulting movement should not be considered to be a deliberate gesture or
198 // touch exploration. 259 // touch exploration.
199 if (distance <= gesture_detector_config_.touch_slop) 260 if (distance <= gesture_detector_config_.touch_slop)
200 return EVENT_REWRITE_DISCARD; 261 return EVENT_REWRITE_DISCARD;
201 262
202 float delta_time = 263 float delta_time =
203 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); 264 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF();
204 float velocity = distance / delta_time; 265 float velocity = distance / delta_time;
205 VLOG(0) << "\n Delta time: " << delta_time 266 if (VLOG_on_) {
206 << "\n Distance: " << distance 267 VLOG(0) << "\n Delta time: " << delta_time << "\n Distance: " << distance
207 << "\n Velocity of click: " << velocity 268 << "\n Velocity of click: " << velocity
208 << "\n Minimum swipe velocity: " 269 << "\n Minimum swipe velocity: "
209 << gesture_detector_config_.minimum_swipe_velocity; 270 << gesture_detector_config_.minimum_swipe_velocity;
210 271 }
211 // Change to slide gesture if the slide occurred at the right edge. 272 // Change to slide gesture if the slide occurred at the right edge.
212 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); 273 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
213 if (edge & RIGHT_EDGE) { 274 if (edge & RIGHT_EDGE && edge != BOTTOM_RIGHT_CORNER) {
214 state_ = SLIDE_GESTURE; 275 state_ = SLIDE_GESTURE;
215 VLOG_STATE(); 276 VLOG_STATE();
216 return InSlideGesture(event, rewritten_event); 277 return InSlideGesture(event, rewritten_event);
217 } 278 }
218 279
219 // If the user moves fast enough from the initial touch location, start 280 // If the user moves fast enough from the initial touch location, start
220 // gesture detection. Otherwise, jump to the touch exploration mode early. 281 // gesture detection. Otherwise, jump to the touch exploration mode early.
221 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 282 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
222 state_ = GESTURE_IN_PROGRESS; 283 state_ = GESTURE_IN_PROGRESS;
223 VLOG_STATE(); 284 VLOG_STATE();
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
392 event.time_stamp())); 453 event.time_stamp()));
393 (*rewritten_event)->set_flags(event.flags()); 454 (*rewritten_event)->set_flags(event.flags());
394 state_ = WAIT_FOR_RELEASE; 455 state_ = WAIT_FOR_RELEASE;
395 return ui::EVENT_REWRITE_REWRITTEN; 456 return ui::EVENT_REWRITE_REWRITTEN;
396 } 457 }
397 } else if (type == ui::ET_TOUCH_PRESSED) { 458 } else if (type == ui::ET_TOUCH_PRESSED) {
398 DCHECK(current_touch_ids_.size() == 3); 459 DCHECK(current_touch_ids_.size() == 3);
399 // If a third finger is pressed, we are now going into passthrough mode 460 // 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 461 // and now need to dispatch the first finger into a press, as well as the
401 // recent press. 462 // recent press.
402 if (current_touch_ids_.size() == 3){ 463 if (current_touch_ids_.size() == 3) {
403 state_ = PASSTHROUGH; 464 state_ = PASSTHROUGH;
404 scoped_ptr<ui::TouchEvent> first_finger_press; 465 scoped_ptr<ui::TouchEvent> first_finger_press;
405 first_finger_press.reset( 466 first_finger_press.reset(
406 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 467 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
407 last_unused_finger_event_->location(), 468 last_unused_finger_event_->location(),
408 last_unused_finger_event_->touch_id(), 469 last_unused_finger_event_->touch_id(),
409 event.time_stamp())); 470 event.time_stamp()));
410 DispatchEvent(first_finger_press.get()); 471 DispatchEvent(first_finger_press.get());
411 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 472 rewritten_event->reset(new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
412 event.location(), 473 event.location(),
(...skipping 18 matching lines...) Expand all
431 event.touch_id(), 492 event.touch_id(),
432 event.time_stamp())); 493 event.time_stamp()));
433 (*rewritten_event)->set_flags(event.flags()); 494 (*rewritten_event)->set_flags(event.flags());
434 return ui::EVENT_REWRITE_REWRITTEN; 495 return ui::EVENT_REWRITE_REWRITTEN;
435 } 496 }
436 } 497 }
437 NOTREACHED() << "Unexpected event type received: " << event.name(); 498 NOTREACHED() << "Unexpected event type received: " << event.name();
438 return ui::EVENT_REWRITE_CONTINUE; 499 return ui::EVENT_REWRITE_CONTINUE;
439 } 500 }
440 501
502 ui::EventRewriteStatus TouchExplorationController::InCornerPassthrough(
503 const ui::TouchEvent& event,
504 scoped_ptr<ui::Event>* rewritten_event) {
505 ui::EventType type = event.type();
506
507 // If the first finger has left the corner, then exit passthrough.
508 if (event.touch_id() == initial_press_->touch_id()) {
509 int edges = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
510 bool in_a_bottom_corner = (edges == BOTTOM_LEFT_CORNER) ||
511 (edges == BOTTOM_RIGHT_CORNER);
512 if (type == ui::ET_TOUCH_MOVED && in_a_bottom_corner)
513 return ui::EVENT_REWRITE_DISCARD;
514
515 if (current_touch_ids_.size() == 0) {
516 ResetToNoFingersDown();
517 return ui::EVENT_REWRITE_DISCARD;
518 }
519
520 waiting_for_corner_passthrough_ = false;
521 state_ = WAIT_FOR_RELEASE;
522 VLOG_STATE();
523 return ui::EVENT_REWRITE_DISCARD;
524 }
525
526 rewritten_event->reset(new ui::TouchEvent(
527 type, event.location(), event.touch_id(), event.time_stamp()));
528 (*rewritten_event)->set_flags(event.flags());
529
530 if (current_touch_ids_.size() == 0)
531 ResetToNoFingersDown();
532
533 return ui::EVENT_REWRITE_REWRITTEN;
534 }
535
441 ui::EventRewriteStatus TouchExplorationController::InPassthrough( 536 ui::EventRewriteStatus TouchExplorationController::InPassthrough(
442 const ui::TouchEvent& event, 537 const ui::TouchEvent& event,
443 scoped_ptr<ui::Event>* rewritten_event) { 538 scoped_ptr<ui::Event>* rewritten_event) {
444 ui::EventType type = event.type(); 539 ui::EventType type = event.type();
445 540
446 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED || 541 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED ||
447 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) { 542 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) {
448 NOTREACHED() << "Unexpected event type received: " << event.name(); 543 NOTREACHED() << "Unexpected event type received: " << event.name();
449 return ui::EVENT_REWRITE_CONTINUE; 544 return ui::EVENT_REWRITE_CONTINUE;
450 } 545 }
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
498 VLOG_STATE(); 593 VLOG_STATE();
499 return ui::EVENT_REWRITE_REWRITTEN; 594 return ui::EVENT_REWRITE_REWRITTEN;
500 } 595 }
501 NOTREACHED() << "Unexpected event type received: " << event.name(); 596 NOTREACHED() << "Unexpected event type received: " << event.name();
502 return ui::EVENT_REWRITE_CONTINUE; 597 return ui::EVENT_REWRITE_CONTINUE;
503 } 598 }
504 599
505 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease( 600 ui::EventRewriteStatus TouchExplorationController::InWaitForRelease(
506 const ui::TouchEvent& event, 601 const ui::TouchEvent& event,
507 scoped_ptr<ui::Event>* rewritten_event) { 602 scoped_ptr<ui::Event>* rewritten_event) {
603 waiting_for_corner_passthrough_ = false;
508 ui::EventType type = event.type(); 604 ui::EventType type = event.type();
509 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || 605 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED ||
510 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { 606 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) {
511 NOTREACHED() << "Unexpected event type received: " << event.name(); 607 NOTREACHED() << "Unexpected event type received: " << event.name();
512 return ui::EVENT_REWRITE_CONTINUE; 608 return ui::EVENT_REWRITE_CONTINUE;
513 } 609 }
514 if (current_touch_ids_.size() == 0) { 610 if (current_touch_ids_.size() == 0) {
515 state_ = NO_FINGERS_DOWN; 611 state_ = NO_FINGERS_DOWN;
516 VLOG_STATE(); 612 VLOG_STATE();
517 ResetToNoFingersDown(); 613 ResetToNoFingersDown();
518 } 614 }
519 return EVENT_REWRITE_DISCARD; 615 return EVENT_REWRITE_DISCARD;
520 } 616 }
521 617
522 void TouchExplorationController::PlaySoundForTimer() { 618 void TouchExplorationController::PlaySoundForTimer() {
523 delegate_->PlayVolumeAdjustSound(); 619 delegate_->PlayVolumeAdjustEarcon();
524 } 620 }
525 621
526 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( 622 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
527 const ui::TouchEvent& event, 623 const ui::TouchEvent& event,
528 scoped_ptr<ui::Event>* rewritten_event) { 624 scoped_ptr<ui::Event>* rewritten_event) {
529 // The timer should not fire when sliding. 625 // The timer should not fire when sliding.
530 if (tap_timer_.IsRunning()) 626 if (tap_timer_.IsRunning())
531 tap_timer_.Stop(); 627 tap_timer_.Stop();
532 628
533 ui::EventType type = event.type(); 629 ui::EventType type = event.type();
(...skipping 19 matching lines...) Expand all
553 return EVENT_REWRITE_DISCARD; 649 return EVENT_REWRITE_DISCARD;
554 } 650 }
555 651
556 // This can occur if the user leaves the screen edge and then returns to it to 652 // This can occur if the user leaves the screen edge and then returns to it to
557 // continue adjusting the sound. 653 // continue adjusting the sound.
558 if (!sound_timer_.IsRunning()) { 654 if (!sound_timer_.IsRunning()) {
559 sound_timer_.Start(FROM_HERE, 655 sound_timer_.Start(FROM_HERE,
560 kSoundDelay, 656 kSoundDelay,
561 this, 657 this,
562 &ui::TouchExplorationController::PlaySoundForTimer); 658 &ui::TouchExplorationController::PlaySoundForTimer);
563 delegate_->PlayVolumeAdjustSound(); 659 delegate_->PlayVolumeAdjustEarcon();
564 } 660 }
565 661
566 // There should not be more than one finger down. 662 // There should not be more than one finger down.
567 DCHECK(current_touch_ids_.size() <= 1); 663 DCHECK(current_touch_ids_.size() <= 1);
568 if (type == ui::ET_TOUCH_MOVED) { 664 if (type == ui::ET_TOUCH_MOVED) {
569 gesture_provider_.OnTouchEvent(event); 665 gesture_provider_.OnTouchEvent(event);
570 gesture_provider_.OnTouchEventAck(false); 666 gesture_provider_.OnTouchEventAck(false);
571 } 667 }
572 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 668 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
573 gesture_provider_.OnTouchEvent(event); 669 gesture_provider_.OnTouchEvent(event);
(...skipping 11 matching lines...) Expand all
585 void TouchExplorationController::OnTapTimerFired() { 681 void TouchExplorationController::OnTapTimerFired() {
586 switch (state_) { 682 switch (state_) {
587 case SINGLE_TAP_RELEASED: 683 case SINGLE_TAP_RELEASED:
588 ResetToNoFingersDown(); 684 ResetToNoFingersDown();
589 break; 685 break;
590 case TOUCH_EXPLORE_RELEASED: 686 case TOUCH_EXPLORE_RELEASED:
591 ResetToNoFingersDown(); 687 ResetToNoFingersDown();
592 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 688 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
593 return; 689 return;
594 case SINGLE_TAP_PRESSED: 690 case SINGLE_TAP_PRESSED:
691 if (waiting_for_corner_passthrough_)
692 return;
595 case GESTURE_IN_PROGRESS: 693 case GESTURE_IN_PROGRESS:
596 // Discard any pending gestures. 694 // Discard any pending gestures.
597 delete gesture_provider_.GetAndResetPendingGestures(); 695 delete gesture_provider_.GetAndResetPendingGestures();
598 EnterTouchToMouseMode(); 696 EnterTouchToMouseMode();
599 state_ = TOUCH_EXPLORATION; 697 state_ = TOUCH_EXPLORATION;
600 VLOG_STATE(); 698 VLOG_STATE();
601 break; 699 break;
602 default: 700 default:
603 return; 701 return;
604 } 702 }
605 scoped_ptr<ui::Event> mouse_move = 703 scoped_ptr<ui::Event> mouse_move =
606 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 704 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
607 DispatchEvent(mouse_move.get()); 705 DispatchEvent(mouse_move.get());
608 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 706 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
609 } 707 }
610 708
709 void TouchExplorationController::OnLongPressTimerFired() {
710 if (waiting_for_corner_passthrough_) {
711 if (sound_timer_.IsRunning())
712 sound_timer_.Stop();
713 delegate_->PlayPassthroughEarcon();
714 delete gesture_provider_.GetAndResetPendingGestures();
715 state_ = CORNER_PASSTHROUGH;
716 VLOG_STATE();
717 return;
718 }
719 }
720
611 void TouchExplorationController::DispatchEvent(ui::Event* event) { 721 void TouchExplorationController::DispatchEvent(ui::Event* event) {
612 if (event_handler_for_testing_) { 722 if (event_handler_for_testing_) {
613 event_handler_for_testing_->OnEvent(event); 723 event_handler_for_testing_->OnEvent(event);
614 return; 724 return;
615 } 725 }
616 ui::EventDispatchDetails result ALLOW_UNUSED = 726 ui::EventDispatchDetails result ALLOW_UNUSED =
617 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 727 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
618 } 728 }
619 729
620 void TouchExplorationController::OnGestureEvent( 730 void TouchExplorationController::OnGestureEvent(
(...skipping 23 matching lines...) Expand all
644 } 754 }
645 } 755 }
646 } 756 }
647 757
648 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { 758 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) {
649 ui::EventType type = gesture->type(); 759 ui::EventType type = gesture->type();
650 if (!gesture->IsScrollGestureEvent()) 760 if (!gesture->IsScrollGestureEvent())
651 return; 761 return;
652 762
653 if (type == ET_GESTURE_SCROLL_BEGIN) { 763 if (type == ET_GESTURE_SCROLL_BEGIN) {
654 delegate_->PlayVolumeAdjustSound(); 764 delegate_->PlayVolumeAdjustEarcon();
655 } 765 }
656 766
657 if (type == ET_GESTURE_SCROLL_END) { 767 if (type == ET_GESTURE_SCROLL_END) {
658 if (sound_timer_.IsRunning()) 768 if (sound_timer_.IsRunning())
659 sound_timer_.Stop(); 769 sound_timer_.Stop();
660 delegate_->PlayVolumeAdjustSound(); 770 delegate_->PlayVolumeAdjustEarcon();
661 } 771 }
662 772
663 // If the user is in the corner of the right side of the screen, the volume 773 // 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 774 // 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 775 // 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 776 // their finger along the right side of the screen. Volume is relative to
667 // where they are on the right side of the screen. 777 // where they are on the right side of the screen.
668 gfx::Point location = gesture->location(); 778 gfx::Point location = gesture->location();
669 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); 779 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge);
670 if (!(edge & RIGHT_EDGE)) 780 if (!(edge & RIGHT_EDGE))
671 return; 781 return;
672 782
673 if (edge & TOP_EDGE) { 783 if (edge & TOP_EDGE) {
674 delegate_->SetOutputLevel(100); 784 delegate_->SetOutputLevel(100);
675 return; 785 return;
676 } 786 }
677 if (edge & BOTTOM_EDGE) { 787 if (edge & BOTTOM_EDGE) {
678 delegate_->SetOutputLevel(0); 788 delegate_->SetOutputLevel(0);
679 return; 789 return;
680 } 790 }
681 791
682 location = gesture->location(); 792 location = gesture->location();
683 root_window_->GetHost()->ConvertPointFromNativeScreen(&location); 793 root_window_->GetHost()->ConvertPointFromNativeScreen(&location);
684 float volume_adjust_height = 794 float volume_adjust_height =
685 root_window_->bounds().height() - 2 * kMaxDistanceFromEdge; 795 root_window_->bounds().height() - 2 * kMaxDistanceFromEdge;
686 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height; 796 float ratio = (location.y() - kMaxDistanceFromEdge) / volume_adjust_height;
687 float volume = 100 - 100 * ratio; 797 float volume = 100 - 100 * ratio;
688 VLOG(0) << "\n Volume = " << volume << "\n Location = " << location.ToString() 798 if (VLOG_on_) {
689 << "\n Bounds = " << root_window_->bounds().right(); 799 VLOG(0) << "\n Volume = " << volume
690 800 << "\n Location = " << location.ToString()
801 << "\n Bounds = " << root_window_->bounds().right();
802 }
691 delegate_->SetOutputLevel(int(volume)); 803 delegate_->SetOutputLevel(int(volume));
692 } 804 }
693 805
694 806
695 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) { 807 void TouchExplorationController::OnSwipeEvent(ui::GestureEvent* swipe_gesture) {
696 // A swipe gesture contains details for the direction in which the swipe 808 // A swipe gesture contains details for the direction in which the swipe
697 // occurred. 809 // occurred.
698 GestureEventDetails event_details = swipe_gesture->details(); 810 GestureEventDetails event_details = swipe_gesture->details();
699 if (event_details.swipe_left()) { 811 if (event_details.swipe_left()) {
700 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT); 812 DispatchShiftSearchKeyEvent(ui::VKEY_LEFT);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
795 void TouchExplorationController::EnterTouchToMouseMode() { 907 void TouchExplorationController::EnterTouchToMouseMode() {
796 aura::client::CursorClient* cursor_client = 908 aura::client::CursorClient* cursor_client =
797 aura::client::GetCursorClient(root_window_); 909 aura::client::GetCursorClient(root_window_);
798 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) 910 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
799 cursor_client->EnableMouseEvents(); 911 cursor_client->EnableMouseEvents();
800 if (cursor_client && cursor_client->IsCursorVisible()) 912 if (cursor_client && cursor_client->IsCursorVisible())
801 cursor_client->HideCursor(); 913 cursor_client->HideCursor();
802 } 914 }
803 915
804 void TouchExplorationController::ResetToNoFingersDown() { 916 void TouchExplorationController::ResetToNoFingersDown() {
917 waiting_for_corner_passthrough_ = false;
805 ProcessGestureEvents(); 918 ProcessGestureEvents();
806 if (sound_timer_.IsRunning()) 919 if (sound_timer_.IsRunning())
807 sound_timer_.Stop(); 920 sound_timer_.Stop();
808 state_ = NO_FINGERS_DOWN; 921 state_ = NO_FINGERS_DOWN;
809 VLOG_STATE(); 922 VLOG_STATE();
810 if (tap_timer_.IsRunning()) 923 if (tap_timer_.IsRunning())
811 tap_timer_.Stop(); 924 tap_timer_.Stop();
812 } 925 }
813 926
814 void TouchExplorationController::VlogState(const char* function_name) { 927 void TouchExplorationController::VlogState(const char* function_name) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
865 case DOUBLE_TAP_PRESSED: 978 case DOUBLE_TAP_PRESSED:
866 return "DOUBLE_TAP_PRESSED"; 979 return "DOUBLE_TAP_PRESSED";
867 case TOUCH_EXPLORATION: 980 case TOUCH_EXPLORATION:
868 return "TOUCH_EXPLORATION"; 981 return "TOUCH_EXPLORATION";
869 case GESTURE_IN_PROGRESS: 982 case GESTURE_IN_PROGRESS:
870 return "GESTURE_IN_PROGRESS"; 983 return "GESTURE_IN_PROGRESS";
871 case TOUCH_EXPLORE_SECOND_PRESS: 984 case TOUCH_EXPLORE_SECOND_PRESS:
872 return "TOUCH_EXPLORE_SECOND_PRESS"; 985 return "TOUCH_EXPLORE_SECOND_PRESS";
873 case TWO_TO_ONE_FINGER: 986 case TWO_TO_ONE_FINGER:
874 return "TWO_TO_ONE_FINGER"; 987 return "TWO_TO_ONE_FINGER";
988 case CORNER_PASSTHROUGH:
989 return "CORNER_PASSTHROUGH";
875 case PASSTHROUGH: 990 case PASSTHROUGH:
876 return "PASSTHROUGH"; 991 return "PASSTHROUGH";
877 case WAIT_FOR_RELEASE: 992 case WAIT_FOR_RELEASE:
878 return "WAIT_FOR_RELEASE"; 993 return "WAIT_FOR_RELEASE";
879 case SLIDE_GESTURE: 994 case SLIDE_GESTURE:
880 return "SLIDE_GESTURE"; 995 return "SLIDE_GESTURE";
881 } 996 }
882 return "Not a state"; 997 return "Not a state";
883 } 998 }
884 999
885 } // namespace ui 1000 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698