// 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 <set>

#include "ash/accessibility/accessibility_controller.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 "base/macros.h"
#include "ui/aura/test/aura_test_base.h"
#include "ui/aura/window.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"

namespace ash {
namespace {

// Records all key events for testing.
class EventCapturer : public ui::EventHandler {
 public:
  EventCapturer() {}
  ~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_.reset(new ui::MouseEvent(*event));
  }
  void OnKeyEvent(ui::KeyEvent* event) override {
    last_key_event_.reset(new ui::KeyEvent(*event));
  }
  void OnTouchEvent(ui::TouchEvent* event) override {
    last_touch_event_.reset(new 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_;

  DISALLOW_COPY_AND_ASSIGN(EventCapturer);
};

class TestDelegate : public mojom::SelectToSpeakEventHandlerDelegate {
 public:
  TestDelegate() : binding_(this) {}
  ~TestDelegate() override = default;

  mojom::SelectToSpeakEventHandlerDelegatePtr BindInterface() {
    mojom::SelectToSpeakEventHandlerDelegatePtr ptr;
    binding_.Bind(MakeRequest(&ptr));
    return ptr;
  }

  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);
  }

  gfx::Point last_mouse_event_location() { return last_mouse_location_; }

 private:
  // SelectToSpeakEventHandlerDelegate:
  void DispatchMouseEvent(std::unique_ptr<ui::Event> event) override {
    mouse_events_captured_.insert(event->type());
    last_mouse_location_ = event->AsMouseEvent()->location();
  }
  void DispatchKeyEvent(std::unique_ptr<ui::Event> event) override {
    // Unused for now.
  }

  gfx::Point last_mouse_location_;
  std::set<ui::EventType> mouse_events_captured_;

  // The binding that backs the interface pointer held by the event handler.
  mojo::Binding<mojom::SelectToSpeakEventHandlerDelegate> binding_;

  DISALLOW_COPY_AND_ASSIGN(TestDelegate);
};

class SelectToSpeakEventHandlerTest : public AshTestBase {
 public:
  SelectToSpeakEventHandlerTest() = default;
  ~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.
    Shell::Get()->aura_env()->set_throttle_input_on_resize_for_testing(false);
    delegate_ = std::make_unique<TestDelegate>();
    generator_ = AshTestBase::GetEventGenerator();
    CurrentContext()->AddPreTargetHandler(&event_capturer_);

    controller_ = Shell::Get()->accessibility_controller();
    controller_->SetSelectToSpeakEnabled(true);
    controller_->SetSelectToSpeakEventHandlerDelegate(
        delegate_->BindInterface());
  }

  void TearDown() override {
    CurrentContext()->RemovePreTargetHandler(&event_capturer_);
    generator_ = nullptr;
    controller_ = nullptr;
    AshTestBase::TearDown();
  }

  // Flush messages to the delegate before callers check its state.
  TestDelegate* GetDelegate() {
    controller_->FlushMojoForTest();
    return delegate_.get();
  }

 protected:
  ui::test::EventGenerator* generator_ = nullptr;
  EventCapturer event_capturer_;
  AccessibilityController* controller_ = nullptr;

 private:
  std::unique_ptr<TestDelegate> delegate_;

  DISALLOW_COPY_AND_ASSIGN(SelectToSpeakEventHandlerTest);
};

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(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  EXPECT_EQ(click_location, GetDelegate()->last_mouse_event_location());

  generator_->ReleaseLeftButton();
  EXPECT_FALSE(event_capturer_.last_mouse_event());

  EXPECT_TRUE(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));
  EXPECT_EQ(click_location, GetDelegate()->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, GetDelegate()->last_mouse_event_location());

  // Drags are not blocked.
  gfx::Point drag_location = gfx::Point(120, 32);
  generator_->DragMouseTo(drag_location);
  EXPECT_EQ(drag_location, GetDelegate()->last_mouse_event_location());
  EXPECT_TRUE(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
  EXPECT_TRUE(event_capturer_.last_mouse_event());
  event_capturer_.Reset();

  generator_->ReleaseLeftButton();
  EXPECT_EQ(drag_location, GetDelegate()->last_mouse_event_location());
  EXPECT_TRUE(GetDelegate()->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),
            GetDelegate()->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),
            GetDelegate()->last_mouse_event_location());
  EXPECT_TRUE(GetDelegate()->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),
            GetDelegate()->last_mouse_event_location());
  EXPECT_TRUE(GetDelegate()->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(GetDelegate()->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(GetDelegate()->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(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));

  generator_->ReleaseLeftButton();
  EXPECT_FALSE(event_capturer_.last_mouse_event());
  EXPECT_TRUE(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));

  GetDelegate()->Reset();
  EXPECT_FALSE(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  EXPECT_FALSE(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_RELEASED));

  generator_->PressLeftButton();
  EXPECT_FALSE(event_capturer_.last_mouse_event());
  EXPECT_TRUE(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));

  generator_->ReleaseLeftButton();
  EXPECT_FALSE(event_capturer_.last_mouse_event());
  EXPECT_TRUE(GetDelegate()->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(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));

  generator_->ReleaseLeftButton();
  ASSERT_TRUE(event_capturer_.last_mouse_event());
  EXPECT_FALSE(event_capturer_.last_mouse_event()->handled());

  EXPECT_FALSE(GetDelegate()->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(
      mojom::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(
      mojom::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(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  generator_->ReleaseLeftButton();
  EXPECT_FALSE(event_capturer_.last_mouse_event());
  EXPECT_TRUE(GetDelegate()->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(
      mojom::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(
      mojom::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(
      mojom::SelectToSpeakState::kSelectToSpeakStateSelecting);

  generator_->PressLeftButton();
  EXPECT_FALSE(event_capturer_.last_mouse_event());
  EXPECT_TRUE(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  event_capturer_.Reset();

  gfx::Point drag_location = gfx::Point(120, 32);
  generator_->DragMouseTo(drag_location);
  EXPECT_EQ(drag_location, GetDelegate()->last_mouse_event_location());
  EXPECT_TRUE(GetDelegate()->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(
      mojom::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(
      mojom::SelectToSpeakState::kSelectToSpeakStateSelecting);

  generator_->PressTouch();
  EXPECT_FALSE(event_capturer_.last_touch_event());
  // Touch events are converted to mouse events for the extension.
  EXPECT_TRUE(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  event_capturer_.Reset();

  gfx::Point drag_location = gfx::Point(120, 32);
  generator_->MoveTouch(drag_location);
  EXPECT_EQ(drag_location, GetDelegate()->last_mouse_event_location());
  EXPECT_TRUE(GetDelegate()->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(GetDelegate()->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(
      mojom::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(GetDelegate()->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(
      mojom::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(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  event_capturer_.Reset();
  GetDelegate()->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(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  generator_->MoveTouchId(drag_location, 2);
  EXPECT_FALSE(event_capturer_.last_touch_event());
  EXPECT_FALSE(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_DRAGGED));
  generator_->ReleaseTouchId(2);
  EXPECT_FALSE(event_capturer_.last_touch_event());
  EXPECT_FALSE(GetDelegate()->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(GetDelegate()->CapturedMouseEvent(ui::ET_MOUSE_PRESSED));
  generator_->ExitPenPointerMode();

  // The first pointer is still tracked.
  generator_->MoveTouchId(drag_location, 1);
  EXPECT_EQ(drag_location, GetDelegate()->last_mouse_event_location());
  EXPECT_TRUE(GetDelegate()->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();
}

}  // namespace
}  // namespace ash
