123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681 |
- // Copyright 2018 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "ash/events/select_to_speak_event_handler.h"
- #include <memory>
- #include <set>
- #include "ash/accessibility/accessibility_controller_impl.h"
- #include "ash/public/cpp/select_to_speak_event_handler_delegate.h"
- #include "ash/shell.h"
- #include "ash/test/ash_test_base.h"
- #include "ash/test/ash_test_helper.h"
- #include "ash/test/ash_test_views_delegate.h"
- #include "ui/aura/test/aura_test_base.h"
- #include "ui/aura/window.h"
- #include "ui/display/manager/display_manager.h"
- #include "ui/events/event.h"
- #include "ui/events/event_constants.h"
- #include "ui/events/test/event_generator.h"
- #include "ui/events/test/events_test_utils.h"
- #include "ui/events/types/event_type.h"
- 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;
- TestDelegate(const TestDelegate&) = delete;
- TestDelegate& operator=(const TestDelegate&) = delete;
- virtual ~TestDelegate() = default;
- bool CapturedMouseEvent(ui::EventType event_type) {
- return mouse_events_captured_.find(event_type) !=
- mouse_events_captured_.end();
- }
- void Reset() {
- mouse_events_captured_.clear();
- last_mouse_location_.SetPoint(0, 0);
- last_mouse_root_location_.SetPoint(0, 0);
- }
- gfx::Point last_mouse_event_location() { return last_mouse_location_; }
- gfx::Point last_mouse_event_root_location() {
- return last_mouse_root_location_;
- }
- private:
- // SelectToSpeakEventHandlerDelegate:
- void DispatchMouseEvent(const ui::MouseEvent& event) override {
- mouse_events_captured_.insert(event.type());
- last_mouse_location_ = event.location();
- last_mouse_root_location_ = event.root_location();
- }
- void DispatchKeyEvent(const ui::KeyEvent& event) override {
- // Unused for now.
- }
- gfx::Point last_mouse_location_;
- gfx::Point last_mouse_root_location_;
- std::set<ui::EventType> mouse_events_captured_;
- };
- class SelectToSpeakEventHandlerTest : public AshTestBase {
- public:
- SelectToSpeakEventHandlerTest() = default;
- SelectToSpeakEventHandlerTest(const SelectToSpeakEventHandlerTest&) = delete;
- SelectToSpeakEventHandlerTest& operator=(
- const SelectToSpeakEventHandlerTest&) = delete;
- ~SelectToSpeakEventHandlerTest() override = default;
- void SetUp() override {
- AshTestBase::SetUp();
- // This test triggers a resize of WindowTreeHost, which will end up
- // throttling events. set_throttle_input_on_resize_for_testing() disables
- // this.
- aura::Env::GetInstance()->set_throttle_input_on_resize_for_testing(false);
- // Make sure the display is initialized so we don't fail the test due to any
- // input events caused from creating the display.
- Shell::Get()->display_manager()->UpdateDisplays();
- base::RunLoop().RunUntilIdle();
- delegate_ = std::make_unique<TestDelegate>();
- generator_ = AshTestBase::GetEventGenerator();
- GetContext()->AddPreTargetHandler(&event_capturer_);
- controller_ = Shell::Get()->accessibility_controller();
- controller_->select_to_speak().SetEnabled(true);
- controller_->SetSelectToSpeakEventHandlerDelegate(delegate_.get());
- }
- void TearDown() override {
- GetContext()->RemovePreTargetHandler(&event_capturer_);
- generator_ = nullptr;
- controller_ = nullptr;
- AshTestBase::TearDown();
- }
- protected:
- ui::test::EventGenerator* generator_ = nullptr;
- EventCapturer event_capturer_;
- AccessibilityControllerImpl* controller_ = nullptr;
- std::unique_ptr<TestDelegate> delegate_;
- };
- TEST_F(SelectToSpeakEventHandlerTest, PressAndReleaseSearchNotHandled) {
- // If the user presses and releases the Search key, with no mouse
- // presses, the key events won't be handled by the SelectToSpeakEventHandler
- // and the normal behavior will occur.
- EXPECT_FALSE(event_capturer_.last_key_event());
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- ASSERT_TRUE(event_capturer_.last_key_event());
- EXPECT_FALSE(event_capturer_.last_key_event()->handled());
- event_capturer_.Reset();
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- ASSERT_TRUE(event_capturer_.last_key_event());
- EXPECT_FALSE(event_capturer_.last_key_event()->handled());
- }
- // Note: when running these tests locally on desktop Linux, you may need
- // to use xvfb-run, otherwise simulating the Search key press may not work.
- TEST_F(SelectToSpeakEventHandlerTest, SearchPlusClick) {
- // If the user holds the Search key and then clicks the mouse button,
- // the mouse events and the key release event get handled by the
- // SelectToSpeakEventHandler, and mouse events are forwarded to the
- // 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());
- 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_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_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
- EXPECT_EQ(click_location, delegate_->last_mouse_event_location());
- event_capturer_.Reset();
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- EXPECT_FALSE(event_capturer_.last_key_event());
- }
- TEST_F(SelectToSpeakEventHandlerTest, SearchPlusDrag) {
- // Mouse move events should also be captured.
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- gfx::Point click_location = gfx::Point(100, 12);
- generator_->set_current_screen_location(click_location);
- generator_->PressLeftButton();
- EXPECT_EQ(click_location, delegate_->last_mouse_event_location());
- // Drags are not blocked.
- 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_TRUE(event_capturer_.last_mouse_event());
- event_capturer_.Reset();
- generator_->ReleaseLeftButton();
- EXPECT_EQ(drag_location, delegate_->last_mouse_event_location());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- }
- TEST_F(SelectToSpeakEventHandlerTest, SearchPlusDragOnLargeDisplay) {
- // This display has twice the number of pixels per DIP. This means that
- // each event coming in in px needs to be divided by two to be converted
- // to DIPs.
- UpdateDisplay("800x600*2");
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- gfx::Point click_location_px = gfx::Point(100, 12);
- generator_->set_current_screen_location(click_location_px);
- generator_->PressLeftButton();
- EXPECT_EQ(gfx::Point(click_location_px.x() / 2, click_location_px.y() / 2),
- delegate_->last_mouse_event_location());
- gfx::Point drag_location_px = gfx::Point(120, 32);
- generator_->DragMouseTo(drag_location_px);
- 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();
- generator_->ReleaseLeftButton();
- 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_RELEASED));
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- }
- TEST_F(SelectToSpeakEventHandlerTest, RepeatSearchKey) {
- // Holding the Search key may generate key repeat events. Make sure it's
- // still treated as if the search key is down.
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- generator_->set_current_screen_location(gfx::Point(100, 12));
- generator_->PressLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- generator_->ReleaseLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
- event_capturer_.Reset();
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- EXPECT_FALSE(event_capturer_.last_key_event());
- }
- TEST_F(SelectToSpeakEventHandlerTest, TapSearchKey) {
- // Tapping the search key should not steal future events.
- event_capturer_.Reset();
- 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());
- generator_->ReleaseLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());
- }
- TEST_F(SelectToSpeakEventHandlerTest, SearchPlusClickTwice) {
- // Same as SearchPlusClick, above, but test that the user can keep
- // 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());
- generator_->set_current_screen_location(gfx::Point(100, 12));
- generator_->PressLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- generator_->ReleaseLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
- delegate_->Reset();
- EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
- generator_->PressLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- generator_->ReleaseLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
- event_capturer_.Reset();
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- EXPECT_FALSE(event_capturer_.last_key_event());
- }
- TEST_F(SelectToSpeakEventHandlerTest, SearchPlusKeyIgnoresClicks) {
- // If the user presses the Search key and then some other key,
- // we should assume the user does not want select-to-speak, 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());
- generator_->PressKey(ui::VKEY_I, ui::EF_COMMAND_DOWN);
- ASSERT_TRUE(event_capturer_.last_key_event());
- EXPECT_FALSE(event_capturer_.last_key_event()->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());
- 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());
- EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
- event_capturer_.Reset();
- generator_->ReleaseKey(ui::VKEY_I, ui::EF_COMMAND_DOWN);
- ASSERT_TRUE(event_capturer_.last_key_event());
- EXPECT_FALSE(event_capturer_.last_key_event()->handled());
- event_capturer_.Reset();
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- ASSERT_TRUE(event_capturer_.last_key_event());
- EXPECT_FALSE(event_capturer_.last_key_event()->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();
- generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
- ASSERT_FALSE(event_capturer_.last_key_event());
- generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
- ASSERT_FALSE(event_capturer_.last_key_event());
- // 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());
- generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
- ASSERT_FALSE(event_capturer_.last_key_event());
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- ASSERT_FALSE(event_capturer_.last_key_event());
- // 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());
- }
- TEST_F(SelectToSpeakEventHandlerTest, SearchPlusSIgnoresMouse) {
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- // Press S
- event_capturer_.Reset();
- generator_->PressKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
- ASSERT_FALSE(event_capturer_.last_key_event());
- // Mouse events are passed through like normal.
- generator_->PressLeftButton();
- EXPECT_TRUE(event_capturer_.last_mouse_event());
- event_capturer_.Reset();
- generator_->ReleaseLeftButton();
- EXPECT_TRUE(event_capturer_.last_mouse_event());
- generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
- ASSERT_FALSE(event_capturer_.last_key_event());
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- ASSERT_FALSE(event_capturer_.last_key_event());
- }
- TEST_F(SelectToSpeakEventHandlerTest, SearchPlusMouseIgnoresS) {
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- // Press the mouse
- event_capturer_.Reset();
- generator_->PressLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- // 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();
- generator_->ReleaseKey(ui::VKEY_S, ui::EF_COMMAND_DOWN);
- EXPECT_TRUE(event_capturer_.last_key_event());
- generator_->ReleaseLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- event_capturer_.Reset();
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- EXPECT_FALSE(event_capturer_.last_key_event());
- }
- TEST_F(SelectToSpeakEventHandlerTest, DoesntStartSelectionModeIfNotInactive) {
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- // This shouldn't cause any changes since the state is not inactive.
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateSelecting);
- // Mouse event still captured.
- gfx::Point click_location = gfx::Point(100, 12);
- generator_->set_current_screen_location(click_location);
- generator_->PressLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- // This shouldn't cause any changes since the state is not inactive.
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateSelecting);
- generator_->ReleaseLeftButton();
- // Releasing the search key is still captured per the end of the search+click
- // mode.
- event_capturer_.Reset();
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- EXPECT_FALSE(event_capturer_.last_key_event());
- }
- TEST_F(SelectToSpeakEventHandlerTest,
- CancelSearchKeyUpAfterEarlyInactiveStateChange) {
- generator_->PressKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- 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_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- generator_->ReleaseLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
- // Set the state to inactive.
- // This is realistic because Select-to-Speak will set the state to inactive
- // after the hittest / search for the focused node callbacks, which may occur
- // before the user actually releases the search key.
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateInactive);
- // The search key release should still be captured.
- event_capturer_.Reset();
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- EXPECT_FALSE(event_capturer_.last_key_event());
- }
- TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedWorksWithMouse) {
- gfx::Point click_location = gfx::Point(100, 12);
- generator_->set_current_screen_location(click_location);
- // Mouse events are let through normally before entering selecting state.
- // Another mouse event is let through normally.
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateInactive);
- generator_->PressLeftButton();
- EXPECT_TRUE(event_capturer_.last_mouse_event());
- event_capturer_.Reset();
- generator_->ReleaseLeftButton();
- EXPECT_TRUE(event_capturer_.last_mouse_event());
- event_capturer_.Reset();
- // Start selection mode.
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateSelecting);
- generator_->PressLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- event_capturer_.Reset();
- 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_TRUE(event_capturer_.last_mouse_event());
- event_capturer_.Reset();
- // Mouse up is the last event captured in the sequence
- generator_->ReleaseLeftButton();
- EXPECT_FALSE(event_capturer_.last_mouse_event());
- event_capturer_.Reset();
- // Another mouse event is let through normally.
- generator_->PressLeftButton();
- EXPECT_TRUE(event_capturer_.last_mouse_event());
- event_capturer_.Reset();
- }
- TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedWorksWithTouch) {
- gfx::Point touch_location = gfx::Point(100, 12);
- generator_->set_current_screen_location(touch_location);
- // Mouse events are let through normally before entering selecting state.
- // Another mouse event is let through normally.
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateInactive);
- generator_->PressTouch();
- EXPECT_TRUE(event_capturer_.last_touch_event());
- event_capturer_.Reset();
- generator_->ReleaseTouch();
- EXPECT_TRUE(event_capturer_.last_touch_event());
- event_capturer_.Reset();
- // Start selection mode.
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateSelecting);
- generator_->PressTouch();
- EXPECT_FALSE(event_capturer_.last_touch_event());
- // Touch events are converted to mouse events for the extension.
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- event_capturer_.Reset();
- 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();
- // Touch up is the last event captured in the sequence
- generator_->ReleaseTouch();
- EXPECT_FALSE(event_capturer_.last_touch_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
- event_capturer_.Reset();
- // Another touch event is let through normally.
- generator_->PressTouch();
- EXPECT_TRUE(event_capturer_.last_touch_event());
- event_capturer_.Reset();
- }
- TEST_F(SelectToSpeakEventHandlerTest, SelectionRequestedIgnoresOtherInput) {
- // Start selection mode.
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateSelecting);
- // 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();
- generator_->ReleaseKey(ui::VKEY_LWIN, ui::EF_COMMAND_DOWN);
- EXPECT_TRUE(event_capturer_.last_key_event());
- event_capturer_.Reset();
- // Start a touch selection, it should get captured and forwarded.
- generator_->PressTouch();
- EXPECT_FALSE(event_capturer_.last_touch_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- event_capturer_.Reset();
- // 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();
- generator_->ReleaseLeftButton();
- EXPECT_TRUE(event_capturer_.last_mouse_event());
- event_capturer_.Reset();
- // Complete the touch selection.
- generator_->ReleaseTouch();
- EXPECT_FALSE(event_capturer_.last_touch_event());
- event_capturer_.Reset();
- }
- TEST_F(SelectToSpeakEventHandlerTest, TrackingTouchIgnoresOtherTouchPointers) {
- gfx::Point touch_location = gfx::Point(100, 12);
- gfx::Point drag_location = gfx::Point(120, 32);
- generator_->set_current_screen_location(touch_location);
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateSelecting);
- // The first touch event is captured and sent to the extension.
- generator_->PressTouchId(1);
- EXPECT_FALSE(event_capturer_.last_touch_event());
- EXPECT_TRUE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- event_capturer_.Reset();
- 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(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- generator_->MoveTouchId(drag_location, 2);
- EXPECT_FALSE(event_capturer_.last_touch_event());
- EXPECT_FALSE(delegate_->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
- generator_->ReleaseTouchId(2);
- EXPECT_FALSE(event_capturer_.last_touch_event());
- 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(delegate_->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
- generator_->ExitPenPointerMode();
- // The first pointer is still tracked.
- 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();
- // Touch up is the last event captured in the sequence
- generator_->ReleaseTouchId(1);
- EXPECT_FALSE(event_capturer_.last_touch_event());
- event_capturer_.Reset();
- // Another touch event is let through normally.
- generator_->PressTouchId(3);
- EXPECT_TRUE(event_capturer_.last_touch_event());
- event_capturer_.Reset();
- }
- TEST_F(SelectToSpeakEventHandlerTest, TouchFirstOfMultipleDisplays) {
- UpdateDisplay("1+0-800x700,801+1-800x700");
- // On the first display.
- gfx::Point touch_location(200, 200);
- generator_->set_current_screen_location(touch_location);
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateSelecting);
- generator_->PressTouch();
- EXPECT_EQ(touch_location, delegate_->last_mouse_event_root_location());
- }
- TEST_F(SelectToSpeakEventHandlerTest, TouchSecondOfMultipleDisplays) {
- UpdateDisplay("1+0-800x700,801+1-800x700");
- // On the second display.
- gfx::Point touch_location(1000, 200);
- generator_->set_current_screen_location(touch_location);
- controller_->SetSelectToSpeakState(
- SelectToSpeakState::kSelectToSpeakStateSelecting);
- generator_->PressTouch();
- EXPECT_EQ(touch_location, delegate_->last_mouse_event_root_location());
- }
- } // namespace
- } // namespace ash
|