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

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

Powered by Google App Engine
This is Rietveld 408576698