#include "ash/accessibility/accessibility_controller.h"
#include "ash/accessibility/autoclick/autoclick_controller.h"
#include "ash/events/test_event_capturer.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/system/accessibility/accessibility_feature_disable_dialog.h"
#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/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/base/cursor/mojom/cursor_type.mojom-shared.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/events/types/event_type.h"
#include "ui/views/accessibility/view_accessibility.h"
namespace ash {
namespace {
const int kScrollToMenuBoundsBuffer = 18;
}
class AutoclickTest : public AshTestBase {
public:
AutoclickTest()
: AshTestBase(base::test::TaskEnvironment::TimeSource::MOCK_TIME) {}
AutoclickTest(const AutoclickTest&) = delete;
AutoclickTest& operator=(const AutoclickTest&) = delete;
~AutoclickTest() override = default;
void SetUp() override {
AshTestBase::SetUp();
mouse_event_capturer_.set_capture_mouse_move(false);
mouse_event_capturer_.set_capture_mouse_enter_exit(false);
Shell::Get()->AddPreTargetHandler(&mouse_event_capturer_);
GetAutoclickController()->SetAutoclickDelay(base::TimeDelta());
GetEventGenerator()->MoveMouseTo(100, 100);
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();
base::RunLoop().RunUntilIdle();
return GetMouseEvents();
}
void FastForwardBy(int milliseconds) {
task_environment()->FastForwardBy(base::Milliseconds(milliseconds));
}
AutoclickController* GetAutoclickController() {
return Shell::Get()->autoclick_controller();
}
int UpdateAnimationDelayAndGetFullDelay(float animation_delay) {
float ratio =
GetAutoclickController()->GetStartGestureDelayRatioForTesting();
int full_delay = ceil(1.0 / ratio) * animation_delay;
GetAutoclickController()->SetAutoclickDelay(base::Milliseconds(full_delay));
return full_delay;
}
AutoclickMenuView* GetAutoclickMenuView() {
return GetAutoclickController()
->GetMenuBubbleControllerForTesting()
->menu_view_;
}
AutoclickScrollBubbleController* GetAutoclickScrollBubbleController() {
return GetAutoclickController()
->GetMenuBubbleControllerForTesting()
->scroll_bubble_controller_.get();
}
AutoclickScrollView* GetAutoclickScrollView() {
AutoclickScrollBubbleController* controller =
GetAutoclickScrollBubbleController();
return controller ? controller->scroll_view_.get() : nullptr;
}
AutoclickScrollBubbleView* GetAutoclickScrollBubbleView() {
AutoclickScrollBubbleController* controller =
GetAutoclickScrollBubbleController();
return controller ? controller->bubble_view_.get() : 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_.ClearEvents(); }
const std::vector<ui::MouseEvent>& GetMouseEvents() {
return mouse_event_capturer_.mouse_events();
}
const std::vector<ui::MouseWheelEvent>& GetMouseWheelEvents() {
return mouse_event_capturer_.captured_mouse_wheel_events();
}
private:
TestEventCapturer mouse_event_capturer_;
};
TEST_F(AutoclickTest, ToggleEnabled) {
std::vector<ui::MouseEvent> events;
EXPECT_FALSE(GetAutoclickController()->IsEnabled());
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
GetAutoclickController()->SetEnabled(true, false );
GetEventGenerator()->MoveMouseTo(0, 0);
EXPECT_TRUE(GetAutoclickController()->IsEnabled());
events = WaitForMouseEvents();
ASSERT_EQ(2u, events.size());
EXPECT_EQ(ui::EventType::kMousePressed, events[0].type());
EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());
EXPECT_EQ(ui::EventType::kMouseReleased, events[1].type());
EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
GetEventGenerator()->MoveMouseTo(30, 30);
events = WaitForMouseEvents();
ASSERT_EQ(2u, events.size());
EXPECT_EQ(ui::EventType::kMousePressed, events[0].type());
EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[0].flags());
EXPECT_EQ(ui::EventType::kMouseReleased, events[1].type());
EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());
GetAutoclickController()->SetEnabled(false, false );
EXPECT_FALSE(GetAutoclickController()->IsEnabled());
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
EXPECT_EQ(AutoclickEventType::kLeftClick,
Shell::Get()->accessibility_controller()->GetAutoclickEventType());
}
TEST_F(AutoclickTest, MouseMovement) {
std::vector<ui::MouseEvent> events;
GetAutoclickController()->SetEnabled(true, false );
gfx::Point p1(0, 0);
gfx::Point p2(20, 20);
gfx::Point p3(40, 40);
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());
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);
for (aura::Window* root_window : root_windows) {
gfx::Point center = root_window->GetBoundsInScreen().CenterPoint();
GetAutoclickController()->SetEnabled(true,
false );
GetEventGenerator()->MoveMouseTo(center);
ClearMouseEvents();
EXPECT_EQ(2u, WaitForMouseEvents().size());
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());
GetEventGenerator()->MoveMouseTo(
center +
gfx::Vector2d(movement_threshold + 1, movement_threshold + 1));
EXPECT_EQ(2u, WaitForMouseEvents().size());
int full_delay = UpdateAnimationDelayAndGetFullDelay(animation_delay);
GetEventGenerator()->MoveMouseTo(
center - gfx::Vector2d(movement_threshold, movement_threshold));
FastForwardBy(animation_delay + 1);
GetEventGenerator()->MoveMouseTo(center);
ClearMouseEvents();
FastForwardBy(full_delay * 2);
EXPECT_EQ(2u, GetMouseEvents().size());
gfx::Rect display_bounds =
display::Screen::Get()->GetDisplayNearestWindow(root_window).bounds();
EXPECT_EQ(center - gfx::Vector2d(display_bounds.origin().x(),
display_bounds.origin().y()),
GetMouseEvents()[0].location());
GetEventGenerator()->MoveMouseTo(gfx::Point(0, 0));
GetAutoclickController()->SetAutoclickDelay(base::TimeDelta());
}
}
GetAutoclickController()->SetMovementThreshold(20);
GetAutoclickController()->set_stabilize_click_position(false);
}
TEST_F(AutoclickTest, MovementWithinThresholdWhileTimerRunning) {
GetAutoclickController()->SetEnabled(true, false );
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);
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::EventType::kMousePressed, 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::EventType::kMouseReleased, events[1].type());
EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, events[1].flags());
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::EventType::kMousePressed, 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::EventType::kMouseReleased, events[1].type());
EXPECT_EQ(ui::EF_LEFT_MOUSE_BUTTON, events[1].flags());
GetAutoclickController()->SetAutoclickDelay(base::TimeDelta());
}
TEST_F(AutoclickTest, SingleKeyModifier) {
GetAutoclickController()->SetEnabled(true, false );
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 );
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 );
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);
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 );
std::vector<ui::MouseEvent> events;
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());
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());
GetEventGenerator()->MoveMouseTo(300, 300);
GetEventGenerator()->MoveMouseWheel(0, 20);
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
GetEventGenerator()->MoveMouseTo(200, 200);
GetEventGenerator()->GestureTapDownAndUp(gfx::Point(100, 100));
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
GetEventGenerator()->MoveMouseTo(100, 100);
GetEventGenerator()->GestureScrollSequence(
gfx::Point(100, 100), gfx::Point(200, 200), base::Milliseconds(200), 3);
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
GetEventGenerator()->MoveMouseTo(200, 200);
GetEventGenerator()->ScrollSequence(gfx::Point(100, 100),
base::Milliseconds(200), 0, 100, 3, 2);
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
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 );
std::vector<ui::MouseEvent> events;
GetEventGenerator()->MoveMouseTo(100, 100);
events = WaitForMouseEvents();
EXPECT_EQ(2u, events.size());
aura::test::EventCountDelegate delegate;
std::unique_ptr<aura::Window> window(CreateTestWindowInShell(
{.delegate = &delegate, .bounds = {50, 50, 100, 100}, .window_id = 123}));
window->Show();
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
EXPECT_EQ("1 1 0", delegate.GetMouseMotionCountsAndReset());
}
TEST_F(AutoclickTest, AutoclickChangeEventTypes) {
GetAutoclickController()->SetEnabled(true, false );
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::EventType::kMousePressed, events[0].type());
EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[0].flags());
EXPECT_EQ(ui::EventType::kMouseReleased, events[1].type());
EXPECT_TRUE(ui::EF_RIGHT_MOUSE_BUTTON & events[1].flags());
GetEventGenerator()->MoveMouseTo(60, 60);
GetAutoclickController()->SetAutoclickEventType(
AutoclickEventType::kLeftClick);
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
GetEventGenerator()->MoveMouseTo(90, 90);
GetAutoclickController()->SetAutoclickEventType(
AutoclickEventType::kLeftClick);
events = WaitForMouseEvents();
ASSERT_EQ(2u, events.size());
EXPECT_EQ(ui::EventType::kMousePressed, 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::EventType::kMouseReleased, events[1].type());
EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[1].flags());
EXPECT_FALSE(ui::EF_IS_DOUBLE_CLICK & events[1].flags());
GetAutoclickController()->SetAutoclickEventType(
AutoclickEventType::kDoubleClick);
GetEventGenerator()->MoveMouseTo(120, 120);
events = WaitForMouseEvents();
ASSERT_EQ(4u, events.size());
EXPECT_EQ(ui::EventType::kMousePressed, 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::EventType::kMouseReleased, 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::EventType::kMousePressed, 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::EventType::kMouseReleased, events[3].type());
EXPECT_TRUE(ui::EF_LEFT_MOUSE_BUTTON & events[3].flags());
EXPECT_TRUE(ui::EF_IS_DOUBLE_CLICK & events[3].flags());
GetAutoclickController()->SetAutoclickEventType(
AutoclickEventType::kNoAction);
GetEventGenerator()->MoveMouseTo(120, 120);
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
}
TEST_F(AutoclickTest, AutoclickDragAndDropEvents) {
GetAutoclickController()->SetEnabled(true, false );
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::EventType::kMousePressed, 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::EventType::kMouseDragged, events[0].type());
ClearMouseEvents();
GetEventGenerator()->MoveMouseTo(90, 90);
events = GetMouseEvents();
ASSERT_EQ(1u, events.size());
EXPECT_EQ(ui::EventType::kMouseDragged, events[0].type());
events = WaitForMouseEvents();
ASSERT_EQ(1u, events.size());
EXPECT_EQ(ui::EventType::kMouseReleased, events[0].type());
}
TEST_F(AutoclickTest, AutoclickScrollEvents) {
UpdateDisplay("800x600");
GetAutoclickController()->SetEnabled(true, false );
GetAutoclickController()->SetAutoclickEventType(AutoclickEventType::kScroll);
std::vector<ui::MouseEvent> events;
std::vector<ui::MouseWheelEvent> wheel_events;
GetAutoclickController()->DoScrollAction(
AutoclickController::ScrollPadAction::kScrollUp);
events = GetMouseEvents();
wheel_events = GetMouseWheelEvents();
EXPECT_EQ(0u, events.size());
ASSERT_EQ(1u, wheel_events.size());
EXPECT_EQ(ui::EventType::kMousewheel, wheel_events[0].type());
EXPECT_EQ(gfx::Point(400, 300), wheel_events[0].location());
EXPECT_GT(wheel_events[0].y_offset(), 0);
ClearMouseEvents();
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::EventType::kMousewheel, 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::EventType::kMousewheel, wheel_events[0].type());
EXPECT_EQ(gfx::Point(90, 90), wheel_events[0].location());
EXPECT_GT(wheel_events[0].x_offset(), 0);
ClearMouseEvents();
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::EventType::kMousewheel, 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::EventType::kMousewheel, 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 );
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());
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());
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());
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());
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());
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 );
std::vector<ui::MouseEvent> events;
GetEventGenerator()->MoveMouseTo(210, 210);
FastForwardBy(animation_delay - 1);
GetEventGenerator()->MoveMouseTo(205, 205);
FastForwardBy(full_delay);
events = GetMouseEvents();
ASSERT_EQ(2u, events.size());
EXPECT_EQ(gfx::Point(205, 205), events[0].location());
ClearMouseEvents();
GetEventGenerator()->MoveMouseTo(100, 100);
FastForwardBy(animation_delay - 1);
GetEventGenerator()->MoveMouseTo(105, 105);
FastForwardBy(animation_delay);
GetEventGenerator()->MoveMouseTo(110, 110);
FastForwardBy(full_delay);
events = GetMouseEvents();
ASSERT_EQ(2u, events.size());
EXPECT_EQ(gfx::Point(110, 110), events[0].location());
GetAutoclickController()->set_stabilize_click_position(true);
ClearMouseEvents();
GetEventGenerator()->MoveMouseTo(200, 200);
FastForwardBy(animation_delay - 1);
GetEventGenerator()->MoveMouseTo(205, 205);
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());
GetAutoclickController()->set_stabilize_click_position(false);
}
TEST_F(AutoclickTest, DoesActionOnBubbleWhenInDifferentModes) {
AccessibilityController* accessibility_controller =
Shell::Get()->accessibility_controller();
accessibility_controller->autoclick().SetEnabled(true);
GetAutoclickController()->set_revert_to_left_click(false);
std::vector<ui::MouseEvent> events;
const struct {
const std::string display_spec;
float scale;
FloatingMenuPosition position;
} kTestCases[] = {
{"800x600", 1.0f, FloatingMenuPosition::kBottomRight},
{"1024x800*2.0", 2.0f, FloatingMenuPosition::kBottomRight},
{"800x600", 1.0f, FloatingMenuPosition::kTopLeft},
{"1024x800*2.0", 2.0f, FloatingMenuPosition::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);
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());
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());
EXPECT_EQ(AutoclickEventType::kDoubleClick,
accessibility_controller->GetAutoclickEventType());
accessibility_controller->SetAutoclickEventType(
AutoclickEventType::kNoAction);
GetEventGenerator()->MoveMouseTo(200 * test.scale, 200 * test.scale);
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
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());
EXPECT_EQ(AutoclickEventType::kNoAction,
accessibility_controller->GetAutoclickEventType());
GetEventGenerator()->MoveMouseTo(200 * test.scale, 200 * test.scale);
events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
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()->autoclick().SetEnabled(true);
GetAutoclickController()->set_revert_to_left_click(false);
GetAutoclickController()->SetAutoclickEventType(
AutoclickEventType::kNoAction);
Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
FloatingMenuPosition::kBottomRight);
int animation_delay = 5;
int full_delay = UpdateAnimationDelayAndGetFullDelay(animation_delay);
std::vector<ui::MouseEvent> events;
AutoclickMenuView* menu = GetAutoclickMenuView();
ASSERT_TRUE(menu);
GetEventGenerator()->MoveMouseTo(menu->GetBoundsInScreen().origin());
FastForwardBy(animation_delay - 1);
GetEventGenerator()->MoveMouseTo(30, 30);
FastForwardBy(full_delay);
events = GetMouseEvents();
ASSERT_EQ(0u, events.size());
GetEventGenerator()->MoveMouseTo(menu->GetBoundsInScreen().origin());
FastForwardBy(animation_delay + 1);
GetEventGenerator()->MoveMouseTo(30, 30);
FastForwardBy(full_delay);
events = GetMouseEvents();
ASSERT_EQ(0u, events.size());
}
TEST_F(AutoclickTest, ShelfAutohidesWithAutoclickBubble) {
Shelf* shelf = GetPrimaryShelf();
std::unique_ptr<views::Widget> widget =
CreateTestWidget(views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
nullptr, desks_util::GetActiveDeskContainerId(),
gfx::Rect(0, 0, 200, 200), true );
shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kAlways);
EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
Shell::Get()->accessibility_controller()->autoclick().SetEnabled(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;
std::unique_ptr<views::Widget> widget =
CreateTestWidget(views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
nullptr, desks_util::GetActiveDeskContainerId(),
gfx::Rect(0, 0, 200, 200), true );
Shell::Get()->accessibility_controller()->autoclick().SetEnabled(true);
Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
FloatingMenuPosition::kBottomRight);
Shelf* shelf = GetPrimaryShelf();
shelf->SetAutoHideBehavior(ShelfAutoHideBehavior::kNever);
EXPECT_EQ(shelf->GetVisibilityState(), SHELF_VISIBLE);
AutoclickMenuView* menu = GetAutoclickMenuView();
ASSERT_TRUE(menu);
shelf->SetAlignment(ShelfAlignment::kBottom);
EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().y(),
screen_height - shelf->GetIdealBounds().height() -
kCollisionWindowWorkAreaInsetsDp);
EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().x(),
screen_width - kCollisionWindowWorkAreaInsetsDp);
shelf->SetAlignment(ShelfAlignment::kLeft);
EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().y(),
screen_height - kCollisionWindowWorkAreaInsetsDp);
EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().x(),
screen_width - kCollisionWindowWorkAreaInsetsDp);
shelf->SetAlignment(ShelfAlignment::kRight);
EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().y(),
screen_height - kCollisionWindowWorkAreaInsetsDp);
EXPECT_EQ(menu->GetBoundsInScreen().bottom_right().x(),
screen_width - kCollisionWindowWorkAreaInsetsDp -
shelf->GetIdealBounds().width());
shelf->SetAlignment(ShelfAlignment::kBottom);
}
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);
Shell::Get()->accessibility_controller()->autoclick().SetEnabled(true);
Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
FloatingMenuPosition::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();
gfx::Rect new_menu_bounds = menu->GetBoundsInScreen();
const int dx = abs(menu_bounds.x() - new_menu_bounds.x());
const int dy = abs(menu_bounds.y() - new_menu_bounds.y());
const gfx::Rect bubble_bounds =
unified_system_tray->GetBubbleBoundsInScreen();
EXPECT_TRUE((dx < 5 && dy > bubble_bounds.height()) ||
(dy < 5 && dx > bubble_bounds.width()));
unified_system_tray->CloseBubble();
new_menu_bounds = menu->GetBoundsInScreen();
EXPECT_EQ(menu_bounds, new_menu_bounds);
}
}
TEST_F(AutoclickTest, ConfirmationDialogShownWhenDisablingFeature) {
EXPECT_FALSE(GetAutoclickController()->GetDisableDialogForTesting());
Shell::Get()->accessibility_controller()->autoclick().SetEnabled(true);
EXPECT_FALSE(GetAutoclickController()->GetDisableDialogForTesting());
Shell::Get()->accessibility_controller()->autoclick().SetEnabled(false);
AccessibilityFeatureDisableDialog* dialog =
GetAutoclickController()->GetDisableDialogForTesting();
ASSERT_TRUE(dialog);
dialog->CancelDialog();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetAutoclickController()->GetDisableDialogForTesting());
EXPECT_TRUE(Shell::Get()->accessibility_controller()->autoclick().enabled());
EXPECT_TRUE(GetAutoclickController()->IsEnabled());
Shell::Get()->accessibility_controller()->autoclick().SetEnabled(false);
dialog = GetAutoclickController()->GetDisableDialogForTesting();
ASSERT_TRUE(dialog);
dialog->AcceptDialog();
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()->autoclick().SetEnabled(true);
::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
cursor_manager->SetCursor(ui::mojom::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(
views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET, nullptr,
desks_util::GetActiveDeskContainerId(), test.widget_position,
true);
EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
GetEventGenerator()->MoveMouseTo(test.widget_position.origin());
cursor_manager->HideCursor();
EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
cursor_manager->ShowCursor();
EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
widget->SetFullscreen(true);
EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
cursor_manager->HideCursor();
EXPECT_FALSE(GetAutoclickBubbleWidget()->IsVisible());
cursor_manager->ShowCursor();
EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
cursor_manager->SetCursor(ui::mojom::CursorType::kHand);
EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
cursor_manager->SetCursor(ui::mojom::CursorType::kNone);
EXPECT_FALSE(GetAutoclickBubbleWidget()->IsVisible());
cursor_manager->HideCursor();
EXPECT_FALSE(GetAutoclickBubbleWidget()->IsVisible());
cursor_manager->ShowCursor();
EXPECT_FALSE(GetAutoclickBubbleWidget()->IsVisible());
cursor_manager->SetCursor(ui::mojom::CursorType::kPointer);
EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
}
}
TEST_F(AutoclickTest, DoesNotHideBubbleWhenNotOverFullscreenWindow) {
UpdateDisplay("800x600,800x600");
Shell::Get()->accessibility_controller()->autoclick().SetEnabled(true);
::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
cursor_manager->SetCursor(ui::mojom::CursorType::kPointer);
std::unique_ptr<views::Widget> widget =
CreateTestWidget(views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET,
nullptr, desks_util::GetActiveDeskContainerId(),
gfx::Rect(1000, 0, 200, 200), true);
EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
GetEventGenerator()->MoveMouseTo(gfx::Point(10, 10));
widget->SetFullscreen(true);
cursor_manager->HideCursor();
EXPECT_TRUE(GetAutoclickBubbleWidget()->IsVisible());
}
TEST_F(AutoclickTest, DoesNotHideBubbleWhenOverInactiveFullscreenWindow) {
Shell::Get()->accessibility_controller()->autoclick().SetEnabled(true);
::wm::CursorManager* cursor_manager = Shell::Get()->cursor_manager();
cursor_manager->SetCursor(ui::mojom::CursorType::kPointer);
std::unique_ptr<views::Widget> widget = CreateTestWidget(
views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET, 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::CreateWindowWithContext(
nullptr, GetContext(), 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 );
GetAutoclickController()->SetAutoclickEventType(
AutoclickEventType::kLeftClick);
EXPECT_FALSE(GetAutoclickScrollView());
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);
std::vector<ui::MouseEvent> events = WaitForMouseEvents();
EXPECT_EQ(0u, events.size());
EXPECT_EQ(AutoclickEventType::kLeftClick,
Shell::Get()->accessibility_controller()->GetAutoclickEventType());
EXPECT_FALSE(GetAutoclickScrollView());
}
TEST_F(AutoclickTest, ScrollOccursWhenHoveredOverScrollButtons) {
UpdateDisplay("800x600");
GetAutoclickController()->SetEnabled(true, false );
GetAutoclickController()->SetAutoclickEventType(AutoclickEventType::kScroll);
ASSERT_TRUE(GetAutoclickScrollView());
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);
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());
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());
events = GetMouseEvents();
EXPECT_EQ(0u, events.size());
ClearMouseEvents();
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());
events = GetMouseEvents();
EXPECT_EQ(0u, events.size());
ClearMouseEvents();
}
}
TEST_F(AutoclickTest, ScrollMenuBubblePostioning) {
UpdateDisplay("800x600");
GetAutoclickController()->SetEnabled(true, false );
Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
FloatingMenuPosition::kBottomRight);
GetAutoclickController()->SetAutoclickEventType(AutoclickEventType::kScroll);
ASSERT_TRUE(GetAutoclickScrollView());
gfx::Rect display_bounds = gfx::Rect(0, 0, 800, 600);
GetAutoclickController()->HandleAutoclickScrollableBoundsFound(
display_bounds);
gfx::Rect scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
gfx::Rect menu_bounds = GetAutoclickMenuView()->GetBoundsInScreen();
EXPECT_LT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
kScrollToMenuBoundsBuffer);
Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
FloatingMenuPosition::kBottomLeft);
scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
menu_bounds = GetAutoclickMenuView()->GetBoundsInScreen();
EXPECT_LT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
kScrollToMenuBoundsBuffer);
Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
FloatingMenuPosition::kTopLeft);
scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
menu_bounds = GetAutoclickMenuView()->GetBoundsInScreen();
EXPECT_LT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
kScrollToMenuBoundsBuffer);
Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
FloatingMenuPosition::kTopRight);
scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
menu_bounds = GetAutoclickMenuView()->GetBoundsInScreen();
EXPECT_LT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
kScrollToMenuBoundsBuffer);
gfx::Point scroll_point = gfx::Point(0, 0);
GetEventGenerator()->MoveMouseTo(scroll_point);
base::RunLoop().RunUntilIdle();
GetAutoclickController()->HandleAutoclickScrollableBoundsFound(
display_bounds);
scroll_bounds = GetAutoclickScrollView()->GetBoundsInScreen();
EXPECT_GT(menu_bounds.ManhattanInternalDistance(scroll_bounds),
kScrollToMenuBoundsBuffer);
Shell::Get()->accessibility_controller()->SetAutoclickMenuPosition(
FloatingMenuPosition::kBottomRight);
EXPECT_EQ(GetAutoclickScrollView()->GetBoundsInScreen(), scroll_bounds);
}
TEST_F(AutoclickTest, ScrollBubbleViewAccessibleName) {
GetAutoclickController()->SetEnabled(true,
false);
GetAutoclickController()->SetAutoclickEventType(
AutoclickEventType::kLeftClick);
EXPECT_FALSE(GetAutoclickScrollView());
EXPECT_FALSE(GetAutoclickScrollBubbleView());
GetAutoclickController()->SetAutoclickEventType(AutoclickEventType::kScroll);
ASSERT_TRUE(GetAutoclickScrollView());
ASSERT_TRUE(GetAutoclickScrollBubbleView());
AutoclickScrollBubbleController* controller =
GetAutoclickScrollBubbleController();
AutoclickScrollBubbleView* bubble_view = GetAutoclickScrollBubbleView();
ui::AXNodeData node_data;
bubble_view->GetViewAccessibility().GetAccessibleNodeData(&node_data);
EXPECT_EQ(node_data.GetString16Attribute(ax::mojom::StringAttribute::kName),
controller->GetAccessibleNameForBubble());
}
}