// Copyright 2013 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/accessibility/accessibility_controller_impl.h"
#include "ash/autoclick/autoclick_controller.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/system/accessibility/accessibility_feature_disable_dialog.h"
#include "ash/system/accessibility/autoclick_menu_bubble_controller.h"
#include "ash/system/accessibility/autoclick_menu_view.h"
#include "ash/system/accessibility/autoclick_scroll_bubble_controller.h"
#include "ash/system/accessibility/autoclick_scroll_view.h"
#include "ash/system/unified/unified_system_tray.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/collision_detection/collision_detection_utils.h"
#include "ash/wm/desks/desks_util.h"
#include "ash/wm/window_state.h"
#include "ash/wm/wm_event.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/display/manager/display_manager.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
#include "ui/events/event_handler.h"
#include "ui/events/event_utils.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/events/test/event_generator.h"
#include "ui/views/window/dialog_client_view.h"

namespace ash {

namespace {
const int kScrollToMenuBoundsBuffer = 18;
}

class MouseEventCapturer : public ui::EventHandler {
 public:
  MouseEventCapturer() { Reset(); }
  ~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_;

  DISALLOW_COPY_AND_ASSIGN(MouseEventCapturer);
};

class AutoclickTest : public AshTestBase {
 public:
  AutoclickTest()
      : AshTestBase(base::test::ScopedTaskEnvironment::TimeSource::MOCK_TIME) {}
  ~AutoclickTest() override = default;

  void SetUp() override {
    AshTestBase::SetUp();
    Shell::Get()->AddPreTargetHandler(&mouse_event_capturer_);
    GetAutoclickController()->SetAutoclickDelay(base::TimeDelta());

    // Move mouse to deterministic location at the start of each test.
    GetEventGenerator()->MoveMouseTo(100, 100);

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

  void TearDown() override {
    Shell::Get()->RemovePreTargetHandler(&mouse_event_capturer_);
    AshTestBase::TearDown();
  }

  void MoveMouseWithFlagsTo(int x, int y, ui::EventFlags flags) {
    GetEventGenerator()->set_flags(flags);
    GetEventGenerator()->MoveMouseTo(x, y);
    GetEventGenerator()->set_flags(ui::EF_NONE);
  }

  const std::vector<ui::MouseEvent>& WaitForMouseEvents() {
    ClearMouseEvents();
    // TODO(katie): Consider using quit closure instead of RunUntilIdle.
    base::RunLoop().RunUntilIdle();
    return GetMouseEvents();
  }

  void FastForwardBy(int milliseconds) {
    scoped_task_environment_->FastForwardBy(
        base::TimeDelta::FromMilliseconds(milliseconds));
  }

  AutoclickController* GetAutoclickController() {
    return Shell::Get()->autoclick_controller();
  }

  // Calculates and returns full delay from the animation delay, after setting
  // that delay on the autoclick controller.
  int UpdateAnimationDelayAndGetFullDelay(float animation_delay) {
    float ratio =
        GetAutoclickController()->GetStartGestureDelayRatioForTesting();
    int full_delay = ceil(1.0 / ratio) * animation_delay;
    GetAutoclickController()->SetAutoclickDelay(
        base::TimeDelta::FromMilliseconds(full_delay));
    return full_delay;
  }

  AutoclickMenuView* GetAutoclickMenuView() {
    return GetAutoclickController()
        ->GetMenuBubbleControllerForTesting()
        ->menu_view_;
  }

  AutoclickScrollView* GetAutoclickScrollView() {
    AutoclickScrollBubbleController* controller =
        GetAutoclickController()
            ->GetMenuBubbleControllerForTesting()
            ->scroll_bubble_controller_.get();
    return controller ? controller->scroll_view_ : nullptr;
  }

  views::Widget* GetAutoclickBubbleWidget() {
    return GetAutoclickController()
        ->GetMenuBubbleControllerForTesting()
        ->bubble_widget_;
  }

  views::View* GetMenuButton(AutoclickMenuView::ButtonId view_id) {
    AutoclickMenuView* menu_view = GetAutoclickMenuView();
    if (!menu_view)
      return nullptr;
    return menu_view->GetViewByID(static_cast<int>(view_id));
  }

  views::View* GetScrollButton(AutoclickScrollView::ButtonId view_id) {
    AutoclickScrollView* scroll_view = GetAutoclickScrollView();
    if (!scroll_view)
      return nullptr;
    return scroll_view->GetViewByID(static_cast<int>(view_id));
  }

  void ClearMouseEvents() { mouse_event_capturer_.Reset(); }

  const std::vector<ui::MouseEvent>& GetMouseEvents() {
    return mouse_event_capturer_.captured_events();
  }

  const std::vector<ui::MouseWheelEvent>& GetMouseWheelEvents() {
    return mouse_event_capturer_.captured_mouse_wheel_events();
  }

 private:
  MouseEventCapturer mouse_event_capturer_;

  DISALLOW_COPY_AND_ASSIGN(AutoclickTest);
};

TEST_F(AutoclickTest, ToggleEnabled) {
  std::vector<ui::MouseEvent> events;

  // We should not see any events initially.
  EXPECT_FALSE(GetAutoclickController()->IsEnabled());
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());

  // Enable autoclick, and we should see a mouse pressed and
  // a mouse released event, simulating a click.
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  GetEventGenerator()->MoveMouseTo(0, 0);
  EXPECT_TRUE(GetAutoclickController()->IsEnabled());
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());

  // We should not get any more clicks until we move the mouse.
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());
  GetEventGenerator()->MoveMouseTo(30, 30);
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());

  // Disable autoclick, and we should see the original behaviour.
  GetAutoclickController()->SetEnabled(false, false /* do not show dialog */);
  EXPECT_FALSE(GetAutoclickController()->IsEnabled());
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());

  // After disable, autoclick should be set back to left click.
  EXPECT_EQ(AutoclickEventType::kLeftClick,
            Shell::Get()->accessibility_controller()->GetAutoclickEventType());
}

