Supervised user import: Listen for profile creation/deletion
[chromium-blink-merge.git] / components / view_manager / gesture_manager_unittest.cc
blob403e6f0a59e584a8a3e4fea0bf829138ecf34aa1
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 root_.SetVisible(true);
153 MarkAsRespondsToTouch(&root_);
154 root_.SetBounds(gfx::Rect(0, 0, 100, 100));
156 ~GestureManagerTest() override {}
158 void SetGestures(const ServerView* view,
159 int32_t pointer_id,
160 uint32_t chosen_gesture_id,
161 const std::set<uint32_t>& possible_gesture_ids,
162 const std::set<uint32_t>& canceled_ids) {
163 scoped_ptr<ChangeMap> result(
164 gesture_manager_.SetGestures(view, pointer_id, chosen_gesture_id,
165 possible_gesture_ids, canceled_ids));
166 gesture_delegate_.AppendDescriptionsFromResults(*result);
169 void AddChildView() {
170 MarkAsRespondsToTouch(&child_);
171 child_.SetVisible(true);
172 root_.Add(&child_);
173 child_.SetBounds(gfx::Rect(0, 0, 100, 100));
176 protected:
177 TestServerViewDelegate view_delegate_;
178 ServerView root_;
179 ServerView child_;
180 TestGestureManagerDelegate gesture_delegate_;
181 GestureManager gesture_manager_;
183 private:
184 DISALLOW_COPY_AND_ASSIGN(GestureManagerTest);
187 TEST_F(GestureManagerTest, SingleViewAndSingleGesture) {
188 const int32_t pointer_id = 1;
189 gesture_manager_.ProcessEvent(
190 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
191 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
192 gesture_delegate_.GetAndClearDescriptions());
194 // Choose this pointer.
195 SetGestures(&root_, pointer_id, 10u, SetWith(10u), std::set<uint32_t>());
196 EXPECT_EQ("connection=1 chosen=10",
197 gesture_delegate_.GetAndClearDescriptions());
200 TEST_F(GestureManagerTest, SingleViewAndTwoGestures) {
201 const int32_t pointer_id = 1;
202 gesture_manager_.ProcessEvent(
203 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
204 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
205 gesture_delegate_.GetAndClearDescriptions());
207 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
208 std::set<uint32_t>());
210 // Delegate should have got nothing.
211 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
213 // Cancel 10, 5 should become active.
214 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
215 SetWith(10u));
217 EXPECT_EQ("connection=1 chosen=5 canceled=10",
218 gesture_delegate_.GetAndClearDescriptions());
221 TEST_F(GestureManagerTest, TwoViewsSingleGesture) {
222 AddChildView();
224 const int32_t pointer_id = 1;
225 gesture_manager_.ProcessEvent(
226 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
227 // Deepest child should be queried first.
228 EXPECT_EQ("down pointer=1 connection=2 chosen=false",
229 gesture_delegate_.GetAndClearDescriptions());
231 // Respond from the first view, which triggers the second to be queried.
232 SetGestures(&child_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
233 std::set<uint32_t>());
234 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
235 gesture_delegate_.GetAndClearDescriptions());
237 // Respond with 5,10 for the second view. Should get nothing.
238 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
239 std::set<uint32_t>());
240 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
242 // Cancel 10 in the child.
243 SetGestures(&child_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
244 SetWith(10u));
245 EXPECT_EQ("connection=2 canceled=10",
246 gesture_delegate_.GetAndClearDescriptions());
248 // Choose 5 in the root. This should choose 5 in the root and cancel 5 in
249 // the child.
250 SetGestures(&root_, pointer_id, 5u, SetWith(5u, 10u), SetWith(10u));
251 ASSERT_EQ(2u, gesture_delegate_.descriptions().size());
252 EXPECT_EQ("connection=1 chosen=5 canceled=10",
253 gesture_delegate_.descriptions()[0]);
254 EXPECT_EQ("connection=2 canceled=5", gesture_delegate_.descriptions()[1]);
257 TEST_F(GestureManagerTest, TwoViewsWaitForMoveToChoose) {
258 AddChildView();
260 const int32_t pointer_id = 1;
261 gesture_manager_.ProcessEvent(
262 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
263 // Deepest child should be queried first.
264 EXPECT_EQ("down pointer=1 connection=2 chosen=false",
265 gesture_delegate_.GetAndClearDescriptions());
267 // Send a move. The move should not be processed as GestureManager is
268 // still waiting for responses.
269 gesture_manager_.ProcessEvent(
270 *CreateEvent(mojo::EVENT_TYPE_POINTER_MOVE, pointer_id, 6, 6));
271 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
273 // Respond from the first view, which triggers the second to be queried.
274 SetGestures(&child_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
275 std::set<uint32_t>());
276 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
277 gesture_delegate_.GetAndClearDescriptions());
279 // Respond with 1,2 for the second view.
280 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(1u, 2u),
281 std::set<uint32_t>());
282 // Now that we've responded to the down requests we should get a move for the
283 // child.
284 EXPECT_EQ("move pointer=1 connection=2 chosen=false",
285 gesture_delegate_.GetAndClearDescriptions());
287 // Respond for the child, root should now get move.
288 SetGestures(&child_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
289 std::set<uint32_t>());
290 EXPECT_EQ("move pointer=1 connection=1 chosen=false",
291 gesture_delegate_.GetAndClearDescriptions());
293 // Respond with nothing chosen for the root. Nothing should come in as no
294 // pending moves.
295 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(1u, 2u),
296 std::set<uint32_t>());
297 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
299 // Send another move event and respond with a chosen id.
300 gesture_manager_.ProcessEvent(
301 *CreateEvent(mojo::EVENT_TYPE_POINTER_MOVE, pointer_id, 7, 7));
302 EXPECT_EQ("move pointer=1 connection=2 chosen=false",
303 gesture_delegate_.GetAndClearDescriptions());
304 SetGestures(&child_, pointer_id, 5u, SetWith(5u, 10u), std::set<uint32_t>());
305 ASSERT_EQ(3u, gesture_delegate_.descriptions().size());
306 // Now that a gesture is chosen the move event is generated.
307 EXPECT_EQ("move pointer=1 connection=1 chosen=true",
308 gesture_delegate_.descriptions()[0]);
309 EXPECT_EQ("connection=1 canceled=1,2", gesture_delegate_.descriptions()[1]);
310 EXPECT_EQ("connection=2 chosen=5 canceled=10",
311 gesture_delegate_.descriptions()[2]);
314 TEST_F(GestureManagerTest, SingleViewNewPointerAfterChoose) {
315 const int32_t pointer_id = 1;
316 gesture_manager_.ProcessEvent(
317 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
318 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
319 gesture_delegate_.GetAndClearDescriptions());
321 // Choose 5.
322 SetGestures(&root_, pointer_id, 5u, SetWith(5u, 10u), std::set<uint32_t>());
323 EXPECT_EQ("connection=1 chosen=5 canceled=10",
324 gesture_delegate_.GetAndClearDescriptions());
326 // Start another down event with a different pointer.
327 const int32_t pointer_id2 = 2;
328 gesture_manager_.ProcessEvent(
329 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id2, 5, 5));
330 EXPECT_EQ("down pointer=2 connection=1 chosen=false",
331 gesture_delegate_.GetAndClearDescriptions());
333 // For the new pointer supply the id of a gesture that has been chosen.
334 // Even though we didn't explicitly supply 5 as chosen, 5 is chosen because
335 // it's already in the chosen state for pointer 1.
336 SetGestures(&root_, pointer_id2, kInvalidGestureId, SetWith(5u, 11u),
337 std::set<uint32_t>());
338 EXPECT_EQ("connection=1 chosen=5 canceled=11",
339 gesture_delegate_.GetAndClearDescriptions());
342 TEST_F(GestureManagerTest, SingleViewChoosingConflictingGestures) {
343 // For pointer1 choose 1 with 1,2,3 as possibilities.
344 const int32_t pointer1 = 1;
345 gesture_manager_.ProcessEvent(
346 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer1, 5, 5));
347 gesture_delegate_.GetAndClearDescriptions();
348 SetGestures(&root_, pointer1, 1u, SetWith(1u, 2u, 3u), std::set<uint32_t>());
349 EXPECT_EQ("connection=1 chosen=1 canceled=2,3",
350 gesture_delegate_.GetAndClearDescriptions());
352 // For pointer2 choose 11 with 11,12 as possibilities.
353 const int32_t pointer2 = 2;
354 gesture_manager_.ProcessEvent(
355 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer2, 5, 5));
356 gesture_delegate_.GetAndClearDescriptions();
357 SetGestures(&root_, pointer2, 11u, SetWith(11u, 12u), std::set<uint32_t>());
358 EXPECT_EQ("connection=1 chosen=11 canceled=12",
359 gesture_delegate_.GetAndClearDescriptions());
361 // For pointer3 choose 21 with 1,11,21 as possibilties.
362 const int32_t pointer3 = 3;
363 gesture_manager_.ProcessEvent(
364 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer3, 5, 5));
365 gesture_delegate_.GetAndClearDescriptions();
366 SetGestures(&root_, pointer3, 21u, SetWith(1u, 11u, 21u),
367 std::set<uint32_t>());
368 EXPECT_EQ("connection=1 chosen=21 canceled=1,11",
369 gesture_delegate_.GetAndClearDescriptions());
372 TEST_F(GestureManagerTest,
373 TwoViewsRespondingWithChosenGestureSendsRemainingEvents) {
374 AddChildView();
376 // Start two pointer downs, don't respond to either.
377 const int32_t pointer1 = 1;
378 gesture_manager_.ProcessEvent(
379 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer1, 5, 5));
380 EXPECT_EQ("down pointer=1 connection=2 chosen=false",
381 gesture_delegate_.GetAndClearDescriptions());
383 const int32_t pointer2 = 2;
384 gesture_manager_.ProcessEvent(
385 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer2, 5, 5));
386 EXPECT_EQ("down pointer=2 connection=2 chosen=false",
387 gesture_delegate_.GetAndClearDescriptions());
389 // Queue up a move event for pointer1. The event should not be forwarded
390 // as we're still waiting.
391 gesture_manager_.ProcessEvent(
392 *CreateEvent(mojo::EVENT_TYPE_POINTER_MOVE, pointer1, 5, 5));
393 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
395 // Respond with 1,2 for pointer1 (nothing chosen yet).
396 SetGestures(&child_, pointer1, kInvalidGestureId, SetWith(1u, 2u),
397 std::set<uint32_t>());
398 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
399 gesture_delegate_.GetAndClearDescriptions());
401 // Respond with 1,2 and choose 1 for pointer2. This results in the following:
402 // down for pointer 1 (because we chose a gesture in common with pointer1),
403 // move for pointer 1 in both connections (because a gesture was chosen queued
404 // up events are sent), down for pointer2 for the root and finally
405 // notification of what was chosen.
406 SetGestures(&child_, pointer2, 1u, SetWith(1u, 2u), std::set<uint32_t>());
407 ASSERT_EQ(5u, gesture_delegate_.descriptions().size());
408 EXPECT_EQ("down pointer=1 connection=1 chosen=true",
409 gesture_delegate_.descriptions()[0]);
410 EXPECT_EQ("move pointer=1 connection=2 chosen=true",
411 gesture_delegate_.descriptions()[1]);
412 EXPECT_EQ("move pointer=1 connection=1 chosen=true",
413 gesture_delegate_.descriptions()[2]);
414 EXPECT_EQ("down pointer=2 connection=1 chosen=true",
415 gesture_delegate_.descriptions()[3]);
416 EXPECT_EQ("connection=2 chosen=1 canceled=2",
417 gesture_delegate_.descriptions()[4]);
420 TEST_F(GestureManagerTest, TwoViewsSingleGestureUp) {
421 AddChildView();
423 const int32_t pointer_id = 1;
424 gesture_manager_.ProcessEvent(
425 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
426 // Deepest child should be queried first.
427 EXPECT_EQ("down pointer=1 connection=2 chosen=false",
428 gesture_delegate_.GetAndClearDescriptions());
430 // Send an up, shouldn't result in anything.
431 gesture_manager_.ProcessEvent(
432 *CreateEvent(mojo::EVENT_TYPE_POINTER_UP, pointer_id, 5, 5));
433 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
435 // Respond from the first view, with a chosen gesture.
436 SetGestures(&child_, pointer_id, 5u, SetWith(5u, 10u), std::set<uint32_t>());
437 ASSERT_EQ(4u, gesture_delegate_.descriptions().size());
438 EXPECT_EQ("down pointer=1 connection=1 chosen=true",
439 gesture_delegate_.descriptions()[0]);
440 EXPECT_EQ("up pointer=1 connection=2 chosen=true",
441 gesture_delegate_.descriptions()[1]);
442 EXPECT_EQ("up pointer=1 connection=1 chosen=true",
443 gesture_delegate_.descriptions()[2]);
444 EXPECT_EQ("connection=2 chosen=5 canceled=10",
445 gesture_delegate_.descriptions()[3]);
448 TEST_F(GestureManagerTest, SingleViewSingleGestureCancel) {
449 const int32_t pointer_id = 1;
450 gesture_manager_.ProcessEvent(
451 *CreateEvent(mojo::EVENT_TYPE_POINTER_DOWN, pointer_id, 5, 5));
452 EXPECT_EQ("down pointer=1 connection=1 chosen=false",
453 gesture_delegate_.GetAndClearDescriptions());
455 // Send a cancel, shouldn't result in anything.
456 gesture_manager_.ProcessEvent(
457 *CreateEvent(mojo::EVENT_TYPE_POINTER_CANCEL, pointer_id, 5, 5));
458 EXPECT_EQ(std::string(), gesture_delegate_.GetAndClearDescriptions());
460 // Respond from the first view, with no gesture, should unblock cancel.
461 SetGestures(&root_, pointer_id, kInvalidGestureId, SetWith(5u, 10u),
462 std::set<uint32_t>());
463 EXPECT_EQ("cancel pointer=1 connection=1 chosen=false",
464 gesture_delegate_.GetAndClearDescriptions());
467 } // namespace view_manager