event_monitor_unittest.cc 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  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
  3. // found in the LICENSE file.
  4. #include "ui/views/event_monitor.h"
  5. #include <utility>
  6. #include "base/memory/raw_ptr.h"
  7. #include "ui/events/event_observer.h"
  8. #include "ui/events/test/event_generator.h"
  9. #include "ui/views/test/widget_test.h"
  10. #include "ui/views/widget/widget_utils.h"
  11. #if defined(USE_AURA)
  12. #include "ui/aura/window.h"
  13. #endif
  14. namespace views {
  15. namespace test {
  16. // A simple event observer that records the number of events.
  17. class TestEventObserver : public ui::EventObserver {
  18. public:
  19. TestEventObserver() = default;
  20. TestEventObserver(const TestEventObserver&) = delete;
  21. TestEventObserver& operator=(const TestEventObserver&) = delete;
  22. ~TestEventObserver() override = default;
  23. // ui::EventObserver:
  24. void OnEvent(const ui::Event& event) override { ++observed_event_count_; }
  25. size_t observed_event_count() const { return observed_event_count_; }
  26. private:
  27. size_t observed_event_count_ = 0;
  28. };
  29. class EventMonitorTest : public WidgetTest {
  30. public:
  31. EventMonitorTest() = default;
  32. EventMonitorTest(const EventMonitorTest&) = delete;
  33. EventMonitorTest& operator=(const EventMonitorTest&) = delete;
  34. // testing::Test:
  35. void SetUp() override {
  36. WidgetTest::SetUp();
  37. widget_ = CreateTopLevelNativeWidget();
  38. widget_->SetSize(gfx::Size(100, 100));
  39. widget_->Show();
  40. generator_ = std::make_unique<ui::test::EventGenerator>(
  41. GetContext(), widget_->GetNativeWindow());
  42. generator_->set_target(ui::test::EventGenerator::Target::APPLICATION);
  43. }
  44. void TearDown() override {
  45. widget_->CloseNow();
  46. WidgetTest::TearDown();
  47. }
  48. protected:
  49. raw_ptr<Widget> widget_ = nullptr;
  50. std::unique_ptr<ui::test::EventGenerator> generator_;
  51. TestEventObserver observer_;
  52. };
  53. TEST_F(EventMonitorTest, ShouldReceiveAppEventsWhileInstalled) {
  54. std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateApplicationMonitor(
  55. &observer_, widget_->GetNativeWindow(),
  56. {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_RELEASED}));
  57. generator_->ClickLeftButton();
  58. EXPECT_EQ(2u, observer_.observed_event_count());
  59. monitor.reset();
  60. generator_->ClickLeftButton();
  61. EXPECT_EQ(2u, observer_.observed_event_count());
  62. }
  63. TEST_F(EventMonitorTest, ShouldReceiveWindowEventsWhileInstalled) {
  64. std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateWindowMonitor(
  65. &observer_, widget_->GetNativeWindow(),
  66. {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_RELEASED}));
  67. generator_->ClickLeftButton();
  68. EXPECT_EQ(2u, observer_.observed_event_count());
  69. monitor.reset();
  70. generator_->ClickLeftButton();
  71. EXPECT_EQ(2u, observer_.observed_event_count());
  72. }
  73. TEST_F(EventMonitorTest, ShouldNotReceiveEventsFromOtherWindow) {
  74. Widget* widget2 = CreateTopLevelNativeWidget();
  75. std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateWindowMonitor(
  76. &observer_, widget2->GetNativeWindow(),
  77. {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_RELEASED}));
  78. generator_->ClickLeftButton();
  79. EXPECT_EQ(0u, observer_.observed_event_count());
  80. monitor.reset();
  81. widget2->CloseNow();
  82. }
  83. TEST_F(EventMonitorTest, ShouldOnlyReceiveRequestedEventTypes) {
  84. // This event monitor only listens to mouse press, not release.
  85. std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateWindowMonitor(
  86. &observer_, widget_->GetNativeWindow(), {ui::ET_MOUSE_PRESSED}));
  87. generator_->ClickLeftButton();
  88. EXPECT_EQ(1u, observer_.observed_event_count());
  89. monitor.reset();
  90. }
  91. TEST_F(EventMonitorTest, WindowMonitorTornDownOnWindowClose) {
  92. Widget* widget2 = CreateTopLevelNativeWidget();
  93. widget2->Show();
  94. std::unique_ptr<EventMonitor> monitor(EventMonitor::CreateWindowMonitor(
  95. &observer_, widget2->GetNativeWindow(), {ui::ET_MOUSE_PRESSED}));
  96. // Closing the widget before destroying the monitor should not crash.
  97. widget2->CloseNow();
  98. monitor.reset();
  99. }
  100. namespace {
  101. class DeleteOtherOnEventObserver : public ui::EventObserver {
  102. public:
  103. explicit DeleteOtherOnEventObserver(gfx::NativeWindow context) {
  104. monitor_ = EventMonitor::CreateApplicationMonitor(
  105. this, context, {ui::ET_MOUSE_PRESSED, ui::ET_MOUSE_RELEASED});
  106. }
  107. DeleteOtherOnEventObserver(const DeleteOtherOnEventObserver&) = delete;
  108. DeleteOtherOnEventObserver& operator=(const DeleteOtherOnEventObserver&) =
  109. delete;
  110. bool DidDelete() const { return !observer_to_delete_; }
  111. void set_monitor_to_delete(
  112. std::unique_ptr<DeleteOtherOnEventObserver> observer_to_delete) {
  113. observer_to_delete_ = std::move(observer_to_delete);
  114. }
  115. // ui::EventObserver:
  116. void OnEvent(const ui::Event& event) override {
  117. observer_to_delete_ = nullptr;
  118. }
  119. private:
  120. std::unique_ptr<EventMonitor> monitor_;
  121. std::unique_ptr<DeleteOtherOnEventObserver> observer_to_delete_;
  122. };
  123. } // namespace
  124. // Ensure correct behavior when an event monitor is removed while iterating
  125. // over the OS-controlled observer list.
  126. TEST_F(EventMonitorTest, TwoMonitors) {
  127. gfx::NativeWindow window = widget_->GetNativeWindow();
  128. auto deleter = std::make_unique<DeleteOtherOnEventObserver>(window);
  129. auto deletee = std::make_unique<DeleteOtherOnEventObserver>(window);
  130. deleter->set_monitor_to_delete(std::move(deletee));
  131. EXPECT_FALSE(deleter->DidDelete());
  132. generator_->PressLeftButton();
  133. EXPECT_TRUE(deleter->DidDelete());
  134. // Now try setting up observers in the alternate order.
  135. deletee = std::make_unique<DeleteOtherOnEventObserver>(window);
  136. deleter = std::make_unique<DeleteOtherOnEventObserver>(window);
  137. deleter->set_monitor_to_delete(std::move(deletee));
  138. EXPECT_FALSE(deleter->DidDelete());
  139. generator_->ReleaseLeftButton();
  140. EXPECT_TRUE(deleter->DidDelete());
  141. }
  142. } // namespace test
  143. } // namespace views