TEST_F(AutoclickTest, MouseMovement) {
  std::vector<ui::MouseEvent> events;
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);

  gfx::Point p1(0, 0);
  gfx::Point p2(20, 20);
  gfx::Point p3(40, 40);

  // Move mouse to p1.
  GetEventGenerator()->MoveMouseTo(p1);
  events = WaitForMouseEvents();
  EXPECT_EQ(2u, events.size());
  EXPECT_EQ(p1.ToString(), events[0].root_location().ToString());
  EXPECT_EQ(p1.ToString(), events[1].root_location().ToString());

  // Move mouse to multiple locations and finally arrive at p3.
  GetEventGenerator()->MoveMouseTo(p2);
  GetEventGenerator()->MoveMouseTo(p1);
  GetEventGenerator()->MoveMouseTo(p3);
  events = WaitForMouseEvents();
  EXPECT_EQ(2u, events.size());
  EXPECT_EQ(p3.ToString(), events[0].root_location().ToString());
  EXPECT_EQ(p3.ToString(), events[1].root_location().ToString());
}

TEST_F(AutoclickTest, MovementThreshold) {
  UpdateDisplay("1280x1024,800x600");
  base::RunLoop().RunUntilIdle();
  aura::Window::Windows root_windows = Shell::GetAllRootWindows();
  EXPECT_EQ(2u, root_windows.size());

  int animation_delay = 5;

  const struct {
    int movement_threshold;
    bool stabilize_click_position;
  } kTestCases[] = {
      {10, false}, {20, false}, {30, false}, {40, false}, {50, false},
      {10, true},  {20, true},  {30, true},  {40, true},  {50, true},
  };

  for (const auto& test : kTestCases) {
    GetAutoclickController()->set_stabilize_click_position(
        test.stabilize_click_position);
    int movement_threshold = test.movement_threshold;
    GetAutoclickController()->SetMovementThreshold(movement_threshold);

    // Run test for the secondary display too to test fix for crbug.com/449870.
    for (auto* root_window : root_windows) {
      gfx::Point center = root_window->GetBoundsInScreen().CenterPoint();

      GetAutoclickController()->SetEnabled(true,
                                           false /* do not show dialog */);
      GetEventGenerator()->MoveMouseTo(center);
      ClearMouseEvents();
      EXPECT_EQ(2u, WaitForMouseEvents().size());

      // Small mouse movements should not trigger an autoclick, i.e. movements
      // within the radius of the movement_threshold.
      GetEventGenerator()->MoveMouseTo(
          center + gfx::Vector2d(std::sqrt(movement_threshold) - 1,
                                 std::sqrt(movement_threshold) - 1));
      EXPECT_EQ(0u, WaitForMouseEvents().size());
      GetEventGenerator()->MoveMouseTo(
          center + gfx::Vector2d(movement_threshold - 1, 0));
      EXPECT_EQ(0u, WaitForMouseEvents().size());
      GetEventGenerator()->MoveMouseTo(
          center + gfx::Vector2d(0, -movement_threshold + 1));
      EXPECT_EQ(0u, WaitForMouseEvents().size());
      GetEventGenerator()->MoveMouseTo(center);
      EXPECT_EQ(0u, WaitForMouseEvents().size());

      // A larger mouse movement should trigger an autoclick.
      GetEventGenerator()->MoveMouseTo(
          center +
          gfx::Vector2d(movement_threshold + 1, movement_threshold + 1));
      EXPECT_EQ(2u, WaitForMouseEvents().size());

      // Moving outside the threshold after the gesture begins should cancel
      // the autoclick. Update the delay so we can do events between the initial
      // trigger of the feature and the click.
      int full_delay = UpdateAnimationDelayAndGetFullDelay(animation_delay);
      GetEventGenerator()->MoveMouseTo(
          center - gfx::Vector2d(movement_threshold, movement_threshold));
      FastForwardBy(animation_delay + 1);
      GetEventGenerator()->MoveMouseTo(center);
      ClearMouseEvents();

      // After a time, a new click will occur at the second location. The first
      // location should never get a click.
      FastForwardBy(full_delay * 2);
      EXPECT_EQ(2u, GetMouseEvents().size());
      gfx::Rect display_bounds = display::Screen::GetScreen()
                                     ->GetDisplayNearestWindow(root_window)
                                     .bounds();
      EXPECT_EQ(center - gfx::Vector2d(display_bounds.origin().x(),
                                       display_bounds.origin().y()),
                GetMouseEvents()[0].location());

      // Move it out of the way so the next cycle starts properly.
      GetEventGenerator()->MoveMouseTo(gfx::Point(0, 0));
      GetAutoclickController()->SetAutoclickDelay(base::TimeDelta());
    }
  }

  // Reset to defaults.
  GetAutoclickController()->SetMovementThreshold(20);
  GetAutoclickController()->set_stabilize_click_position(false);
}

TEST_F(AutoclickTest, MovementWithinThresholdWhileTimerRunning) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  GetAutoclickController()->SetMovementThreshold(20);
  int animation_delay = 5;
  int full_delay = UpdateAnimationDelayAndGetFullDelay(animation_delay);

  GetAutoclickController()->set_stabilize_click_position(true);
  GetEventGenerator()->MoveMouseTo(100, 100);
  FastForwardBy(animation_delay + 1);

  // Move the mouse within the threshold. It shouldn't change the eventual
  // target of the event, or cancel the click.
  GetEventGenerator()->MoveMouseTo(110, 110);
  ClearMouseEvents();
  FastForwardBy(full_delay);
  std::vector<ui::MouseEvent> events = GetMouseEvents();

  EXPECT_EQ(2u, events.size());
  EXPECT_EQ(gfx::Point(100, 100), events[0].location());
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
  EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, events[0].flags());
  EXPECT_EQ(gfx::Point(100, 100), events[1].location());
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
  EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, events[1].flags());

  // When the click position is not stabilized, the mouse movement should
  // translate into the target of the event, but not cancel the click.
  GetAutoclickController()->set_stabilize_click_position(false);
  GetEventGenerator()->MoveMouseTo(200, 200);
  FastForwardBy(animation_delay + 1);
  GetEventGenerator()->MoveMouseTo(210, 210);

  ClearMouseEvents();
  FastForwardBy(full_delay);
  events = GetMouseEvents();

  EXPECT_EQ(2u, events.size());
  EXPECT_EQ(gfx::Point(210, 210), events[0].location());
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
  EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, events[0].flags());
  EXPECT_EQ(gfx::Point(210, 210), events[1].location());
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
  EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, events[1].flags());

  // Reset delay.
  GetAutoclickController()->SetAutoclickDelay(base::TimeDelta());
}

