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

Side by Side Diff: ui/chromeos/touch_exploration_controller.cc

Issue 330763007: Swipe Gestures for Accessibility (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gesture-vlogs
Patch Set: Rebased off Master Created 6 years, 6 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"
(...skipping 21 matching lines...) Expand all
32 // until all fingers are released. 32 // until all fingers are released.
33 const int kTouchIdNone = -1; 33 const int kTouchIdNone = -1;
34 } // namespace 34 } // namespace
35 35
36 TouchExplorationController::TouchExplorationController( 36 TouchExplorationController::TouchExplorationController(
37 aura::Window* root_window) 37 aura::Window* root_window)
38 : root_window_(root_window), 38 : root_window_(root_window),
39 initial_touch_id_passthrough_mapping_(kTouchIdUnassigned), 39 initial_touch_id_passthrough_mapping_(kTouchIdUnassigned),
40 state_(NO_FINGERS_DOWN), 40 state_(NO_FINGERS_DOWN),
41 event_handler_for_testing_(NULL), 41 event_handler_for_testing_(NULL),
42 gesture_provider_(this),
42 prev_state_(NO_FINGERS_DOWN) { 43 prev_state_(NO_FINGERS_DOWN) {
43 CHECK(root_window); 44 CHECK(root_window);
44 root_window->GetHost()->GetEventSource()->AddEventRewriter(this); 45 root_window->GetHost()->GetEventSource()->AddEventRewriter(this);
45 } 46 }
46 47
47 TouchExplorationController::~TouchExplorationController() { 48 TouchExplorationController::~TouchExplorationController() {
48 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this); 49 root_window_->GetHost()->GetEventSource()->RemoveEventRewriter(this);
49 } 50 }
50 51
51 void TouchExplorationController::CallTapTimerNowForTesting() { 52 void TouchExplorationController::CallTapTimerNowForTesting() {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 case NO_FINGERS_DOWN: 121 case NO_FINGERS_DOWN:
121 return InNoFingersDown(touch_event, rewritten_event); 122 return InNoFingersDown(touch_event, rewritten_event);
122 case SINGLE_TAP_PRESSED: 123 case SINGLE_TAP_PRESSED:
123 return InSingleTapPressed(touch_event, rewritten_event); 124 return InSingleTapPressed(touch_event, rewritten_event);
124 case SINGLE_TAP_RELEASED: 125 case SINGLE_TAP_RELEASED:
125 return InSingleTapReleased(touch_event, rewritten_event); 126 return InSingleTapReleased(touch_event, rewritten_event);
126 case DOUBLE_TAP_PRESSED: 127 case DOUBLE_TAP_PRESSED:
127 return InDoubleTapPressed(touch_event, rewritten_event); 128 return InDoubleTapPressed(touch_event, rewritten_event);
128 case TOUCH_EXPLORATION: 129 case TOUCH_EXPLORATION:
129 return InTouchExploration(touch_event, rewritten_event); 130 return InTouchExploration(touch_event, rewritten_event);
131 case GESTURE_IN_PROGRESS:
132 return InGestureInProgress(touch_event, rewritten_event);
130 case PASSTHROUGH_MINUS_ONE: 133 case PASSTHROUGH_MINUS_ONE:
131 return InPassthroughMinusOne(touch_event, rewritten_event); 134 return InPassthroughMinusOne(touch_event, rewritten_event);
132 case TOUCH_EXPLORE_SECOND_PRESS: 135 case TOUCH_EXPLORE_SECOND_PRESS:
133 return InTouchExploreSecondPress(touch_event, rewritten_event); 136 return InTouchExploreSecondPress(touch_event, rewritten_event);
134 } 137 }
135 138
136 NOTREACHED(); 139 NOTREACHED();
137 return ui::EVENT_REWRITE_CONTINUE; 140 return ui::EVENT_REWRITE_CONTINUE;
138 } 141 }
139 142
140 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent( 143 ui::EventRewriteStatus TouchExplorationController::NextDispatchEvent(
141 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) { 144 const ui::Event& last_event, scoped_ptr<ui::Event>* new_event) {
142 NOTREACHED(); 145 NOTREACHED();
143 return ui::EVENT_REWRITE_CONTINUE; 146 return ui::EVENT_REWRITE_CONTINUE;
144 } 147 }
145 148
146 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown( 149 ui::EventRewriteStatus TouchExplorationController::InNoFingersDown(
147 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 150 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
148 const ui::EventType type = event.type(); 151 const ui::EventType type = event.type();
149 if (type == ui::ET_TOUCH_PRESSED) { 152 if (type == ui::ET_TOUCH_PRESSED) {
150 initial_press_.reset(new TouchEvent(event)); 153 initial_press_.reset(new TouchEvent(event));
151 tap_timer_.Start(FROM_HERE, 154 tap_timer_.Start(FROM_HERE,
152 gesture_detector_config_.double_tap_timeout, 155 gesture_detector_config_.double_tap_timeout,
153 this, 156 this,
154 &TouchExplorationController::OnTapTimerFired); 157 &TouchExplorationController::OnTapTimerFired);
158 gesture_provider_.OnTouchEvent(event);
159 gesture_provider_.OnTouchEventAck(false);
155 state_ = SINGLE_TAP_PRESSED; 160 state_ = SINGLE_TAP_PRESSED;
156 VLOG_STATE(); 161 VLOG_STATE();
157 return ui::EVENT_REWRITE_DISCARD; 162 return ui::EVENT_REWRITE_DISCARD;
158 } 163 }
159 164
160 NOTREACHED(); 165 NOTREACHED();
161 return ui::EVENT_REWRITE_CONTINUE; 166 return ui::EVENT_REWRITE_CONTINUE;
162 } 167 }
163 168
164 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed( 169 ui::EventRewriteStatus TouchExplorationController::InSingleTapPressed(
165 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 170 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
166 const ui::EventType type = event.type(); 171 const ui::EventType type = event.type();
167 172
168 if (type == ui::ET_TOUCH_PRESSED) { 173 if (type == ui::ET_TOUCH_PRESSED) {
169 // Adding a second finger within the timeout period switches to 174 // Adding a second finger within the timeout period switches to
170 // passthrough. 175 // passthrough.
171 state_ = PASSTHROUGH_MINUS_ONE; 176 state_ = PASSTHROUGH_MINUS_ONE;
172 return InPassthroughMinusOne(event, rewritten_event); 177 return InPassthroughMinusOne(event, rewritten_event);
173 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 178 } else if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
174 DCHECK_EQ(0U, current_touch_ids_.size()); 179 DCHECK_EQ(0U, current_touch_ids_.size());
175 state_ = SINGLE_TAP_RELEASED; 180 state_ = SINGLE_TAP_RELEASED;
176 VLOG_STATE(); 181 VLOG_STATE();
177 return EVENT_REWRITE_DISCARD; 182 return EVENT_REWRITE_DISCARD;
178 } else if (type == ui::ET_TOUCH_MOVED) { 183 } else if (type == ui::ET_TOUCH_MOVED) {
179 // If the user moves far enough from the initial touch location (outside 184 // If the user moves fast enough from the initial touch location,
180 // the "slop" region, jump to the touch exploration mode early. 185 // start gesture detection
181 // TODO(evy, lisayin): Add gesture recognition here instead - 186 float delta_time =
182 // we should probably jump to gesture mode here if the velocity is 187 (event.time_stamp() - initial_press_->time_stamp()).InSecondsF();
183 // high enough, and touch exploration if the velocity is lower. 188 float delta_distance =
184 float delta = (event.location() - initial_press_->location()).Length(); 189 (event.location() - initial_press_->location()).Length();
185 if (delta > gesture_detector_config_.touch_slop) { 190 float velocity = delta_distance / delta_time;
191 VLOG(0) << "\n Delta time: " << delta_time
192 << "\n Delta distance: " << delta_distance
193 << "\n Velocity of click: " << velocity
194 << "\n Minimum swipe velocity: "
195 << gesture_detector_config_.minimum_swipe_velocity;
196 if (velocity > gesture_detector_config_.minimum_swipe_velocity) {
197 gesture_provider_.OnTouchEvent(event);
dmazzoni 2014/06/20 16:26:54 I think you're forwarding the same event to the ge
lisayin 2014/06/20 21:34:39 Fixed.
198 gesture_provider_.OnTouchEventAck(false);
199 state_ = GESTURE_IN_PROGRESS;
200 VLOG_STATE();
201 return InGestureInProgress(event, rewritten_event);
202 }
203 // Otherwise, if the user moves far enough from the initial touch location
204 // outside the "slop" region, jump to the touch exploration mode early.
205 else if (delta_distance > gesture_detector_config_.touch_slop) {
186 EnterTouchToMouseMode(); 206 EnterTouchToMouseMode();
187 state_ = TOUCH_EXPLORATION; 207 state_ = TOUCH_EXPLORATION;
188 VLOG_STATE(); 208 VLOG_STATE();
189 return InTouchExploration(event, rewritten_event); 209 return InTouchExploration(event, rewritten_event);
190 } 210 }
191 211
192 return EVENT_REWRITE_DISCARD; 212 return EVENT_REWRITE_DISCARD;
193 } 213 }
194 NOTREACHED() << "Unexpected event type received."; 214 NOTREACHED() << "Unexpected event type received.";
195 return ui::EVENT_REWRITE_CONTINUE; 215 return ui::EVENT_REWRITE_CONTINUE;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 NOTREACHED() << "Unexpected event type received."; 296 NOTREACHED() << "Unexpected event type received.";
277 return ui::EVENT_REWRITE_CONTINUE; 297 return ui::EVENT_REWRITE_CONTINUE;
278 } 298 }
279 299
280 // Rewrite as a mouse-move event. 300 // Rewrite as a mouse-move event.
281 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags()); 301 *rewritten_event = CreateMouseMoveEvent(event.location(), event.flags());
282 last_touch_exploration_.reset(new TouchEvent(event)); 302 last_touch_exploration_.reset(new TouchEvent(event));
283 return ui::EVENT_REWRITE_REWRITTEN; 303 return ui::EVENT_REWRITE_REWRITTEN;
284 } 304 }
285 305
306 ui::EventRewriteStatus TouchExplorationController::InGestureInProgress(
307 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
308 ui::EventType type = event.type();
309 gfx::PointF location = event.location_f();
310 if (type == ui::ET_TOUCH_PRESSED) {
311 return EVENT_REWRITE_DISCARD;
312 }
313 if (type == ui::ET_TOUCH_MOVED) {
314 gesture_provider_.OnTouchEvent(event);
315 gesture_provider_.OnTouchEventAck(false);
316 }
317 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
318 gesture_provider_.OnTouchEvent(event);
319 gesture_provider_.OnTouchEventAck(true);
dmazzoni 2014/06/20 16:26:54 Why true here and false otherwise?
lisayin 2014/06/20 21:34:39 To be honest, it was something that I was just try
320 if (current_touch_ids_.size() == 0)
321 ResetToNoFingersDown();
322 }
323 return ui::EVENT_REWRITE_DISCARD;
324 }
325
286 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne( 326 ui::EventRewriteStatus TouchExplorationController::InPassthroughMinusOne(
287 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) { 327 const ui::TouchEvent& event, scoped_ptr<ui::Event>* rewritten_event) {
288 ui::EventType type = event.type(); 328 ui::EventType type = event.type();
289 gfx::PointF location = event.location_f(); 329 gfx::PointF location = event.location_f();
290 330
291 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) { 331 if (type == ui::ET_TOUCH_RELEASED || type == ui::ET_TOUCH_CANCELLED) {
292 if (current_touch_ids_.size() == 0) 332 if (current_touch_ids_.size() == 0)
293 ResetToNoFingersDown(); 333 ResetToNoFingersDown();
294 334
295 if (initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) { 335 if (initial_touch_id_passthrough_mapping_ == kTouchIdUnassigned) {
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 void TouchExplorationController::DispatchEvent(ui::Event* event) { 435 void TouchExplorationController::DispatchEvent(ui::Event* event) {
396 if (event_handler_for_testing_) { 436 if (event_handler_for_testing_) {
397 event_handler_for_testing_->OnEvent(event); 437 event_handler_for_testing_->OnEvent(event);
398 return; 438 return;
399 } 439 }
400 440
401 ui::EventDispatchDetails result ALLOW_UNUSED = 441 ui::EventDispatchDetails result ALLOW_UNUSED =
402 root_window_->GetHost()->dispatcher()->OnEventFromSource(event); 442 root_window_->GetHost()->dispatcher()->OnEventFromSource(event);
403 } 443 }
404 444
445 void TouchExplorationController::OnGestureEvent(
446 ui::GestureEvent* gesture) {
447 std::string message = "\n Gesture Triggered: ";
448 switch (gesture->type()) {
449 case ET_GESTURE_SHOW_PRESS:
450 message += "ET_GESTURE_SHOW_PRESS";
451 break;
452 case ET_GESTURE_SWIPE:
453 message += "ET_GESTURE_SWIPE";
454 break;
455 case ET_GESTURE_LONG_TAP:
456 message += "ET_GESTURE_LONG_TAP";
457 break;
458 case ET_GESTURE_LONG_PRESS:
459 message += "ET_GESTURE_LONG_PRESS";
460 break;
461 case ET_GESTURE_PINCH_UPDATE:
462 message += "ET_GESTURE_PINCH_UPDATE";
463 break;
464 case ET_GESTURE_PINCH_END:
465 message += "ET_GESTURE_PINCH_END";
466 break;
467 default:
468 return;
469 }
470 VLOG(0) << message;
471 }
472
405 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent( 473 scoped_ptr<ui::Event> TouchExplorationController::CreateMouseMoveEvent(
406 const gfx::PointF& location, 474 const gfx::PointF& location,
407 int flags) { 475 int flags) {
408 return scoped_ptr<ui::Event>( 476 return scoped_ptr<ui::Event>(
409 new ui::MouseEvent( 477 new ui::MouseEvent(
410 ui::ET_MOUSE_MOVED, 478 ui::ET_MOUSE_MOVED,
411 location, 479 location,
412 location, 480 location,
413 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY, 481 flags | ui::EF_IS_SYNTHESIZED | ui::EF_TOUCH_ACCESSIBILITY,
414 0)); 482 0));
415 } 483 }
416 484
417 void TouchExplorationController::EnterTouchToMouseMode() { 485 void TouchExplorationController::EnterTouchToMouseMode() {
418 aura::client::CursorClient* cursor_client = 486 aura::client::CursorClient* cursor_client =
419 aura::client::GetCursorClient(root_window_); 487 aura::client::GetCursorClient(root_window_);
420 if (cursor_client && !cursor_client->IsMouseEventsEnabled()) 488 if (cursor_client && !cursor_client->IsMouseEventsEnabled())
421 cursor_client->EnableMouseEvents(); 489 cursor_client->EnableMouseEvents();
422 if (cursor_client && cursor_client->IsCursorVisible()) 490 if (cursor_client && cursor_client->IsCursorVisible())
423 cursor_client->HideCursor(); 491 cursor_client->HideCursor();
424 } 492 }
425 493
426 void TouchExplorationController::ResetToNoFingersDown() { 494 void TouchExplorationController::ResetToNoFingersDown() {
495 gesture_provider_.GetAndResetPendingGestures();
427 state_ = NO_FINGERS_DOWN; 496 state_ = NO_FINGERS_DOWN;
428 initial_touch_id_passthrough_mapping_ = kTouchIdUnassigned; 497 initial_touch_id_passthrough_mapping_ = kTouchIdUnassigned;
429 VLOG_STATE(); 498 VLOG_STATE();
430 if (tap_timer_.IsRunning()) 499 if (tap_timer_.IsRunning())
431 tap_timer_.Stop(); 500 tap_timer_.Stop();
432 } 501 }
433 502
434 void TouchExplorationController::VlogState(const char* function_name) { 503 void TouchExplorationController::VlogState(const char* function_name) {
435 if (prev_state_ == state_) 504 if (prev_state_ == state_)
436 return; 505 return;
(...skipping 26 matching lines...) Expand all
463 case NO_FINGERS_DOWN: 532 case NO_FINGERS_DOWN:
464 return "NO_FINGERS_DOWN"; 533 return "NO_FINGERS_DOWN";
465 case SINGLE_TAP_PRESSED: 534 case SINGLE_TAP_PRESSED:
466 return "SINGLE_TAP_PRESSED"; 535 return "SINGLE_TAP_PRESSED";
467 case SINGLE_TAP_RELEASED: 536 case SINGLE_TAP_RELEASED:
468 return "SINGLE_TAP_RELEASED"; 537 return "SINGLE_TAP_RELEASED";
469 case DOUBLE_TAP_PRESSED: 538 case DOUBLE_TAP_PRESSED:
470 return "DOUBLE_TAP_PRESSED"; 539 return "DOUBLE_TAP_PRESSED";
471 case TOUCH_EXPLORATION: 540 case TOUCH_EXPLORATION:
472 return "TOUCH_EXPLORATION"; 541 return "TOUCH_EXPLORATION";
542 case GESTURE_IN_PROGRESS:
543 return "GESTURE_IN_PROGRESS";
473 case PASSTHROUGH_MINUS_ONE: 544 case PASSTHROUGH_MINUS_ONE:
474 return "PASSTHROUGH_MINUS_ONE"; 545 return "PASSTHROUGH_MINUS_ONE";
475 case TOUCH_EXPLORE_SECOND_PRESS: 546 case TOUCH_EXPLORE_SECOND_PRESS:
476 return "TOUCH_EXPLORE_SECOND_PRESS"; 547 return "TOUCH_EXPLORE_SECOND_PRESS";
477 } 548 }
478 return "Not a state"; 549 return "Not a state";
479 } 550 }
480 551
481 std::string TouchExplorationController::EnumEventTypeToString( 552 std::string TouchExplorationController::EnumEventTypeToString(
482 ui::EventType type) { 553 ui::EventType type) {
483 // Add more cases later. For now, these are the most frequently seen 554 // Add more cases later. For now, these are the most frequently seen
484 // event types. 555 // event types.
485 switch (type) { 556 switch (type) {
486 case ET_TOUCH_RELEASED: 557 case ET_TOUCH_RELEASED:
487 return "ET_TOUCH_RELEASED"; 558 return "ET_TOUCH_RELEASED";
488 case ET_TOUCH_PRESSED: 559 case ET_TOUCH_PRESSED:
489 return "ET_TOUCH_PRESSED"; 560 return "ET_TOUCH_PRESSED";
490 case ET_TOUCH_MOVED: 561 case ET_TOUCH_MOVED:
491 return "ET_TOUCH_MOVED"; 562 return "ET_TOUCH_MOVED";
492 case ET_TOUCH_CANCELLED: 563 case ET_TOUCH_CANCELLED:
493 return "ET_TOUCH_CANCELLED"; 564 return "ET_TOUCH_CANCELLED";
494 default: 565 default:
495 return base::IntToString(type); 566 return base::IntToString(type);
496 } 567 }
497 } 568 }
498 569
499 } // namespace ui 570 } // namespace ui
OLDNEW
« no previous file with comments | « ui/chromeos/touch_exploration_controller.h ('k') | ui/chromeos/touch_exploration_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698