OLD | NEW |
---|---|
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), |
(...skipping 23 matching lines...) Expand all Loading... | |
61 // the timer. | 65 // the timer. |
62 if (tap_timer_.IsRunning() && | 66 if (tap_timer_.IsRunning() && |
63 touch_event.time_stamp() - initial_press_->time_stamp() > | 67 touch_event.time_stamp() - initial_press_->time_stamp() > |
64 gesture_detector_config_.double_tap_timeout) { | 68 gesture_detector_config_.double_tap_timeout) { |
65 tap_timer_.Stop(); | 69 tap_timer_.Stop(); |
66 OnTapTimerFired(); | 70 OnTapTimerFired(); |
67 // Note: this may change the state. We should now continue and process | 71 // Note: this may change the state. We should now continue and process |
68 // this event under this new state. | 72 // this event under this new state. |
69 } | 73 } |
70 | 74 |
75 if (passthrough_timer_.IsRunning() && | |
76 event.time_stamp() - initial_press_->time_stamp() > | |
77 gesture_detector_config_.longpress_timeout) { | |
78 passthrough_timer_.Stop(); | |
79 OnPassthroughTimerFired(); | |
80 } | |
81 | |
71 const ui::EventType type = touch_event.type(); | 82 const ui::EventType type = touch_event.type(); |
72 const gfx::PointF& location = touch_event.location_f(); | 83 const gfx::PointF& location = touch_event.location_f(); |
73 const int touch_id = touch_event.touch_id(); | 84 const int touch_id = touch_event.touch_id(); |
74 | 85 |
75 // Always update touch ids and touch locations, so we can use those | 86 // Always update touch ids and touch locations, so we can use those |
76 // no matter what state we're in. | 87 // no matter what state we're in. |
77 if (type == ui::ET_TOUCH_PRESSED) { | 88 if (type == ui::ET_TOUCH_PRESSED) { |
78 current_touch_ids_.push_back(touch_id); | 89 current_touch_ids_.push_back(touch_id); |
79 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); | 90 touch_locations_.insert(std::pair<int, gfx::PointF>(touch_id, location)); |
80 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 91 } 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 | 92 // In order to avoid accidentally double tapping when moving off the edge of |
82 // the screen, the state will be rewritten to NoFingersDown. | 93 // the screen, the state will be rewritten to NoFingersDown. |
83 TouchEvent touch_event = static_cast<const TouchEvent&>(event); | 94 TouchEvent touch_event = static_cast<const TouchEvent&>(event); |
84 if (FindEdgesWithinBounds(touch_event.location(), kLeavingScreenEdge) != | 95 gfx::Point edges = touch_event.location(); |
85 NO_EDGE) { | 96 if (FindEdgesWithinBounds(edges, kLeavingScreenEdge) != NO_EDGE) { |
86 if (current_touch_ids_.size() == 0) { | 97 // Indicates to the user that they are leaving the screen. |
87 ResetToNoFingersDown(); | 98 if (VLOG_on_) |
88 } | 99 VLOG(0) << "Leaving the Screen"; |
100 delegate_->PlayExitScreenEarcon(); | |
101 if (current_touch_ids_.size() == 0) | |
102 ResetToNoFingersDown(); | |
89 } | 103 } |
90 | 104 |
91 std::vector<int>::iterator it = std::find( | 105 std::vector<int>::iterator it = std::find( |
92 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); | 106 current_touch_ids_.begin(), current_touch_ids_.end(), touch_id); |
93 | 107 |
94 // Can happen if touch exploration is enabled while fingers were down. | 108 // Can happen if touch exploration is enabled while fingers were down. |
95 if (it == current_touch_ids_.end()) | 109 if (it == current_touch_ids_.end()) |
96 return ui::EVENT_REWRITE_CONTINUE; | 110 return ui::EVENT_REWRITE_CONTINUE; |
97 | 111 |
98 current_touch_ids_.erase(it); | 112 current_touch_ids_.erase(it); |
(...skipping 22 matching lines...) Expand all Loading... | |
121 case DOUBLE_TAP_PENDING: | 135 case DOUBLE_TAP_PENDING: |
122 return InDoubleTapPending(touch_event, rewritten_event); | 136 return InDoubleTapPending(touch_event, rewritten_event); |
123 case TOUCH_RELEASE_PENDING: | 137 case TOUCH_RELEASE_PENDING: |
124 return InTouchReleasePending(touch_event, rewritten_event); | 138 return InTouchReleasePending(touch_event, rewritten_event); |
125 case TOUCH_EXPLORATION: | 139 case TOUCH_EXPLORATION: |
126 return InTouchExploration(touch_event, rewritten_event); | 140 return InTouchExploration(touch_event, rewritten_event); |
127 case GESTURE_IN_PROGRESS: | 141 case GESTURE_IN_PROGRESS: |
128 return InGestureInProgress(touch_event, rewritten_event); | 142 return InGestureInProgress(touch_event, rewritten_event); |
129 case TOUCH_EXPLORE_SECOND_PRESS: | 143 case TOUCH_EXPLORE_SECOND_PRESS: |
130 return InTouchExploreSecondPress(touch_event, rewritten_event); | 144 return InTouchExploreSecondPress(touch_event, rewritten_event); |
145 case CORNER_PASSTHROUGH: | |
146 return InCornerPassthrough(touch_event, rewritten_event); | |
131 case SLIDE_GESTURE: | 147 case SLIDE_GESTURE: |
132 return InSlideGesture(touch_event, rewritten_event); | 148 return InSlideGesture(touch_event, rewritten_event); |
133 case ONE_FINGER_PASSTHROUGH: | 149 case ONE_FINGER_PASSTHROUGH: |
134 return InOneFingerPassthrough(touch_event, rewritten_event); | 150 return InOneFingerPassthrough(touch_event, rewritten_event); |
135 case WAIT_FOR_ONE_FINGER: | 151 case WAIT_FOR_ONE_FINGER: |
136 return InWaitForOneFinger(touch_event, rewritten_event); | 152 return InWaitForOneFinger(touch_event, rewritten_event); |
137 } | 153 } |
138 NOTREACHED(); | 154 NOTREACHED(); |
139 return ui::EVENT_REWRITE_CONTINUE; | 155 return ui::EVENT_REWRITE_CONTINUE; |
140 } | 156 } |
141 | 157 |
142 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( | 158 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( |
143 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { | 159 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { |
144 NOTREACHED(); | 160 NOTREACHED(); |
145 return ui::EVENT_REWRITE_CONTINUE; | 161 return ui::EVENT_REWRITE_CONTINUE; |
146 } | 162 } |
147 | 163 |
148 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( | 164 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( |
149 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 165 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
150 const ui::EventType type = event.type(); | 166 const ui::EventType type = event.type(); |
151 if (type == ui::ET_TOUCH_PRESSED) { | 167 if (type != ui::ET_TOUCH_PRESSED) { |
152 initial_press_.reset(new TouchEvent(event)); | 168 NOTREACHED() << "Unexpected event type received: " << event.name(); |
153 last_unused_finger_event_.reset(new TouchEvent(event)); | 169 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 } | 170 } |
162 NOTREACHED() << "Unexpected event type received: " << event.name(); | 171 |
163 return ui::EVENT_REWRITE_CONTINUE; | 172 // If the user enters the screen from the edge then send an earcon. |
173 int edge = FindEdgesWithinBounds(event.location(), kLeavingScreenEdge); | |
174 if (edge != NO_EDGE) | |
175 delegate_->PlayEnterScreenEarcon(); | |
176 | |
177 int location = FindEdgesWithinBounds(event.location(), kSlopDistanceFromEdge); | |
178 // If the press was at a corner, the user might go into corner passthrough | |
179 // instead. | |
180 bool in_a_bottom_corner = | |
181 (BOTTOM_LEFT_CORNER == location) || (BOTTOM_RIGHT_CORNER == location); | |
182 if (in_a_bottom_corner) { | |
183 passthrough_timer_.Start( | |
184 FROM_HERE, | |
185 gesture_detector_config_.longpress_timeout, | |
186 this, | |
187 &TouchExplorationController::OnPassthroughTimerFired); | |
188 } | |
189 | |
190 tap_timer_.Start(FROM_HERE, | |
191 gesture_detector_config_.double_tap_timeout, | |
192 this, | |
193 &TouchExplorationController::OnTapTimerFired); | |
194 initial_press_.reset(new TouchEvent(event)); | |
195 last_unused_finger_event_.reset(new TouchEvent(event)); | |
196 gesture_provider_.OnTouchEvent(event); | |
197 gesture_provider_.OnTouchEventAck(false); | |
198 ProcessGestureEvents(); | |
199 state_ = SINGLE_TAP_PRESSED; | |
200 VLOG_STATE(); | |
201 return ui::EVENT_REWRITE_DISCARD; | |
164 } | 202 } |
165 | 203 |
166 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( | 204 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( |
167 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { | 205 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { |
168 const ui::EventType type = event.type(); | 206 const ui::EventType type = event.type(); |
169 | 207 |
208 int location = FindEdgesWithinBounds(event.location(), kMaxDistanceFromEdge); | |
209 bool in_a_bottom_corner = | |
210 (location == BOTTOM_LEFT_CORNER) || (location == BOTTOM_RIGHT_CORNER); | |
211 // If the event is from the initial press and the location is no longer in the | |
212 // corner, then we are not waiting for a corner passthrough anymore. | |
213 if (event.touch_id() == initial_press_->touch_id() && !in_a_bottom_corner) { | |
214 if (passthrough_timer_.IsRunning()) { | |
215 passthrough_timer_.Stop(); | |
216 // Since the long press timer has been running, it is possible that the | |
217 // tap timer has timed out before the long press timer has. If the tap | |
218 // timer timeout has elapsed, then fire the tap timer. | |
219 if (event.time_stamp() - initial_press_->time_stamp() > | |
220 gesture_detector_config_.double_tap_timeout) { | |
221 OnTapTimerFired(); | |
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 Loading... | |
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 Loading... | |
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 state_ = WAIT_FOR_ONE_FINGER; | |
471 VLOG_STATE(); | |
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 ResetToNoFingersDown(); | |
481 | |
482 return ui::EVENT_REWRITE_REWRITTEN; | |
483 } | |
484 | |
396 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( | 485 ui::EventRewriteStatus TouchExplorationController::InOneFingerPassthrough( |
397 const ui::TouchEvent& event, | 486 const ui::TouchEvent& event, |
398 scoped_ptr<ui::Event>* rewritten_event) { | 487 scoped_ptr<ui::Event>* rewritten_event) { |
399 ui::EventType type = event.type(); | 488 ui::EventType type = event.type(); |
400 | 489 |
401 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED || | 490 if (!(type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED || |
402 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) { | 491 type == ui::ET_TOUCH_MOVED || type == ui::ET_TOUCH_PRESSED)) { |
403 NOTREACHED() << "Unexpected event type received: " << event.name(); | 492 NOTREACHED() << "Unexpected event type received: " << event.name(); |
404 return ui::EVENT_REWRITE_CONTINUE; | 493 return ui::EVENT_REWRITE_CONTINUE; |
405 } | 494 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
479 state_ = TOUCH_EXPLORATION; | 568 state_ = TOUCH_EXPLORATION; |
480 VLOG_STATE(); | 569 VLOG_STATE(); |
481 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); | 570 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); |
482 last_touch_exploration_.reset(new TouchEvent(event)); | 571 last_touch_exploration_.reset(new TouchEvent(event)); |
483 return ui::EVENT_REWRITE_REWRITTEN; | 572 return ui::EVENT_REWRITE_REWRITTEN; |
484 } | 573 } |
485 return EVENT_REWRITE_DISCARD; | 574 return EVENT_REWRITE_DISCARD; |
486 } | 575 } |
487 | 576 |
488 void TouchExplorationController::PlaySoundForTimer() { | 577 void TouchExplorationController::PlaySoundForTimer() { |
489 delegate_->PlayVolumeAdjustSound(); | 578 delegate_->PlayVolumeAdjustEarcon(); |
490 } | 579 } |
491 | 580 |
492 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( | 581 ui::EventRewriteStatus TouchExplorationController::InSlideGesture( |
493 const ui::TouchEvent& event, | 582 const ui::TouchEvent& event, |
494 scoped_ptr<ui::Event>* rewritten_event) { | 583 scoped_ptr<ui::Event>* rewritten_event) { |
495 // The timer should not fire when sliding. | 584 // The timer should not fire when sliding. |
496 if (tap_timer_.IsRunning()) | 585 if (tap_timer_.IsRunning()) |
497 tap_timer_.Stop(); | 586 tap_timer_.Stop(); |
498 | 587 |
499 ui::EventType type = event.type(); | 588 ui::EventType type = event.type(); |
(...skipping 19 matching lines...) Expand all Loading... | |
519 return EVENT_REWRITE_DISCARD; | 608 return EVENT_REWRITE_DISCARD; |
520 } | 609 } |
521 | 610 |
522 // This can occur if the user leaves the screen edge and then returns to it to | 611 // This can occur if the user leaves the screen edge and then returns to it to |
523 // continue adjusting the sound. | 612 // continue adjusting the sound. |
524 if (!sound_timer_.IsRunning()) { | 613 if (!sound_timer_.IsRunning()) { |
525 sound_timer_.Start(FROM_HERE, | 614 sound_timer_.Start(FROM_HERE, |
526 kSoundDelay, | 615 kSoundDelay, |
527 this, | 616 this, |
528 &ui::TouchExplorationController::PlaySoundForTimer); | 617 &ui::TouchExplorationController::PlaySoundForTimer); |
529 delegate_->PlayVolumeAdjustSound(); | 618 delegate_->PlayVolumeAdjustEarcon(); |
530 } | 619 } |
531 | 620 |
532 // There should not be more than one finger down. | 621 // There should not be more than one finger down. |
533 DCHECK(current_touch_ids_.size() <= 1); | 622 DCHECK(current_touch_ids_.size() <= 1); |
534 if (type == ui::ET_TOUCH_MOVED) { | 623 if (type == ui::ET_TOUCH_MOVED) { |
535 gesture_provider_.OnTouchEvent(event); | 624 gesture_provider_.OnTouchEvent(event); |
536 gesture_provider_.OnTouchEventAck(false); | 625 gesture_provider_.OnTouchEventAck(false); |
537 } | 626 } |
538 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { | 627 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { |
539 gesture_provider_.OnTouchEvent(event); | 628 gesture_provider_.OnTouchEvent(event); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
582 last_touch_exploration_->location(); | 671 last_touch_exploration_->location(); |
583 scoped_ptr<ui::TouchEvent> passthrough_press( | 672 scoped_ptr<ui::TouchEvent> passthrough_press( |
584 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, | 673 new ui::TouchEvent(ui::ET_TOUCH_PRESSED, |
585 last_touch_exploration_->location(), | 674 last_touch_exploration_->location(), |
586 last_unused_finger_event_->touch_id(), | 675 last_unused_finger_event_->touch_id(), |
587 Now())); | 676 Now())); |
588 DispatchEvent(passthrough_press.get()); | 677 DispatchEvent(passthrough_press.get()); |
589 return; | 678 return; |
590 } | 679 } |
591 case SINGLE_TAP_PRESSED: | 680 case SINGLE_TAP_PRESSED: |
681 if (passthrough_timer_.IsRunning()) | |
682 return; | |
592 case GESTURE_IN_PROGRESS: | 683 case GESTURE_IN_PROGRESS: |
593 // Discard any pending gestures. | 684 // Discard any pending gestures. |
594 delete gesture_provider_.GetAndResetPendingGestures(); | 685 delete gesture_provider_.GetAndResetPendingGestures(); |
595 state_ = TOUCH_EXPLORATION; | 686 state_ = TOUCH_EXPLORATION; |
596 VLOG_STATE(); | 687 VLOG_STATE(); |
597 break; | 688 break; |
598 default: | 689 default: |
599 return; | 690 return; |
600 } | 691 } |
601 EnterTouchToMouseMode(); | 692 EnterTouchToMouseMode(); |
602 scoped_ptr<ui::Event> mouse_move = | 693 scoped_ptr<ui::Event> mouse_move = |
603 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); | 694 CreateMouseMoveEvent(initial_press_->location(), initial_press_->flags()); |
604 DispatchEvent(mouse_move.get()); | 695 DispatchEvent(mouse_move.get()); |
605 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); | 696 last_touch_exploration_.reset(new TouchEvent(*initial_press_)); |
606 } | 697 } |
607 | 698 |
699 void TouchExplorationController::OnPassthroughTimerFired() { | |
700 // The long press timer should only be running if one finger is in the corner | |
aboxhall
2014/08/06 21:03:12
I see why this comment was added, but I think it's
lisayin
2014/08/06 21:48:23
Done.
| |
701 // ready for corner passthrough | |
702 | |
703 // Check that initial press isn't null and that the id of the initial press | |
704 // still exists in touch_locations_. | |
705 if (!initial_press_ || | |
706 touch_locations_.end() == | |
707 touch_locations_.find(initial_press_->touch_id())) | |
708 return; | |
aboxhall
2014/08/06 21:03:12
Is this an error/shouldn't happen condition? Also,
lisayin
2014/08/06 21:48:22
Done.
| |
709 | |
710 gfx::Point location = | |
711 ToRoundedPoint(touch_locations_[initial_press_->touch_id()]); | |
712 int corner = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); | |
713 if (corner != BOTTOM_LEFT_CORNER && corner != BOTTOM_RIGHT_CORNER) | |
714 return; | |
715 | |
716 if (sound_timer_.IsRunning()) | |
717 sound_timer_.Stop(); | |
718 delegate_->PlayPassthroughEarcon(); | |
719 delete gesture_provider_.GetAndResetPendingGestures(); | |
720 state_ = CORNER_PASSTHROUGH; | |
721 VLOG_STATE(); | |
722 return; | |
723 } | |
724 | |
608 void TouchExplorationController::DispatchEvent(ui::Event* event) { | 725 void TouchExplorationController::DispatchEvent(ui::Event* event) { |
609 ui::EventDispatchDetails result ALLOW_UNUSED = | 726 ui::EventDispatchDetails result ALLOW_UNUSED = |
610 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); | 727 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); |
611 } | 728 } |
612 | 729 |
613 void TouchExplorationController::OnGestureEvent( | 730 void TouchExplorationController::OnGestureEvent( |
614 ui::GestureEvent* gesture) { | 731 ui::GestureEvent* gesture) { |
615 CHECK(gesture->IsGestureEvent()); | 732 CHECK(gesture->IsGestureEvent()); |
616 ui::EventType type = gesture->type(); | 733 ui::EventType type = gesture->type(); |
617 if (VLOG_on_) | 734 if (VLOG_on_) |
(...skipping 21 matching lines...) Expand all Loading... | |
639 } | 756 } |
640 } | 757 } |
641 } | 758 } |
642 | 759 |
643 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { | 760 void TouchExplorationController::SideSlideControl(ui::GestureEvent* gesture) { |
644 ui::EventType type = gesture->type(); | 761 ui::EventType type = gesture->type(); |
645 if (!gesture->IsScrollGestureEvent()) | 762 if (!gesture->IsScrollGestureEvent()) |
646 return; | 763 return; |
647 | 764 |
648 if (type == ET_GESTURE_SCROLL_BEGIN) { | 765 if (type == ET_GESTURE_SCROLL_BEGIN) { |
649 delegate_->PlayVolumeAdjustSound(); | 766 delegate_->PlayVolumeAdjustEarcon(); |
650 } | 767 } |
651 | 768 |
652 if (type == ET_GESTURE_SCROLL_END) { | 769 if (type == ET_GESTURE_SCROLL_END) { |
653 if (sound_timer_.IsRunning()) | 770 if (sound_timer_.IsRunning()) |
654 sound_timer_.Stop(); | 771 sound_timer_.Stop(); |
655 delegate_->PlayVolumeAdjustSound(); | 772 delegate_->PlayVolumeAdjustEarcon(); |
656 } | 773 } |
657 | 774 |
658 // If the user is in the corner of the right side of the screen, the volume | 775 // 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 | 776 // 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 | 777 // 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 | 778 // their finger along the right side of the screen. Volume is relative to |
662 // where they are on the right side of the screen. | 779 // where they are on the right side of the screen. |
663 gfx::Point location = gesture->location(); | 780 gfx::Point location = gesture->location(); |
664 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); | 781 int edge = FindEdgesWithinBounds(location, kSlopDistanceFromEdge); |
665 if (!(edge & RIGHT_EDGE)) | 782 if (!(edge & RIGHT_EDGE)) |
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
792 void TouchExplorationController::EnterTouchToMouseMode() { | 909 void TouchExplorationController::EnterTouchToMouseMode() { |
793 aura::client::CursorClient* cursor_client = | 910 aura::client::CursorClient* cursor_client = |
794 aura::client::GetCursorClient(root_window_); | 911 aura::client::GetCursorClient(root_window_); |
795 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) | 912 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) |
796 cursor_client->EnableMouseEvents(); | 913 cursor_client->EnableMouseEvents(); |
797 if (cursor_client && cursor_client->IsCursorVisible()) | 914 if (cursor_client && cursor_client->IsCursorVisible()) |
798 cursor_client->HideCursor(); | 915 cursor_client->HideCursor(); |
799 } | 916 } |
800 | 917 |
801 void TouchExplorationController::ResetToNoFingersDown() { | 918 void TouchExplorationController::ResetToNoFingersDown() { |
802 ProcessGestureEvents(); | 919 if (passthrough_timer_.IsRunning()) |
aboxhall
2014/08/06 21:03:12
Note that in each of these cases, the IsRunning()
lisayin
2014/08/06 21:48:23
Done.
| |
920 passthrough_timer_.Stop(); | |
803 if (sound_timer_.IsRunning()) | 921 if (sound_timer_.IsRunning()) |
804 sound_timer_.Stop(); | 922 sound_timer_.Stop(); |
923 if (tap_timer_.IsRunning()) | |
924 tap_timer_.Stop(); | |
925 ProcessGestureEvents(); | |
805 state_ = NO_FINGERS_DOWN; | 926 state_ = NO_FINGERS_DOWN; |
806 VLOG_STATE(); | 927 VLOG_STATE(); |
807 if (tap_timer_.IsRunning()) | 928 |
808 tap_timer_.Stop(); | |
809 } | 929 } |
810 | 930 |
811 void TouchExplorationController::VlogState(const char* function_name) { | 931 void TouchExplorationController::VlogState(const char* function_name) { |
812 if (!VLOG_on_) | 932 if (!VLOG_on_) |
813 return; | 933 return; |
814 if (prev_state_ == state_) | 934 if (prev_state_ == state_) |
815 return; | 935 return; |
816 prev_state_ = state_; | 936 prev_state_ = state_; |
817 const char* state_string = EnumStateToString(state_); | 937 const char* state_string = EnumStateToString(state_); |
818 VLOG(0) << "\n Function name: " << function_name | 938 VLOG(0) << "\n Function name: " << function_name |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
862 case DOUBLE_TAP_PENDING: | 982 case DOUBLE_TAP_PENDING: |
863 return "DOUBLE_TAP_PENDING"; | 983 return "DOUBLE_TAP_PENDING"; |
864 case TOUCH_RELEASE_PENDING: | 984 case TOUCH_RELEASE_PENDING: |
865 return "TOUCH_RELEASE_PENDING"; | 985 return "TOUCH_RELEASE_PENDING"; |
866 case TOUCH_EXPLORATION: | 986 case TOUCH_EXPLORATION: |
867 return "TOUCH_EXPLORATION"; | 987 return "TOUCH_EXPLORATION"; |
868 case GESTURE_IN_PROGRESS: | 988 case GESTURE_IN_PROGRESS: |
869 return "GESTURE_IN_PROGRESS"; | 989 return "GESTURE_IN_PROGRESS"; |
870 case TOUCH_EXPLORE_SECOND_PRESS: | 990 case TOUCH_EXPLORE_SECOND_PRESS: |
871 return "TOUCH_EXPLORE_SECOND_PRESS"; | 991 return "TOUCH_EXPLORE_SECOND_PRESS"; |
992 case CORNER_PASSTHROUGH: | |
993 return "CORNER_PASSTHROUGH"; | |
872 case SLIDE_GESTURE: | 994 case SLIDE_GESTURE: |
873 return "SLIDE_GESTURE"; | 995 return "SLIDE_GESTURE"; |
874 case ONE_FINGER_PASSTHROUGH: | 996 case ONE_FINGER_PASSTHROUGH: |
875 return "ONE_FINGER_PASSTHROUGH"; | 997 return "ONE_FINGER_PASSTHROUGH"; |
876 case WAIT_FOR_ONE_FINGER: | 998 case WAIT_FOR_ONE_FINGER: |
877 return "WAIT_FOR_ONE_FINGER"; | 999 return "WAIT_FOR_ONE_FINGER"; |
878 } | 1000 } |
879 return "Not a state"; | 1001 return "Not a state"; |
880 } | 1002 } |
881 | 1003 |
882 } // namespace ui | 1004 } // namespace ui |
OLD | NEW |