0

[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:
Tzarial Kuznia
2024-04-16 16:38:10 +00:00
committed by Chromium LUCI CQ
parent 67f98ed5f1
commit afbac8567b
7 changed files with 331 additions and 335 deletions

@ -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) {

@ -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

@ -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_