TEST_F(AutoclickTest, SingleKeyModifier) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  MoveMouseWithFlagsTo(20, 20, ui::EF_SHIFT_DOWN);
  std::vector<ui::MouseEvent> events = WaitForMouseEvents();
  EXPECT_EQ(2u, events.size());
  EXPECT_EQ(ui::EF_SHIFT_DOWN, events[0].flags() & ui::EF_SHIFT_DOWN);
  EXPECT_EQ(ui::EF_SHIFT_DOWN, events[1].flags() & ui::EF_SHIFT_DOWN);
}

TEST_F(AutoclickTest, MultipleKeyModifiers) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  ui::EventFlags modifier_flags = static_cast<ui::EventFlags>(
      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN);
  MoveMouseWithFlagsTo(30, 30, modifier_flags);
  std::vector<ui::MouseEvent> events = WaitForMouseEvents();
  EXPECT_EQ(2u, events.size());
  EXPECT_EQ(modifier_flags, events[0].flags() & modifier_flags);
  EXPECT_EQ(modifier_flags, events[1].flags() & modifier_flags);
}

TEST_F(AutoclickTest, KeyModifiersReleased) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);

  ui::EventFlags modifier_flags = static_cast<ui::EventFlags>(
      ui::EF_CONTROL_DOWN | ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN);
  MoveMouseWithFlagsTo(12, 12, modifier_flags);

  // Simulate releasing key modifiers by sending key released events.
  GetEventGenerator()->ReleaseKey(
      ui::VKEY_CONTROL,
      static_cast<ui::EventFlags>(ui::EF_ALT_DOWN | ui::EF_SHIFT_DOWN));
  GetEventGenerator()->ReleaseKey(ui::VKEY_SHIFT, ui::EF_ALT_DOWN);

  std::vector<ui::MouseEvent> events;
  events = WaitForMouseEvents();
  EXPECT_EQ(2u, events.size());
  EXPECT_EQ(0, events[0].flags() & ui::EF_CONTROL_DOWN);
  EXPECT_EQ(0, events[0].flags() & ui::EF_SHIFT_DOWN);
  EXPECT_EQ(ui::EF_ALT_DOWN, events[0].flags() & ui::EF_ALT_DOWN);
}

TEST_F(AutoclickTest, UserInputCancelsAutoclick) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  std::vector<ui::MouseEvent> events;

  // Pressing a normal key should cancel the autoclick.
  GetEventGenerator()->MoveMouseTo(200, 200);
  GetEventGenerator()->PressKey(ui::VKEY_K, ui::EF_NONE);
  GetEventGenerator()->ReleaseKey(ui::VKEY_K, ui::EF_NONE);
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());

  // Pressing a modifier key should NOT cancel the autoclick.
  GetEventGenerator()->MoveMouseTo(100, 100);
  GetEventGenerator()->PressKey(ui::VKEY_SHIFT, ui::EF_SHIFT_DOWN);
  GetEventGenerator()->ReleaseKey(ui::VKEY_SHIFT, ui::EF_NONE);
  events = WaitForMouseEvents();
  EXPECT_EQ(2u, events.size());

  // Mouse-wheel scroll events should cancel the autoclick.
  GetEventGenerator()->MoveMouseTo(300, 300);
  GetEventGenerator()->MoveMouseWheel(0, 20);
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());

  // Performing a gesture should cancel the autoclick.
  GetEventGenerator()->MoveMouseTo(200, 200);
  GetEventGenerator()->GestureTapDownAndUp(gfx::Point(100, 100));
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());

  // Test another gesture.
  GetEventGenerator()->MoveMouseTo(100, 100);
  GetEventGenerator()->GestureScrollSequence(
      gfx::Point(100, 100), gfx::Point(200, 200),
      base::TimeDelta::FromMilliseconds(200), 3);
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());

  // Test scroll events.
  GetEventGenerator()->MoveMouseTo(200, 200);
  GetEventGenerator()->ScrollSequence(gfx::Point(100, 100),
                                      base::TimeDelta::FromMilliseconds(200), 0,
                                      100, 3, 2);
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());

  // However, just starting a scroll doesn't cancel. If you tap a touchpad on
  // an Eve chromebook, for example, it can send an ET_SCROLL_FLING_CANCEL
  // event, which shouldn't actually cancel autoclick.
  GetEventGenerator()->MoveMouseTo(100, 100);
  GetEventGenerator()->ScrollSequence(gfx::Point(100, 100), base::TimeDelta(),
                                      0, 0, 0, 1);
  events = WaitForMouseEvents();
  EXPECT_EQ(2u, events.size());
}

TEST_F(AutoclickTest, SynthesizedMouseMovesIgnored) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  std::vector<ui::MouseEvent> events;
  GetEventGenerator()->MoveMouseTo(100, 100);
  events = WaitForMouseEvents();
  EXPECT_EQ(2u, events.size());

  // Show a window and make sure the new window is under the cursor. As a
  // result, synthesized mouse events will be dispatched to the window, but it
  // should not trigger an autoclick.
  aura::test::EventCountDelegate delegate;
  std::unique_ptr<aura::Window> window(CreateTestWindowInShellWithDelegate(
      &delegate, 123, gfx::Rect(50, 50, 100, 100)));
  window->Show();
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());
  EXPECT_EQ("1 1 0", delegate.GetMouseMotionCountsAndReset());
}

TEST_F(AutoclickTest, AutoclickChangeEventTypes) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  GetAutoclickController()->set_revert_to_left_click(false);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kRightClick);
  std::vector<ui::MouseEvent> events;

  GetEventGenerator()->MoveMouseTo(30, 30);
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
  EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[0].flags());
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
  EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[1].flags());

  // Changing the event type cancels the event
  GetEventGenerator()->MoveMouseTo(60, 60);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kLeftClick);
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());

  // Changing the event type to the same thing does not cancel the event.
  // kLeftClick type does not produce a double-click.
  GetEventGenerator()->MoveMouseTo(90, 90);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kLeftClick);
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());
  EXPECT_FALSE(ui::EF_IS_DOUBLE_CLICK & events[0].flags());
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());
  EXPECT_FALSE(ui::EF_IS_DOUBLE_CLICK & events[1].flags());

  // Double-click works as expected.
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kDoubleClick);
  GetEventGenerator()->MoveMouseTo(120, 120);
  events = WaitForMouseEvents();
  ASSERT_EQ(4u, events.size());
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());
  EXPECT_FALSE(ui::EF_IS_DOUBLE_CLICK & events[0].flags());
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[1].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());
  EXPECT_FALSE(ui::EF_IS_DOUBLE_CLICK & events[1].flags());
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[2].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[2].flags());
  EXPECT_TRUE(ui::EF_IS_DOUBLE_CLICK & events[2].flags());
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[3].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[3].flags());
  EXPECT_TRUE(ui::EF_IS_DOUBLE_CLICK & events[3].flags());

  // Pause / no action does not cause events to be generated even when the
  // mouse moves.
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kNoAction);
  GetEventGenerator()->MoveMouseTo(120, 120);
  events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());
}

