1// Copyright (c) 2013 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.
4
5#include <vector>
6
7#include "testing/gtest/include/gtest/gtest.h"
8#include "ui/events/event.h"
9#include "ui/events/event_targeter.h"
10#include "ui/events/test/events_test_utils.h"
11#include "ui/events/test/test_event_handler.h"
12#include "ui/events/test/test_event_processor.h"
13#include "ui/events/test/test_event_target.h"
14
15typedef std::vector<std::string> HandlerSequenceRecorder;
16
17namespace ui {
18namespace test {
19
20class EventProcessorTest : public testing::Test {
21 public:
22  EventProcessorTest() {}
23  virtual ~EventProcessorTest() {}
24
25  // testing::Test:
26  virtual void SetUp() OVERRIDE {
27    processor_.SetRoot(scoped_ptr<EventTarget>(new TestEventTarget()));
28    processor_.ResetCounts();
29    root()->SetEventTargeter(make_scoped_ptr(new EventTargeter()));
30  }
31
32  TestEventTarget* root() {
33    return static_cast<TestEventTarget*>(processor_.GetRootTarget());
34  }
35
36  TestEventProcessor* processor() {
37    return &processor_;
38  }
39
40  void DispatchEvent(Event* event) {
41    processor_.OnEventFromSource(event);
42  }
43
44 protected:
45  TestEventProcessor processor_;
46
47  DISALLOW_COPY_AND_ASSIGN(EventProcessorTest);
48};
49
50TEST_F(EventProcessorTest, Basic) {
51  scoped_ptr<TestEventTarget> child(new TestEventTarget());
52  root()->AddChild(child.Pass());
53
54  MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
55                   EF_NONE, EF_NONE);
56  DispatchEvent(&mouse);
57  EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
58  EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
59
60  root()->RemoveChild(root()->child_at(0));
61  DispatchEvent(&mouse);
62  EXPECT_TRUE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
63}
64
65template<typename T>
66class BoundsEventTargeter : public EventTargeter {
67 public:
68  virtual ~BoundsEventTargeter() {}
69
70 protected:
71  virtual bool SubtreeShouldBeExploredForEvent(
72      EventTarget* target, const LocatedEvent& event) OVERRIDE {
73    T* t = static_cast<T*>(target);
74    return (t->bounds().Contains(event.location()));
75  }
76};
77
78class BoundsTestTarget : public TestEventTarget {
79 public:
80  BoundsTestTarget() {}
81  virtual ~BoundsTestTarget() {}
82
83  void set_bounds(gfx::Rect rect) { bounds_ = rect; }
84  gfx::Rect bounds() const { return bounds_; }
85
86  static void ConvertPointToTarget(BoundsTestTarget* source,
87                                   BoundsTestTarget* target,
88                                   gfx::Point* location) {
89    gfx::Vector2d vector;
90    if (source->Contains(target)) {
91      for (; target && target != source;
92           target = static_cast<BoundsTestTarget*>(target->parent())) {
93        vector += target->bounds().OffsetFromOrigin();
94      }
95      *location -= vector;
96    } else if (target->Contains(source)) {
97      for (; source && source != target;
98           source = static_cast<BoundsTestTarget*>(source->parent())) {
99        vector += source->bounds().OffsetFromOrigin();
100      }
101      *location += vector;
102    } else {
103      NOTREACHED();
104    }
105  }
106
107 private:
108  // EventTarget:
109  virtual void ConvertEventToTarget(EventTarget* target,
110                                    LocatedEvent* event) OVERRIDE {
111    event->ConvertLocationToTarget(this,
112                                   static_cast<BoundsTestTarget*>(target));
113  }
114
115  gfx::Rect bounds_;
116
117  DISALLOW_COPY_AND_ASSIGN(BoundsTestTarget);
118};
119
120TEST_F(EventProcessorTest, Bounds) {
121  scoped_ptr<BoundsTestTarget> parent(new BoundsTestTarget());
122  scoped_ptr<BoundsTestTarget> child(new BoundsTestTarget());
123  scoped_ptr<BoundsTestTarget> grandchild(new BoundsTestTarget());
124
125  parent->set_bounds(gfx::Rect(0, 0, 30, 30));
126  child->set_bounds(gfx::Rect(5, 5, 20, 20));
127  grandchild->set_bounds(gfx::Rect(5, 5, 5, 5));
128
129  child->AddChild(scoped_ptr<TestEventTarget>(grandchild.Pass()));
130  parent->AddChild(scoped_ptr<TestEventTarget>(child.Pass()));
131  root()->AddChild(scoped_ptr<TestEventTarget>(parent.Pass()));
132
133  ASSERT_EQ(1u, root()->child_count());
134  ASSERT_EQ(1u, root()->child_at(0)->child_count());
135  ASSERT_EQ(1u, root()->child_at(0)->child_at(0)->child_count());
136
137  TestEventTarget* parent_r = root()->child_at(0);
138  TestEventTarget* child_r = parent_r->child_at(0);
139  TestEventTarget* grandchild_r = child_r->child_at(0);
140
141  // Dispatch a mouse event that falls on the parent, but not on the child. When
142  // the default event-targeter used, the event will still reach |grandchild|,
143  // because the default targeter does not look at the bounds.
144  MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(1, 1), EF_NONE,
145                   EF_NONE);
146  DispatchEvent(&mouse);
147  EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
148  EXPECT_FALSE(parent_r->DidReceiveEvent(ET_MOUSE_MOVED));
149  EXPECT_FALSE(child_r->DidReceiveEvent(ET_MOUSE_MOVED));
150  EXPECT_TRUE(grandchild_r->DidReceiveEvent(ET_MOUSE_MOVED));
151  grandchild_r->ResetReceivedEvents();
152
153  // Now install a targeter on the parent that looks at the bounds and makes
154  // sure the event reaches the target only if the location of the event within
155  // the bounds of the target.
156  MouseEvent mouse2(ET_MOUSE_MOVED, gfx::Point(1, 1), gfx::Point(1, 1), EF_NONE,
157                    EF_NONE);
158  parent_r->SetEventTargeter(scoped_ptr<EventTargeter>(
159      new BoundsEventTargeter<BoundsTestTarget>()));
160  DispatchEvent(&mouse2);
161  EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
162  EXPECT_TRUE(parent_r->DidReceiveEvent(ET_MOUSE_MOVED));
163  EXPECT_FALSE(child_r->DidReceiveEvent(ET_MOUSE_MOVED));
164  EXPECT_FALSE(grandchild_r->DidReceiveEvent(ET_MOUSE_MOVED));
165  parent_r->ResetReceivedEvents();
166
167  MouseEvent second(ET_MOUSE_MOVED, gfx::Point(12, 12), gfx::Point(12, 12),
168                    EF_NONE, EF_NONE);
169  DispatchEvent(&second);
170  EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
171  EXPECT_FALSE(parent_r->DidReceiveEvent(ET_MOUSE_MOVED));
172  EXPECT_FALSE(child_r->DidReceiveEvent(ET_MOUSE_MOVED));
173  EXPECT_TRUE(grandchild_r->DidReceiveEvent(ET_MOUSE_MOVED));
174}
175
176// ReDispatchEventHandler is used to receive mouse events and forward them
177// to a specified EventProcessor. Verifies that the event has the correct
178// target and phase both before and after the nested event processing. Also
179// verifies that the location of the event remains the same after it has
180// been processed by the second EventProcessor.
181class ReDispatchEventHandler : public TestEventHandler {
182 public:
183  ReDispatchEventHandler(EventProcessor* processor, EventTarget* target)
184      : processor_(processor), expected_target_(target) {}
185  virtual ~ReDispatchEventHandler() {}
186
187  // TestEventHandler:
188  virtual void OnMouseEvent(MouseEvent* event) OVERRIDE {
189    TestEventHandler::OnMouseEvent(event);
190
191    EXPECT_EQ(expected_target_, event->target());
192    EXPECT_EQ(EP_TARGET, event->phase());
193
194    gfx::Point location(event->location());
195    EventDispatchDetails details = processor_->OnEventFromSource(event);
196    EXPECT_FALSE(details.dispatcher_destroyed);
197    EXPECT_FALSE(details.target_destroyed);
198
199    // The nested event-processing should not have mutated the target,
200    // phase, or location of |event|.
201    EXPECT_EQ(expected_target_, event->target());
202    EXPECT_EQ(EP_TARGET, event->phase());
203    EXPECT_EQ(location, event->location());
204  }
205
206 private:
207  EventProcessor* processor_;
208  EventTarget* expected_target_;
209
210  DISALLOW_COPY_AND_ASSIGN(ReDispatchEventHandler);
211};
212
213// Verifies that the phase and target information of an event is not mutated
214// as a result of sending the event to an event processor while it is still
215// being processed by another event processor.
216TEST_F(EventProcessorTest, NestedEventProcessing) {
217  // Add one child to the default event processor used in this test suite.
218  scoped_ptr<TestEventTarget> child(new TestEventTarget());
219  root()->AddChild(child.Pass());
220
221  // Define a second root target and child.
222  scoped_ptr<EventTarget> second_root_scoped(new TestEventTarget());
223  TestEventTarget* second_root =
224      static_cast<TestEventTarget*>(second_root_scoped.get());
225  second_root->SetEventTargeter(make_scoped_ptr(new EventTargeter()));
226  scoped_ptr<TestEventTarget> second_child(new TestEventTarget());
227  second_root->AddChild(second_child.Pass());
228
229  // Define a second event processor which owns the second root.
230  scoped_ptr<TestEventProcessor> second_processor(new TestEventProcessor());
231  second_processor->SetRoot(second_root_scoped.Pass());
232
233  // Indicate that an event which is dispatched to the child target owned by the
234  // first event processor should be handled by |target_handler| instead.
235  scoped_ptr<TestEventHandler> target_handler(
236      new ReDispatchEventHandler(second_processor.get(), root()->child_at(0)));
237  root()->child_at(0)->set_target_handler(target_handler.get());
238
239  // Dispatch a mouse event to the tree of event targets owned by the first
240  // event processor, checking in ReDispatchEventHandler that the phase and
241  // target information of the event is correct.
242  MouseEvent mouse(
243      ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10), EF_NONE, EF_NONE);
244  DispatchEvent(&mouse);
245
246  // Verify also that |mouse| was seen by the child nodes contained in both
247  // event processors and that the event was not handled.
248  EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
249  EXPECT_TRUE(second_root->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
250  EXPECT_FALSE(mouse.handled());
251  second_root->child_at(0)->ResetReceivedEvents();
252  root()->child_at(0)->ResetReceivedEvents();
253
254  // Indicate that the child of the second root should handle events, and
255  // dispatch another mouse event to verify that it is marked as handled.
256  second_root->child_at(0)->set_mark_events_as_handled(true);
257  MouseEvent mouse2(
258      ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10), EF_NONE, EF_NONE);
259  DispatchEvent(&mouse2);
260  EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
261  EXPECT_TRUE(second_root->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
262  EXPECT_TRUE(mouse2.handled());
263}
264
265// Verifies that OnEventProcessingFinished() is called when an event
266// has been handled.
267TEST_F(EventProcessorTest, OnEventProcessingFinished) {
268  scoped_ptr<TestEventTarget> child(new TestEventTarget());
269  child->set_mark_events_as_handled(true);
270  root()->AddChild(child.Pass());
271
272  // Dispatch a mouse event. We expect the event to be seen by the target,
273  // handled, and we expect OnEventProcessingFinished() to be invoked once.
274  MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
275                   EF_NONE, EF_NONE);
276  DispatchEvent(&mouse);
277  EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
278  EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
279  EXPECT_TRUE(mouse.handled());
280  EXPECT_EQ(1, processor()->num_times_processing_finished());
281}
282
283class IgnoreEventTargeter : public EventTargeter {
284 public:
285  IgnoreEventTargeter() {}
286  virtual ~IgnoreEventTargeter() {}
287
288 private:
289  // EventTargeter:
290  virtual bool SubtreeShouldBeExploredForEvent(
291      EventTarget* target, const LocatedEvent& event) OVERRIDE {
292    return false;
293  }
294};
295
296// Verifies that the EventTargeter installed on an EventTarget can dictate
297// whether the target itself can process an event.
298TEST_F(EventProcessorTest, TargeterChecksOwningEventTarget) {
299  scoped_ptr<TestEventTarget> child(new TestEventTarget());
300  root()->AddChild(child.Pass());
301
302  MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
303                   EF_NONE, EF_NONE);
304  DispatchEvent(&mouse);
305  EXPECT_TRUE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
306  EXPECT_FALSE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
307  root()->child_at(0)->ResetReceivedEvents();
308
309  // Install an event handler on |child| which always prevents the target from
310  // receiving event.
311  root()->child_at(0)->SetEventTargeter(
312      scoped_ptr<EventTargeter>(new IgnoreEventTargeter()));
313  MouseEvent mouse2(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
314                    EF_NONE, EF_NONE);
315  DispatchEvent(&mouse2);
316  EXPECT_FALSE(root()->child_at(0)->DidReceiveEvent(ET_MOUSE_MOVED));
317  EXPECT_TRUE(root()->DidReceiveEvent(ET_MOUSE_MOVED));
318}
319
320// An EventTargeter which is used to allow a bubbling behaviour in event
321// dispatch: if an event is not handled after being dispatched to its
322// initial target, the event is dispatched to the next-best target as
323// specified by FindNextBestTarget().
324class BubblingEventTargeter : public EventTargeter {
325 public:
326  explicit BubblingEventTargeter(TestEventTarget* initial_target)
327    : initial_target_(initial_target) {}
328  virtual ~BubblingEventTargeter() {}
329
330 private:
331  // EventTargeter:
332  virtual EventTarget* FindTargetForEvent(EventTarget* root,
333                                          Event* event) OVERRIDE {
334    return initial_target_;
335  }
336
337  virtual EventTarget* FindNextBestTarget(EventTarget* previous_target,
338                                          Event* event) OVERRIDE {
339    return previous_target->GetParentTarget();
340  }
341
342  TestEventTarget* initial_target_;
343
344  DISALLOW_COPY_AND_ASSIGN(BubblingEventTargeter);
345};
346
347// Tests that unhandled events are correctly dispatched to the next-best
348// target as decided by the BubblingEventTargeter.
349TEST_F(EventProcessorTest, DispatchToNextBestTarget) {
350  scoped_ptr<TestEventTarget> child(new TestEventTarget());
351  scoped_ptr<TestEventTarget> grandchild(new TestEventTarget());
352
353  root()->SetEventTargeter(
354      scoped_ptr<EventTargeter>(new BubblingEventTargeter(grandchild.get())));
355  child->AddChild(grandchild.Pass());
356  root()->AddChild(child.Pass());
357
358  ASSERT_EQ(1u, root()->child_count());
359  ASSERT_EQ(1u, root()->child_at(0)->child_count());
360  ASSERT_EQ(0u, root()->child_at(0)->child_at(0)->child_count());
361
362  TestEventTarget* child_r = root()->child_at(0);
363  TestEventTarget* grandchild_r = child_r->child_at(0);
364
365  // When the root has a BubblingEventTargeter installed, events targeted
366  // at the grandchild target should be dispatched to all three targets.
367  KeyEvent key_event(ET_KEY_PRESSED, VKEY_ESCAPE, EF_NONE);
368  DispatchEvent(&key_event);
369  EXPECT_TRUE(root()->DidReceiveEvent(ET_KEY_PRESSED));
370  EXPECT_TRUE(child_r->DidReceiveEvent(ET_KEY_PRESSED));
371  EXPECT_TRUE(grandchild_r->DidReceiveEvent(ET_KEY_PRESSED));
372  root()->ResetReceivedEvents();
373  child_r->ResetReceivedEvents();
374  grandchild_r->ResetReceivedEvents();
375
376  // Add a pre-target handler on the child of the root that will mark the event
377  // as handled. No targets in the hierarchy should receive the event.
378  TestEventHandler handler;
379  child_r->AddPreTargetHandler(&handler);
380  key_event = KeyEvent(ET_KEY_PRESSED, VKEY_ESCAPE, EF_NONE);
381  DispatchEvent(&key_event);
382  EXPECT_FALSE(root()->DidReceiveEvent(ET_KEY_PRESSED));
383  EXPECT_FALSE(child_r->DidReceiveEvent(ET_KEY_PRESSED));
384  EXPECT_FALSE(grandchild_r->DidReceiveEvent(ET_KEY_PRESSED));
385  EXPECT_EQ(1, handler.num_key_events());
386  handler.Reset();
387
388  // Add a post-target handler on the child of the root that will mark the event
389  // as handled. Only the grandchild (the initial target) should receive the
390  // event.
391  child_r->RemovePreTargetHandler(&handler);
392  child_r->AddPostTargetHandler(&handler);
393  key_event = KeyEvent(ET_KEY_PRESSED, VKEY_ESCAPE, EF_NONE);
394  DispatchEvent(&key_event);
395  EXPECT_FALSE(root()->DidReceiveEvent(ET_KEY_PRESSED));
396  EXPECT_FALSE(child_r->DidReceiveEvent(ET_KEY_PRESSED));
397  EXPECT_TRUE(grandchild_r->DidReceiveEvent(ET_KEY_PRESSED));
398  EXPECT_EQ(1, handler.num_key_events());
399  handler.Reset();
400  grandchild_r->ResetReceivedEvents();
401  child_r->RemovePostTargetHandler(&handler);
402
403  // Mark the event as handled when it reaches the EP_TARGET phase of
404  // dispatch at the child of the root. The child and grandchild
405  // targets should both receive the event, but the root should not.
406  child_r->set_mark_events_as_handled(true);
407  key_event = KeyEvent(ET_KEY_PRESSED, VKEY_ESCAPE, EF_NONE);
408  DispatchEvent(&key_event);
409  EXPECT_FALSE(root()->DidReceiveEvent(ET_KEY_PRESSED));
410  EXPECT_TRUE(child_r->DidReceiveEvent(ET_KEY_PRESSED));
411  EXPECT_TRUE(grandchild_r->DidReceiveEvent(ET_KEY_PRESSED));
412  root()->ResetReceivedEvents();
413  child_r->ResetReceivedEvents();
414  grandchild_r->ResetReceivedEvents();
415  child_r->set_mark_events_as_handled(false);
416}
417
418// Tests that unhandled events are seen by the correct sequence of
419// targets, pre-target handlers, and post-target handlers when
420// a BubblingEventTargeter is installed on the root target.
421TEST_F(EventProcessorTest, HandlerSequence) {
422  scoped_ptr<TestEventTarget> child(new TestEventTarget());
423  scoped_ptr<TestEventTarget> grandchild(new TestEventTarget());
424
425  root()->SetEventTargeter(
426      scoped_ptr<EventTargeter>(new BubblingEventTargeter(grandchild.get())));
427  child->AddChild(grandchild.Pass());
428  root()->AddChild(child.Pass());
429
430  ASSERT_EQ(1u, root()->child_count());
431  ASSERT_EQ(1u, root()->child_at(0)->child_count());
432  ASSERT_EQ(0u, root()->child_at(0)->child_at(0)->child_count());
433
434  TestEventTarget* child_r = root()->child_at(0);
435  TestEventTarget* grandchild_r = child_r->child_at(0);
436
437  HandlerSequenceRecorder recorder;
438  root()->set_target_name("R");
439  root()->set_recorder(&recorder);
440  child_r->set_target_name("C");
441  child_r->set_recorder(&recorder);
442  grandchild_r->set_target_name("G");
443  grandchild_r->set_recorder(&recorder);
444
445  TestEventHandler pre_root;
446  pre_root.set_handler_name("PreR");
447  pre_root.set_recorder(&recorder);
448  root()->AddPreTargetHandler(&pre_root);
449
450  TestEventHandler pre_child;
451  pre_child.set_handler_name("PreC");
452  pre_child.set_recorder(&recorder);
453  child_r->AddPreTargetHandler(&pre_child);
454
455  TestEventHandler pre_grandchild;
456  pre_grandchild.set_handler_name("PreG");
457  pre_grandchild.set_recorder(&recorder);
458  grandchild_r->AddPreTargetHandler(&pre_grandchild);
459
460  TestEventHandler post_root;
461  post_root.set_handler_name("PostR");
462  post_root.set_recorder(&recorder);
463  root()->AddPostTargetHandler(&post_root);
464
465  TestEventHandler post_child;
466  post_child.set_handler_name("PostC");
467  post_child.set_recorder(&recorder);
468  child_r->AddPostTargetHandler(&post_child);
469
470  TestEventHandler post_grandchild;
471  post_grandchild.set_handler_name("PostG");
472  post_grandchild.set_recorder(&recorder);
473  grandchild_r->AddPostTargetHandler(&post_grandchild);
474
475  MouseEvent mouse(ET_MOUSE_MOVED, gfx::Point(10, 10), gfx::Point(10, 10),
476                   EF_NONE, EF_NONE);
477  DispatchEvent(&mouse);
478
479  std::string expected[] = { "PreR", "PreC", "PreG", "G", "PostG", "PostC",
480      "PostR", "PreR", "PreC", "C", "PostC", "PostR", "PreR", "R", "PostR" };
481  EXPECT_EQ(std::vector<std::string>(
482      expected, expected + arraysize(expected)), recorder);
483}
484
485}  // namespace test
486}  // namespace ui
487