blob: 18a89ec92e9a821cd49b22771b0886dcae241512 [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/keyboard/ui/keyboard_ui_controller.h"
#include "ash/keyboard/ui/keyboard_util.h"
#include "ash/keyboard/ui/test/keyboard_test_util.h"
#include "ash/public/cpp/keyboard/keyboard_switches.h"
#include "ash/shell.h"
#include "ash/test/ash_test_base.h"
#include "base/functional/callback_helpers.h"
#include "ui/aura/test/test_window_delegate.h"
#include "ui/events/test/event_generator.h"
namespace ash {
class VirtualKeyboardTest : public AshTestBase {
public:
VirtualKeyboardTest() = default;
VirtualKeyboardTest(const VirtualKeyboardTest&) = delete;
VirtualKeyboardTest& operator=(const VirtualKeyboardTest&) = delete;
~VirtualKeyboardTest() override = default;
void SetUp() override {
AshTestBase::SetUp();
SetVirtualKeyboardEnabled(true);
}
void TearDown() override {
SetVirtualKeyboardEnabled(false);
AshTestBase::TearDown();
}
};
TEST_F(VirtualKeyboardTest, EventsAreHandledBasedOnHitTestBounds) {
aura::Window* root_window = Shell::GetPrimaryRootWindow();
// Create a test window in the background with the same size as the screen.
aura::test::EventCountDelegate delegate;
std::unique_ptr<aura::Window> background_window(
CreateTestWindowInShellWithDelegate(&delegate, 0, root_window->bounds()));
auto* keyboard_controller = keyboard::KeyboardUIController::Get();
keyboard_controller->ShowKeyboard(false);
ASSERT_TRUE(keyboard::WaitUntilShown());
// Add two hit test bounds (coordinates relative to keyboard window).
// Both are 10x10 squares, but placed in different locations.
std::vector<gfx::Rect> hit_test_bounds;
hit_test_bounds.emplace_back(0, 0, 10, 10);
hit_test_bounds.emplace_back(20, 20, 10, 10);
keyboard_controller->SetHitTestBounds(hit_test_bounds);
// Click at various places within the keyboard window and check whether the
// event passes through the keyboard window to the background window.
ui::test::EventGenerator generator(root_window);
const gfx::Point origin =
keyboard_controller->GetVisualBoundsInScreen().origin();
// (0, 0) is inside the first hit rect, so the event is handled by the window
// and is not received by the background window.
generator.MoveMouseTo(origin);
generator.ClickLeftButton();
EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset());
// (25, 25) is inside the second hit rect, so the background window does not
// receive the event.
generator.MoveMouseTo(origin + gfx::Vector2d(25, 25));
generator.ClickLeftButton();
EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset());
// (5, 25) is not inside any hit rect, so the background window receives the
// event.
generator.MoveMouseTo(origin + gfx::Vector2d(5, 25));
generator.ClickLeftButton();
EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset());
// (25, 5) is not inside any hit rect, so the background window receives the
// event.
generator.MoveMouseTo(origin + gfx::Vector2d(25, 5));
generator.ClickLeftButton();
EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset());
}
TEST_F(VirtualKeyboardTest, HitTestBoundsAreResetWhenContainerTypeChanges) {
aura::Window* root_window = Shell::GetPrimaryRootWindow();
// Create a test window in the background with the same size as the screen.
aura::test::EventCountDelegate delegate;
std::unique_ptr<aura::Window> background_window(
CreateTestWindowInShellWithDelegate(&delegate, 0, root_window->bounds()));
auto* keyboard_controller = keyboard::KeyboardUIController::Get();
keyboard_controller->ShowKeyboard(false);
ASSERT_TRUE(keyboard::WaitUntilShown());
// Set empty hit test bounds, so all events pass through to the background.
keyboard_controller->SetHitTestBounds(std::vector<gfx::Rect>());
ui::test::EventGenerator generator(root_window);
aura::Window* keyboard_window = keyboard_controller->GetKeyboardWindow();
// (0, 0) passes through and is received by background window.
generator.MoveMouseTo(keyboard_window->bounds().origin());
generator.ClickLeftButton();
EXPECT_EQ("1 1", delegate.GetMouseButtonCountsAndReset());
// Change the container behavior, which should reset the hit test bounds to
// the whole keyboard window.
keyboard_controller->HideKeyboardExplicitlyBySystem();
keyboard_controller->SetContainerType(keyboard::ContainerType::kFloating,
gfx::Rect(0, 0, 400, 200),
base::DoNothing());
keyboard_controller->ShowKeyboard(false);
// (0, 0) should no longer pass through the keyboard window.
generator.MoveMouseTo(keyboard_window->bounds().origin());
generator.ClickLeftButton();
EXPECT_EQ("0 0", delegate.GetMouseButtonCountsAndReset());
}
} // namespace ash