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

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

Issue 296403011: Support double-tap to click in touch accessibility controller. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address feedback 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 | Annotate | Revision Log
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/time/time.h" 7 #include "base/time/time.h"
8 #include "ui/aura/client/cursor_client.h" 8 #include "ui/aura/client/cursor_client.h"
9 #include "ui/aura/test/aura_test_base.h" 9 #include "ui/aura/test/aura_test_base.h"
10 #include "ui/aura/test/event_generator.h" 10 #include "ui/aura/test/event_generator.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 public: 62 public:
63 TouchExplorationTest() {} 63 TouchExplorationTest() {}
64 virtual ~TouchExplorationTest() {} 64 virtual ~TouchExplorationTest() {}
65 65
66 virtual void SetUp() OVERRIDE { 66 virtual void SetUp() OVERRIDE {
67 if (gfx::GetGLImplementation() == gfx::kGLImplementationNone) 67 if (gfx::GetGLImplementation() == gfx::kGLImplementationNone)
68 gfx::GLSurface::InitializeOneOffForTests(); 68 gfx::GLSurface::InitializeOneOffForTests();
69 aura::test::AuraTestBase::SetUp(); 69 aura::test::AuraTestBase::SetUp();
70 cursor_client_.reset(new aura::test::TestCursorClient(root_window())); 70 cursor_client_.reset(new aura::test::TestCursorClient(root_window()));
71 root_window()->AddPreTargetHandler(&event_capturer_); 71 root_window()->AddPreTargetHandler(&event_capturer_);
72 generator_.reset(new aura::test::EventGenerator(root_window()));
73 generator_->UseSimulatedTime();
74 cursor_client()->ShowCursor();
75 cursor_client()->DisableMouseEvents();
72 } 76 }
73 77
74 virtual void TearDown() OVERRIDE { 78 virtual void TearDown() OVERRIDE {
75 root_window()->RemovePreTargetHandler(&event_capturer_); 79 root_window()->RemovePreTargetHandler(&event_capturer_);
76 SwitchTouchExplorationMode(false); 80 SwitchTouchExplorationMode(false);
77 cursor_client_.reset(); 81 cursor_client_.reset();
78 aura::test::AuraTestBase::TearDown(); 82 aura::test::AuraTestBase::TearDown();
79 } 83 }
80 84
85 protected:
86 aura::client::CursorClient* cursor_client() { return cursor_client_.get(); }
87
81 const ScopedVector<ui::LocatedEvent>& GetCapturedEvents() { 88 const ScopedVector<ui::LocatedEvent>& GetCapturedEvents() {
82 return event_capturer_.captured_events(); 89 return event_capturer_.captured_events();
83 } 90 }
84 91
92 std::vector<ui::LocatedEvent*> GetCapturedEventsOfType(int type) {
93 const ScopedVector<ui::LocatedEvent>& all_events = GetCapturedEvents();
94 std::vector<ui::LocatedEvent*> events;
95 for (size_t i = 0; i < all_events.size(); ++i) {
96 if (type == all_events[i]->type())
97 events.push_back(all_events[i]);
98 }
99 return events;
100 }
101
85 void ClearCapturedEvents() { 102 void ClearCapturedEvents() {
86 event_capturer_.Reset(); 103 event_capturer_.Reset();
87 } 104 }
88 105
89 protected: 106 void AdvanceSimulatedTimePastTapDelay() {
90 aura::client::CursorClient* cursor_client() { return cursor_client_.get(); } 107 generator_->AdvanceSimulatedTimeBy(
108 base::TimeDelta::FromMilliseconds(1000));
109 touch_exploration_controller_->CallTapTimerNowForTesting();
110 }
91 111
92 void SwitchTouchExplorationMode(bool on) { 112 void SwitchTouchExplorationMode(bool on) {
93 if (!on && touch_exploration_controller_.get()) 113 if (!on && touch_exploration_controller_.get()) {
94 touch_exploration_controller_.reset(); 114 touch_exploration_controller_.reset();
95 else if (on && !touch_exploration_controller_.get()) 115 } else if (on && !touch_exploration_controller_.get()) {
96 touch_exploration_controller_.reset( 116 touch_exploration_controller_.reset(
97 new ui::TouchExplorationController(root_window())); 117 new ui::TouchExplorationController(root_window()));
118 touch_exploration_controller_->SetEventHandlerForTesting(
119 &event_capturer_);
120 cursor_client()->ShowCursor();
121 cursor_client()->DisableMouseEvents();
122 }
98 } 123 }
99 124
100 bool IsInTouchToMouseMode() { 125 bool IsInTouchToMouseMode() {
101 aura::client::CursorClient* cursor_client = 126 aura::client::CursorClient* cursor_client =
102 aura::client::GetCursorClient(root_window()); 127 aura::client::GetCursorClient(root_window());
103 return cursor_client && 128 return cursor_client &&
104 cursor_client->IsMouseEventsEnabled() && 129 cursor_client->IsMouseEventsEnabled() &&
105 !cursor_client->IsCursorVisible(); 130 !cursor_client->IsCursorVisible();
106 } 131 }
107 132
133 bool IsInNoFingersDownState() {
134 return touch_exploration_controller_->IsInNoFingersDownStateForTesting();
135 }
136
137 protected:
138 scoped_ptr<aura::test::EventGenerator> generator_;
139 ui::GestureDetector::Config gesture_detector_config_;
140
108 private: 141 private:
109 EventCapturer event_capturer_; 142 EventCapturer event_capturer_;
110 scoped_ptr<ui::TouchExplorationController> touch_exploration_controller_; 143 scoped_ptr<ui::TouchExplorationController> touch_exploration_controller_;
111 scoped_ptr<aura::test::TestCursorClient> cursor_client_; 144 scoped_ptr<aura::test::TestCursorClient> cursor_client_;
112 145
113 DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest); 146 DISALLOW_COPY_AND_ASSIGN(TouchExplorationTest);
114 }; 147 };
115 148
116 // Executes a number of assertions to confirm that |e1| and |e2| are touch 149 // Executes a number of assertions to confirm that |e1| and |e2| are touch
117 // events and are equal to each other. 150 // events and are equal to each other.
(...skipping 25 matching lines...) Expand all
143 #define CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(e1, e2) \ 176 #define CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(e1, e2) \
144 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreTouchAndEqual(e1, e2)) 177 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreTouchAndEqual(e1, e2))
145 178
146 #define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \ 179 #define CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(e1, e2) \
147 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2)) 180 ASSERT_NO_FATAL_FAILURE(ConfirmEventsAreMouseAndEqual(e1, e2))
148 181
149 // TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit 182 // TODO(mfomitchev): Need to investigate why we don't get mouse enter/exit
150 // events when running these tests as part of ui_unittests. We do get them when 183 // events when running these tests as part of ui_unittests. We do get them when
151 // the tests are run as part of ash unit tests. 184 // the tests are run as part of ash unit tests.
152 185
153 // Simple test to confirm one-finger touches are transformed into mouse moves. 186 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterPressAndDelay) {
154 TEST_F(TouchExplorationTest, OneFingerTouch) {
155 SwitchTouchExplorationMode(true); 187 SwitchTouchExplorationMode(true);
156 cursor_client()->ShowCursor(); 188 EXPECT_FALSE(IsInTouchToMouseMode());
157 cursor_client()->DisableMouseEvents(); 189 generator_->PressTouch();
158 aura::test::EventGenerator generator(root_window()); 190 AdvanceSimulatedTimePastTapDelay();
159 gfx::Point location_start = generator.current_location();
160 gfx::Point location_end(11, 12);
161 generator.PressTouch();
162 EXPECT_TRUE(IsInTouchToMouseMode()); 191 EXPECT_TRUE(IsInTouchToMouseMode());
163 generator.MoveTouch(location_end); 192 }
164 // Confirm the actual mouse moves are unaffected. 193
194 TEST_F(TouchExplorationTest, EntersTouchToMouseModeAfterMoveOutsideSlop) {
195 int slop = gesture_detector_config_.touch_slop;
196 int half_slop = slop / 2;
197
198 SwitchTouchExplorationMode(true);
199 EXPECT_FALSE(IsInTouchToMouseMode());
200 generator_->set_current_location(gfx::Point(11, 12));
201 generator_->PressTouch();
202 generator_->MoveTouch(gfx::Point(11 + half_slop, 12));
203 EXPECT_FALSE(IsInTouchToMouseMode());
204 generator_->MoveTouch(gfx::Point(11, 12 + half_slop));
205 EXPECT_FALSE(IsInTouchToMouseMode());
206 generator_->MoveTouch(gfx::Point(11 + slop + 1, 12));
207 EXPECT_TRUE(IsInTouchToMouseMode());
208 }
209
210 TEST_F(TouchExplorationTest, OneFingerTap) {
211 SwitchTouchExplorationMode(true);
212 gfx::Point location(11, 12);
213 generator_->set_current_location(location);
214 generator_->PressTouch();
215 generator_->ReleaseTouch();
216 AdvanceSimulatedTimePastTapDelay();
217
218 std::vector<ui::LocatedEvent*> events =
219 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
220 ASSERT_EQ(1U, events.size());
221
222 EXPECT_EQ(location, events[0]->location());
223 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
224 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
225 EXPECT_TRUE(IsInNoFingersDownState());
226 }
227
228 TEST_F(TouchExplorationTest, ActualMouseMovesUnaffected) {
229 SwitchTouchExplorationMode(true);
230
231 gfx::Point location_start(11, 12);
232 gfx::Point location_end(13, 14);
233 generator_->set_current_location(location_start);
234 generator_->PressTouch();
235 AdvanceSimulatedTimePastTapDelay();
236 generator_->MoveTouch(location_end);
237
238 gfx::Point location_real_mouse_move(15, 16);
165 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, 239 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED,
166 gfx::Point(13, 14), 240 location_real_mouse_move,
167 gfx::Point(13, 14), 241 location_real_mouse_move,
168 0, 242 0,
169 0); 243 0);
170 generator.Dispatch(&mouse_move); 244 generator_->Dispatch(&mouse_move);
171 generator.ReleaseTouch(); 245 generator_->ReleaseTouch();
172 246
173 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 247 std::vector<ui::LocatedEvent*> events =
174 ScopedVector<ui::LocatedEvent>::const_iterator it; 248 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
175 // TODO(mfomitchev): mouse enter/exit events 249 ASSERT_EQ(4U, events.size());
176 int num_mouse_moves = 0; 250
177 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 251 EXPECT_EQ(location_start, events[0]->location());
178 int type = (*it)->type(); 252 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
179 // Ignore enter and exit mouse events synthesized when the mouse cursor is 253 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
180 // shown or hidden. 254
181 if (type == ui::ET_MOUSE_ENTERED || type == ui::ET_MOUSE_EXITED) 255 EXPECT_EQ(location_end, events[1]->location());
182 continue; 256 EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED);
183 EXPECT_EQ(ui::ET_MOUSE_MOVED, (*it)->type()); 257 EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
184 if (num_mouse_moves == 0) 258
185 EXPECT_EQ(location_start, (*it)->location()); 259 // The real mouse move goes through.
186 if (num_mouse_moves == 1 || num_mouse_moves == 3) 260 EXPECT_EQ(location_real_mouse_move, events[2]->location());
187 EXPECT_EQ(location_end, (*it)->location()); 261 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(events[2], &mouse_move);
188 if (num_mouse_moves == 2) 262 EXPECT_FALSE(events[2]->flags() & ui::EF_IS_SYNTHESIZED);
189 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(*it, &mouse_move); 263 EXPECT_FALSE(events[2]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
190 if (num_mouse_moves != 2) { 264
191 EXPECT_TRUE((*it)->flags() & ui::EF_IS_SYNTHESIZED); 265 // The touch release gets written as a mouse move.
192 EXPECT_TRUE((*it)->flags() & ui::EF_TOUCH_ACCESSIBILITY); 266 EXPECT_EQ(location_end, events[3]->location());
193 } 267 EXPECT_TRUE(events[3]->flags() & ui::EF_IS_SYNTHESIZED);
194 num_mouse_moves++; 268 EXPECT_TRUE(events[3]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
195 } 269 EXPECT_TRUE(IsInNoFingersDownState());
196 EXPECT_EQ(4, num_mouse_moves);
197 } 270 }
198 271
199 // Turn the touch exploration mode on in the middle of the touch gesture. 272 // Turn the touch exploration mode on in the middle of the touch gesture.
200 // Confirm that events from the finger which was touching when the mode was 273 // Confirm that events from the finger which was touching when the mode was
201 // turned on don't get rewritten. 274 // turned on don't get rewritten.
202 TEST_F(TouchExplorationTest, TurnOnMidTouch) { 275 TEST_F(TouchExplorationTest, TurnOnMidTouch) {
203 SwitchTouchExplorationMode(false); 276 SwitchTouchExplorationMode(false);
204 cursor_client()->ShowCursor(); 277 generator_->PressTouchId(1);
205 cursor_client()->DisableMouseEvents();
206 aura::test::EventGenerator generator(root_window());
207 generator.PressTouchId(1);
208 EXPECT_TRUE(cursor_client()->IsCursorVisible()); 278 EXPECT_TRUE(cursor_client()->IsCursorVisible());
209 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
210 ClearCapturedEvents(); 279 ClearCapturedEvents();
211 280
212 // Enable touch exploration mode while the first finger is touching the 281 // Enable touch exploration mode while the first finger is touching the
213 // screen. Ensure that subsequent events from that first finger are not 282 // screen. Ensure that subsequent events from that first finger are not
214 // affected by the touch exploration mode, while the touch events from another 283 // affected by the touch exploration mode, while the touch events from another
215 // finger get rewritten. 284 // finger get rewritten.
216 SwitchTouchExplorationMode(true); 285 SwitchTouchExplorationMode(true);
217 ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED, 286 ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED,
218 gfx::Point(11, 12), 287 gfx::Point(11, 12),
219 1, 288 1,
220 ui::EventTimeForNow()); 289 ui::EventTimeForNow());
221 generator.Dispatch(&touch_move); 290 generator_->Dispatch(&touch_move);
222 EXPECT_TRUE(cursor_client()->IsCursorVisible()); 291 EXPECT_TRUE(cursor_client()->IsCursorVisible());
223 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled()); 292 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
224 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 293 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
225 ASSERT_EQ(1u, captured_events.size()); 294 ASSERT_EQ(1u, captured_events.size());
226 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move); 295 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
227 ClearCapturedEvents(); 296 ClearCapturedEvents();
228 297
229 // The press from the second finger should get rewritten. 298 // The press from the second finger should get rewritten.
230 generator.PressTouchId(2); 299 generator_->PressTouchId(2);
300 AdvanceSimulatedTimePastTapDelay();
231 EXPECT_TRUE(IsInTouchToMouseMode()); 301 EXPECT_TRUE(IsInTouchToMouseMode());
232 // TODO(mfomitchev): mouse enter/exit events
233 ScopedVector<ui::LocatedEvent>::const_iterator it; 302 ScopedVector<ui::LocatedEvent>::const_iterator it;
234 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 303 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
235 if ((*it)->type() == ui::ET_MOUSE_MOVED) 304 if ((*it)->type() == ui::ET_MOUSE_MOVED)
236 break; 305 break;
237 } 306 }
238 EXPECT_NE(captured_events.end(), it); 307 EXPECT_NE(captured_events.end(), it);
239 ClearCapturedEvents(); 308 ClearCapturedEvents();
240 309
241 // The release of the first finger shouldn't be affected. 310 // The release of the first finger shouldn't be affected.
242 ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED, 311 ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED,
243 gfx::Point(11, 12), 312 gfx::Point(11, 12),
244 1, 313 1,
245 ui::EventTimeForNow()); 314 ui::EventTimeForNow());
246 generator.Dispatch(&touch_release); 315 generator_->Dispatch(&touch_release);
247 ASSERT_EQ(1u, captured_events.size()); 316 ASSERT_EQ(1u, captured_events.size());
248 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release); 317 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release);
249 ClearCapturedEvents(); 318 ClearCapturedEvents();
250 319
251 // The move and release from the second finger should get rewritten. 320 // The move and release from the second finger should get rewritten.
252 generator.MoveTouchId(gfx::Point(13, 14), 2); 321 generator_->MoveTouchId(gfx::Point(13, 14), 2);
253 generator.ReleaseTouchId(2); 322 generator_->ReleaseTouchId(2);
254 ASSERT_EQ(2u, captured_events.size()); 323 ASSERT_EQ(2u, captured_events.size());
255 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type()); 324 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[0]->type());
256 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type()); 325 EXPECT_EQ(ui::ET_MOUSE_MOVED, captured_events[1]->type());
326 EXPECT_TRUE(IsInNoFingersDownState());
257 } 327 }
258 328
259 TEST_F(TouchExplorationTest, TwoFingerTouch) { 329 TEST_F(TouchExplorationTest, TwoFingerTouch) {
260 SwitchTouchExplorationMode(true); 330 SwitchTouchExplorationMode(true);
261 aura::test::EventGenerator generator(root_window()); 331 generator_->PressTouchId(1);
262 generator.PressTouchId(1);
263 ClearCapturedEvents(); 332 ClearCapturedEvents();
264 333
265 // Confirm events from the second finger go through as is. 334 // Confirm events from the second finger go through as is.
266 cursor_client()->ShowCursor(); 335 ui::TouchEvent touch_press(
267 cursor_client()->DisableMouseEvents(); 336 ui::ET_TOUCH_PRESSED,
268 ui::TouchEvent touch_press(ui::ET_TOUCH_PRESSED, 337 gfx::Point(10, 11),
269 gfx::Point(10, 11), 338 2,
270 2, 339 generator_->Now());
271 ui::EventTimeForNow()); 340 generator_->Dispatch(&touch_press);
272 generator.Dispatch(&touch_press);
273 EXPECT_TRUE(cursor_client()->IsCursorVisible()); 341 EXPECT_TRUE(cursor_client()->IsCursorVisible());
274 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled()); 342 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
275 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 343 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
276 // TODO(mfomitchev): mouse enter/exit events 344 // TODO(mfomitchev): mouse enter/exit events
277 // There will be a ET_MOUSE_EXITED event synthesized when the mouse cursor is 345 // There will be a ET_MOUSE_EXITED event synthesized when the mouse cursor is
278 // hidden - ignore it. 346 // hidden - ignore it.
279 ScopedVector<ui::LocatedEvent>::const_iterator it; 347 ScopedVector<ui::LocatedEvent>::const_iterator it;
280 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 348 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
281 if ((*it)->type() == ui::ET_TOUCH_PRESSED) { 349 if ((*it)->type() == ui::ET_TOUCH_PRESSED) {
282 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(*it, &touch_press); 350 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(*it, &touch_press);
283 break; 351 break;
284 } 352 }
285 } 353 }
286 EXPECT_NE(captured_events.end(), it); 354 EXPECT_NE(captured_events.end(), it);
287 ClearCapturedEvents(); 355 ClearCapturedEvents();
288 ui::TouchEvent touch_move(ui::ET_TOUCH_MOVED, 356 ui::TouchEvent touch_move(
289 gfx::Point(20, 21), 357 ui::ET_TOUCH_MOVED,
290 2, 358 gfx::Point(20, 21),
291 ui::EventTimeForNow()); 359 2,
292 generator.Dispatch(&touch_move); 360 generator_->Now());
361 generator_->Dispatch(&touch_move);
293 ASSERT_EQ(1u, captured_events.size()); 362 ASSERT_EQ(1u, captured_events.size());
294 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move); 363 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_move);
295 ClearCapturedEvents(); 364 ClearCapturedEvents();
296 365
297 // Confirm mouse moves go through unaffected. 366 // Confirm mouse moves go through unaffected.
298 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED, 367 ui::MouseEvent mouse_move(ui::ET_MOUSE_MOVED,
299 gfx::Point(13, 14), 368 gfx::Point(13, 14),
300 gfx::Point(13, 14), 369 gfx::Point(13, 14),
301 0, 370 0,
302 0); 371 0);
303 generator.Dispatch(&mouse_move); 372 generator_->Dispatch(&mouse_move);
304 // TODO(mfomitchev): mouse enter/exit events 373 // TODO(mfomitchev): mouse enter/exit events
305 // Ignore synthesized ET_MOUSE_ENTERED/ET_MOUSE_EXITED 374 // Ignore synthesized ET_MOUSE_ENTERED/ET_MOUSE_EXITED
306 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 375 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
307 if ((*it)->type() == ui::ET_MOUSE_MOVED) { 376 if ((*it)->type() == ui::ET_MOUSE_MOVED) {
308 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(*it, &mouse_move); 377 CONFIRM_EVENTS_ARE_MOUSE_AND_EQUAL(*it, &mouse_move);
309 break; 378 break;
310 } 379 }
311 } 380 }
312 EXPECT_NE(captured_events.end(), it); 381 EXPECT_NE(captured_events.end(), it);
313 ClearCapturedEvents(); 382 ClearCapturedEvents();
314 383
315 // Have some other fingers touch/move/release
316 generator.PressTouchId(3);
317 generator.PressTouchId(4);
318 generator.MoveTouchId(gfx::Point(30, 31), 3);
319 generator.ReleaseTouchId(3);
320 generator.ReleaseTouchId(4);
321 ClearCapturedEvents();
322
323 // Events from the first finger should not go through while the second finger 384 // Events from the first finger should not go through while the second finger
324 // is touching. 385 // is touching.
325 gfx::Point touch1_location = gfx::Point(15, 16); 386 gfx::Point touch1_location = gfx::Point(15, 16);
326 generator.MoveTouchId(touch1_location, 1); 387 generator_->MoveTouchId(touch1_location, 1);
327 EXPECT_EQ(0u, GetCapturedEvents().size()); 388 EXPECT_EQ(0u, GetCapturedEvents().size());
328 389
329 EXPECT_TRUE(cursor_client()->IsCursorVisible()); 390 EXPECT_TRUE(cursor_client()->IsCursorVisible());
330 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled()); 391 EXPECT_FALSE(cursor_client()->IsMouseEventsEnabled());
331 392
332 // A release of the second finger should go through, plus there should be a 393 // A release of the second finger should be rewritten as a mouse move
333 // mouse move at |touch1_location| generated. 394 // of that finger to the |touch1_location| and we stay in passthrough
334 ui::TouchEvent touch_release(ui::ET_TOUCH_RELEASED, 395 // mode.
335 gfx::Point(25, 26), 396 ui::TouchEvent touch_release(
336 2, 397 ui::ET_TOUCH_RELEASED,
337 ui::EventTimeForNow()); 398 gfx::Point(25, 26),
338 generator.Dispatch(&touch_release); 399 2,
339 EXPECT_TRUE(IsInTouchToMouseMode()); 400 generator_->Now());
340 ASSERT_GE(captured_events.size(), 2u); 401 generator_->Dispatch(&touch_release);
341 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch_release); 402 EXPECT_FALSE(IsInTouchToMouseMode());
342 // TODO(mfomitchev): mouse enter/exit events 403 ASSERT_EQ(captured_events.size(), 1u);
343 // Ignore synthesized ET_MOUSE_ENTERED/ET_MOUSE_EXITED 404 EXPECT_EQ(touch1_location, captured_events[0]->location());
344 for (it = captured_events.begin(); it != captured_events.end(); ++it) {
345 if ((*it)->type() == ui::ET_MOUSE_MOVED) {
346 EXPECT_EQ(touch1_location, (*it)->location());
347 break;
348 }
349 }
350 EXPECT_NE(captured_events.end(), it);
351 } 405 }
352 406
353 TEST_F(TouchExplorationTest, MultiFingerTouch) { 407 TEST_F(TouchExplorationTest, MultiFingerTouch) {
354 SwitchTouchExplorationMode(true); 408 SwitchTouchExplorationMode(true);
355 aura::test::EventGenerator generator(root_window()); 409 generator_->PressTouchId(1);
356 generator.PressTouchId(1); 410 generator_->PressTouchId(2);
357 generator.PressTouchId(2);
358 ClearCapturedEvents(); 411 ClearCapturedEvents();
359 412
360 // Confirm events from other fingers go through as is. 413 // Confirm events from other fingers go through as is.
361 ui::TouchEvent touch3_press(ui::ET_TOUCH_PRESSED, 414 ui::TouchEvent touch3_press(ui::ET_TOUCH_PRESSED,
362 gfx::Point(10, 11), 415 gfx::Point(10, 11),
363 3, 416 3,
364 ui::EventTimeForNow()); 417 generator_->Now());
365 ui::TouchEvent touch3_move1(ui::ET_TOUCH_MOVED, 418 ui::TouchEvent touch3_move1(ui::ET_TOUCH_MOVED,
366 gfx::Point(12, 13), 419 gfx::Point(12, 13),
367 3, 420 3,
368 ui::EventTimeForNow()); 421 generator_->Now());
369 ui::TouchEvent touch4_press(ui::ET_TOUCH_PRESSED, 422 ui::TouchEvent touch4_press(ui::ET_TOUCH_PRESSED,
370 gfx::Point(20, 21), 423 gfx::Point(20, 21),
371 4, 424 4,
372 ui::EventTimeForNow()); 425 generator_->Now());
373 ui::TouchEvent touch3_move2(ui::ET_TOUCH_MOVED, 426 ui::TouchEvent touch3_move2(ui::ET_TOUCH_MOVED,
374 gfx::Point(14, 15), 427 gfx::Point(14, 15),
375 3, 428 3,
376 ui::EventTimeForNow()); 429 generator_->Now());
377 ui::TouchEvent touch4_move(ui::ET_TOUCH_MOVED, 430 ui::TouchEvent touch4_move(ui::ET_TOUCH_MOVED,
378 gfx::Point(22, 23), 431 gfx::Point(22, 23),
379 4, 432 4,
380 ui::EventTimeForNow()); 433 generator_->Now());
381 ui::TouchEvent touch3_release(ui::ET_TOUCH_RELEASED, 434 ui::TouchEvent touch3_release(ui::ET_TOUCH_RELEASED,
382 gfx::Point(14, 15), 435 gfx::Point(14, 15),
383 3, 436 3,
384 ui::EventTimeForNow()); 437 generator_->Now());
385 ui::TouchEvent touch4_release(ui::ET_TOUCH_RELEASED, 438 ui::TouchEvent touch4_release(ui::ET_TOUCH_RELEASED,
386 gfx::Point(22, 23), 439 gfx::Point(22, 23),
387 4, 440 4,
388 ui::EventTimeForNow()); 441 generator_->Now());
389 generator.Dispatch(&touch3_press); 442 generator_->Dispatch(&touch3_press);
390 generator.Dispatch(&touch3_move1); 443 generator_->Dispatch(&touch3_move1);
391 generator.Dispatch(&touch4_press); 444 generator_->Dispatch(&touch4_press);
392 generator.Dispatch(&touch3_move2); 445 generator_->Dispatch(&touch3_move2);
393 generator.Dispatch(&touch4_move); 446 generator_->Dispatch(&touch4_move);
394 generator.Dispatch(&touch3_release); 447 generator_->Dispatch(&touch3_release);
395 generator.Dispatch(&touch4_release); 448 generator_->Dispatch(&touch4_release);
396 449
397 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 450 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
398 ASSERT_EQ(7u, captured_events.size()); 451 ASSERT_EQ(7u, captured_events.size());
399 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch3_press); 452 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch3_press);
400 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[1], &touch3_move1); 453 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[1], &touch3_move1);
401 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[2], &touch4_press); 454 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[2], &touch4_press);
402 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[3], &touch3_move2); 455 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[3], &touch3_move2);
403 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[4], &touch4_move); 456 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[4], &touch4_move);
404 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[5], &touch3_release); 457
458 // The release of finger 3 is rewritten as a move to the former location
459 // of finger 1.
460 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[5]->type());
405 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[6], &touch4_release); 461 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[6], &touch4_release);
406 } 462 }
407 463
408 // Test the case when there are multiple fingers on the screen and the first 464 // Test the case when there are multiple fingers on the screen and the first
409 // finger is released. This should be rewritten as a release of the second 465 // finger is released. This should be ignored, but then the second finger
410 // finger. Additionally, if the second finger is the only finger left touching, 466 // release should be passed through.
411 // we should enter a mouse move mode, and a mouse move event should be
412 // dispatched.
413 TEST_F(TouchExplorationTest, FirstFingerLifted) { 467 TEST_F(TouchExplorationTest, FirstFingerLifted) {
414 SwitchTouchExplorationMode(true); 468 SwitchTouchExplorationMode(true);
415 aura::test::EventGenerator generator(root_window()); 469 generator_->PressTouchId(1);
416 generator.PressTouchId(1); 470 generator_->PressTouchId(2);
417 generator.PressTouchId(2);
418 gfx::Point touch2_location(10, 11); 471 gfx::Point touch2_location(10, 11);
419 generator.MoveTouchId(touch2_location, 2); 472 generator_->MoveTouchId(touch2_location, 2);
420 generator.PressTouchId(3); 473 generator_->PressTouchId(3);
421 gfx::Point touch3_location(20, 21); 474 gfx::Point touch3_location(20, 21);
422 generator.MoveTouchId(touch3_location, 3); 475 generator_->MoveTouchId(touch3_location, 3);
423 ClearCapturedEvents(); 476 ClearCapturedEvents();
424 477
425 // Release of finger 1 should be rewritten as a release of finger 2. 478 // Release of finger 1 should be ignored.
426 generator.ReleaseTouchId(1); 479 generator_->ReleaseTouchId(1);
480 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
481 ASSERT_EQ(0u, captured_events.size());
482
483 // Move of finger 2 should be passed through.
484 gfx::Point touch2_new_location(20, 11);
485 generator_->MoveTouchId(touch2_new_location, 2);
486 ASSERT_EQ(1u, captured_events.size());
487 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
488 EXPECT_EQ(touch2_new_location, captured_events[0]->location());
489 ClearCapturedEvents();
490
491 // Release of finger 2 should be passed through.
492 ui::TouchEvent touch2_release(
493 ui::ET_TOUCH_RELEASED,
494 gfx::Point(14, 15),
495 2,
496 generator_->Now());
497 generator_->Dispatch(&touch2_release);
498 ASSERT_EQ(1u, captured_events.size());
499 CONFIRM_EVENTS_ARE_TOUCH_AND_EQUAL(captured_events[0], &touch2_release);
500 }
501
502 // Test the case when there are multiple fingers on the screen and the
503 // second finger is released. This should be rewritten as a move to the
504 // location of the first finger.
505 TEST_F(TouchExplorationTest, SecondFingerLifted) {
506 SwitchTouchExplorationMode(true);
507 gfx::Point touch1_location(0, 11);
508 generator_->set_current_location(touch1_location);
509 generator_->PressTouchId(1);
510 generator_->PressTouchId(2);
511 gfx::Point touch2_location(10, 11);
512 generator_->MoveTouchId(touch2_location, 2);
513 generator_->PressTouchId(3);
514 gfx::Point touch3_location(20, 21);
515 generator_->MoveTouchId(touch3_location, 3);
516 ClearCapturedEvents();
517
518 // Release of finger 2 should be rewritten as a move to the location
519 // of the first finger.
520 generator_->ReleaseTouchId(2);
427 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents(); 521 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
428 ASSERT_EQ(1u, captured_events.size()); 522 ASSERT_EQ(1u, captured_events.size());
429 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type()); 523 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
430 ui::TouchEvent* touch_event = 524 EXPECT_EQ(2, static_cast<ui::TouchEvent*>(captured_events[0])->touch_id());
431 static_cast<ui::TouchEvent*>(captured_events[0]); 525 EXPECT_EQ(touch1_location, captured_events[0]->location());
432 EXPECT_EQ(2, touch_event->touch_id());
433 EXPECT_EQ(touch2_location, touch_event->location());
434 ClearCapturedEvents(); 526 ClearCapturedEvents();
435 527
436 // Release of finger 2 should be rewritten as a release of finger 3, plus 528 // Move of finger 1 should be rewritten as a move of finger 2.
437 // we should enter the mouse move mode and a mouse move event should be 529 gfx::Point touch1_new_location(0, 41);
438 // dispatched. 530 generator_->MoveTouchId(touch1_new_location, 1);
439 cursor_client()->ShowCursor(); 531 ASSERT_EQ(1u, captured_events.size());
440 cursor_client()->DisableMouseEvents(); 532 EXPECT_EQ(ui::ET_TOUCH_MOVED, captured_events[0]->type());
441 generator.ReleaseTouchId(2); 533 EXPECT_EQ(2, static_cast<ui::TouchEvent*>(captured_events[0])->touch_id());
442 EXPECT_TRUE(IsInTouchToMouseMode()); 534 EXPECT_EQ(touch1_new_location, captured_events[0]->location());
443 ASSERT_GE(2u, captured_events.size()); 535 ClearCapturedEvents();
536
537 // Release of finger 1 should be rewritten as release of finger 2.
538 gfx::Point touch1_final_location(0, 41);
539 ui::TouchEvent touch1_release(
540 ui::ET_TOUCH_RELEASED,
541 touch1_final_location,
542 1,
543 generator_->Now());
544 generator_->Dispatch(&touch1_release);
545 ASSERT_EQ(1u, captured_events.size());
444 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type()); 546 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[0]->type());
445 touch_event = static_cast<ui::TouchEvent*>(captured_events[0]); 547 EXPECT_EQ(2, static_cast<ui::TouchEvent*>(captured_events[0])->touch_id());
446 EXPECT_EQ(3, touch_event->touch_id()); 548 EXPECT_EQ(touch1_final_location, captured_events[0]->location());
447 EXPECT_EQ(touch3_location, touch_event->location()); 549 }
448 // TODO(mfomitchev): mouse enter/exit events 550
449 ScopedVector<ui::LocatedEvent>::const_iterator it; 551 // If an event is received after the double-tap timeout has elapsed, but
450 for (it = captured_events.begin(); it != captured_events.end(); ++it) { 552 // before the timer has fired, a mouse move should still be generated.
451 if ((*it)->type() == ui::ET_MOUSE_MOVED) { 553 TEST_F(TouchExplorationTest, TimerFiresLateDuringTouchExploration) {
452 EXPECT_EQ(touch3_location, (*it)->location()); 554 SwitchTouchExplorationMode(true);
453 break; 555
454 } 556 // Send a press, then add another finger after the double-tap timeout.
455 } 557 generator_->PressTouchId(1);
456 EXPECT_NE(captured_events.end(), it); 558 generator_->AdvanceSimulatedTimeBy(
559 base::TimeDelta::FromMilliseconds(1000));
560 generator_->PressTouchId(2);
561 std::vector<ui::LocatedEvent*> events =
562 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
563 ASSERT_EQ(1U, events.size());
564 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
565 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
566
567 generator_->ReleaseTouchId(2);
568 generator_->ReleaseTouchId(1);
569 EXPECT_TRUE(IsInNoFingersDownState());
570 }
571
572 // If a new tap is received after the double-tap timeout has elapsed from
573 // a previous tap, but before the timer has fired, a mouse move should
574 // still be generated from the old tap.
575 TEST_F(TouchExplorationTest, TimerFiresLateAfterTap) {
576 SwitchTouchExplorationMode(true);
577
578 // Send a tap at location1.
579 gfx::Point location0(11, 12);
580 generator_->set_current_location(location0);
581 generator_->PressTouch();
582 generator_->ReleaseTouch();
583
584 // Send a tap at location2, after the double-tap timeout, but before the
585 // timer fires.
586 gfx::Point location1(33, 34);
587 generator_->set_current_location(location1);
588 generator_->AdvanceSimulatedTimeBy(
589 base::TimeDelta::FromMilliseconds(301));
590 generator_->PressTouch();
591 generator_->ReleaseTouch();
592 AdvanceSimulatedTimePastTapDelay();
593
594 std::vector<ui::LocatedEvent*> events =
595 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
596 ASSERT_EQ(2U, events.size());
597 EXPECT_EQ(location0, events[0]->location());
598 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
599 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
600 EXPECT_EQ(location1, events[1]->location());
601 EXPECT_TRUE(events[1]->flags() & ui::EF_IS_SYNTHESIZED);
602 EXPECT_TRUE(events[1]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
603 EXPECT_TRUE(IsInNoFingersDownState());
604 }
605
606 // Double-tapping should send a touch press and release through to the location
607 // of the last successful touch exploration.
608 TEST_F(TouchExplorationTest, DoubleTap) {
609 SwitchTouchExplorationMode(true);
610
611 // Tap at one location, and get a mouse move event.
612 gfx::Point tap_location(11, 12);
613 generator_->set_current_location(tap_location);
614 generator_->PressTouch();
615 generator_->ReleaseTouch();
616 AdvanceSimulatedTimePastTapDelay();
617
618 std::vector<ui::LocatedEvent*> events =
619 GetCapturedEventsOfType(ui::ET_MOUSE_MOVED);
620 ASSERT_EQ(1U, events.size());
621
622 EXPECT_EQ(tap_location, events[0]->location());
623 EXPECT_TRUE(events[0]->flags() & ui::EF_IS_SYNTHESIZED);
624 EXPECT_TRUE(events[0]->flags() & ui::EF_TOUCH_ACCESSIBILITY);
625 ClearCapturedEvents();
626
627 // Now double-tap at a different location. This should result in
628 // a single touch press and release at the location of the tap,
629 // not at the location of the double-tap.
630 gfx::Point double_tap_location(33, 34);
631 generator_->set_current_location(double_tap_location);
632 generator_->PressTouch();
633 generator_->ReleaseTouch();
634 generator_->PressTouch();
635 generator_->ReleaseTouch();
636
637 const ScopedVector<ui::LocatedEvent>& captured_events = GetCapturedEvents();
638 ASSERT_EQ(2U, captured_events.size());
639 EXPECT_EQ(ui::ET_TOUCH_PRESSED, captured_events[0]->type());
640 EXPECT_EQ(tap_location, captured_events[0]->location());
641 EXPECT_EQ(ui::ET_TOUCH_RELEASED, captured_events[1]->type());
642 EXPECT_EQ(tap_location, captured_events[1]->location());
643 EXPECT_TRUE(IsInNoFingersDownState());
457 } 644 }
458 645
459 } // namespace ui 646 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698