[a11y] Refactor EventCapturer into shared class.
There are several versions of this class used by a11y tests in ash_unittests. This creates a shared version that replaces all but the one in TouchExplorationControllerUnittest which requires more complex work. BUG=None TEST=ash_unittests --gtest_filter=MouseKeysTest.*:AutoclickTest.*:SelectToSpeakEventHandlerTest.*:All/ChromeVoxAccessibilityEventRewriterTest.* AX-Relnotes: n/a. Change-Id: I22d486f4a41cc3156338e3c85b37e516fdcee000 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5448761 Reviewed-by: Akihiro Ota <akihiroota@chromium.org> Commit-Queue: Tzarial Kuznia <zork@chromium.org> Reviewed-by: James Cook <jamescook@chromium.org> Reviewed-by: Katie Dektar <katie@chromium.org> Cr-Commit-Position: refs/heads/main@{#1288102}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
67f98ed5f1
commit
afbac8567b
@ -3557,6 +3557,8 @@ test("ash_unittests") {
|
||||
"events/peripheral_customization_event_rewriter_unittest.cc",
|
||||
"events/prerewritten_event_forwarder_unittest.cc",
|
||||
"events/select_to_speak_event_handler_unittest.cc",
|
||||
"events/test_event_capturer.cc",
|
||||
"events/test_event_capturer.h",
|
||||
"extended_desktop_unittest.cc",
|
||||
"fast_ink/fast_ink_host_frame_utils_unittest.cc",
|
||||
"fast_ink/fast_ink_host_unittest.cc",
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "ash/accessibility/accessibility_controller.h"
|
||||
#include "ash/accessibility/autoclick/autoclick_controller.h"
|
||||
#include "ash/events/test_event_capturer.h"
|
||||
#include "ash/shelf/shelf.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/system/accessibility/accessibility_feature_disable_dialog.h"
|
||||
@ -36,71 +37,6 @@ namespace ash {
|
||||
|
||||
namespace {
|
||||
const int kScrollToMenuBoundsBuffer = 18;
|
||||
|
||||
class MouseEventCapturer : public ui::EventHandler {
|
||||
public:
|
||||
MouseEventCapturer() { Reset(); }
|
||||
|
||||
MouseEventCapturer(const MouseEventCapturer&) = delete;
|
||||
MouseEventCapturer& operator=(const MouseEventCapturer&) = delete;
|
||||
|
||||
~MouseEventCapturer() override = default;
|
||||
|
||||
void Reset() {
|
||||
events_.clear();
|
||||
wheel_events_.clear();
|
||||
}
|
||||
|
||||
void OnMouseEvent(ui::MouseEvent* event) override {
|
||||
bool save_event = false;
|
||||
bool stop_event = false;
|
||||
// Filter out extraneous mouse events like mouse entered, exited,
|
||||
// capture changed, etc.
|
||||
ui::EventType type = event->type();
|
||||
if (type == ui::ET_MOUSE_PRESSED || type == ui::ET_MOUSE_RELEASED) {
|
||||
// Only track left and right mouse button events, ensuring that we get
|
||||
// left-click, right-click and double-click.
|
||||
if (!(event->flags() & ui::EF_LEFT_MOUSE_BUTTON) &&
|
||||
(!(event->flags() & ui::EF_RIGHT_MOUSE_BUTTON)))
|
||||
return;
|
||||
save_event = true;
|
||||
// Stop event propagation so we don't click on random stuff that
|
||||
// might break test assumptions.
|
||||
stop_event = true;
|
||||
} else if (type == ui::ET_MOUSE_DRAGGED) {
|
||||
save_event = true;
|
||||
stop_event = false;
|
||||
} else if (type == ui::ET_MOUSEWHEEL) {
|
||||
// Save it immediately as a MouseWheelEvent.
|
||||
wheel_events_.push_back(ui::MouseWheelEvent(
|
||||
event->AsMouseWheelEvent()->offset(), event->location(),
|
||||
event->root_location(), ui::EventTimeForNow(), event->flags(),
|
||||
event->changed_button_flags()));
|
||||
}
|
||||
if (save_event) {
|
||||
events_.push_back(ui::MouseEvent(event->type(), event->location(),
|
||||
event->root_location(),
|
||||
ui::EventTimeForNow(), event->flags(),
|
||||
event->changed_button_flags()));
|
||||
}
|
||||
if (stop_event)
|
||||
event->StopPropagation();
|
||||
|
||||
// If there is a possibility that we're in an infinite loop, we should
|
||||
// exit early with a sensible error rather than letting the test time out.
|
||||
ASSERT_LT(events_.size(), 100u);
|
||||
}
|
||||
|
||||
const std::vector<ui::MouseEvent>& captured_events() const { return events_; }
|
||||
const std::vector<ui::MouseWheelEvent>& captured_mouse_wheel_events() const {
|
||||
return wheel_events_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ui::MouseEvent> events_;
|
||||
std::vector<ui::MouseWheelEvent> wheel_events_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
class AutoclickTest : public AshTestBase {
|
||||
@ -115,6 +51,8 @@ class AutoclickTest : public AshTestBase {
|
||||
|
||||
void SetUp() override {
|
||||
AshTestBase::SetUp();
|
||||
mouse_event_capturer_.set_capture_mouse_move(false);
|
||||
mouse_event_capturer_.set_capture_mouse_enter_exit(false);
|
||||
Shell::Get()->AddPreTargetHandler(&mouse_event_capturer_);
|
||||
GetAutoclickController()->SetAutoclickDelay(base::TimeDelta());
|
||||
|
||||
@ -197,10 +135,10 @@ class AutoclickTest : public AshTestBase {
|
||||
return scroll_view->GetViewByID(static_cast<int>(view_id));
|
||||
}
|
||||
|
||||
void ClearMouseEvents() { mouse_event_capturer_.Reset(); }
|
||||
void ClearMouseEvents() { mouse_event_capturer_.ClearEvents(); }
|
||||
|
||||
const std::vector<ui::MouseEvent>& GetMouseEvents() {
|
||||
return mouse_event_capturer_.captured_events();
|
||||
return mouse_event_capturer_.mouse_events();
|
||||
}
|
||||
|
||||
const std::vector<ui::MouseWheelEvent>& GetMouseWheelEvents() {
|
||||
@ -208,7 +146,7 @@ class AutoclickTest : public AshTestBase {
|
||||
}
|
||||
|
||||
private:
|
||||
MouseEventCapturer mouse_event_capturer_;
|
||||
TestEventCapturer mouse_event_capturer_;
|
||||
};
|
||||
|
||||
TEST_F(AutoclickTest, ToggleEnabled) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "ash/accessibility/accessibility_controller.h"
|
||||
#include "ash/accessibility/mouse_keys/mouse_keys_controller.h"
|
||||
#include "ash/constants/ash_pref_names.h"
|
||||
#include "ash/events/test_event_capturer.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/test/ash_test_base.h"
|
||||
#include "base/run_loop.h"
|
||||
@ -61,58 +62,6 @@ class TestTextInputView : public views::WidgetDelegateView {
|
||||
raw_ptr<views::Textfield> text_field_; // owned by views hierarchy.
|
||||
};
|
||||
|
||||
class EventCapturer : public ui::EventHandler {
|
||||
public:
|
||||
EventCapturer() { Reset(); }
|
||||
|
||||
EventCapturer(const EventCapturer&) = delete;
|
||||
EventCapturer& operator=(const EventCapturer&) = delete;
|
||||
|
||||
~EventCapturer() override = default;
|
||||
|
||||
void Reset() {
|
||||
key_events_.clear();
|
||||
mouse_events_.clear();
|
||||
}
|
||||
|
||||
void OnKeyEventRewrite(const ui::KeyEvent* event) {}
|
||||
|
||||
void OnKeyEvent(ui::KeyEvent* event) override {
|
||||
key_events_.push_back(*event);
|
||||
|
||||
// If there is a possibility that we're in an infinite loop, we should
|
||||
// exit early with a sensible error rather than letting the test time out.
|
||||
ASSERT_LT(key_events_.size(), 100u);
|
||||
}
|
||||
|
||||
void OnMouseEvent(ui::MouseEvent* event) override {
|
||||
// Filter out extraneous mouse events like mouse entered, exited,
|
||||
// capture changed, etc.
|
||||
ui::EventType type = event->type();
|
||||
if (type == ui::ET_MOUSE_PRESSED || type == ui::ET_MOUSE_RELEASED ||
|
||||
type == ui::ET_MOUSE_MOVED) {
|
||||
mouse_events_.push_back(
|
||||
ui::MouseEvent(event->type(), event->location(),
|
||||
event->root_location(), ui::EventTimeForNow(),
|
||||
event->flags(), event->changed_button_flags()));
|
||||
event->StopPropagation();
|
||||
|
||||
// If there is a possibility that we're in an infinite loop, we should
|
||||
// exit early with a sensible error rather than letting the test time out.
|
||||
ASSERT_LT(mouse_events_.size(), 100u);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<ui::KeyEvent>& key_events() const { return key_events_; }
|
||||
const std::vector<ui::MouseEvent>& mouse_events() const {
|
||||
return mouse_events_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<ui::KeyEvent> key_events_;
|
||||
std::vector<ui::MouseEvent> mouse_events_;
|
||||
};
|
||||
|
||||
class EventRewriterWrapper : public ui::EventRewriter {
|
||||
public:
|
||||
EventRewriterWrapper() = default;
|
||||
@ -142,6 +91,7 @@ class MouseKeysTest : public AshTestBase {
|
||||
scoped_feature_list_.InitAndEnableFeature(
|
||||
::features::kAccessibilityMouseKeys);
|
||||
AshTestBase::SetUp();
|
||||
event_capturer_.set_capture_mouse_enter_exit(false);
|
||||
GetContext()->GetHost()->GetEventSource()->AddEventRewriter(&rewriter_);
|
||||
GetContext()->AddPreTargetHandler(&event_capturer_);
|
||||
|
||||
@ -226,7 +176,7 @@ class MouseKeysTest : public AshTestBase {
|
||||
static_cast<int>(dominant_hand));
|
||||
}
|
||||
|
||||
void ClearEvents() { event_capturer_.Reset(); }
|
||||
void ClearEvents() { event_capturer_.ClearEvents(); }
|
||||
|
||||
void PressKey(ui::KeyboardCode key_code, int flags = 0) {
|
||||
GetEventGenerator()->PressKey(key_code, flags);
|
||||
@ -306,7 +256,7 @@ class MouseKeysTest : public AshTestBase {
|
||||
|
||||
private:
|
||||
base::test::ScopedFeatureList scoped_feature_list_;
|
||||
EventCapturer event_capturer_;
|
||||
TestEventCapturer event_capturer_;
|
||||
EventRewriterWrapper rewriter_;
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include "ash/accessibility/mouse_keys/mouse_keys_controller.h"
|
||||
#include "ash/constants/ash_constants.h"
|
||||
#include "ash/constants/ash_features.h"
|
||||
#include "ash/events/test_event_capturer.h"
|
||||
#include "ash/public/cpp/accessibility_event_rewriter_delegate.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/test/ash_test_base.h"
|
||||
@ -104,26 +105,6 @@ class TestAccessibilityEventRewriterDelegate
|
||||
std::vector<MagnifierCommand> magnifier_commands_;
|
||||
};
|
||||
|
||||
// Records all key events for testing.
|
||||
class EventCapturer : public ui::EventHandler {
|
||||
public:
|
||||
EventCapturer() = default;
|
||||
EventCapturer(const EventCapturer&) = delete;
|
||||
EventCapturer& operator=(const EventCapturer&) = delete;
|
||||
~EventCapturer() override = default;
|
||||
|
||||
void Reset() { last_key_event_.reset(); }
|
||||
|
||||
ui::KeyEvent* last_key_event() { return last_key_event_.get(); }
|
||||
|
||||
private:
|
||||
void OnKeyEvent(ui::KeyEvent* event) override {
|
||||
last_key_event_ = std::make_unique<ui::KeyEvent>(*event);
|
||||
}
|
||||
|
||||
std::unique_ptr<ui::KeyEvent> last_key_event_;
|
||||
};
|
||||
|
||||
class KeyboardModifierEventRewriterDelegate
|
||||
: public ui::KeyboardModifierEventRewriter::Delegate {
|
||||
public:
|
||||
@ -159,6 +140,7 @@ class AccessibilityEventRewriterTestBase : public ash::AshTestBase {
|
||||
|
||||
void SetUp() override {
|
||||
ash::AshTestBase::SetUp();
|
||||
event_capturer_.set_capture_mouse_enter_exit(false);
|
||||
generator_ = AshTestBase::GetEventGenerator();
|
||||
|
||||
accessibility_event_rewriter_ =
|
||||
@ -196,7 +178,7 @@ class AccessibilityEventRewriterTestBase : public ash::AshTestBase {
|
||||
}
|
||||
|
||||
protected:
|
||||
EventCapturer& event_capturer() { return event_capturer_; }
|
||||
TestEventCapturer& event_capturer() { return event_capturer_; }
|
||||
|
||||
TestAccessibilityEventRewriterDelegate&
|
||||
accessibility_event_rewriter_delegate() {
|
||||
@ -219,7 +201,7 @@ class AccessibilityEventRewriterTestBase : public ash::AshTestBase {
|
||||
}
|
||||
|
||||
private:
|
||||
EventCapturer event_capturer_;
|
||||
TestEventCapturer event_capturer_;
|
||||
|
||||
ui::test::FakeEventRewriterAshDelegate event_rewriter_ash_delegate_;
|
||||
ui::StubKeyboardLayoutEngine keyboard_layout_engine_;
|
||||
@ -583,12 +565,12 @@ class MouseKeysAccessibilityEventRewriterTest
|
||||
TEST_F(MouseKeysAccessibilityEventRewriterTest, CapturesCorrectInput) {
|
||||
// Mouse Keys should treat 'i' as a click.
|
||||
GetEventGenerator()->PressAndReleaseKey(ui::VKEY_I);
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
|
||||
// Mouse Keys should not capture 'g'.
|
||||
GetEventGenerator()->PressAndReleaseKey(ui::VKEY_G);
|
||||
ASSERT_TRUE(event_capturer().last_key_event());
|
||||
EXPECT_EQ(ui::VKEY_G, event_capturer().last_key_event()->key_code());
|
||||
ASSERT_TRUE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(ui::VKEY_G, event_capturer().LastKeyEvent()->key_code());
|
||||
}
|
||||
|
||||
class SwitchAccessAccessibilityEventRewriterTest
|
||||
@ -656,14 +638,14 @@ TEST_P(SwitchAccessAccessibilityEventRewriterTest, CaptureSpecifiedKeys) {
|
||||
{ui::VKEY_2, {kSwitchAccessUsbDevice}}},
|
||||
SwitchAccessCommand::kSelect);
|
||||
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
|
||||
// Press 1 from the internal keyboard.
|
||||
generator().PressKey(ui::VKEY_1, ui::EF_NONE, 1 /* keyboard id */);
|
||||
generator().ReleaseKey(ui::VKEY_1, ui::EF_NONE, 1 /* keyboard id */);
|
||||
|
||||
// The event was captured by AccessibilityEventRewriter.
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
SwitchAccessCommand::kSelect,
|
||||
accessibility_event_rewriter_delegate().switch_access_commands().back());
|
||||
@ -675,7 +657,7 @@ TEST_P(SwitchAccessAccessibilityEventRewriterTest, CaptureSpecifiedKeys) {
|
||||
generator().ReleaseKey(ui::VKEY_1, ui::EF_NONE, 3 /* keyboard id */);
|
||||
|
||||
// The event was not captured by AccessibilityEventRewriter.
|
||||
EXPECT_TRUE(event_capturer().last_key_event());
|
||||
EXPECT_TRUE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
0u,
|
||||
accessibility_event_rewriter_delegate().switch_access_commands().size());
|
||||
@ -685,7 +667,7 @@ TEST_P(SwitchAccessAccessibilityEventRewriterTest, CaptureSpecifiedKeys) {
|
||||
generator().ReleaseKey(ui::VKEY_2, ui::EF_NONE, 2 /* keyboard id */);
|
||||
|
||||
// The event was captured by AccessibilityEventRewriter.
|
||||
EXPECT_TRUE(event_capturer().last_key_event());
|
||||
EXPECT_TRUE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
SwitchAccessCommand::kSelect,
|
||||
accessibility_event_rewriter_delegate().switch_access_commands().back());
|
||||
@ -697,7 +679,7 @@ TEST_P(SwitchAccessAccessibilityEventRewriterTest, CaptureSpecifiedKeys) {
|
||||
generator().ReleaseKey(ui::VKEY_3, ui::EF_NONE, 1 /* keyboard id */);
|
||||
|
||||
// The event was not captured by AccessibilityEventRewriter.
|
||||
EXPECT_TRUE(event_capturer().last_key_event());
|
||||
EXPECT_TRUE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
0u,
|
||||
accessibility_event_rewriter_delegate().switch_access_commands().size());
|
||||
@ -712,14 +694,14 @@ TEST_P(SwitchAccessAccessibilityEventRewriterTest,
|
||||
{ui::VKEY_3, {kSwitchAccessInternalDevice}}},
|
||||
SwitchAccessCommand::kSelect);
|
||||
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
|
||||
// Press the "1" key.
|
||||
generator().PressKey(ui::VKEY_1, ui::EF_NONE, 1 /* keyboard id */);
|
||||
generator().ReleaseKey(ui::VKEY_1, ui::EF_NONE, 1 /* keyboard id */);
|
||||
|
||||
// The event was captured by AccessibilityEventRewriter.
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
SwitchAccessCommand::kSelect,
|
||||
accessibility_event_rewriter_delegate().switch_access_commands().back());
|
||||
@ -738,16 +720,16 @@ TEST_P(SwitchAccessAccessibilityEventRewriterTest,
|
||||
// We received a new event.
|
||||
|
||||
// The event was NOT captured by AccessibilityEventRewriter.
|
||||
EXPECT_TRUE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().last_key_event()->handled());
|
||||
EXPECT_TRUE(event_capturer().LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent()->handled());
|
||||
|
||||
// Press the "4" key.
|
||||
event_capturer().Reset();
|
||||
event_capturer().ClearEvents();
|
||||
generator().PressKey(ui::VKEY_4, ui::EF_NONE, 1 /* keyboard id */);
|
||||
generator().ReleaseKey(ui::VKEY_4, ui::EF_NONE, 1 /* keyboard id */);
|
||||
|
||||
// The event was captured by AccessibilityEventRewriter.
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
SwitchAccessCommand::kSelect,
|
||||
accessibility_event_rewriter_delegate().switch_access_commands().back());
|
||||
@ -951,16 +933,16 @@ TEST_P(MagnifierAccessibilityEventRewriterTest, CaptureKeys) {
|
||||
// Press and release Ctrl+Alt+Up.
|
||||
// Verify that the events are captured by AccessibilityEventRewriter.
|
||||
generator().PressModifierKeys(ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
|
||||
event_capturer().Reset();
|
||||
event_capturer().ClearEvents();
|
||||
|
||||
generator().PressKey(ui::VKEY_UP, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
MagnifierCommand::kMoveUp,
|
||||
accessibility_event_rewriter_delegate().magnifier_commands().back());
|
||||
|
||||
generator().ReleaseKey(ui::VKEY_UP, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
MagnifierCommand::kMoveStop,
|
||||
accessibility_event_rewriter_delegate().magnifier_commands().back());
|
||||
@ -968,27 +950,27 @@ TEST_P(MagnifierAccessibilityEventRewriterTest, CaptureKeys) {
|
||||
// Press and release Ctrl+Alt+Down.
|
||||
// Verify that the events are captured by AccessibilityEventRewriter.
|
||||
generator().PressKey(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
MagnifierCommand::kMoveDown,
|
||||
accessibility_event_rewriter_delegate().magnifier_commands().back());
|
||||
|
||||
generator().ReleaseKey(ui::VKEY_DOWN, ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
|
||||
EXPECT_FALSE(event_capturer().last_key_event());
|
||||
EXPECT_FALSE(event_capturer().LastKeyEvent());
|
||||
EXPECT_EQ(
|
||||
MagnifierCommand::kMoveStop,
|
||||
accessibility_event_rewriter_delegate().magnifier_commands().back());
|
||||
|
||||
generator().ReleaseModifierKeys(ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN);
|
||||
event_capturer().Reset();
|
||||
event_capturer().ClearEvents();
|
||||
|
||||
// Press and release the "3" key.
|
||||
// Verify that the events are not captured by AccessibilityEventRewriter.
|
||||
generator().PressKey(ui::VKEY_3, ui::EF_NONE);
|
||||
EXPECT_TRUE(event_capturer().last_key_event());
|
||||
EXPECT_TRUE(event_capturer().LastKeyEvent());
|
||||
|
||||
generator().ReleaseKey(ui::VKEY_3, ui::EF_NONE);
|
||||
EXPECT_TRUE(event_capturer().last_key_event());
|
||||
EXPECT_TRUE(event_capturer().LastKeyEvent());
|
||||
}
|
||||
|
||||
} // namespace ash
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include <set>
|
||||
|
||||
#include "ash/accessibility/accessibility_controller.h"
|
||||
#include "ash/events/test_event_capturer.h"
|
||||
#include "ash/public/cpp/select_to_speak_event_handler_delegate.h"
|
||||
#include "ash/shell.h"
|
||||
#include "ash/test/ash_test_base.h"
|
||||
@ -19,6 +20,7 @@
|
||||
#include "ui/display/manager/display_manager.h"
|
||||
#include "ui/events/event.h"
|
||||
#include "ui/events/event_constants.h"
|
||||
#include "ui/events/event_utils.h"
|
||||
#include "ui/events/test/event_generator.h"
|
||||
#include "ui/events/test/events_test_utils.h"
|
||||
#include "ui/events/types/event_type.h"
|
||||
@ -26,42 +28,6 @@
|
||||
namespace ash {
|
||||
namespace {
|
||||
|
||||
// Records all key events for testing.
|
||||
class EventCapturer : public ui::EventHandler {
|
||||
public:
|
||||
EventCapturer() {}
|
||||
|
||||
EventCapturer(const EventCapturer&) = delete;
|
||||
EventCapturer& operator=(const EventCapturer&) = delete;
|
||||
|
||||
~EventCapturer() override {}
|
||||
|
||||
void Reset() {
|
||||
last_key_event_.reset();
|
||||
last_mouse_event_.reset();
|
||||
last_touch_event_.reset();
|
||||
}
|
||||
|
||||
ui::KeyEvent* last_key_event() { return last_key_event_.get(); }
|
||||
ui::MouseEvent* last_mouse_event() { return last_mouse_event_.get(); }
|
||||
ui::TouchEvent* last_touch_event() { return last_touch_event_.get(); }
|
||||
|
||||
private:
|
||||
void OnMouseEvent(ui::MouseEvent* event) override {
|
||||
last_mouse_event_ = std::make_unique<ui::MouseEvent>(*event);
|
||||
}
|
||||
void OnKeyEvent(ui::KeyEvent* event) override {
|
||||
last_key_event_ = std::make_unique<ui::KeyEvent>(*event);
|
||||
}
|
||||
void OnTouchEvent(ui::TouchEvent* event) override {
|
||||
last_touch_event_ = std::make_unique<ui::TouchEvent>(*event);
|
||||
}
|
||||
|
||||
std::unique_ptr<ui::KeyEvent> last_key_event_;
|
||||
std::unique_ptr<ui::MouseEvent> last_mouse_event_;
|
||||
std::unique_ptr<ui::TouchEvent> last_touch_event_;
|
||||
};
|
||||
|
||||
class TestDelegate : public SelectToSpeakEventHandlerDelegate {
|
||||
public:
|
||||
TestDelegate() = default;
|
||||
@ -144,7 +110,7 @@ class SelectToSpeakEventHandlerTest : public AshTestBase {
|
||||
|
||||
protected:
|
||||
raw_ptr<ui::test::EventGenerator> generator_ = nullptr;
|
||||
EventCapturer event_capturer_;
|
||||
TestEventCapturer event_capturer_;
|
||||
raw_ptr<AccessibilityController> controller_ = nullptr;
|
||||
std::unique_ptr<TestDelegate> delegate_;
|
||||
};
|
||||
@ -154,16 +120,16 @@ TEST_F(SelectToSpeakEventHandlerTest, PressAndReleaseSearchNotHandled) {
|
||||
// presses, the key events won't be handled by the SelectToSpeakEventHandler
|
||||
// and the normal behavior will occur.
|
||||
|
||||
EXPECT_FALSE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent());
|
||||
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
}
|
||||
|
||||
// Note: when running these tests locally on desktop Linux, you may need
|
||||
@ -175,26 +141,26 @@ TEST_F(SelectToSpeakEventHandlerTest, SearchPlusClick) {
|
||||
// extension.
|
||||
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
|
||||
gfx::Point click_location = gfx::Point(100, 12);
|
||||
generator_->set_current_screen_location(click_location);
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
EXPECT_EQ(click_location, delegate_->last_mouse_event_location());
|
||||
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
|
||||
EXPECT_EQ(click_location, delegate_->last_mouse_event_location());
|
||||
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_FALSE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SearchPlusDrag) {
|
||||
@ -212,8 +178,8 @@ TEST_F(SelectToSpeakEventHandlerTest, SearchPlusDrag) {
|
||||
generator_->DragMouseTo(drag_location);
|
||||
EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
|
||||
@ -230,8 +196,8 @@ TEST_F(SelectToSpeakEventHandlerTest, SearchPlusMove) {
|
||||
// Hovers are not passed through.
|
||||
gfx::Point move_location = gfx::Point(120, 32);
|
||||
generator_->MoveMouseTo(move_location);
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
}
|
||||
@ -254,8 +220,8 @@ TEST_F(SelectToSpeakEventHandlerTest, SearchPlusDragOnLargeDisplay) {
|
||||
EXPECT_EQ(gfx::Point(drag_location_px.x() / 2, drag_location_px.y() / 2),
|
||||
delegate_->last_mouse_event_location());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
|
||||
EXPECT_TRUE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_EQ(gfx::Point(drag_location_px.x() / 2, drag_location_px.y() / 2),
|
||||
@ -273,7 +239,7 @@ TEST_F(SelectToSpeakEventHandlerTest, RepeatSearchKey) {
|
||||
|
||||
generator_->set_current_screen_location(gfx::Point(100, 12));
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
|
||||
@ -281,25 +247,25 @@ TEST_F(SelectToSpeakEventHandlerTest, RepeatSearchKey) {
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
|
||||
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_FALSE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, TapSearchKey) {
|
||||
// Tapping the search key should not steal future events.
|
||||
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent()->handled());
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent()->handled());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SearchPlusClickTwice) {
|
||||
@ -307,16 +273,16 @@ TEST_F(SelectToSpeakEventHandlerTest, SearchPlusClickTwice) {
|
||||
// holding down Search and click again.
|
||||
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
|
||||
generator_->set_current_screen_location(gfx::Point(100, 12));
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
|
||||
|
||||
delegate_->Reset();
|
||||
@ -324,16 +290,16 @@ TEST_F(SelectToSpeakEventHandlerTest, SearchPlusClickTwice) {
|
||||
EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
|
||||
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
|
||||
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_FALSE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SearchPlusKeyIgnoresClicks) {
|
||||
@ -342,108 +308,108 @@ TEST_F(SelectToSpeakEventHandlerTest, SearchPlusKeyIgnoresClicks) {
|
||||
// and click events should be ignored.
|
||||
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
|
||||
generator_->PressKey(ui::VKEY_I, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
|
||||
generator_->set_current_screen_location(gfx::Point(100, 12));
|
||||
generator_->PressLeftButton();
|
||||
ASSERT_TRUE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastMouseEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent()->handled());
|
||||
|
||||
EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
|
||||
generator_->ReleaseLeftButton();
|
||||
ASSERT_TRUE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastMouseEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent()->handled());
|
||||
|
||||
EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
|
||||
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_I, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SearchPlusSIsCaptured) {
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
|
||||
// Press and release S, key presses should be captured.
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_FALSE(event_capturer_.last_key_event());
|
||||
ASSERT_FALSE(event_capturer_.LastKeyEvent());
|
||||
|
||||
generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_FALSE(event_capturer_.last_key_event());
|
||||
ASSERT_FALSE(event_capturer_.LastKeyEvent());
|
||||
|
||||
// Press and release again while still holding down search.
|
||||
// The events should continue to be captured.
|
||||
generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_FALSE(event_capturer_.last_key_event());
|
||||
ASSERT_FALSE(event_capturer_.LastKeyEvent());
|
||||
|
||||
generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_FALSE(event_capturer_.last_key_event());
|
||||
ASSERT_FALSE(event_capturer_.LastKeyEvent());
|
||||
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_FALSE(event_capturer_.last_key_event());
|
||||
ASSERT_FALSE(event_capturer_.LastKeyEvent());
|
||||
|
||||
// S alone is not captured
|
||||
generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
ASSERT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
ASSERT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SearchPlusSIgnoresMouse) {
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
|
||||
// Press S
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_FALSE(event_capturer_.last_key_event());
|
||||
ASSERT_FALSE(event_capturer_.LastKeyEvent());
|
||||
|
||||
// Mouse events are passed through like normal.
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_TRUE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_TRUE(event_capturer_.last_mouse_event());
|
||||
EXPECT_TRUE(event_capturer_.LastMouseEvent());
|
||||
|
||||
generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_FALSE(event_capturer_.last_key_event());
|
||||
ASSERT_FALSE(event_capturer_.LastKeyEvent());
|
||||
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
ASSERT_FALSE(event_capturer_.last_key_event());
|
||||
ASSERT_FALSE(event_capturer_.LastKeyEvent());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SearchPlusMouseIgnoresS) {
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
|
||||
// Press the mouse
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
|
||||
// S key events are passed through like normal.
|
||||
generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_TRUE(event_capturer_.last_key_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastKeyEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_TRUE(event_capturer_.LastKeyEvent());
|
||||
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_FALSE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, DoesntStartSelectionModeIfNotInactive) {
|
||||
@ -457,7 +423,7 @@ TEST_F(SelectToSpeakEventHandlerTest, DoesntStartSelectionModeIfNotInactive) {
|
||||
gfx::Point click_location = gfx::Point(100, 12);
|
||||
generator_->set_current_screen_location(click_location);
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
|
||||
// This shouldn't cause any changes since the state is not inactive.
|
||||
controller_->SetSelectToSpeakState(
|
||||
@ -467,9 +433,9 @@ TEST_F(SelectToSpeakEventHandlerTest, DoesntStartSelectionModeIfNotInactive) {
|
||||
|
||||
// Releasing the search key is still captured per the end of the search+click
|
||||
// mode.
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_FALSE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest,
|
||||
@ -478,10 +444,10 @@ TEST_F(SelectToSpeakEventHandlerTest,
|
||||
gfx::Point click_location = gfx::Point(100, 12);
|
||||
generator_->set_current_screen_location(click_location);
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
|
||||
|
||||
// Set the state to inactive.
|
||||
@ -492,19 +458,19 @@ TEST_F(SelectToSpeakEventHandlerTest,
|
||||
SelectToSpeakState::kSelectToSpeakStateInactive);
|
||||
|
||||
// The search key release should still be captured.
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_FALSE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, PassesCtrlKey) {
|
||||
generator_->PressKey(ui::VKEY_CONTROL, /*flags=*/0);
|
||||
ASSERT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
event_capturer_.Reset();
|
||||
ASSERT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_CONTROL, /*flags=*/0);
|
||||
EXPECT_TRUE(event_capturer_.last_key_event());
|
||||
EXPECT_FALSE(event_capturer_.last_key_event()->handled());
|
||||
EXPECT_TRUE(event_capturer_.LastKeyEvent());
|
||||
EXPECT_FALSE(event_capturer_.LastKeyEvent()->handled());
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedWorksWithMouse) {
|
||||
@ -516,37 +482,37 @@ TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedWorksWithMouse) {
|
||||
controller_->SetSelectToSpeakState(
|
||||
SelectToSpeakState::kSelectToSpeakStateInactive);
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_TRUE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_TRUE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Start selection mode.
|
||||
controller_->SetSelectToSpeakState(
|
||||
SelectToSpeakState::kSelectToSpeakStateSelecting);
|
||||
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
gfx::Point drag_location = gfx::Point(120, 32);
|
||||
generator_->DragMouseTo(drag_location);
|
||||
EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Mouse up is the last event captured in the sequence
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Another mouse event is let through normally.
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_TRUE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedWorksWithTouch) {
|
||||
@ -558,39 +524,39 @@ TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedWorksWithTouch) {
|
||||
controller_->SetSelectToSpeakState(
|
||||
SelectToSpeakState::kSelectToSpeakStateInactive);
|
||||
generator_->PressTouch();
|
||||
EXPECT_TRUE(event_capturer_.last_touch_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastTouchEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseTouch();
|
||||
EXPECT_TRUE(event_capturer_.last_touch_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastTouchEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Start selection mode.
|
||||
controller_->SetSelectToSpeakState(
|
||||
SelectToSpeakState::kSelectToSpeakStateSelecting);
|
||||
|
||||
generator_->PressTouch();
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
// Touch events are converted to mouse events for the extension.
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
gfx::Point drag_location = gfx::Point(120, 32);
|
||||
generator_->MoveTouch(drag_location);
|
||||
EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
|
||||
EXPECT_TRUE(event_capturer_.last_touch_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastTouchEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Touch up is the last event captured in the sequence
|
||||
generator_->ReleaseTouch();
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Another touch event is let through normally.
|
||||
generator_->PressTouch();
|
||||
EXPECT_TRUE(event_capturer_.last_touch_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastTouchEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedIgnoresOtherInput) {
|
||||
@ -600,31 +566,31 @@ TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedIgnoresOtherInput) {
|
||||
|
||||
// Search key events are not impacted.
|
||||
generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_TRUE(event_capturer_.last_key_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastKeyEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
|
||||
EXPECT_TRUE(event_capturer_.last_key_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastKeyEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Start a touch selection, it should get captured and forwarded.
|
||||
generator_->PressTouch();
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Mouse event happening during the touch selection are not impacted;
|
||||
// we are locked into a touch selection mode.
|
||||
generator_->PressLeftButton();
|
||||
EXPECT_TRUE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
generator_->ReleaseLeftButton();
|
||||
EXPECT_TRUE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Complete the touch selection.
|
||||
generator_->ReleaseTouch();
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedPreventsHovers) {
|
||||
@ -639,8 +605,8 @@ TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedPreventsHovers) {
|
||||
// Hovers are not passed through.
|
||||
gfx::Point move_location = gfx::Point(120, 32);
|
||||
generator_->MoveMouseTo(move_location);
|
||||
EXPECT_FALSE(event_capturer_.last_mouse_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_FALSE(event_capturer_.LastMouseEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, TrackingTouchIgnoresOtherTouchPointers) {
|
||||
@ -652,27 +618,27 @@ TEST_F(SelectToSpeakEventHandlerTest, TrackingTouchIgnoresOtherTouchPointers) {
|
||||
|
||||
// The first touch event is captured and sent to the extension.
|
||||
generator_->PressTouchId(1);
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
event_capturer_.Reset();
|
||||
event_capturer_.ClearEvents();
|
||||
delegate_->Reset();
|
||||
|
||||
// A second touch event up and down is canceled but not sent to the extension.
|
||||
generator_->PressTouchId(2);
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
generator_->MoveTouchId(drag_location, 2);
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
|
||||
generator_->ReleaseTouchId(2);
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
|
||||
|
||||
// A pointer type event will not be sent either, as we are tracking touch,
|
||||
// even if the ID is the same.
|
||||
generator_->EnterPenPointerMode();
|
||||
generator_->PressTouchId(1);
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
|
||||
generator_->ExitPenPointerMode();
|
||||
|
||||
@ -680,18 +646,18 @@ TEST_F(SelectToSpeakEventHandlerTest, TrackingTouchIgnoresOtherTouchPointers) {
|
||||
generator_->MoveTouchId(drag_location, 1);
|
||||
EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
|
||||
EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
|
||||
EXPECT_TRUE(event_capturer_.last_touch_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastTouchEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Touch up is the last event captured in the sequence
|
||||
generator_->ReleaseTouchId(1);
|
||||
EXPECT_FALSE(event_capturer_.last_touch_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_FALSE(event_capturer_.LastTouchEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
|
||||
// Another touch event is let through normally.
|
||||
generator_->PressTouchId(3);
|
||||
EXPECT_TRUE(event_capturer_.last_touch_event());
|
||||
event_capturer_.Reset();
|
||||
EXPECT_TRUE(event_capturer_.LastTouchEvent());
|
||||
event_capturer_.ClearEvents();
|
||||
}
|
||||
|
||||
TEST_F(SelectToSpeakEventHandlerTest, TouchFirstOfMultipleDisplays) {
|
||||
|
96
ash/events/test_event_capturer.cc
Normal file
96
ash/events/test_event_capturer.cc
Normal file
@ -0,0 +1,96 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "ash/events/test_event_capturer.h"
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/events/event_utils.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
TestEventCapturer::TestEventCapturer() {}
|
||||
TestEventCapturer::~TestEventCapturer() {}
|
||||
|
||||
void TestEventCapturer::ClearEvents() {
|
||||
key_events_.clear();
|
||||
mouse_events_.clear();
|
||||
touch_events_.clear();
|
||||
wheel_events_.clear();
|
||||
}
|
||||
|
||||
void TestEventCapturer::OnKeyEvent(ui::KeyEvent* event) {
|
||||
key_events_.push_back(*event);
|
||||
|
||||
// If there is a possibility that we're in an infinite loop, we should
|
||||
// exit early with a sensible error rather than letting the test time out.
|
||||
ASSERT_LT(key_events_.size(), 100u);
|
||||
}
|
||||
|
||||
void TestEventCapturer::OnMouseEvent(ui::MouseEvent* event) {
|
||||
bool save_event = false;
|
||||
bool stop_event = false;
|
||||
ui::EventType type = event->type();
|
||||
if (type == ui::ET_MOUSE_PRESSED || type == ui::ET_MOUSE_RELEASED) {
|
||||
// Only track left and right mouse button events, ensuring that we get
|
||||
// left-click, right-click and double-click.
|
||||
if (!(event->flags() & ui::EF_LEFT_MOUSE_BUTTON) &&
|
||||
(!(event->flags() & ui::EF_RIGHT_MOUSE_BUTTON))) {
|
||||
return;
|
||||
}
|
||||
save_event = true;
|
||||
// Stop event propagation so we don't click on random stuff that
|
||||
// might break test assumptions.
|
||||
stop_event = true;
|
||||
} else if (type == ui::ET_MOUSE_DRAGGED ||
|
||||
(capture_mouse_move_ && type == ui::ET_MOUSE_MOVED) ||
|
||||
(capture_mouse_enter_exit_ &&
|
||||
(type == ui::ET_MOUSE_ENTERED || type == ui::ET_MOUSE_EXITED))) {
|
||||
save_event = true;
|
||||
stop_event = false;
|
||||
} else if (type == ui::ET_MOUSEWHEEL) {
|
||||
// Save it immediately as a MouseWheelEvent.
|
||||
wheel_events_.push_back(ui::MouseWheelEvent(
|
||||
event->AsMouseWheelEvent()->offset(), event->location(),
|
||||
event->root_location(), ui::EventTimeForNow(), event->flags(),
|
||||
event->changed_button_flags()));
|
||||
}
|
||||
|
||||
if (save_event) {
|
||||
mouse_events_.push_back(ui::MouseEvent(
|
||||
event->type(), event->location(), event->root_location(),
|
||||
ui::EventTimeForNow(), event->flags(), event->changed_button_flags()));
|
||||
}
|
||||
|
||||
if (stop_event) {
|
||||
event->StopPropagation();
|
||||
}
|
||||
|
||||
// If there is a possibility that we're in an infinite loop, we should
|
||||
// exit early with a sensible error rather than letting the test time out.
|
||||
ASSERT_LT(mouse_events_.size(), 100u);
|
||||
ASSERT_LT(wheel_events_.size(), 100u);
|
||||
}
|
||||
|
||||
void TestEventCapturer::OnTouchEvent(ui::TouchEvent* event) {
|
||||
touch_events_.push_back(*event);
|
||||
|
||||
// If there is a possibility that we're in an infinite loop, we should
|
||||
// exit early with a sensible error rather than letting the test time out.
|
||||
ASSERT_LT(touch_events_.size(), 100u);
|
||||
}
|
||||
|
||||
ui::KeyEvent* TestEventCapturer::LastKeyEvent() {
|
||||
return key_events_.empty() ? nullptr : &key_events_.back();
|
||||
}
|
||||
|
||||
ui::MouseEvent* TestEventCapturer::LastMouseEvent() {
|
||||
return mouse_events_.empty() ? nullptr : &mouse_events_.back();
|
||||
}
|
||||
|
||||
ui::TouchEvent* TestEventCapturer::LastTouchEvent() {
|
||||
return touch_events_.empty() ? nullptr : &touch_events_.back();
|
||||
}
|
||||
|
||||
} // namespace ash
|
62
ash/events/test_event_capturer.h
Normal file
62
ash/events/test_event_capturer.h
Normal file
@ -0,0 +1,62 @@
|
||||
// Copyright 2024 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ASH_EVENTS_TEST_EVENT_CAPTURER_H_
|
||||
#define ASH_EVENTS_TEST_EVENT_CAPTURER_H_
|
||||
|
||||
#include "ui/events/event.h"
|
||||
#include "ui/events/event_handler.h"
|
||||
|
||||
namespace ash {
|
||||
|
||||
// Used to capture and inspect events in ash_unittests. By default it captures
|
||||
// all KeyEvents, MouseEvents, and TouchEvents.
|
||||
// ET_MOUSE_MOVED, ET_MOUSE_ENTERED and ET_MOUSE_EXITED can be optionally
|
||||
// filtered out to make the stored events less noisy.
|
||||
class TestEventCapturer : public ui::EventHandler {
|
||||
public:
|
||||
TestEventCapturer();
|
||||
TestEventCapturer(const TestEventCapturer&) = delete;
|
||||
TestEventCapturer& operator=(const TestEventCapturer&) = delete;
|
||||
~TestEventCapturer() override;
|
||||
|
||||
void ClearEvents();
|
||||
|
||||
// ui::EventHandler:
|
||||
void OnKeyEvent(ui::KeyEvent* event) override;
|
||||
void OnMouseEvent(ui::MouseEvent* event) override;
|
||||
void OnTouchEvent(ui::TouchEvent* event) override;
|
||||
|
||||
ui::KeyEvent* LastKeyEvent();
|
||||
ui::MouseEvent* LastMouseEvent();
|
||||
ui::TouchEvent* LastTouchEvent();
|
||||
|
||||
void set_capture_mouse_move(bool value) { capture_mouse_move_ = value; }
|
||||
void set_capture_mouse_enter_exit(bool value) {
|
||||
capture_mouse_enter_exit_ = value;
|
||||
}
|
||||
|
||||
const std::vector<ui::KeyEvent>& key_events() const { return key_events_; }
|
||||
const std::vector<ui::MouseEvent>& mouse_events() const {
|
||||
return mouse_events_;
|
||||
}
|
||||
const std::vector<ui::TouchEvent>& touch_events() const {
|
||||
return touch_events_;
|
||||
}
|
||||
const std::vector<ui::MouseWheelEvent>& captured_mouse_wheel_events() const {
|
||||
return wheel_events_;
|
||||
}
|
||||
|
||||
private:
|
||||
bool capture_mouse_move_ = true;
|
||||
bool capture_mouse_enter_exit_ = true;
|
||||
std::vector<ui::KeyEvent> key_events_;
|
||||
std::vector<ui::MouseEvent> mouse_events_;
|
||||
std::vector<ui::TouchEvent> touch_events_;
|
||||
std::vector<ui::MouseWheelEvent> wheel_events_;
|
||||
};
|
||||
|
||||
} // namespace ash
|
||||
|
||||
#endif // ASH_EVENTS_TEST_EVENT_CAPTURER_H_
|
Reference in New Issue
Block a user