TEST_F(AutoclickTest, AutoclickDragAndDropEvents) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  GetAutoclickController()->set_revert_to_left_click(false);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kDragAndDrop);
  std::vector<ui::MouseEvent> events;

  GetEventGenerator()->MoveMouseTo(30, 30);
  events = WaitForMouseEvents();
  ASSERT_EQ(1u, events.size());
  EXPECT_EQ(ui::ET_MOUSE_PRESSED, events[0].type());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());

  ClearMouseEvents();
  GetEventGenerator()->MoveMouseTo(60, 60);
  events = GetMouseEvents();
  ASSERT_EQ(1u, events.size());
  EXPECT_EQ(ui::ET_MOUSE_DRAGGED, events[0].type());

  // Another move creates a drag
  ClearMouseEvents();
  GetEventGenerator()->MoveMouseTo(90, 90);
  events = GetMouseEvents();
  ASSERT_EQ(1u, events.size());
  EXPECT_EQ(ui::ET_MOUSE_DRAGGED, events[0].type());

  // Waiting in place creates the released event.
  events = WaitForMouseEvents();
  ASSERT_EQ(1u, events.size());
  EXPECT_EQ(ui::ET_MOUSE_RELEASED, events[0].type());
}

TEST_F(AutoclickTest, AutoclickScrollEvents) {
  UpdateDisplay("800x600");
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  GetAutoclickController()->SetAutoclickEventType(AutoclickEventType::kScroll);
  std::vector<ui::MouseEvent> events;
  std::vector<ui::MouseWheelEvent> wheel_events;

  // Expect that the first scroll action occurs at the middle of the screen,
  // since the position has not been set by the user.
  GetAutoclickController()->DoScrollAction(
      AutoclickController::ScrollPadAction::kScrollUp);
  events = GetMouseEvents();
  wheel_events = GetMouseWheelEvents();
  EXPECT_EQ(0u, events.size());
  ASSERT_EQ(1u, wheel_events.size());
  EXPECT_EQ(ui::ET_MOUSEWHEEL, wheel_events[0].type());
  EXPECT_EQ(gfx::Point(400, 300), wheel_events[0].location());
  EXPECT_GT(wheel_events[0].y_offset(), 0);
  ClearMouseEvents();

  // Expect that a dwell will set the scroll location.
  GetEventGenerator()->MoveMouseTo(90, 90);
  base::RunLoop().RunUntilIdle();
  GetAutoclickController()->DoScrollAction(
      AutoclickController::ScrollPadAction::kScrollUp);
  events = GetMouseEvents();
  wheel_events = GetMouseWheelEvents();
  EXPECT_EQ(0u, events.size());
  ASSERT_EQ(1u, wheel_events.size());
  EXPECT_EQ(ui::ET_MOUSEWHEEL, wheel_events[0].type());
  EXPECT_EQ(gfx::Point(90, 90), wheel_events[0].location());
  EXPECT_GT(wheel_events[0].y_offset(), 0);
  ClearMouseEvents();

  GetAutoclickController()->DoScrollAction(
      AutoclickController::ScrollPadAction::kScrollLeft);
  events = GetMouseEvents();
  wheel_events = GetMouseWheelEvents();
  EXPECT_EQ(0u, events.size());
  ASSERT_EQ(1u, wheel_events.size());
  EXPECT_EQ(ui::ET_MOUSEWHEEL, wheel_events[0].type());
  EXPECT_EQ(gfx::Point(90, 90), wheel_events[0].location());
  EXPECT_GT(wheel_events[0].x_offset(), 0);
  ClearMouseEvents();

  // Try another position, and the other two types of scroll action.
  GetEventGenerator()->MoveMouseTo(200, 200);
  base::RunLoop().RunUntilIdle();
  GetAutoclickController()->DoScrollAction(
      AutoclickController::ScrollPadAction::kScrollDown);
  events = GetMouseEvents();
  wheel_events = GetMouseWheelEvents();
  EXPECT_EQ(0u, events.size());
  ASSERT_EQ(1u, wheel_events.size());
  EXPECT_EQ(ui::ET_MOUSEWHEEL, wheel_events[0].type());
  EXPECT_EQ(gfx::Point(200, 200), wheel_events[0].location());
  EXPECT_LT(wheel_events[0].y_offset(), 0);
  ClearMouseEvents();

  GetAutoclickController()->DoScrollAction(
      AutoclickController::ScrollPadAction::kScrollRight);
  events = GetMouseEvents();
  wheel_events = GetMouseWheelEvents();
  EXPECT_EQ(0u, events.size());
  ASSERT_EQ(1u, wheel_events.size());
  EXPECT_EQ(ui::ET_MOUSEWHEEL, wheel_events[0].type());
  EXPECT_EQ(gfx::Point(200, 200), wheel_events[0].location());
  EXPECT_LT(wheel_events[0].x_offset(), 0);
  ClearMouseEvents();
}

TEST_F(AutoclickTest, AutoclickRevertsToLeftClick) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  GetAutoclickController()->set_revert_to_left_click(true);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kRightClick);
  std::vector<ui::MouseEvent> events;

  GetEventGenerator()->MoveMouseTo(30, 30);
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[0].flags());
  EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[1].flags());

  // Another event is now left-click; we've reverted to left click.
  GetEventGenerator()->MoveMouseTo(90, 90);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kLeftClick);
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());

  // The next event is also a left click.
  GetEventGenerator()->MoveMouseTo(120, 120);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kLeftClick);
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());

  // Changing revert to false doesn't change that we are on left click at
  // present.
  GetAutoclickController()->set_revert_to_left_click(false);
  GetEventGenerator()->MoveMouseTo(150, 150);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kLeftClick);
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());
  EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());

  // But we should no longer revert to left click if the type is something else.
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kRightClick);
  GetEventGenerator()->MoveMouseTo(180, 180);
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[0].flags());
  EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[1].flags());

  // Should still be right click.
  GetEventGenerator()->MoveMouseTo(210, 210);
  events = WaitForMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[0].flags());
  EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[1].flags());
}

