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

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: Removed extra comment 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/logging.h" 7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h" 8 #include "base/strings/string_number_conversions.h"
9 #include "base/time/default_tick_clock.h" 9 #include "base/time/default_tick_clock.h"
10 #include "ui/aura/client/cursor_client.h" 10 #include "ui/aura/client/cursor_client.h"
11 #include "ui/aura/window.h" 11 #include "ui/aura/window.h"
12 #include "ui/aura/window_event_dispatcher.h" 12 #include "ui/aura/window_event_dispatcher.h"
13 #include "ui/aura/window_tree_host.h" 13 #include "ui/aura/window_tree_host.h"
14 #include "ui/events/event.h" 14 #include "ui/events/event.h"
15 #include "ui/events/event_processor.h" 15 #include "ui/events/event_processor.h"
16 #include "ui/events/event_utils.h" 16 #include "ui/events/event_utils.h"
17 #include "ui/gfx/geometry/rect.h" 17 #include "ui/gfx/geometry/rect.h"
18 18
19 #define SET_STATE(state) SetState(state, __func__) 19 #define SET_STATE(state) SetState(state, __func__)
20 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) 20 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__)
21 21
22 namespace ui { 22 namespace ui {
23 23
24 namespace { 24 namespace {
25 25
26 // Delay between adjustment sounds. 26 // Delay between adjustment sounds.
27 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150); 27 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150);
28 28
29 // Delay before corner passthrough activates.
30 const base::TimeDelta kCornerPassthroughDelay =
31 base::TimeDelta::FromMilliseconds(700);
32
29 // In ChromeOS, VKEY_LWIN is synonymous for the search key. 33 // In ChromeOS, VKEY_LWIN is synonymous for the search key.
30 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; 34 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
31 } // namespace 35 } // namespace
32 36
33 TouchExplorationController::TouchExplorationController( 37 TouchExplorationController::TouchExplorationController(
34 aura::Window* root_window, 38 aura::Window* root_window,
35 TouchExplorationControllerDelegate* delegate) 39 TouchExplorationControllerDelegate* delegate)
36 : root_window_(root_window), 40 : root_window_(root_window),
37 delegate_(delegate), 41 delegate_(delegate),
38 state_(NO_FINGERS_DOWN), 42 state_(NO_FINGERS_DOWN),
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 // the timer. 74 // the timer.
71 if (tap_timer_.IsRunning() && 75 if (tap_timer_.IsRunning() &&
72 touch_event.time_stamp() - initial_press_->time_stamp() > 76 touch_event.time_stamp() - initial_press_->time_stamp() >
73 gesture_detector_config_.double_tap_timeout) { 77 gesture_detector_config_.double_tap_timeout) {
74 tap_timer_.Stop(); 78 tap_timer_.Stop();
75 OnTapTimerFired(); 79 OnTapTimerFired();
76 // Note: this may change the state. We should now continue and process 80 // Note: this may change the state. We should now continue and process
77 // this event under this new state. 81 // this event under this new state.
78 } 82 }
79 83
84 if (passthrough_timer_.IsRunning() &&
85 event.time_stamp() - initial_press_->time_stamp() >
86 gesture_detector_config_.longpress_timeout) {
87 passthrough_timer_.Stop();
88 OnPassthroughTimerFired();
89 }
90
80 const ui::EventType type = touch_event.type(); 91 const ui::EventType type = touch_event.type();
81 const gfx::PointF& location = touch_event.location_f(); 92 const gfx::PointF& location = touch_event.location_f();
82 const int touch_id = touch_event.touch_id(); 93 const int touch_id = touch_event.touch_id();
83 94
84 // Always update touch ids and touch locations, so we can use those 95 // Always update touch ids and touch locations, so we can use those
85 // no matter what state we're in. 96 // no matter what state we're in.
86 if (type == ui::ET_TOUCH_PRESSED) { 97 if (type == ui::ET_TOUCH_PRESSED) {
87 current_touch_ids_.push_back(touch_id); 98 current_touch_ids_.push_back(touch_id);
88 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); 99 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
89 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 100 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
(...skipping 19 matching lines...) Expand all
109 NOTREACHED() << "Unexpected event type received: " << event.name(); 120 NOTREACHED() << "Unexpected event type received: " << event.name();
110 return ui::EVENT_REWRITE_CONTINUE; 121 return ui::EVENT_REWRITE_CONTINUE;
111 } 122 }
112 VLOG_EVENT(touch_event); 123 VLOG_EVENT(touch_event);
113 124
114 // In order to avoid accidentally double tapping when moving off the edge 125 // In order to avoid accidentally double tapping when moving off the edge
115 // of the screen, the state will be rewritten to NoFingersDown. 126 // of the screen, the state will be rewritten to NoFingersDown.
116 if ((type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) && 127 if ((type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) &&
117 FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != 128 FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) !=
118 NO_EDGE) { 129 NO_EDGE) {
130 if (VLOG_on_)
131 VLOG(0) << "Leaving screen";
132
133 // Indicates to the user that they are leaving the screen.
134 delegate_->PlayExitScreenEarcon();
135
119 if (current_touch_ids_.size() == 0) { 136 if (current_touch_ids_.size() == 0) {
120 SET_STATE(NO_FINGERS_DOWN); 137 SET_STATE(NO_FINGERS_DOWN);
121 if (VLOG_on_) { 138 if (VLOG_on_) {
122 VLOG(0) << "Reset to no fingers in Rewrite event because the touch " 139 VLOG(0) << "Reset to no fingers in Rewrite event because the touch "
123 "release or cancel was on the edge of the screen."; 140 "release or cancel was on the edge of the screen.";
124 } 141 }
125 return ui::EVENT_REWRITE_DISCARD; 142 return ui::EVENT_REWRITE_DISCARD;
126 } 143 }
127 } 144 }
128 145
(...skipping 20 matching lines...) Expand all
149 case DOUBLE_TAP_PENDING: 166 case DOUBLE_TAP_PENDING:
150 return InDoubleTapPending(touch_event, rewritten_event); 167 return InDoubleTapPending(touch_event, rewritten_event);
151 case TOUCH_RELEASE_PENDING: 168 case TOUCH_RELEASE_PENDING:
152 return InTouchReleasePending(touch_event, rewritten_event); 169 return InTouchReleasePending(touch_event, rewritten_event);
153 case TOUCH_EXPLORATION: 170 case TOUCH_EXPLORATION:
154 return InTouchExploration(touch_event, rewritten_event); 171 return InTouchExploration(touch_event, rewritten_event);
155 case GESTURE_IN_PROGRESS: 172 case GESTURE_IN_PROGRESS:
156 return InGestureInProgress(touch_event, rewritten_event); 173 return InGestureInProgress(touch_event, rewritten_event);
157 case TOUCH_EXPLORE_SECOND_PRESS: 174 case TOUCH_EXPLORE_SECOND_PRESS:
158 return InTouchExploreSecondPress(touch_event, rewritten_event); 175 return InTouchExploreSecondPress(touch_event, rewritten_event);
176 case CORNER_PASSTHROUGH:
177 return InCornerPassthrough(touch_event, rewritten_event);
159 case SLIDE_GESTURE: 178 case SLIDE_GESTURE:
160 return InSlideGesture(touch_event, rewritten_event); 179 return InSlideGesture(touch_event, rewritten_event);
161 case ONE_FINGER_PASSTHROUGH: 180 case ONE_FINGER_PASSTHROUGH:
162 return InOneFingerPassthrough(touch_event, rewritten_event); 181 return InOneFingerPassthrough(touch_event, rewritten_event);
163 case WAIT_FOR_NO_FINGERS: 182 case WAIT_FOR_NO_FINGERS:
164 return InWaitForNoFingers(touch_event, rewritten_event); 183 return InWaitForNoFingers(touch_event, rewritten_event);
165 case TWO_FINGER_TAP: 184 case TWO_FINGER_TAP:
166 return InTwoFingerTap(touch_event, rewritten_event); 185 return InTwoFingerTap(touch_event, rewritten_event);
167 } 186 }
168 NOTREACHED(); 187 NOTREACHED();
169 return ui::EVENT_REWRITE_CONTINUE; 188 return ui::EVENT_REWRITE_CONTINUE;
170 } 189 }
171 190
172 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 191 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
173 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 192 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
174 NOTREACHED(); 193 NOTREACHED();
175 return ui::EVENT_REWRITE_CONTINUE; 194 return ui::EVENT_REWRITE_CONTINUE;
176 } 195 }
177 196
178 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 197 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
179 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 198 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
180 ui::EventType type = event.type(); 199 const ui::EventType type = event.type();
181 if (type == ui::ET_TOUCH_PRESSED) { 200 if (type != ui::ET_TOUCH_PRESSED) {
182 initial_press_.reset(new TouchEvent(event)); 201 NOTREACHED() << "Unexpected event type received: " << event.name();
183 initial_presses_[event.touch_id()] = event.location(); 202 return ui::EVENT_REWRITE_CONTINUE;
184 last_unused_finger_event_.reset(new TouchEvent(event));
185 StartTapTimer();
186 SET_STATE(SINGLE_TAP_PRESSED);
187 return ui::EVENT_REWRITE_DISCARD;
188 } 203 }
189 NOTREACHED() << "Unexpected event type received: " << event.name(); 204
190 return ui::EVENT_REWRITE_CONTINUE; 205 // If the user enters the screen from the edge then send an earcon.
206 int edge = FindEdgesWithinBounds(event.location(), kLeavingScreenEdge);
207 if (edge != NO_EDGE)
208 delegate_->PlayEnterScreenEarcon();
209
210 int location = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
211 // If the press was at a corner, the user might go into corner passthrough
212 // instead.
213 bool in_a_bottom_corner =
214 (BOTTOM_LEFT_CORNER == location) || (BOTTOM_RIGHT_CORNER == location);
215 if (in_a_bottom_corner) {
216 passthrough_timer_.Start(
217 FROM_HERE,
218 gesture_detector_config_.longpress_timeout,
219 this,
220 &TouchExplorationController::OnPassthroughTimerFired);
221 }
222 initial_press_.reset(new TouchEvent(event));
223 initial_presses_[event.touch_id()] = event.location();
224 last_unused_finger_event_.reset(new TouchEvent(event));
225 StartTapTimer();
226 SET_STATE(SINGLE_TAP_PRESSED);
227 return ui::EVENT_REWRITE_DISCARD;
191 } 228 }
192 229
193 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 230 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
194 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 231 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
195 const ui::EventType type = event.type(); 232 const ui::EventType type = event.type();
196 233
234 int location = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
235 bool in_a_bottom_corner =
236 (location == BOTTOM_LEFT_CORNER) || (location == BOTTOM_RIGHT_CORNER);
237 // If the event is from the initial press and the location is no longer in the
238 // corner, then we are not waiting for a corner passthrough anymore.
239 if (event.touch_id() == initial_press_->touch_id() && !in_a_bottom_corner) {
240 if (passthrough_timer_.IsRunning()) {
241 passthrough_timer_.Stop();
242 // Since the long press timer has been running, it is possible that the
243 // tap timer has timed out before the long press timer has. If the tap
244 // timer timeout has elapsed, then fire the tap timer.
245 if (event.time_stamp() - initial_press_->time_stamp() >
246 gesture_detector_config_.double_tap_timeout) {
247 OnTapTimerFired();
248 }
249 }
250 }
251
197 if (type == ui::ET_TOUCH_PRESSED) { 252 if (type == ui::ET_TOUCH_PRESSED) {
198 initial_presses_[event.touch_id()] = event.location(); 253 initial_presses_[event.touch_id()] = event.location();
199 SET_STATE(TWO_FINGER_TAP); 254 SET_STATE(TWO_FINGER_TAP);
200 return EVENT_REWRITE_DISCARD; 255 return EVENT_REWRITE_DISCARD;
201 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 256 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
257 if (passthrough_timer_.IsRunning())
258 passthrough_timer_.Stop();
202 if (current_touch_ids_.size() == 0 && 259 if (current_touch_ids_.size() == 0 &&
203 event.touch_id() == initial_press_->touch_id()) { 260 event.touch_id() == initial_press_->touch_id()) {
204 SET_STATE(SINGLE_TAP_RELEASED); 261 SET_STATE(SINGLE_TAP_RELEASED);
205 } else if (current_touch_ids_.size() == 0) { 262 } else if (current_touch_ids_.size() == 0) {
206 SET_STATE(NO_FINGERS_DOWN); 263 SET_STATE(NO_FINGERS_DOWN);
207 } 264 }
208 return EVENT_REWRITE_DISCARD; 265 return EVENT_REWRITE_DISCARD;
209 } else if (type == ui::ET_TOUCH_MOVED) { 266 } else if (type == ui::ET_TOUCH_MOVED) {
210 float distance = (event.location() - initial_press_->location()).Length(); 267 float distance = (event.location() - initial_press_->location()).Length();
211 // If the user does not move far enough from the original position, then the 268 // If the user does not move far enough from the original position, then the
212 // resulting movement should not be considered to be a deliberate gesture or 269 // resulting movement should not be considered to be a deliberate gesture or
213 // touch exploration. 270 // touch exploration.
214 if (distance <= gesture_detector_config_.touch_slop) 271 if (distance <= gesture_detector_config_.touch_slop)
215 return EVENT_REWRITE_DISCARD; 272 return EVENT_REWRITE_DISCARD;
216 273
217 float delta_time = 274 float delta_time =
218 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); 275 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF();
219 float velocity = distance / delta_time; 276 float velocity = distance / delta_time;
220 if (VLOG_on_) { 277 if (VLOG_on_) {
221 VLOG(0) << "\n Delta time: " << delta_time << "\n Distance: " << distance 278 VLOG(0) << "\n Delta time: " << delta_time << "\n Distance: " << distance
222 << "\n Velocity of click: " << velocity 279 << "\n Velocity of click: " << velocity
223 << "\n Minimum swipe velocity: " 280 << "\n Minimum swipe velocity: "
224 << gesture_detector_config_.minimum_swipe_velocity; 281 << gesture_detector_config_.minimum_swipe_velocity;
225 } 282 }
226 // Change to slide gesture if the slide occurred at the right edge. 283 // Change to slide gesture if the slide occurred at the right edge.
227 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); 284 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
228 if (edge & RIGHT_EDGE) { 285 if (edge & RIGHT_EDGE && edge != BOTTOM_RIGHT_CORNER) {
229 SET_STATE(SLIDE_GESTURE); 286 SET_STATE(SLIDE_GESTURE);
230 return InSlideGesture(event, rewritten_event); 287 return InSlideGesture(event, rewritten_event);
231 } 288 }
232 289
233 // If the user moves fast enough from the initial touch location, start 290 // If the user moves fast enough from the initial touch location, start
234 // gesture detection. Otherwise, jump to the touch exploration mode early. 291 // gesture detection. Otherwise, jump to the touch exploration mode early.
235 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 292 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
236 SET_STATE(GESTURE_IN_PROGRESS); 293 SET_STATE(GESTURE_IN_PROGRESS);
237 return InGestureInProgress(event, rewritten_event); 294 return InGestureInProgress(event, rewritten_event);
238 } 295 }
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 // The events were sent to the gesture provider in RewriteEvent already. 444 // The events were sent to the gesture provider in RewriteEvent already.
388 // If no gesture is registered before the tap timer times out, the state 445 // If no gesture is registered before the tap timer times out, the state
389 // will change to "wait for no fingers down" or "touch exploration" depending 446 // will change to "wait for no fingers down" or "touch exploration" depending
390 // on the number of fingers down, and this function will stop being called. 447 // on the number of fingers down, and this function will stop being called.
391 if (current_touch_ids_.size() == 0) { 448 if (current_touch_ids_.size() == 0) {
392 SET_STATE(NO_FINGERS_DOWN); 449 SET_STATE(NO_FINGERS_DOWN);
393 } 450 }
394 return ui::EVENT_REWRITE_DISCARD; 451 return ui::EVENT_REWRITE_DISCARD;
395 } 452 }
396 453
454 ui::EventRewriteStatus TouchExplorationController::InCornerPassthrough(
455 const ui::TouchEvent& event,
456 scoped_ptr<ui::Event>* rewritten_event) {
457 ui::EventType type = event.type();
458
459 // If the first finger has left the corner, then exit passthrough.
460 if (event.touch_id() == initial_press_->touch_id()) {
461 int edges = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
462 bool in_a_bottom_corner = (edges == BOTTOM_LEFT_CORNER) ||
463 (edges == BOTTOM_RIGHT_CORNER);
464 if (type == ui::ET_TOUCH_MOVED && in_a_bottom_corner)
465 return ui::EVENT_REWRITE_DISCARD;
466
467 if (current_touch_ids_.size() == 0) {
468 SET_STATE(NO_FINGERS_DOWN);
469 return ui::EVENT_REWRITE_DISCARD;
470 }
471 SET_STATE(WAIT_FOR_NO_FINGERS);
472 return ui::EVENT_REWRITE_DISCARD;
473 }
474
475 rewritten_event->reset(new ui::TouchEvent(
476 type, event.location(), event.touch_id(), event.time_stamp()));
477 (*rewritten_event)->set_flags(event.flags());
478
479 if (current_touch_ids_.size() == 0)
480 SET_STATE(NO_FINGERS_DOWN);
481
482 return ui::EVENT_REWRITE_REWRITTEN;
483 }
484
397 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( 485 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough(
398 const ui::TouchEvent& event, 486 const ui::TouchEvent& event,
399 scoped_ptr<ui::Event>* rewritten_event) { 487 scoped_ptr<ui::Event>* rewritten_event) {
400 if (event.touch_id() != initial_press_->touch_id()) { 488 if (event.touch_id() != initial_press_->touch_id()) {
401 if (current_touch_ids_.size() == 0) { 489 if (current_touch_ids_.size() == 0) {
402 SET_STATE(NO_FINGERS_DOWN); 490 SET_STATE(NO_FINGERS_DOWN);
403 } 491 }
404 return ui::EVENT_REWRITE_DISCARD; 492 return ui::EVENT_REWRITE_DISCARD;
405 } 493 }
406 rewritten_event->reset( 494 rewritten_event->reset(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 546
459 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers( 547 ui::EventRewriteStatus TouchExplorationController::InWaitForNoFingers(
460 const ui::TouchEvent& event, 548 const ui::TouchEvent& event,
461 scoped_ptr<ui::Event>* rewritten_event) { 549 scoped_ptr<ui::Event>* rewritten_event) {
462 if (current_touch_ids_.size() == 0) 550 if (current_touch_ids_.size() == 0)
463 SET_STATE(NO_FINGERS_DOWN); 551 SET_STATE(NO_FINGERS_DOWN);
464 return EVENT_REWRITE_DISCARD; 552 return EVENT_REWRITE_DISCARD;
465 } 553 }
466 554
467 void TouchExplorationController::PlaySoundForTimer() { 555 void TouchExplorationController::PlaySoundForTimer() {
468 delegate_->PlayVolumeAdjustSound(); 556 delegate_->PlayVolumeAdjustEarcon();
469 } 557 }
470 558
471 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( 559 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
472 const ui::TouchEvent& event, 560 const ui::TouchEvent& event,
473 scoped_ptr<ui::Event>* rewritten_event) { 561 scoped_ptr<ui::Event>* rewritten_event) {
474 // The timer should not fire when sliding. 562 // The timer should not fire when sliding.
475 tap_timer_.Stop(); 563 tap_timer_.Stop();
476 564
477 ui::EventType type = event.type(); 565 ui::EventType type = event.type();
478 // If additional fingers are added before a swipe gesture has been registered, 566 // If additional fingers are added before a swipe gesture has been registered,
(...skipping 19 matching lines...) Expand all
498 return EVENT_REWRITE_DISCARD; 586 return EVENT_REWRITE_DISCARD;
499 } 587 }
500 588
501 // This can occur if the user leaves the screen edge and then returns to it to 589 // This can occur if the user leaves the screen edge and then returns to it to
502 // continue adjusting the sound. 590 // continue adjusting the sound.
503 if (!sound_timer_.IsRunning()) { 591 if (!sound_timer_.IsRunning()) {
504 sound_timer_.Start(FROM_HERE, 592 sound_timer_.Start(FROM_HERE,
505 kSoundDelay, 593 kSoundDelay,
506 this, 594 this,
507 &ui::TouchExplorationController::PlaySoundForTimer); 595 &ui::TouchExplorationController::PlaySoundForTimer);
508 delegate_->PlayVolumeAdjustSound(); 596 delegate_->PlayVolumeAdjustEarcon();
509 } 597 }
510 598
511 if (current_touch_ids_.size() == 0) { 599 if (current_touch_ids_.size() == 0) {
512 SET_STATE(NO_FINGERS_DOWN); 600 SET_STATE(NO_FINGERS_DOWN);
513 } 601 }
514 return ui::EVENT_REWRITE_DISCARD; 602 return ui::EVENT_REWRITE_DISCARD;
515 } 603 }
516 604
517 ui::EventRewriteStatus TouchExplorationController::InTwoFingerTap( 605 ui::EventRewriteStatus TouchExplorationController::InTwoFingerTap(
518 const ui::TouchEvent& event, 606 const ui::TouchEvent& event,
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 last_touch_exploration_->location(); 673 last_touch_exploration_->location();
586 scoped_ptr<ui::TouchEvent> passthrough_press( 674 scoped_ptr<ui::TouchEvent> passthrough_press(
587 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 675 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
588 last_touch_exploration_->location(), 676 last_touch_exploration_->location(),
589 last_unused_finger_event_->touch_id(), 677 last_unused_finger_event_->touch_id(),
590 Now())); 678 Now()));
591 DispatchEvent(passthrough_press.get()); 679 DispatchEvent(passthrough_press.get());
592 return; 680 return;
593 } 681 }
594 case SINGLE_TAP_PRESSED: 682 case SINGLE_TAP_PRESSED:
595 EnterTouchToMouseMode(); 683 if (passthrough_timer_.IsRunning())
596 SET_STATE(TOUCH_EXPLORATION); 684 return;
597 break;
598 case GESTURE_IN_PROGRESS: 685 case GESTURE_IN_PROGRESS:
599 // If only one finger is down, go into touch exploration. 686 // If only one finger is down, go into touch exploration.
600 if (current_touch_ids_.size() == 1) { 687 if (current_touch_ids_.size() == 1) {
601 EnterTouchToMouseMode();
602 SET_STATE(TOUCH_EXPLORATION); 688 SET_STATE(TOUCH_EXPLORATION);
603 break; 689 break;
604 } 690 }
605 // Otherwise wait for all fingers to be lifted. 691 // Otherwise wait for all fingers to be lifted.
606 SET_STATE(WAIT_FOR_NO_FINGERS); 692 SET_STATE(WAIT_FOR_NO_FINGERS);
607 return; 693 return;
608 case TWO_FINGER_TAP: 694 case TWO_FINGER_TAP:
609 SET_STATE(WAIT_FOR_NO_FINGERS); 695 SET_STATE(WAIT_FOR_NO_FINGERS);
610 break; 696 break;
611 default: 697 default:
612 return; 698 return;
613 } 699 }
614 EnterTouchToMouseMode(); 700 EnterTouchToMouseMode();
615 scoped_ptr<ui::Event> mouse_move = 701 scoped_ptr<ui::Event> mouse_move =
616 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 702 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
617 DispatchEvent(mouse_move.get()); 703 DispatchEvent(mouse_move.get());
618 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 704 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
619 } 705 }
620 706
707 void TouchExplorationController::OnPassthroughTimerFired() {
708 // The passthrough timer will only fire if if the user has held a finger in
709 // one of the passthrough corners for the duration of the passthrough timeout.
710
711 // Check that initial press isn't null. Also a check that if the initial
712 // corner press was released, then it should not be in corner passthrough.
713 if (!initial_press_ ||
714 touch_locations_.find(initial_press_->touch_id()) !=
715 touch_locations_.end()) {
716 LOG(ERROR) << "No initial press or the initial press has been released.";
717 }
718
719 gfx::Point location =
720 ToRoundedPoint(touch_locations_[initial_press_->touch_id()]);
721 int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge);
722 if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER)
723 return;
724
725 if (sound_timer_.IsRunning())
726 sound_timer_.Stop();
727 delegate_->PlayPassthroughEarcon();
728 SET_STATE(CORNER_PASSTHROUGH);
729 return;
730 }
731
621 void TouchExplorationController::DispatchEvent(ui::Event* event) { 732 void TouchExplorationController::DispatchEvent(ui::Event* event) {
622 ui::EventDispatchDetails result ALLOW_UNUSED = 733 ui::EventDispatchDetails result ALLOW_UNUSED =
623 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 734 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
624 } 735 }
625 736
626 // This is an override for a function that is only called for timer-based events 737 // This is an override for a function that is only called for timer-based events
627 // like long press. Events that are created synchronously as a result of 738 // like long press. Events that are created synchronously as a result of
628 // certain touch events are added to the vector accessible via 739 // certain touch events are added to the vector accessible via
629 // GetAndResetPendingGestures(). We only care about swipes (which are created 740 // GetAndResetPendingGestures(). We only care about swipes (which are created
630 // synchronously), so we ignore this callback. 741 // synchronously), so we ignore this callback.
(...skipping 20 matching lines...) Expand all
651 SideSlideControl(*i); 762 SideSlideControl(*i);
652 } 763 }
653 } 764 }
654 } 765 }
655 } 766 }
656 767
657 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { 768 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) {
658 ui::EventType type = gesture->type(); 769 ui::EventType type = gesture->type();
659 770
660 if (type == ET_GESTURE_SCROLL_BEGIN) { 771 if (type == ET_GESTURE_SCROLL_BEGIN) {
661 delegate_->PlayVolumeAdjustSound(); 772 delegate_->PlayVolumeAdjustEarcon();
662 } 773 }
663 774
664 if (type == ET_GESTURE_SCROLL_END) { 775 if (type == ET_GESTURE_SCROLL_END) {
665 if (sound_timer_.IsRunning()) 776 if (sound_timer_.IsRunning())
666 sound_timer_.Stop(); 777 sound_timer_.Stop();
667 delegate_->PlayVolumeAdjustSound(); 778 delegate_->PlayVolumeAdjustEarcon();
668 } 779 }
669 780
670 // If the user is in the corner of the right side of the screen, the volume 781 // If the user is in the corner of the right side of the screen, the volume
671 // will be automatically set to 100% or muted depending on which corner they 782 // will be automatically set to 100% or muted depending on which corner they
672 // are in. Otherwise, the user will be able to adjust the volume by sliding 783 // are in. Otherwise, the user will be able to adjust the volume by sliding
673 // their finger along the right side of the screen. Volume is relative to 784 // their finger along the right side of the screen. Volume is relative to
674 // where they are on the right side of the screen. 785 // where they are on the right side of the screen.
675 gfx::Point location = gesture->location(); 786 gfx::Point location = gesture->location();
676 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); 787 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge);
677 if (!(edge & RIGHT_EDGE)) 788 if (!(edge & RIGHT_EDGE))
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
856 // gesture provider still exists, it's reset to NULL until the user returns 967 // gesture provider still exists, it's reset to NULL until the user returns
857 // to NO_FINGERS_DOWN. 968 // to NO_FINGERS_DOWN.
858 switch (new_state) { 969 switch (new_state) {
859 case SINGLE_TAP_RELEASED: 970 case SINGLE_TAP_RELEASED:
860 case TOUCH_EXPLORE_RELEASED: 971 case TOUCH_EXPLORE_RELEASED:
861 case DOUBLE_TAP_PENDING: 972 case DOUBLE_TAP_PENDING:
862 case TOUCH_RELEASE_PENDING: 973 case TOUCH_RELEASE_PENDING:
863 case TOUCH_EXPLORATION: 974 case TOUCH_EXPLORATION:
864 case TOUCH_EXPLORE_SECOND_PRESS: 975 case TOUCH_EXPLORE_SECOND_PRESS:
865 case ONE_FINGER_PASSTHROUGH: 976 case ONE_FINGER_PASSTHROUGH:
977 case CORNER_PASSTHROUGH:
866 case WAIT_FOR_NO_FINGERS: 978 case WAIT_FOR_NO_FINGERS:
867 if (gesture_provider_.get()) 979 if (gesture_provider_.get())
868 gesture_provider_.reset(NULL); 980 gesture_provider_.reset(NULL);
869 break; 981 break;
870 case NO_FINGERS_DOWN: 982 case NO_FINGERS_DOWN:
871 gesture_provider_.reset(new GestureProviderAura(this)); 983 gesture_provider_.reset(new GestureProviderAura(this));
872 if (sound_timer_.IsRunning()) 984 if (sound_timer_.IsRunning())
873 sound_timer_.Stop(); 985 sound_timer_.Stop();
874 tap_timer_.Stop(); 986 tap_timer_.Stop();
875 break; 987 break;
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 case DOUBLE_TAP_PENDING: 1047 case DOUBLE_TAP_PENDING:
936 return "DOUBLE_TAP_PENDING"; 1048 return "DOUBLE_TAP_PENDING";
937 case TOUCH_RELEASE_PENDING: 1049 case TOUCH_RELEASE_PENDING:
938 return "TOUCH_RELEASE_PENDING"; 1050 return "TOUCH_RELEASE_PENDING";
939 case TOUCH_EXPLORATION: 1051 case TOUCH_EXPLORATION:
940 return "TOUCH_EXPLORATION"; 1052 return "TOUCH_EXPLORATION";
941 case GESTURE_IN_PROGRESS: 1053 case GESTURE_IN_PROGRESS:
942 return "GESTURE_IN_PROGRESS"; 1054 return "GESTURE_IN_PROGRESS";
943 case TOUCH_EXPLORE_SECOND_PRESS: 1055 case TOUCH_EXPLORE_SECOND_PRESS:
944 return "TOUCH_EXPLORE_SECOND_PRESS"; 1056 return "TOUCH_EXPLORE_SECOND_PRESS";
1057 case CORNER_PASSTHROUGH:
1058 return "CORNER_PASSTHROUGH";
945 case SLIDE_GESTURE: 1059 case SLIDE_GESTURE:
946 return "SLIDE_GESTURE"; 1060 return "SLIDE_GESTURE";
947 case ONE_FINGER_PASSTHROUGH: 1061 case ONE_FINGER_PASSTHROUGH:
948 return "ONE_FINGER_PASSTHROUGH"; 1062 return "ONE_FINGER_PASSTHROUGH";
949 case WAIT_FOR_NO_FINGERS: 1063 case WAIT_FOR_NO_FINGERS:
950 return "WAIT_FOR_NO_FINGERS"; 1064 return "WAIT_FOR_NO_FINGERS";
951 case TWO_FINGER_TAP: 1065 case TWO_FINGER_TAP:
952 return "TWO_FINGER_TAP"; 1066 return "TWO_FINGER_TAP";
953 } 1067 }
954 return "Not a state"; 1068 return "Not a state";
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
991 left_swipe_gestures_[4] = 1105 left_swipe_gestures_[4] =
992 BindKeyEventWithFlags(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE); 1106 BindKeyEventWithFlags(ui::VKEY_BRIGHTNESS_DOWN, ui::EF_NONE);
993 right_swipe_gestures_[4] = 1107 right_swipe_gestures_[4] =
994 BindKeyEventWithFlags(VKEY_BRIGHTNESS_UP, ui::EF_NONE); 1108 BindKeyEventWithFlags(VKEY_BRIGHTNESS_UP, ui::EF_NONE);
995 up_swipe_gestures_[4] = BindKeyEventWithFlags(VKEY_BROWSER_HOME, ui::EF_NONE); 1109 up_swipe_gestures_[4] = BindKeyEventWithFlags(VKEY_BROWSER_HOME, ui::EF_NONE);
996 down_swipe_gestures_[4] = 1110 down_swipe_gestures_[4] =
997 BindKeyEventWithFlags(VKEY_BROWSER_REFRESH, ui::EF_NONE); 1111 BindKeyEventWithFlags(VKEY_BROWSER_REFRESH, ui::EF_NONE);
998 } 1112 }
999 1113
1000 } // namespace ui 1114 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/touch_exploration_controller.h ('k') | ui/chromeos/touch_exploration_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698