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

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/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 "ui/aura/client/cursor_client.h" 9 #include "ui/aura/client/cursor_client.h"
10 #include "ui/aura/window.h" 10 #include "ui/aura/window.h"
11 #include "ui/aura/window_event_dispatcher.h" 11 #include "ui/aura/window_event_dispatcher.h"
12 #include "ui/aura/window_tree_host.h" 12 #include "ui/aura/window_tree_host.h"
13 #include "ui/events/event.h" 13 #include "ui/events/event.h"
14 #include "ui/events/event_processor.h" 14 #include "ui/events/event_processor.h"
15 #include "ui/events/event_utils.h" 15 #include "ui/events/event_utils.h"
16 #include "ui/gfx/geometry/rect.h" 16 #include "ui/gfx/geometry/rect.h"
17 17
18 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__) 18 #define VLOG_STATE() if (VLOG_IS_ON(0)) VlogState(__func__)
19 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__) 19 #define VLOG_EVENT(event) if (VLOG_IS_ON(0)) VlogEvent(event, __func__)
20 20
21 namespace ui { 21 namespace ui {
22 22
23 namespace { 23 namespace {
24 24
25 // Delay between adjustment sounds. 25 // Delay between adjustment sounds.
26 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150); 26 const base::TimeDelta kSoundDelay = base::TimeDelta::FromMilliseconds(150);
27 27
28 // Delay before corner passthrough activates.
29 const base::TimeDelta kCornerPassthroughDelay =
30 base::TimeDelta::FromMilliseconds(700);
31
28 // In ChromeOS, VKEY_LWIN is synonymous for the search key. 32 // In ChromeOS, VKEY_LWIN is synonymous for the search key.
29 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN; 33 const ui::KeyboardCode kChromeOSSearchKey = ui::VKEY_LWIN;
30 } // namespace 34 } // namespace
31 35
32 TouchExplorationController::TouchExplorationController( 36 TouchExplorationController::TouchExplorationController(
33 aura::Window* root_window, 37 aura::Window* root_window,
34 TouchExplorationControllerDelegate* delegate) 38 TouchExplorationControllerDelegate* delegate)
35 : root_window_(root_window), 39 : root_window_(root_window),
36 delegate_(delegate), 40 delegate_(delegate),
37 state_(NO_FINGERS_DOWN), 41 state_(NO_FINGERS_DOWN),
38 gesture_provider_(this), 42 gesture_provider_(this),
39 prev_state_(NO_FINGERS_DOWN), 43 prev_state_(NO_FINGERS_DOWN),
40 VLOG_on_(true), 44 VLOG_on_(true),
41 tick_clock_(NULL) { 45 tick_clock_(NULL),
46 waiting_for_corner_passthrough_(false) {
42 CHECK(root_window); 47 CHECK(root_window);
43 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 48 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
44 } 49 }
45 50
46 TouchExplorationController::~TouchExplorationController() { 51 TouchExplorationController::~TouchExplorationController() {
47 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); 52 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
48 } 53 }
49 54
50 ui::EventRewriteStatus TouchExplorationController::RewriteEvent( 55 ui::EventRewriteStatus TouchExplorationController::RewriteEvent(
51 const ui::Event& event, 56 const ui::Event& event,
52 scoped_ptr<ui::Event>* rewritten_event) { 57 scoped_ptr<ui::Event>* rewritten_event) {
53 if (!event.IsTouchEvent()) { 58 if (!event.IsTouchEvent()) {
54 return ui::EVENT_REWRITE_CONTINUE; 59 return ui::EVENT_REWRITE_CONTINUE;
55 } 60 }
56 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event); 61 const ui::TouchEvent& touch_event = static_cast<const ui::TouchEvent&>(event);
57 62
58 // If the tap timer should have fired by now but hasn't, run it now and 63 // If the tap timer should have fired by now but hasn't, run it now and
59 // stop the timer. This is important so that behavior is consistent with 64 // stop the timer. This is important so that behavior is consistent with
60 // the timestamps of the events, and not dependent on the granularity of 65 // the timestamps of the events, and not dependent on the granularity of
61 // the timer. 66 // the timer.
62 if (tap_timer_.IsRunning() && 67 if (tap_timer_.IsRunning() &&
63 touch_event.time_stamp() - initial_press_->time_stamp() > 68 touch_event.time_stamp() - initial_press_->time_stamp() >
64 gesture_detector_config_.double_tap_timeout) { 69 gesture_detector_config_.double_tap_timeout) {
65 tap_timer_.Stop(); 70 tap_timer_.Stop();
66 OnTapTimerFired(); 71 OnTapTimerFired();
67 // Note: this may change the state. We should now continue and process 72 // Note: this may change the state. We should now continue and process
68 // this event under this new state. 73 // this event under this new state.
69 } 74 }
70 75
76 if (long_press_timer_.IsRunning() &&
77 event.time_stamp() - initial_press_->time_stamp() >
78 gesture_detector_config_.longpress_timeout) {
79 long_press_timer_.Stop();
80 OnLongPressTimerFired();
81 }
82
71 const ui::EventType type = touch_event.type(); 83 const ui::EventType type = touch_event.type();
72 const gfx::PointF& location = touch_event.location_f(); 84 const gfx::PointF& location = touch_event.location_f();
73 const int touch_id = touch_event.touch_id(); 85 const int touch_id = touch_event.touch_id();
74 86
75 // Always update touch ids and touch locations, so we can use those 87 // Always update touch ids and touch locations, so we can use those
76 // no matter what state we're in. 88 // no matter what state we're in.
77 if (type == ui::ET_TOUCH_PRESSED) { 89 if (type == ui::ET_TOUCH_PRESSED) {
90 // If the user enters the screen from the edge then send an earcon.
91 gfx::Point edges = touch_event.location();
92 if (FindEdgesWithinBounds(edges, kLeavingScreenEdge) != NO_EDGE)
aboxhall 2014/08/06 18:10:45 Do we want to not play this if a user already has
lisayin 2014/08/06 20:37:35 Hmmm. Good point. I'll move it to InNoFingersDown.
93 delegate_->PlayEnterScreenEarcon();
78 current_touch_ids_.push_back(touch_id); 94 current_touch_ids_.push_back(touch_id);
79 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); 95 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location));
80 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 96 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
81 // In order to avoid accidentally double tapping when moving off the edge of 97 // In order to avoid accidentally double tapping when moving off the edge of
82 // the screen, the state will be rewritten to NoFingersDown. 98 // the screen, the state will be rewritten to NoFingersDown.
83 TouchEvent touch_event = static_cast<const TouchEvent&>(event); 99 TouchEvent touch_event = static_cast<const TouchEvent&>(event);
84 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != 100 gfx::Point edges = touch_event.location();
85 NO_EDGE) { 101 if (FindEdgesWithinBounds(edges, kLeavingScreenEdge) != NO_EDGE) {
aboxhall 2014/08/06 18:10:45 Perhaps this needs to check for state as well: I i
lisayin 2014/08/06 20:37:35 I actually think it makes sense to notify the user
aboxhall 2014/08/06 21:03:12 I guess it could be handy knowing that you'll cons
lisayin 2014/08/06 21:48:22 So another thing that kind of keeps the sound from
86 if (current_touch_ids_.size() == 0) { 102 // Indicates to the user that they are leaving the screen.
87 ResetToNoFingersDown(); 103 if (VLOG_on_)
88 } 104 VLOG(0) << "Leaving the Screen";
105 delegate_->PlayExitScreenEarcon();
106 if (current_touch_ids_.size() == 0)
107 ResetToNoFingersDown();
89 } 108 }
90 109
91 std::vector<int>::iterator it = std::find( 110 std::vector<int>::iterator it = std::find(
92 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); 111 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id);
93 112
94 // Can happen if touch exploration is enabled while fingers were down. 113 // Can happen if touch exploration is enabled while fingers were down.
95 if (it == current_touch_ids_.end()) 114 if (it == current_touch_ids_.end())
96 return ui::EVENT_REWRITE_CONTINUE; 115 return ui::EVENT_REWRITE_CONTINUE;
97 116
98 current_touch_ids_.erase(it); 117 current_touch_ids_.erase(it);
(...skipping 22 matching lines...) Expand all
121 case DOUBLE_TAP_PENDING: 140 case DOUBLE_TAP_PENDING:
122 return InDoubleTapPending(touch_event, rewritten_event); 141 return InDoubleTapPending(touch_event, rewritten_event);
123 case TOUCH_RELEASE_PENDING: 142 case TOUCH_RELEASE_PENDING:
124 return InTouchReleasePending(touch_event, rewritten_event); 143 return InTouchReleasePending(touch_event, rewritten_event);
125 case TOUCH_EXPLORATION: 144 case TOUCH_EXPLORATION:
126 return InTouchExploration(touch_event, rewritten_event); 145 return InTouchExploration(touch_event, rewritten_event);
127 case GESTURE_IN_PROGRESS: 146 case GESTURE_IN_PROGRESS:
128 return InGestureInProgress(touch_event, rewritten_event); 147 return InGestureInProgress(touch_event, rewritten_event);
129 case TOUCH_EXPLORE_SECOND_PRESS: 148 case TOUCH_EXPLORE_SECOND_PRESS:
130 return InTouchExploreSecondPress(touch_event, rewritten_event); 149 return InTouchExploreSecondPress(touch_event, rewritten_event);
150 case CORNER_PASSTHROUGH:
151 return InCornerPassthrough(touch_event, rewritten_event);
131 case SLIDE_GESTURE: 152 case SLIDE_GESTURE:
132 return InSlideGesture(touch_event, rewritten_event); 153 return InSlideGesture(touch_event, rewritten_event);
133 case ONE_FINGER_PASSTHROUGH: 154 case ONE_FINGER_PASSTHROUGH:
134 return InOneFingerPassthrough(touch_event, rewritten_event); 155 return InOneFingerPassthrough(touch_event, rewritten_event);
135 case WAIT_FOR_ONE_FINGER: 156 case WAIT_FOR_ONE_FINGER:
136 return InWaitForOneFinger(touch_event, rewritten_event); 157 return InWaitForOneFinger(touch_event, rewritten_event);
137 } 158 }
138 NOTREACHED(); 159 NOTREACHED();
139 return ui::EVENT_REWRITE_CONTINUE; 160 return ui::EVENT_REWRITE_CONTINUE;
140 } 161 }
141 162
142 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 163 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
143 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 164 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
144 NOTREACHED(); 165 NOTREACHED();
145 return ui::EVENT_REWRITE_CONTINUE; 166 return ui::EVENT_REWRITE_CONTINUE;
146 } 167 }
147 168
148 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 169 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
149 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 170 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
150 const ui::EventType type = event.type(); 171 const ui::EventType type = event.type();
151 if (type == ui::ET_TOUCH_PRESSED) { 172 if (type != ui::ET_TOUCH_PRESSED) {
152 initial_press_.reset(new TouchEvent(event)); 173 NOTREACHED() << "Unexpected event type received: " << event.name();
153 last_unused_finger_event_.reset(new TouchEvent(event)); 174 return ui::EVENT_REWRITE_CONTINUE;
154 StartTapTimer();
155 gesture_provider_.OnTouchEvent(event);
156 gesture_provider_.OnTouchEventAck(false);
157 ProcessGestureEvents();
158 state_ = SINGLE_TAP_PRESSED;
159 VLOG_STATE();
160 return ui::EVENT_REWRITE_DISCARD;
161 } 175 }
162 NOTREACHED() << "Unexpected event type received: " << event.name(); 176 int location = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
163 return ui::EVENT_REWRITE_CONTINUE; 177 base::TimeDelta timeout;
178
179 // If the press was at a corner, the user might go into corner passthrough
180 // instead.
181 bool in_a_bottom_corner =
182 (BOTTOM_LEFT_CORNER == location) || (BOTTOM_RIGHT_CORNER == location);
183 if (in_a_bottom_corner) {
184 long_press_timer_.Start(FROM_HERE,
185 gesture_detector_config_.longpress_timeout,
186 this,
187 &TouchExplorationController::OnLongPressTimerFired);
188 waiting_for_corner_passthrough_ = true;
aboxhall 2014/08/06 18:10:45 Why not just use the long_press_timer_ (or corner_
lisayin 2014/08/06 20:37:35 I'm hoping to use this timer for evy's passthrough
189 } else {
190 waiting_for_corner_passthrough_ = false;
191 }
192 tap_timer_.Start(FROM_HERE,
193 gesture_detector_config_.double_tap_timeout,
194 this,
195 &TouchExplorationController::OnTapTimerFired);
196 initial_press_.reset(new TouchEvent(event));
197 last_unused_finger_event_.reset(new TouchEvent(event));
198 gesture_provider_.OnTouchEvent(event);
199 gesture_provider_.OnTouchEventAck(false);
200 ProcessGestureEvents();
201 state_ = SINGLE_TAP_PRESSED;
202 VLOG_STATE();
203 return ui::EVENT_REWRITE_DISCARD;
164 } 204 }
165 205
166 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 206 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
167 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 207 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
168 const ui::EventType type = event.type(); 208 const ui::EventType type = event.type();
169 209
210 int location = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
211 bool in_a_bottom_corner =
212 (location == BOTTOM_LEFT_CORNER) || (location == BOTTOM_RIGHT_CORNER);
213 // If the event is from the initial press and the location is no longer in the
214 // corner, then we are not waiting for a corner passthrough anymore.
215 if (event.touch_id() == initial_press_->touch_id() && !in_a_bottom_corner) {
216 waiting_for_corner_passthrough_ = false;
217 if (long_press_timer_.IsRunning()) {
aboxhall 2014/08/06 18:10:44 If we're not going to use this for anything other
lisayin 2014/08/06 20:37:35 Done.
218 long_press_timer_.Stop();
219 if (event.time_stamp() - initial_press_->time_stamp() >
220 gesture_detector_config_.double_tap_timeout) {
221 OnTapTimerFired();
aboxhall 2014/08/06 18:10:44 Why do this? Could you add a comment?
lisayin 2014/08/06 20:37:35 This is in case the finger moves out of the corner
aboxhall 2014/08/06 21:03:12 Ah, I see now. But won't the tap timer have been r
lisayin 2014/08/06 21:48:22 In TapTimerFired, if the long press timer is runni
aboxhall 2014/08/06 22:01:24 Oh, duh! Makes sense, thanks for the explanation :
222 }
223 }
224 }
225
170 if (type == ui::ET_TOUCH_PRESSED) { 226 if (type == ui::ET_TOUCH_PRESSED) {
171 // TODO (evy, lisayin) : add support for multifinger swipes. 227 // TODO (evy, lisayin) : add support for multifinger swipes.
172 // For now, we wait for there to be only one finger down again. 228 // For now, we wait for there to be only one finger down again.
173 state_ = WAIT_FOR_ONE_FINGER; 229 state_ = WAIT_FOR_ONE_FINGER;
174 return EVENT_REWRITE_DISCARD; 230 return EVENT_REWRITE_DISCARD;
175 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 231 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
176 if (current_touch_ids_.size() == 0 && 232 if (current_touch_ids_.size() == 0 &&
177 event.touch_id() == initial_press_->touch_id()) { 233 event.touch_id() == initial_press_->touch_id()) {
178 state_ = SINGLE_TAP_RELEASED; 234 state_ = SINGLE_TAP_RELEASED;
179 VLOG_STATE(); 235 VLOG_STATE();
(...skipping 13 matching lines...) Expand all
193 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF(); 249 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF();
194 float velocity = distance / delta_time; 250 float velocity = distance / delta_time;
195 if (VLOG_on_) { 251 if (VLOG_on_) {
196 VLOG(0) << "\n Delta time: " << delta_time << "\n Distance: " << distance 252 VLOG(0) << "\n Delta time: " << delta_time << "\n Distance: " << distance
197 << "\n Velocity of click: " << velocity 253 << "\n Velocity of click: " << velocity
198 << "\n Minimum swipe velocity: " 254 << "\n Minimum swipe velocity: "
199 << gesture_detector_config_.minimum_swipe_velocity; 255 << gesture_detector_config_.minimum_swipe_velocity;
200 } 256 }
201 // Change to slide gesture if the slide occurred at the right edge. 257 // Change to slide gesture if the slide occurred at the right edge.
202 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); 258 int edge = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge);
203 if (edge & RIGHT_EDGE) { 259 if (edge & RIGHT_EDGE && edge != BOTTOM_RIGHT_CORNER) {
204 state_ = SLIDE_GESTURE; 260 state_ = SLIDE_GESTURE;
205 VLOG_STATE(); 261 VLOG_STATE();
206 return InSlideGesture(event, rewritten_event); 262 return InSlideGesture(event, rewritten_event);
207 } 263 }
208 264
209 // If the user moves fast enough from the initial touch location, start 265 // If the user moves fast enough from the initial touch location, start
210 // gesture detection. Otherwise, jump to the touch exploration mode early. 266 // gesture detection. Otherwise, jump to the touch exploration mode early.
211 if (velocity > gesture_detector_config_.minimum_swipe_velocity) { 267 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
212 state_ = GESTURE_IN_PROGRESS; 268 state_ = GESTURE_IN_PROGRESS;
213 VLOG_STATE(); 269 VLOG_STATE();
(...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 gesture_provider_.OnTouchEvent(event); 442 gesture_provider_.OnTouchEvent(event);
387 gesture_provider_.OnTouchEventAck(false); 443 gesture_provider_.OnTouchEventAck(false);
388 if (current_touch_ids_.size() == 0) { 444 if (current_touch_ids_.size() == 0) {
389 ResetToNoFingersDown(); 445 ResetToNoFingersDown();
390 } 446 }
391 } 447 }
392 ProcessGestureEvents(); 448 ProcessGestureEvents();
393 return ui::EVENT_REWRITE_DISCARD; 449 return ui::EVENT_REWRITE_DISCARD;
394 } 450 }
395 451
452 ui::EventRewriteStatus TouchExplorationController::InCornerPassthrough(
453 const ui::TouchEvent& event,
454 scoped_ptr<ui::Event>* rewritten_event) {
455 ui::EventType type = event.type();
456
457 // If the first finger has left the corner, then exit passthrough.
458 if (event.touch_id() == initial_press_->touch_id()) {
459 int edges = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge);
460 bool in_a_bottom_corner = (edges == BOTTOM_LEFT_CORNER) ||
461 (edges == BOTTOM_RIGHT_CORNER);
462 if (type == ui::ET_TOUCH_MOVED && in_a_bottom_corner)
463 return ui::EVENT_REWRITE_DISCARD;
464
465 if (current_touch_ids_.size() == 0) {
466 ResetToNoFingersDown();
467 return ui::EVENT_REWRITE_DISCARD;
468 }
469
470 waiting_for_corner_passthrough_ = false;
471 state_ = WAIT_FOR_ONE_FINGER;
472 VLOG_STATE();
473 return ui::EVENT_REWRITE_DISCARD;
474 }
475
476 rewritten_event->reset(new ui::TouchEvent(
477 type, event.location(), event.touch_id(), event.time_stamp()));
478 (*rewritten_event)->set_flags(event.flags());
479
480 if (current_touch_ids_.size() == 0)
481 ResetToNoFingersDown();
482
483 return ui::EVENT_REWRITE_REWRITTEN;
484 }
485
396 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( 486 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough(
397 const ui::TouchEvent& event, 487 const ui::TouchEvent& event,
398 scoped_ptr<ui::Event>* rewritten_event) { 488 scoped_ptr<ui::Event>* rewritten_event) {
399 ui::EventType type = event.type(); 489 ui::EventType type = event.type();
400 490
401 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED || 491 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED ||
402 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) { 492 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) {
403 NOTREACHED() << "Unexpected event type received: " << event.name(); 493 NOTREACHED() << "Unexpected event type received: " << event.name();
404 return ui::EVENT_REWRITE_CONTINUE; 494 return ui::EVENT_REWRITE_CONTINUE;
405 } 495 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 VLOG_STATE(); 551 VLOG_STATE();
462 return ui::EVENT_REWRITE_REWRITTEN; 552 return ui::EVENT_REWRITE_REWRITTEN;
463 } 553 }
464 NOTREACHED() << "Unexpected event type received: " << event.name(); 554 NOTREACHED() << "Unexpected event type received: " << event.name();
465 return ui::EVENT_REWRITE_CONTINUE; 555 return ui::EVENT_REWRITE_CONTINUE;
466 } 556 }
467 557
468 ui::EventRewriteStatus TouchExplorationController::InWaitForOneFinger( 558 ui::EventRewriteStatus TouchExplorationController::InWaitForOneFinger(
469 const ui::TouchEvent& event, 559 const ui::TouchEvent& event,
470 scoped_ptr<ui::Event>* rewritten_event) { 560 scoped_ptr<ui::Event>* rewritten_event) {
561 waiting_for_corner_passthrough_ = false;
471 ui::EventType type = event.type(); 562 ui::EventType type = event.type();
472 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED || 563 if (!(type == ui::ET_TOUCH_PRESSED || type == ui::ET_TOUCH_MOVED ||
473 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) { 564 type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED)) {
474 NOTREACHED() << "Unexpected event type received: " << event.name(); 565 NOTREACHED() << "Unexpected event type received: " << event.name();
475 return ui::EVENT_REWRITE_CONTINUE; 566 return ui::EVENT_REWRITE_CONTINUE;
476 } 567 }
477 if (current_touch_ids_.size() == 1) { 568 if (current_touch_ids_.size() == 1) {
478 EnterTouchToMouseMode(); 569 EnterTouchToMouseMode();
479 state_ = TOUCH_EXPLORATION; 570 state_ = TOUCH_EXPLORATION;
480 VLOG_STATE(); 571 VLOG_STATE();
481 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); 572 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
482 last_touch_exploration_.reset(new TouchEvent(event)); 573 last_touch_exploration_.reset(new TouchEvent(event));
483 return ui::EVENT_REWRITE_REWRITTEN; 574 return ui::EVENT_REWRITE_REWRITTEN;
484 } 575 }
485 return EVENT_REWRITE_DISCARD; 576 return EVENT_REWRITE_DISCARD;
486 } 577 }
487 578
488 void TouchExplorationController::PlaySoundForTimer() { 579 void TouchExplorationController::PlaySoundForTimer() {
489 delegate_->PlayVolumeAdjustSound(); 580 delegate_->PlayVolumeAdjustEarcon();
490 } 581 }
491 582
492 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( 583 ui::EventRewriteStatus TouchExplorationController::InSlideGesture(
493 const ui::TouchEvent& event, 584 const ui::TouchEvent& event,
494 scoped_ptr<ui::Event>* rewritten_event) { 585 scoped_ptr<ui::Event>* rewritten_event) {
495 // The timer should not fire when sliding. 586 // The timer should not fire when sliding.
496 if (tap_timer_.IsRunning()) 587 if (tap_timer_.IsRunning())
497 tap_timer_.Stop(); 588 tap_timer_.Stop();
498 589
499 ui::EventType type = event.type(); 590 ui::EventType type = event.type();
(...skipping 19 matching lines...) Expand all
519 return EVENT_REWRITE_DISCARD; 610 return EVENT_REWRITE_DISCARD;
520 } 611 }
521 612
522 // This can occur if the user leaves the screen edge and then returns to it to 613 // This can occur if the user leaves the screen edge and then returns to it to
523 // continue adjusting the sound. 614 // continue adjusting the sound.
524 if (!sound_timer_.IsRunning()) { 615 if (!sound_timer_.IsRunning()) {
525 sound_timer_.Start(FROM_HERE, 616 sound_timer_.Start(FROM_HERE,
526 kSoundDelay, 617 kSoundDelay,
527 this, 618 this,
528 &ui::TouchExplorationController::PlaySoundForTimer); 619 &ui::TouchExplorationController::PlaySoundForTimer);
529 delegate_->PlayVolumeAdjustSound(); 620 delegate_->PlayVolumeAdjustEarcon();
530 } 621 }
531 622
532 // There should not be more than one finger down. 623 // There should not be more than one finger down.
533 DCHECK(current_touch_ids_.size() <= 1); 624 DCHECK(current_touch_ids_.size() <= 1);
534 if (type == ui::ET_TOUCH_MOVED) { 625 if (type == ui::ET_TOUCH_MOVED) {
535 gesture_provider_.OnTouchEvent(event); 626 gesture_provider_.OnTouchEvent(event);
536 gesture_provider_.OnTouchEventAck(false); 627 gesture_provider_.OnTouchEventAck(false);
537 } 628 }
538 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 629 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
539 gesture_provider_.OnTouchEvent(event); 630 gesture_provider_.OnTouchEvent(event);
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 last_touch_exploration_->location(); 673 last_touch_exploration_->location();
583 scoped_ptr<ui::TouchEvent> passthrough_press( 674 scoped_ptr<ui::TouchEvent> passthrough_press(
584 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, 675 new ui::TouchEvent(ui::ET_TOUCH_PRESSED,
585 last_touch_exploration_->location(), 676 last_touch_exploration_->location(),
586 last_unused_finger_event_->touch_id(), 677 last_unused_finger_event_->touch_id(),
587 Now())); 678 Now()));
588 DispatchEvent(passthrough_press.get()); 679 DispatchEvent(passthrough_press.get());
589 return; 680 return;
590 } 681 }
591 case SINGLE_TAP_PRESSED: 682 case SINGLE_TAP_PRESSED:
683 if (waiting_for_corner_passthrough_)
684 return;
592 case GESTURE_IN_PROGRESS: 685 case GESTURE_IN_PROGRESS:
593 // Discard any pending gestures. 686 // Discard any pending gestures.
594 delete gesture_provider_.GetAndResetPendingGestures(); 687 delete gesture_provider_.GetAndResetPendingGestures();
595 state_ = TOUCH_EXPLORATION; 688 state_ = TOUCH_EXPLORATION;
596 VLOG_STATE(); 689 VLOG_STATE();
597 break; 690 break;
598 default: 691 default:
599 return; 692 return;
600 } 693 }
601 EnterTouchToMouseMode(); 694 EnterTouchToMouseMode();
602 scoped_ptr<ui::Event> mouse_move = 695 scoped_ptr<ui::Event> mouse_move =
603 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); 696 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags());
604 DispatchEvent(mouse_move.get()); 697 DispatchEvent(mouse_move.get());
605 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); 698 last_touch_exploration_.reset(new TouchEvent(*initial_press_));
606 } 699 }
607 700
701 void TouchExplorationController::OnLongPressTimerFired() {
702 if (waiting_for_corner_passthrough_) {
aboxhall 2014/08/06 18:10:44 Invert this logic: if (!waiting_for_corner_passthr
lisayin 2014/08/06 20:37:35 Done.
703 if (sound_timer_.IsRunning())
704 sound_timer_.Stop();
705 delegate_->PlayPassthroughEarcon();
706 delete gesture_provider_.GetAndResetPendingGestures();
707 state_ = CORNER_PASSTHROUGH;
708 VLOG_STATE();
709 return;
710 }
711 }
712
608 void TouchExplorationController::DispatchEvent(ui::Event* event) { 713 void TouchExplorationController::DispatchEvent(ui::Event* event) {
609 ui::EventDispatchDetails result ALLOW_UNUSED = 714 ui::EventDispatchDetails result ALLOW_UNUSED =
610 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 715 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
611 } 716 }
612 717
613 void TouchExplorationController::OnGestureEvent( 718 void TouchExplorationController::OnGestureEvent(
614 ui::GestureEvent* gesture) { 719 ui::GestureEvent* gesture) {
615 CHECK(gesture->IsGestureEvent()); 720 CHECK(gesture->IsGestureEvent());
616 ui::EventType type = gesture->type(); 721 ui::EventType type = gesture->type();
617 if (VLOG_on_) 722 if (VLOG_on_)
(...skipping 21 matching lines...) Expand all
639 } 744 }
640 } 745 }
641 } 746 }
642 747
643 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { 748 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) {
644 ui::EventType type = gesture->type(); 749 ui::EventType type = gesture->type();
645 if (!gesture->IsScrollGestureEvent()) 750 if (!gesture->IsScrollGestureEvent())
646 return; 751 return;
647 752
648 if (type == ET_GESTURE_SCROLL_BEGIN) { 753 if (type == ET_GESTURE_SCROLL_BEGIN) {
649 delegate_->PlayVolumeAdjustSound(); 754 delegate_->PlayVolumeAdjustEarcon();
650 } 755 }
651 756
652 if (type == ET_GESTURE_SCROLL_END) { 757 if (type == ET_GESTURE_SCROLL_END) {
653 if (sound_timer_.IsRunning()) 758 if (sound_timer_.IsRunning())
654 sound_timer_.Stop(); 759 sound_timer_.Stop();
655 delegate_->PlayVolumeAdjustSound(); 760 delegate_->PlayVolumeAdjustEarcon();
656 } 761 }
657 762
658 // If the user is in the corner of the right side of the screen, the volume 763 // 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 764 // 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 765 // 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 766 // their finger along the right side of the screen. Volume is relative to
662 // where they are on the right side of the screen. 767 // where they are on the right side of the screen.
663 gfx::Point location = gesture->location(); 768 gfx::Point location = gesture->location();
664 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); 769 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge);
665 if (!(edge & RIGHT_EDGE)) 770 if (!(edge & RIGHT_EDGE))
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
792 void TouchExplorationController::EnterTouchToMouseMode() { 897 void TouchExplorationController::EnterTouchToMouseMode() {
793 aura::client::CursorClient* cursor_client = 898 aura::client::CursorClient* cursor_client =
794 aura::client::GetCursorClient(root_window_); 899 aura::client::GetCursorClient(root_window_);
795 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) 900 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
796 cursor_client->EnableMouseEvents(); 901 cursor_client->EnableMouseEvents();
797 if (cursor_client && cursor_client->IsCursorVisible()) 902 if (cursor_client && cursor_client->IsCursorVisible())
798 cursor_client->HideCursor(); 903 cursor_client->HideCursor();
799 } 904 }
800 905
801 void TouchExplorationController::ResetToNoFingersDown() { 906 void TouchExplorationController::ResetToNoFingersDown() {
907 waiting_for_corner_passthrough_ = false;
802 ProcessGestureEvents(); 908 ProcessGestureEvents();
803 if (sound_timer_.IsRunning()) 909 if (sound_timer_.IsRunning())
804 sound_timer_.Stop(); 910 sound_timer_.Stop();
805 state_ = NO_FINGERS_DOWN; 911 state_ = NO_FINGERS_DOWN;
806 VLOG_STATE(); 912 VLOG_STATE();
807 if (tap_timer_.IsRunning()) 913 if (tap_timer_.IsRunning())
808 tap_timer_.Stop(); 914 tap_timer_.Stop();
809 } 915 }
810 916
811 void TouchExplorationController::VlogState(const char* function_name) { 917 void TouchExplorationController::VlogState(const char* function_name) {
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
862 case DOUBLE_TAP_PENDING: 968 case DOUBLE_TAP_PENDING:
863 return "DOUBLE_TAP_PENDING"; 969 return "DOUBLE_TAP_PENDING";
864 case TOUCH_RELEASE_PENDING: 970 case TOUCH_RELEASE_PENDING:
865 return "TOUCH_RELEASE_PENDING"; 971 return "TOUCH_RELEASE_PENDING";
866 case TOUCH_EXPLORATION: 972 case TOUCH_EXPLORATION:
867 return "TOUCH_EXPLORATION"; 973 return "TOUCH_EXPLORATION";
868 case GESTURE_IN_PROGRESS: 974 case GESTURE_IN_PROGRESS:
869 return "GESTURE_IN_PROGRESS"; 975 return "GESTURE_IN_PROGRESS";
870 case TOUCH_EXPLORE_SECOND_PRESS: 976 case TOUCH_EXPLORE_SECOND_PRESS:
871 return "TOUCH_EXPLORE_SECOND_PRESS"; 977 return "TOUCH_EXPLORE_SECOND_PRESS";
978 case CORNER_PASSTHROUGH:
979 return "CORNER_PASSTHROUGH";
872 case SLIDE_GESTURE: 980 case SLIDE_GESTURE:
873 return "SLIDE_GESTURE"; 981 return "SLIDE_GESTURE";
874 case ONE_FINGER_PASSTHROUGH: 982 case ONE_FINGER_PASSTHROUGH:
875 return "ONE_FINGER_PASSTHROUGH"; 983 return "ONE_FINGER_PASSTHROUGH";
876 case WAIT_FOR_ONE_FINGER: 984 case WAIT_FOR_ONE_FINGER:
877 return "WAIT_FOR_ONE_FINGER"; 985 return "WAIT_FOR_ONE_FINGER";
878 } 986 }
879 return "Not a state"; 987 return "Not a state";
880 } 988 }
881 989
882 } // namespace ui 990 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698