TEST_F(AutoclickTest, WaitsToDrawAnimationAfterDwellBegins) {
  int animation_delay = 5;
  int full_delay = UpdateAnimationDelayAndGetFullDelay(animation_delay);
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  std::vector<ui::MouseEvent> events;

  // Start a dwell at (210, 210).
  GetEventGenerator()->MoveMouseTo(210, 210);

  // The center should change to (205, 205) if the adjustment is made before
  // the animation starts.
  FastForwardBy(animation_delay - 1);
  GetEventGenerator()->MoveMouseTo(205, 205);

  // Now wait the full delay to ensure the click has happened, then check
  // the result.
  FastForwardBy(full_delay);
  events = GetMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_EQ(gfx::Point(205, 205), events[0].location());

  // Start another dwell at (100, 100).
  ClearMouseEvents();
  GetEventGenerator()->MoveMouseTo(100, 100);

  // Move the mouse a little to (105, 105), which should become the center.
  FastForwardBy(animation_delay - 1);
  GetEventGenerator()->MoveMouseTo(105, 105);

  // Moving the mouse during the animation changes the center point.
  FastForwardBy(animation_delay);
  GetEventGenerator()->MoveMouseTo(110, 110);

  // Now wait until the click. It should be at the center point from before
  // the animation started.
  FastForwardBy(full_delay);
  events = GetMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_EQ(gfx::Point(110, 110), events[0].location());

  // Turn off stabilize_click_position and try again, the position should update
  // with the cursor's new position until the click occurs.
  GetAutoclickController()->set_stabilize_click_position(true);
  ClearMouseEvents();
  GetEventGenerator()->MoveMouseTo(200, 200);

  // (205, 205) will become the center of the animation.
  FastForwardBy(animation_delay - 1);
  GetEventGenerator()->MoveMouseTo(205, 205);

  // Fast forward until the animation would have started. Now moving the mouse
  // a little does not change the center point because we have stabilize on.
  FastForwardBy(animation_delay);
  GetEventGenerator()->MoveMouseTo(210, 210);
  FastForwardBy(full_delay);
  events = GetMouseEvents();
  ASSERT_EQ(2u, events.size());
  EXPECT_EQ(gfx::Point(205, 205), events[0].location());

  // Reset state.
  GetAutoclickController()->set_stabilize_click_position(false);
}

TEST_F(AutoclickTest, DoesActionOnBubbleWhenInDifferentModes) {
  AccessibilityControllerImpl* accessibility_controller =
      Shell::Get()->accessibility_controller();
  // Enable autoclick from the accessibility controller so that the bubble is
  // constructed too.
  accessibility_controller->SetAutoclickEnabled(true);
  GetAutoclickController()->set_revert_to_left_click(false);
  std::vector<ui::MouseEvent> events;

  // Test at different screen sizes and densities because the fake click on
  // the button involves coordinating between dips and pixels. Try two different
  // positions to ensure offsets are calculated correctly.
  const struct {
    const std::string display_spec;
    float scale;
    AutoclickMenuPosition position;
  } kTestCases[] = {
      {"800x600", 1.0f, AutoclickMenuPosition::kBottomRight},
      {"1024x800*2.0", 2.0f, AutoclickMenuPosition::kBottomRight},
      {"800x600", 1.0f, AutoclickMenuPosition::kTopLeft},
      {"1024x800*2.0", 2.0f, AutoclickMenuPosition::kTopLeft},
  };
  for (const auto& test : kTestCases) {
    UpdateDisplay(test.display_spec);
    accessibility_controller->SetAutoclickMenuPosition(test.position);
    accessibility_controller->SetAutoclickEventType(
        AutoclickEventType::kRightClick);

    AutoclickMenuView* menu = GetAutoclickMenuView();
    ASSERT_TRUE(menu);

    // Outside of the bubble, a right-click still occurs.
    // Move to a central position which will not have any menu but will still be
    // on-screen.
    GetEventGenerator()->MoveMouseTo(200 * test.scale, 200 * test.scale);
    events = WaitForMouseEvents();
    ASSERT_EQ(2u, events.size());
    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[0].flags());
    EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[1].flags());

    // Over the bubble, we get no real click, although the autoclick event
    // type does get changed properly over a button.
    gfx::Point button_location = gfx::ScaleToRoundedPoint(
        GetMenuButton(AutoclickMenuView::ButtonId::kDoubleClick)
            ->GetBoundsInScreen()
            .CenterPoint(),
        test.scale);
    GetEventGenerator()->MoveMouseTo(button_location);
    events = WaitForMouseEvents();
    EXPECT_EQ(0u, events.size());
    // But the event type did change with a the hover on the button.
    EXPECT_EQ(AutoclickEventType::kDoubleClick,
              accessibility_controller->GetAutoclickEventType());

    // Change to a pause action type.
    accessibility_controller->SetAutoclickEventType(
        AutoclickEventType::kNoAction);

    // Outside the bubble, no action occurs.
    GetEventGenerator()->MoveMouseTo(200 * test.scale, 200 * test.scale);
    events = WaitForMouseEvents();
    EXPECT_EQ(0u, events.size());

    // If we move over the bubble but not over any button than no real click
    // occurs. There is no button at the top of the bubble.
    button_location = gfx::ScaleToRoundedPoint(
        GetAutoclickMenuView()->GetBoundsInScreen().top_center() +
            gfx::Vector2d(0, 1),
        test.scale);
    GetEventGenerator()->MoveMouseTo(button_location);
    events = WaitForMouseEvents();
    EXPECT_EQ(0u, events.size());
    // The event type did not change because we were not over any button.
    EXPECT_EQ(AutoclickEventType::kNoAction,
              accessibility_controller->GetAutoclickEventType());

    // Leaving the bubble we are still paused.
    GetEventGenerator()->MoveMouseTo(200 * test.scale, 200 * test.scale);
    events = WaitForMouseEvents();
    EXPECT_EQ(0u, events.size());

    // Moving over another button takes an action.
    button_location = gfx::ScaleToRoundedPoint(
        GetMenuButton(AutoclickMenuView::ButtonId::kLeftClick)
            ->GetBoundsInScreen()
            .CenterPoint(),
        test.scale);
    GetEventGenerator()->MoveMouseTo(button_location);
    events = WaitForMouseEvents();
    EXPECT_EQ(0u, events.size());
    EXPECT_EQ(AutoclickEventType::kLeftClick,
              accessibility_controller->GetAutoclickEventType());
  }
}

