Fix AfterTyping experiment for Android.
[chromium-blink-merge.git] / components / view_manager / gesture_manager_unittest.cc
blobcc180b3c20e73e7bf2581c2b88cbe8d6b9f4791c
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/view_manager/gesture_manager.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/string_util.h"
9 #include "components/view_manager/gesture_manager_delegate.h"
10 #include "components/view_manager/public/cpp/keys.h"
11 #include "components/view_manager/server_view.h"
12 #include "components/view_manager/test_server_view_delegate.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14 #include "ui/mojo/events/input_events.mojom.h"
16 namespace view_manager {
17 namespace {
19 const uint32_t kInvalidGestureId = GestureManager::kInvalidGestureId;
21 void MarkAsRespondsToTouch(ServerView* view) {
22 std::vector<uint8_t> empty_vector;
23 view->SetProperty(mojo::kViewManagerKeyWantsTouchEvents, &empty_vector);
26 std::set<uint32_t> SetWith(uint32_t v1) {
27 std::set<uint32_t> result;
28 result.insert(v1);
29 return result;
32 std::set<uint32_t> SetWith(uint32_t v1, uint32_t v2) {
33 std::set<uint32_t> result;
34 result.insert(v1);
35 result.insert(v2);
36 return result;
39 std::set<uint32_t> SetWith(uint32_t v1, uint32_t v2, uint32_t v3) {
40 std::set<uint32_t> result;
41 result.insert(v1);
42 result.insert(v2);
43 result.insert(v3);
44 return result;
47 std::string EventTypeToString(mojo::EventType event_type) {
48 switch (event_type) {
49 case mojo::EVENT_TYPE_POINTER_CANCEL:
50 return "cancel";
51 case mojo::EVENT_TYPE_POINTER_DOWN:
52 return "down";
53 case mojo::EVENT_TYPE_POINTER_MOVE:
54 return "move";
55 case mojo::EVENT_TYPE_POINTER_UP:
56 return "up";
57 default:
58 break;
60 return std::string("unexpected event");
63 mojo::EventPtr CreateEvent(mojo::EventType type,
64 int32_t pointer_id,
65 int x,
66 int y) {
67 mojo::EventPtr event(mojo::Event::New());
68 event->action = type;
69 event->pointer_data = mojo::PointerData::New();
70 event->pointer_data->pointer_id = pointer_id;
71 event->pointer_data->x = x;
72 event->pointer_data->y = y;
73 return event.Pass();
76 struct CompareViewByConnectionId {
77 bool operator()(const ServerView* a, const ServerView* b) {
78 return a->id().connection_id < b->id().connection_id;
82 std::string IDsToString(const std::set<uint32_t>& ids) {
83 std::string result;
84 for (uint32_t id : ids) {
85 if (!result.empty())
86 result += ",";
87 result += base::UintToString(id);
89 return result;
92 std::string GestureStateChangeToString(const ServerView* view,
93 const GestureStateChange& change) {
94 std::string result =
95 "connection=" + base::IntToString(view->id().connection_id);
96 if (change.chosen_gesture != GestureManager::kInvalidGestureId)
97 result += " chosen=" + base::UintToString(change.chosen_gesture);
98 if (!change.canceled_gestures.empty())
99 result += " canceled=" + IDsToString(change.canceled_gestures);
100 return result;
103 } // namespace
105 class TestGestureManagerDelegate : public GestureManagerDelegate {
106 public:
107 TestGestureManagerDelegate() {}
108 ~TestGestureManagerDelegate() override {}
110 std::string GetAndClearDescriptions() {
111 const std::string result(JoinString(descriptions_, '\n'));
112 descriptions_.clear();
113 return result;
116 std::vector<std::string>& descriptions() { return descriptions_; }
118 void AppendDescriptionsFromResults(const ChangeMap& change_map) {
119 std::set<const ServerView*, CompareViewByConnectionId> views_by_id;
120 for (const auto& pair : change_map)
121 views_by_id.insert(pair.first);
123 for (auto* view : views_by_id) {
124 descriptions_.push_back(
125 GestureStateChangeToString(view, change_map.find(view)->second));
129 // GestureManagerDelegate:
130 void ProcessEvent(const ServerView* view,
131 mojo::EventPtr event,
132 bool has_chosen_gesture) override {
133 descriptions_.push_back(
134 EventTypeToString(event->action) + " pointer=" +
135 base::IntToString(event->pointer_data->pointer_id) + " connection=" +
136 base::UintToString(view->id().connection_id) + " chosen=" +
137 (has_chosen_gesture ? "true" : "false"));
140 private:
141 std::vector<std::string> descriptions_;
143 DISALLOW_COPY_AND_ASSIGN(TestGestureManagerDelegate);
146 class GestureManagerTest : public testing::Test {
147 public:
148 GestureManagerTest()
149 : root_(&view_delegate_, ViewId(1, 1)),
150 child_(&view_delegate_, ViewId(2, 2)),
151 gesture_manager_(&gesture_delegate_, &root_) {
152 view_delegate_.set_root_view(&root_);
153 root_.SetVisible(true);
154 MarkAsRespondsToTouch(&root_);
155 root_.SetBounds(gfx::Rect(0, 0, 100, 100));
157 ~GestureManagerTest() override {}
159 void SetGestures(const ServerView* view,
160 int32_t pointer_id,
161 uint32_t chosen_gesture_id,
162 const std::set<uint32_t>& possible_gesture_ids,
163 const std::set<uint32_t>& canceled_ids) {
164 scoped_ptr<ChangeMap> result(
165 gesture_manager_.SetGestures(view, pointer_id, chosen_gesture_id,
166 possible_gesture_ids, canceled_ids));
167 gesture_delegate_.AppendDescriptionsFromResults(*result);
170 void AddChildView() {
171 MarkAsRespondsToTouch(&child_);
172 child_.SetVisible(true);
173 root_.Add(&child_);
174 child_.SetBounds(gfx::Rect(0, 0, 100, 100));
177 protected:
178 TestServerViewDelegate view_delegate_;
179 ServerView root_;
180 ServerView child_;
181 TestGestureManagerDelegate gesture_delegate_;
182 GestureManager gesture_manager_;
184 private:
185 DISALLOW_COPY_AND_ASSIGN(GestureManagerTest);
188 TEST_F(GestureManagerTest, SingleViewAndSingleGesture) {
189 const int32_t pointer_id = 1;
190 gesture_manager_.ProcessEvent(
191 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
192 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
193 gesture_delegate_.GetAndClearDescriptions());
195 // Choose this pointer.
196 SetGestures(&root_, pointer_id, 10u, SetWith(10u), std::set<uint32_t>());
197 EXPECT_EQ("connection=1 chosen=10",
198 gesture_delegate_.GetAndClearDescriptions());
201 TEST_F(GestureManagerTest, SingleViewAndTwoGestures) {
202 const int32_t pointer_id = 1;
203 gesture_manager_.ProcessEvent(
204 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
205 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
206 gesture_delegate_.GetAndClearDescriptions());
208 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
209 std::set<uint32_t>());
211 // Delegate should have got nothing.
212 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
214 // Cancel 10, 5 should become active.
215 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
216 SetWith(10u));
218 EXPECT_EQ("connection=1 chosen=5 canceled=10",
219 gesture_delegate_.GetAndClearDescriptions());
222 TEST_F(GestureManagerTest, TwoViewsSingleGesture) {
223 AddChildView();
225 const int32_t pointer_id = 1;
226 gesture_manager_.ProcessEvent(
227 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
228 // Deepest child should be queried first.
229 EXPECT_EQ("down pointer=1 connection=2 chosen=false",
230 gesture_delegate_.GetAndClearDescriptions());
232 // Respond from the first view, which triggers the second to be queried.
233 SetGestures(&child_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
234 std::set<uint32_t>());
235 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
236 gesture_delegate_.GetAndClearDescriptions());
238 // Respond with 5,10 for the second view. Should get nothing.
239 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
240 std::set<uint32_t>());
241 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
243 // Cancel 10 in the child.
244 SetGestures(&child_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
245 SetWith(10u));
246 EXPECT_EQ("connection=2 canceled=10",
247 gesture_delegate_.GetAndClearDescriptions());
249 // Choose 5 in the root. This should choose 5 in the root and cancel 5 in
250 // the child.
251 SetGestures(&root_, pointer_id, 5u, SetWith(5u, 10u), SetWith(10u));
252 ASSERT_EQ(2u, gesture_delegate_.descriptions().size());
253 EXPECT_EQ("connection=1 chosen=5 canceled=10",
254 gesture_delegate_.descriptions()[0]);
255 EXPECT_EQ("connection=2 canceled=5", gesture_delegate_.descriptions()[1]);
258 TEST_F(GestureManagerTest, TwoViewsWaitForMoveToChoose) {
259 AddChildView();
261 const int32_t pointer_id = 1;
262 gesture_manager_.ProcessEvent(
263 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
264 // Deepest child should be queried first.
265 EXPECT_EQ("down pointer=1 connection=2 chosen=false",
266 gesture_delegate_.GetAndClearDescriptions());
268 // Send a move. The move should not be processed as GestureManager is
269 // still waiting for responses.
270 gesture_manager_.ProcessEvent(
271 *CreateEvent(mojo::EVENT_TYPE_POINTER_MOVE, pointer_id, 6, 6));
272 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
274 // Respond from the first view, which triggers the second to be queried.
275 SetGestures(&child_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
276 std::set<uint32_t>());
277 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
278 gesture_delegate_.GetAndClearDescriptions());
280 // Respond with 1,2 for the second view.
281 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(1u, 2u),
282 std::set<uint32_t>());
283 // Now that we've responded to the down requests we should get a move for the
284 // child.
285 EXPECT_EQ("move pointer=1 connection=2 chosen=false",
286 gesture_delegate_.GetAndClearDescriptions());
288 // Respond for the child, root should now get move.
289 SetGestures(&child_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
290 std::set<uint32_t>());
291 EXPECT_EQ("move pointer=1 connection=1 chosen=false",
292 gesture_delegate_.GetAndClearDescriptions());
294 // Respond with nothing chosen for the root. Nothing should come in as no
295 // pending moves.
296 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(1u, 2u),
297 std::set<uint32_t>());
298 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
300 // Send another move event and respond with a chosen id.
301 gesture_manager_.ProcessEvent(
302 *CreateEvent(mojo::EVENT_TYPE_POINTER_MOVE, pointer_id, 7, 7));
303 EXPECT_EQ("move pointer=1 connection=2 chosen=false",
304 gesture_delegate_.GetAndClearDescriptions());
305 SetGestures(&child_, pointer_id, 5u, SetWith(5u, 10u), std::set<uint32_t>());
306 ASSERT_EQ(3u, gesture_delegate_.descriptions().size());
307 // Now that a gesture is chosen the move event is generated.
308 EXPECT_EQ("move pointer=1 connection=1 chosen=true",
309 gesture_delegate_.descriptions()[0]);
310 EXPECT_EQ("connection=1 canceled=1,2", gesture_delegate_.descriptions()[1]);
311 EXPECT_EQ("connection=2 chosen=5 canceled=10",
312 gesture_delegate_.descriptions()[2]);
315 TEST_F(GestureManagerTest, SingleViewNewPointerAfterChoose) {
316 const int32_t pointer_id = 1;
317 gesture_manager_.ProcessEvent(
318 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
319 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
320 gesture_delegate_.GetAndClearDescriptions());
322 // Choose 5.
323 SetGestures(&root_, pointer_id, 5u, SetWith(5u, 10u), std::set<uint32_t>());
324 EXPECT_EQ("connection=1 chosen=5 canceled=10",
325 gesture_delegate_.GetAndClearDescriptions());
327 // Start another down event with a different pointer.
328 const int32_t pointer_id2 = 2;
329 gesture_manager_.ProcessEvent(
330 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id2, 5, 5));
331 EXPECT_EQ("down pointer=2 connection=1 chosen=false",
332 gesture_delegate_.GetAndClearDescriptions());
334 // For the new pointer supply the id of a gesture that has been chosen.
335 // Even though we didn't explicitly supply 5 as chosen, 5 is chosen because
336 // it's already in the chosen state for pointer 1.
337 SetGestures(&root_, pointer_id2, kInvalidGestureId, SetWith(5u, 11u),
338 std::set<uint32_t>());
339 EXPECT_EQ("connection=1 chosen=5 canceled=11",
340 gesture_delegate_.GetAndClearDescriptions());
343 TEST_F(GestureManagerTest, SingleViewChoosingConflictingGestures) {
344 // For pointer1 choose 1 with 1,2,3 as possibilities.
345 const int32_t pointer1 = 1;
346 gesture_manager_.ProcessEvent(
347 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer1, 5, 5));
348 gesture_delegate_.GetAndClearDescriptions();
349 SetGestures(&root_, pointer1, 1u, SetWith(1u, 2u, 3u), std::set<uint32_t>());
350 EXPECT_EQ("connection=1 chosen=1 canceled=2,3",
351 gesture_delegate_.GetAndClearDescriptions());
353 // For pointer2 choose 11 with 11,12 as possibilities.
354 const int32_t pointer2 = 2;
355 gesture_manager_.ProcessEvent(
356 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer2, 5, 5));
357 gesture_delegate_.GetAndClearDescriptions();
358 SetGestures(&root_, pointer2, 11u, SetWith(11u, 12u), std::set<uint32_t>());
359 EXPECT_EQ("connection=1 chosen=11 canceled=12",
360 gesture_delegate_.GetAndClearDescriptions());
362 // For pointer3 choose 21 with 1,11,21 as possibilties.
363 const int32_t pointer3 = 3;
364 gesture_manager_.ProcessEvent(
365 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer3, 5, 5));
366 gesture_delegate_.GetAndClearDescriptions();
367 SetGestures(&root_, pointer3, 21u, SetWith(1u, 11u, 21u),
368 std::set<uint32_t>());
369 EXPECT_EQ("connection=1 chosen=21 canceled=1,11",
370 gesture_delegate_.GetAndClearDescriptions());
373 TEST_F(GestureManagerTest,
374 TwoViewsRespondingWithChosenGestureSendsRemainingEvents) {
375 AddChildView();
377 // Start two pointer downs, don't respond to either.
378 const int32_t pointer1 = 1;
379 gesture_manager_.ProcessEvent(
380 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer1, 5, 5));
381 EXPECT_EQ("down pointer=1 connection=2 chosen=false",
382 gesture_delegate_.GetAndClearDescriptions());
384 const int32_t pointer2 = 2;
385 gesture_manager_.ProcessEvent(
386 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer2, 5, 5));
387 EXPECT_EQ("down pointer=2 connection=2 chosen=false",
388 gesture_delegate_.GetAndClearDescriptions());
390 // Queue up a move event for pointer1. The event should not be forwarded
391 // as we're still waiting.
392 gesture_manager_.ProcessEvent(
393 *CreateEvent(mojo::EVENT_TYPE_POINTER_MOVE, pointer1, 5, 5));
394 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
396 // Respond with 1,2 for pointer1 (nothing chosen yet).
397 SetGestures(&child_, pointer1, kInvalidGestureId, SetWith(1u, 2u),
398 std::set<uint32_t>());
399 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
400 gesture_delegate_.GetAndClearDescriptions());
402 // Respond with 1,2 and choose 1 for pointer2. This results in the following:
403 // down for pointer 1 (because we chose a gesture in common with pointer1),
404 // move for pointer 1 in both connections (because a gesture was chosen queued
405 // up events are sent), down for pointer2 for the root and finally
406 // notification of what was chosen.
407 SetGestures(&child_, pointer2, 1u, SetWith(1u, 2u), std::set<uint32_t>());
408 ASSERT_EQ(5u, gesture_delegate_.descriptions().size());
409 EXPECT_EQ("down pointer=1 connection=1 chosen=true",
410 gesture_delegate_.descriptions()[0]);
411 EXPECT_EQ("move pointer=1 connection=2 chosen=true",
412 gesture_delegate_.descriptions()[1]);
413 EXPECT_EQ("move pointer=1 connection=1 chosen=true",
414 gesture_delegate_.descriptions()[2]);
415 EXPECT_EQ("down pointer=2 connection=1 chosen=true",
416 gesture_delegate_.descriptions()[3]);
417 EXPECT_EQ("connection=2 chosen=1 canceled=2",
418 gesture_delegate_.descriptions()[4]);
421 TEST_F(GestureManagerTest, TwoViewsSingleGestureUp) {
422 AddChildView();
424 const int32_t pointer_id = 1;
425 gesture_manager_.ProcessEvent(
426 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
427 // Deepest child should be queried first.
428 EXPECT_EQ("down pointer=1 connection=2 chosen=false",
429 gesture_delegate_.GetAndClearDescriptions());
431 // Send an up, shouldn't result in anything.
432 gesture_manager_.ProcessEvent(
433 *CreateEvent(mojo::EVENT_TYPE_POINTER_UP, pointer_id, 5, 5));
434 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
436 // Respond from the first view, with a chosen gesture.
437 SetGestures(&child_, pointer_id, 5u, SetWith(5u, 10u), std::set<uint32_t>());
438 ASSERT_EQ(4u, gesture_delegate_.descriptions().size());
439 EXPECT_EQ("down pointer=1 connection=1 chosen=true",
440 gesture_delegate_.descriptions()[0]);
441 EXPECT_EQ("up pointer=1 connection=2 chosen=true",
442 gesture_delegate_.descriptions()[1]);
443 EXPECT_EQ("up pointer=1 connection=1 chosen=true",
444 gesture_delegate_.descriptions()[2]);
445 EXPECT_EQ("connection=2 chosen=5 canceled=10",
446 gesture_delegate_.descriptions()[3]);
449 TEST_F(GestureManagerTest, SingleViewSingleGestureCancel) {
450 const int32_t pointer_id = 1;
451 gesture_manager_.ProcessEvent(
452 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
453 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
454 gesture_delegate_.GetAndClearDescriptions());
456 // Send a cancel, shouldn't result in anything.
457 gesture_manager_.ProcessEvent(
458 *CreateEvent(mojo::EVENT_TYPE_POINTER_CANCEL, pointer_id, 5, 5));
459 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
461 // Respond from the first view, with no gesture, should unblock cancel.
462 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
463 std::set<uint32_t>());
464 EXPECT_EQ("cancel pointer=1 connection=1 chosen=false",
465 gesture_delegate_.GetAndClearDescriptions());
468 } // namespace view_manager