scoped_target_handler_unittest.cc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  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.
  4. #include "ui/events/scoped_target_handler.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "base/memory/ptr_util.h"
  8. #include "base/memory/raw_ptr.h"
  9. #include "testing/gtest/include/gtest/gtest.h"
  10. #include "ui/events/event_handler.h"
  11. #include "ui/events/event_target.h"
  12. #include "ui/events/event_target_iterator.h"
  13. #include "ui/events/event_utils.h"
  14. namespace ui {
  15. namespace {
  16. class TestEventTargetIterator : public EventTargetIterator {
  17. public:
  18. TestEventTargetIterator() {}
  19. TestEventTargetIterator(const TestEventTargetIterator&) = delete;
  20. TestEventTargetIterator& operator=(const TestEventTargetIterator&) = delete;
  21. // EventTargetIterator:
  22. EventTarget* GetNextTarget() override { return nullptr; }
  23. };
  24. // An EventTarget that holds ownership of its target and delegate EventHandlers.
  25. class TestEventTarget : public EventTarget {
  26. public:
  27. TestEventTarget() {}
  28. TestEventTarget(const TestEventTarget&) = delete;
  29. TestEventTarget& operator=(const TestEventTarget&) = delete;
  30. ~TestEventTarget() override {}
  31. void SetHandler(std::unique_ptr<EventHandler> target_handler,
  32. std::unique_ptr<EventHandler> delegate) {
  33. target_handler_ = std::move(target_handler);
  34. delegate_ = std::move(delegate);
  35. }
  36. // EventTarget:
  37. void DispatchEvent(Event* event) { target_handler()->OnEvent(event); }
  38. bool CanAcceptEvent(const Event& event) override { return true; }
  39. EventTarget* GetParentTarget() override { return nullptr; }
  40. std::unique_ptr<EventTargetIterator> GetChildIterator() const override {
  41. return base::WrapUnique(new TestEventTargetIterator);
  42. }
  43. EventTargeter* GetEventTargeter() override { return nullptr; }
  44. private:
  45. std::unique_ptr<EventHandler> target_handler_;
  46. std::unique_ptr<EventHandler> delegate_;
  47. };
  48. // An EventHandler that sets itself as a target handler for an EventTarget and
  49. // can recursively dispatch an Event.
  50. class NestedEventHandler : public EventHandler {
  51. public:
  52. NestedEventHandler(TestEventTarget* target, int nesting)
  53. : target_(target), nesting_(nesting) {
  54. original_handler_ = target_->SetTargetHandler(this);
  55. }
  56. NestedEventHandler(const NestedEventHandler&) = delete;
  57. NestedEventHandler& operator=(const NestedEventHandler&) = delete;
  58. ~NestedEventHandler() override {
  59. EventHandler* handler = target_->SetTargetHandler(original_handler_);
  60. DCHECK_EQ(this, handler);
  61. }
  62. protected:
  63. void OnEvent(Event* event) override {
  64. if (--nesting_ == 0)
  65. return;
  66. target_->DispatchEvent(event);
  67. }
  68. private:
  69. raw_ptr<TestEventTarget> target_;
  70. int nesting_;
  71. raw_ptr<EventHandler> original_handler_;
  72. };
  73. // An EventHandler that sets itself as a target handler for an EventTarget and
  74. // destroys that EventTarget when handling an Event, possibly after recursively
  75. // handling the Event.
  76. class TargetDestroyingEventHandler : public EventHandler {
  77. public:
  78. TargetDestroyingEventHandler(TestEventTarget* target, int nesting)
  79. : target_(target), nesting_(nesting) {
  80. original_handler_ = target_->SetTargetHandler(this);
  81. }
  82. TargetDestroyingEventHandler(const TargetDestroyingEventHandler&) = delete;
  83. TargetDestroyingEventHandler& operator=(const TargetDestroyingEventHandler&) =
  84. delete;
  85. ~TargetDestroyingEventHandler() override {
  86. EventHandler* handler = target_->SetTargetHandler(original_handler_);
  87. DCHECK_EQ(this, handler);
  88. }
  89. protected:
  90. void OnEvent(Event* event) override {
  91. if (--nesting_ == 0) {
  92. delete target_;
  93. return;
  94. }
  95. target_->DispatchEvent(event);
  96. }
  97. private:
  98. raw_ptr<TestEventTarget> target_;
  99. int nesting_;
  100. raw_ptr<EventHandler> original_handler_;
  101. };
  102. // An EventHandler that can be set to receive events in addition to the target
  103. // handler and counts the Events that it receives.
  104. class EventCountingEventHandler : public EventHandler {
  105. public:
  106. EventCountingEventHandler(EventTarget* target, int* count)
  107. : scoped_target_handler_(new ScopedTargetHandler(target, this)),
  108. count_(count) {}
  109. EventCountingEventHandler(const EventCountingEventHandler&) = delete;
  110. EventCountingEventHandler& operator=(const EventCountingEventHandler&) =
  111. delete;
  112. ~EventCountingEventHandler() override {}
  113. protected:
  114. void OnEvent(Event* event) override { (*count_)++; }
  115. private:
  116. std::unique_ptr<ScopedTargetHandler> scoped_target_handler_;
  117. raw_ptr<int> count_;
  118. };
  119. // An EventCountingEventHandler that will also mark the event to stop further
  120. // propataion.
  121. class EventStopPropagationHandler : public EventCountingEventHandler {
  122. public:
  123. EventStopPropagationHandler(EventTarget* target, int* count)
  124. : EventCountingEventHandler(target, count) {}
  125. EventStopPropagationHandler(const EventStopPropagationHandler&) = delete;
  126. EventStopPropagationHandler& operator=(const EventStopPropagationHandler&) =
  127. delete;
  128. ~EventStopPropagationHandler() override {}
  129. protected:
  130. void OnEvent(Event* event) override {
  131. EventCountingEventHandler::OnEvent(event);
  132. event->StopPropagation();
  133. }
  134. };
  135. } // namespace
  136. // Tests that a ScopedTargetHandler invokes both the target and a delegate.
  137. TEST(ScopedTargetHandlerTest, HandlerInvoked) {
  138. int count = 0;
  139. std::unique_ptr<TestEventTarget> target = std::make_unique<TestEventTarget>();
  140. std::unique_ptr<NestedEventHandler> target_handler(
  141. new NestedEventHandler(target.get(), 1));
  142. std::unique_ptr<EventCountingEventHandler> delegate(
  143. new EventCountingEventHandler(target.get(), &count));
  144. target->SetHandler(std::move(target_handler), std::move(delegate));
  145. MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
  146. EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
  147. EF_LEFT_MOUSE_BUTTON);
  148. target->DispatchEvent(&event);
  149. EXPECT_EQ(1, count);
  150. }
  151. // Tests that a ScopedTargetHandler invokes both the target and a delegate but
  152. // does not further propagate the event after a handler stops event propagation.
  153. TEST(ScopedTargetHandlerTest, HandlerInvokedOnceThenEventStopsPropagating) {
  154. int count = 0;
  155. std::unique_ptr<TestEventTarget> target = std::make_unique<TestEventTarget>();
  156. std::unique_ptr<NestedEventHandler> target_handler(
  157. new NestedEventHandler(target.get(), 3));
  158. std::unique_ptr<EventStopPropagationHandler> delegate(
  159. new EventStopPropagationHandler(target.get(), &count));
  160. target->SetHandler(std::move(target_handler), std::move(delegate));
  161. MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
  162. EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
  163. EF_LEFT_MOUSE_BUTTON);
  164. target->DispatchEvent(&event);
  165. EXPECT_EQ(1, count);
  166. }
  167. // Tests that a ScopedTargetHandler invokes both the target and a delegate when
  168. // an Event is dispatched recursively such as with synthetic events.
  169. TEST(ScopedTargetHandlerTest, HandlerInvokedNested) {
  170. int count = 0;
  171. std::unique_ptr<TestEventTarget> target = std::make_unique<TestEventTarget>();
  172. std::unique_ptr<NestedEventHandler> target_handler(
  173. new NestedEventHandler(target.get(), 2));
  174. std::unique_ptr<EventCountingEventHandler> delegate(
  175. new EventCountingEventHandler(target.get(), &count));
  176. target->SetHandler(std::move(target_handler), std::move(delegate));
  177. MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
  178. EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
  179. EF_LEFT_MOUSE_BUTTON);
  180. target->DispatchEvent(&event);
  181. EXPECT_EQ(2, count);
  182. }
  183. // Tests that a it is safe to delete a ScopedTargetHandler while handling an
  184. // event.
  185. TEST(ScopedTargetHandlerTest, SafeToDestroy) {
  186. int count = 0;
  187. TestEventTarget* target = new TestEventTarget;
  188. std::unique_ptr<TargetDestroyingEventHandler> target_handler(
  189. new TargetDestroyingEventHandler(target, 1));
  190. std::unique_ptr<EventCountingEventHandler> delegate(
  191. new EventCountingEventHandler(target, &count));
  192. target->SetHandler(std::move(target_handler), std::move(delegate));
  193. MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
  194. EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
  195. EF_LEFT_MOUSE_BUTTON);
  196. target->DispatchEvent(&event);
  197. EXPECT_EQ(0, count);
  198. }
  199. // Tests that a it is safe to delete a ScopedTargetHandler while handling an
  200. // event recursively.
  201. TEST(ScopedTargetHandlerTest, SafeToDestroyNested) {
  202. int count = 0;
  203. TestEventTarget* target = new TestEventTarget;
  204. std::unique_ptr<TargetDestroyingEventHandler> target_handler(
  205. new TargetDestroyingEventHandler(target, 2));
  206. std::unique_ptr<EventCountingEventHandler> delegate(
  207. new EventCountingEventHandler(target, &count));
  208. target->SetHandler(std::move(target_handler), std::move(delegate));
  209. MouseEvent event(ET_MOUSE_PRESSED, gfx::Point(), gfx::Point(),
  210. EventTimeForNow(), EF_LEFT_MOUSE_BUTTON,
  211. EF_LEFT_MOUSE_BUTTON);
  212. target->DispatchEvent(&event);
  213. EXPECT_EQ(0, count);
  214. }
  215. } // namespace ui