TEST_F(AutoclickTest,
       StartsGestureOnBubbleButDoesNotClickIfMouseMovedWhenPaused) {
  Shell::Get()->accessibility_controller()->SetAutoclickEnabled(true);
  GetAutoclickController()->set_revert_to_left_click(false);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kNoAction);
  Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
      AutoclickMenuPosition::kBottomRight);

  int animation_delay = 5;
  int full_delay = UpdateAnimationDelayAndGetFullDelay(animation_delay);

  std::vector<ui::MouseEvent> events;
  AutoclickMenuView* menu = GetAutoclickMenuView();
  ASSERT_TRUE(menu);

  // Start a dwell over the bubble.
  GetEventGenerator()->MoveMouseTo(menu->GetBoundsInScreen().origin());

  // Move back off the bubble before anything happens.
  FastForwardBy(animation_delay - 1);
  GetEventGenerator()->MoveMouseTo(30, 30);

  // Now wait the full delay to ensure pause could have happened.
  FastForwardBy(full_delay);
  events = GetMouseEvents();
  ASSERT_EQ(0u, events.size());

  // This time, dwell over the bubble long enough for the animation to begin.
  // No action should occur if we move off during the dwell.
  GetEventGenerator()->MoveMouseTo(menu->GetBoundsInScreen().origin());

  // Move back off the bubble after the animation begins, but before a click
  // would occur.
  FastForwardBy(animation_delay + 1);
  GetEventGenerator()->MoveMouseTo(30, 30);

  // Now wait the full delay to ensure pause could have happened.
  FastForwardBy(full_delay);
  events = GetMouseEvents();
  ASSERT_EQ(0u, events.size());
}

// The autoclick tray shouldn't stop the shelf from auto-hiding.
TEST_F(AutoclickTest, ShelfAutohidesWithAutoclickBubble) {
  Shelf* shelf = GetPrimaryShelf();

  // Create a visible window so auto-hide behavior is enforced.
  std::unique_ptr<views::Widget> widget =
      CreateTestWidget(nullptr, desks_util::GetActiveDeskContainerId(),
                       gfx::Rect(0, 0, 200, 200), true /* show */);

  // Turn on auto-hide for the shelf.
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());

  // Enable autoclick. The shelf should remain invisible.
  Shell::Get()->accessibility_controller()->SetAutoclickEnabled(true);
  AutoclickMenuView* menu = GetAutoclickMenuView();
  ASSERT_TRUE(menu);
  EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
  EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
}

TEST_F(AutoclickTest, BubbleMovesWithShelfPositionChange) {
  UpdateDisplay("800x600");
  int screen_width = 800;
  int screen_height = 600;

  // Create a visible window so WMEvents occur.
  std::unique_ptr<views::Widget> widget =
      CreateTestWidget(nullptr, desks_util::GetActiveDeskContainerId(),
                       gfx::Rect(0, 0, 200, 200), true /* show */);

  // Set up autoclick and the shelf.
  Shell::Get()->accessibility_controller()->SetAutoclickEnabled(true);
  Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
      AutoclickMenuPosition::kBottomRight);
  Shelf* shelf = GetPrimaryShelf();
  shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
  EXPECT_EQ(shelf->GetVisibilityState(), SHELF_VISIBLE);
  AutoclickMenuView* menu = GetAutoclickMenuView();
  ASSERT_TRUE(menu);

  shelf->SetAlignment(SHELF_ALIGNMENT_BOTTOM);
  // The menu should be positioned above the shelf, not overlapping.
  EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().y(),
            screen_height - shelf->GetIdealBounds().height() -
                kCollisionWindowWorkAreaInsetsDp);
  // And all the way to the right.
  EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().x(),
            screen_width - kCollisionWindowWorkAreaInsetsDp);

  shelf->SetAlignment(SHELF_ALIGNMENT_LEFT);
  // The menu should move to the bottom of the screen.
  EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().y(),
            screen_height - kCollisionWindowWorkAreaInsetsDp);
  // Still be at the far right.
  EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().x(),
            screen_width - kCollisionWindowWorkAreaInsetsDp);

  shelf->SetAlignment(SHELF_ALIGNMENT_RIGHT);
  // The menu should stay at the bottom of the screen.
  EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().y(),
            screen_height - kCollisionWindowWorkAreaInsetsDp);
  // And should be offset from the far right by the shelf width.
  EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().x(),
            screen_width - kCollisionWindowWorkAreaInsetsDp -
                shelf->GetIdealBounds().width());

  // Reset state.
  shelf->SetAlignment(SHELF_ALIGNMENT_BOTTOM);
}

TEST_F(AutoclickTest, AvoidsShelfBubble) {
  const struct {
    session_manager::SessionState session_state;
  } kTestCases[]{
      {session_manager::SessionState::OOBE},
      {session_manager::SessionState::LOGIN_PRIMARY},
      {session_manager::SessionState::ACTIVE},
      {session_manager::SessionState::LOCKED},
  };

  for (auto test : kTestCases) {
    GetSessionControllerClient()->SetSessionState(test.session_state);
    // Set up autoclick and the shelf.
    Shell::Get()->accessibility_controller()->SetAutoclickEnabled(true);
    Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
        AutoclickMenuPosition::kBottomRight);
    auto* unified_system_tray = GetPrimaryUnifiedSystemTray();
    EXPECT_FALSE(unified_system_tray->IsBubbleShown());
    AutoclickMenuView* menu = GetAutoclickMenuView();
    ASSERT_TRUE(menu);
    gfx::Rect menu_bounds = menu->GetBoundsInScreen();

    unified_system_tray->ShowBubble(true /* show_by_click */);
    gfx::Rect new_menu_bounds = menu->GetBoundsInScreen();
    // Y is unchanged when the bubble shows.
    EXPECT_TRUE(abs(menu_bounds.y() - new_menu_bounds.y()) < 5);
    // X is pushed over by at least the bubble's bounds.
    EXPECT_TRUE(menu_bounds.x() -
                    unified_system_tray->GetBubbleBoundsInScreen().width() >
                new_menu_bounds.x());

    unified_system_tray->CloseBubble();
    new_menu_bounds = menu->GetBoundsInScreen();
    EXPECT_EQ(menu_bounds, new_menu_bounds);
  }
}

