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

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

Powered by Google App Engine
This is Rietveld 408576698