TEST_F(AutoclickTest, ConfirmationDialogShownWhenDisablingFeature) {
  // Enable and disable with the AccessibilityController to get real use-case
  // of the dialog.

  // No dialog shown at start-up.
  EXPECT_FALSE(GetAutoclickController()->GetDisableDialogForTesting());

  // No dialog shown when enabling the feature.
  Shell::Get()->accessibility_controller()->SetAutoclickEnabled(true);
  EXPECT_FALSE(GetAutoclickController()->GetDisableDialogForTesting());

  // A dialog should be shown when disabling the feature.
  Shell::Get()->accessibility_controller()->SetAutoclickEnabled(false);
  AccessibilityFeatureDisableDialog* dialog =
      GetAutoclickController()->GetDisableDialogForTesting();
  EXPECT_TRUE(dialog);

  // Canceling the dialog will cause the feature to continue to be enabled.
  dialog->GetDialogClientView()->CancelWindow();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(GetAutoclickController()->GetDisableDialogForTesting());
  EXPECT_TRUE(Shell::Get()->accessibility_controller()->autoclick_enabled());
  EXPECT_TRUE(GetAutoclickController()->IsEnabled());

  // Try to disable it again, and this time accept the dialog to actually
  // disable the feature.
  Shell::Get()->accessibility_controller()->SetAutoclickEnabled(false);
  dialog = GetAutoclickController()->GetDisableDialogForTesting();
  EXPECT_TRUE(dialog);
  dialog->GetDialogClientView()->AcceptWindow();
  base::RunLoop().RunUntilIdle();
  EXPECT_FALSE(GetAutoclickController()->GetDisableDialogForTesting());
  EXPECT_FALSE(Shell::Get()->accessibility_controller()->autoclick_enabled());
  EXPECT_FALSE(GetAutoclickController()->IsEnabled());
}

TEST_F(AutoclickTest, HidesBubbleInFullscreenWhenCursorHides) {
  Shell::Get()->accessibility_controller()->SetAutoclickEnabled(true);
  ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  cursor_manager->SetCursor(ui::CursorType::kPointer);

  const struct {
    const std::string display_spec;
    gfx::Rect widget_position;
  } kTestCases[] = {
      {"800x600", gfx::Rect(0, 0, 200, 200)},
      {"800x600,800x600", gfx::Rect(0, 0, 200, 200)},
      {"800x600,800x600", gfx::Rect(1000, 0, 200, 200)},
  };
  for (const auto& test : kTestCases) {
    SCOPED_TRACE(test.display_spec);
    UpdateDisplay(test.display_spec);

    std::unique_ptr<views::Widget> widget =
        CreateTestWidget(nullptr, desks_util::GetActiveDeskContainerId(),
                         test.widget_position, /*show=*/true);
    EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());

    // Move the mouse over the widget, so it's on the same screen as the widget.
    GetEventGenerator()->MoveMouseTo(test.widget_position.origin());

    // When the widget is not fullscreen, hiding the cursor does not cause
    // the bubble to be hidden.
    cursor_manager->HideCursor();
    EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
    cursor_manager->ShowCursor();
    EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());

    // Bubble is visible in fullscreen mode because the mouse cursor is visible.
    widget->SetFullscreen(true);
    EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());

    // Bubble is hidden when the cursor is hidden in fullscreen mode, and shown
    // when the cursor is shown.
    cursor_manager->HideCursor();
    EXPECT_FALSE(GetAutoclickBubbleWidget()->IsVisible());
    cursor_manager->ShowCursor();
    EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());

    // Changing the type to another visible type doesn't cause the bubble to
    // hide.
    cursor_manager->SetCursor(ui::CursorType::kHand);
    EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());

    // Changing the type to an kNone causes the bubble to hide.
    cursor_manager->SetCursor(ui::CursorType::kNone);
    EXPECT_FALSE(GetAutoclickBubbleWidget()->IsVisible());

    // Hiding and showing don't re-show the bubble because the type is still
    // kNone.
    cursor_manager->HideCursor();
    EXPECT_FALSE(GetAutoclickBubbleWidget()->IsVisible());
    cursor_manager->ShowCursor();
    EXPECT_FALSE(GetAutoclickBubbleWidget()->IsVisible());

    // The bubble is shown when the cursor is a visible type again.
    cursor_manager->SetCursor(ui::CursorType::kPointer);
    EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
  }
}

TEST_F(AutoclickTest, DoesNotHideBubbleWhenNotOverFullscreenWindow) {
  UpdateDisplay("800x600,800x600");
  Shell::Get()->accessibility_controller()->SetAutoclickEnabled(true);
  ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  cursor_manager->SetCursor(ui::CursorType::kPointer);

  std::unique_ptr<views::Widget> widget =
      CreateTestWidget(nullptr, desks_util::GetActiveDeskContainerId(),
                       gfx::Rect(1000, 0, 200, 200), true);

  EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());

  // Move the mouse over the other display.
  GetEventGenerator()->MoveMouseTo(gfx::Point(10, 10));

  // When the widget is fullscreen, hiding the cursor does not hide the bubble
  // because the cursor is on a different display.
  widget->SetFullscreen(true);
  cursor_manager->HideCursor();
  EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
}

TEST_F(AutoclickTest, DoesNotHideBubbleWhenOverInactiveFullscreenWindow) {
  Shell::Get()->accessibility_controller()->SetAutoclickEnabled(true);
  ::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
  cursor_manager->SetCursor(ui::CursorType::kPointer);

  std::unique_ptr<views::Widget> widget =
      CreateTestWidget(nullptr, desks_util::GetActiveDeskContainerId(),
                       gfx::Rect(0, 0, 200, 200), true);
  GetEventGenerator()->MoveMouseTo(gfx::Point(10, 10));
  widget->SetFullscreen(true);
  EXPECT_TRUE(widget->IsActive());
  views::Widget* popup_widget = views::Widget::CreateWindowWithContextAndBounds(
      nullptr, CurrentContext(), gfx::Rect(200, 200, 200, 200));
  popup_widget->Show();

  cursor_manager->HideCursor();
  EXPECT_FALSE(widget->IsActive());
  EXPECT_TRUE(popup_widget->IsActive());
  EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
}

TEST_F(AutoclickTest, ScrollClosesWhenHoveredOverScrollButton) {
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);
  GetAutoclickController()->SetAutoclickEventType(
      AutoclickEventType::kLeftClick);
  EXPECT_FALSE(GetAutoclickScrollView());

  // Enable scroll.
  GetAutoclickController()->SetAutoclickEventType(AutoclickEventType::kScroll);
  ASSERT_TRUE(GetAutoclickScrollView());
  views::View* close_button =
      GetScrollButton(AutoclickScrollView::ButtonId::kCloseScroll);
  ASSERT_TRUE(close_button);

  gfx::Point button_location = close_button->GetBoundsInScreen().CenterPoint();
  GetEventGenerator()->MoveMouseTo(button_location);
  // No mouse event.
  std::vector<ui::MouseEvent> events = WaitForMouseEvents();
  EXPECT_EQ(0u, events.size());

  // Reset to left click and scroll view is gone.
  EXPECT_EQ(AutoclickEventType::kLeftClick,
            Shell::Get()->accessibility_controller()->GetAutoclickEventType());
  EXPECT_FALSE(GetAutoclickScrollView());
}

TEST_F(AutoclickTest, ScrollOccursWhenHoveredOverScrollButtons) {
  UpdateDisplay("800x600");
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);

  // Enable scroll.
  GetAutoclickController()->SetAutoclickEventType(AutoclickEventType::kScroll);
  ASSERT_TRUE(GetAutoclickScrollView());

  // TODO: Do for all four buttons, wait a few scrolls each.
  const struct {
    AutoclickScrollView::ButtonId button_id;
    int scroll_x;
    int scroll_y;
  } kTestCases[] = {
      {AutoclickScrollView::ButtonId::kScrollUp, 0, 10},
      {AutoclickScrollView::ButtonId::kScrollDown, 0, -10},
      {AutoclickScrollView::ButtonId::kScrollLeft, 10, 0},
      {AutoclickScrollView::ButtonId::kScrollRight, -10, 0},
  };
  for (auto& test : kTestCases) {
    views::View* button = GetScrollButton(test.button_id);
    ASSERT_TRUE(button);

    gfx::Point button_location = button->GetBoundsInScreen().CenterPoint();
    GetEventGenerator()->MoveMouseTo(button_location);
    // No mouse event during hover, no wheel events yet.
    FastForwardBy(AutoclickScrollView::kAutoclickScrollDelayMs - 1);
    std::vector<ui::MouseEvent> events = GetMouseEvents();
    EXPECT_EQ(0u, events.size());
    std::vector<ui::MouseWheelEvent> wheel_events = GetMouseWheelEvents();
    EXPECT_EQ(0u, wheel_events.size());

    // But we should get a scroll event after kAutoclickScrollDelayMs.
    FastForwardBy(2);
    wheel_events = GetMouseWheelEvents();
    EXPECT_EQ(1u, wheel_events.size());
    EXPECT_EQ(gfx::Point(400, 300), wheel_events[0].location());
    EXPECT_EQ(test.scroll_x, wheel_events[0].x_offset());
    EXPECT_EQ(test.scroll_y, wheel_events[0].y_offset());
    // No other events expected.
    events = GetMouseEvents();
    EXPECT_EQ(0u, events.size());
    ClearMouseEvents();

    // Wait until another kAutoclickScrollDelayMs has elapsed and expect another
    // scroll to have occurred.
    FastForwardBy(AutoclickScrollView::kAutoclickScrollDelayMs);
    wheel_events = GetMouseWheelEvents();
    EXPECT_EQ(1u, wheel_events.size());
    EXPECT_EQ(gfx::Point(400, 300), wheel_events[0].location());
    EXPECT_EQ(test.scroll_x, wheel_events[0].x_offset());
    EXPECT_EQ(test.scroll_y, wheel_events[0].y_offset());
    // No other events expected.
    events = GetMouseEvents();
    EXPECT_EQ(0u, events.size());
    ClearMouseEvents();
  }
}

TEST_F(AutoclickTest, ScrollMenuBubblePostioning) {
  UpdateDisplay("800x600");
  GetAutoclickController()->SetEnabled(true, false /* do not show dialog */);

  Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
      AutoclickMenuPosition::kBottomRight);
  GetAutoclickController()->SetAutoclickEventType(AutoclickEventType::kScroll);

  ASSERT_TRUE(GetAutoclickScrollView());

  // Set the bounds to be the entire window.
  gfx::Rect display_bounds = gfx::Rect(0, 0, 800, 600);
  GetAutoclickController()->OnAutoclickScrollableBoundsFound(display_bounds);

  // The scroll bubble should start near the autoclick menu.
  gfx::Rect scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
  gfx::Rect menu_bounds = GetAutoclickMenuView()->GetBoundsInScreen();
  EXPECT_LT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
            kScrollToMenuBoundsBuffer);

  // Moving the autoclick menu around the screen moves the scroll bubble too.
  Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
      AutoclickMenuPosition::kBottomLeft);
  scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
  menu_bounds = GetAutoclickMenuView()->GetBoundsInScreen();
  EXPECT_LT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
            kScrollToMenuBoundsBuffer);

  Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
      AutoclickMenuPosition::kTopLeft);
  scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
  menu_bounds = GetAutoclickMenuView()->GetBoundsInScreen();
  EXPECT_LT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
            kScrollToMenuBoundsBuffer);

  Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
      AutoclickMenuPosition::kTopRight);
  scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
  menu_bounds = GetAutoclickMenuView()->GetBoundsInScreen();
  EXPECT_LT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
            kScrollToMenuBoundsBuffer);

  // However, if we dwell somewhere else, the autoclick scroll menu will now
  // move out of the corner and near that point when the display bounds are
  // found.
  gfx::Point scroll_point = gfx::Point(0, 0);
  GetEventGenerator()->MoveMouseTo(scroll_point);
  base::RunLoop().RunUntilIdle();
  GetAutoclickController()->OnAutoclickScrollableBoundsFound(display_bounds);
  scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
  EXPECT_GT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
            kScrollToMenuBoundsBuffer);

  // Moving the bubble menu now does not change the scroll bubble's position,
  // it remains near its point.
  Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
      AutoclickMenuPosition::kBottomRight);
  EXPECT_EQ(GetAutoclickScrollView()->GetBoundsInScreen(), scroll_bounds);
}

}  // namespace ash
