123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555 |
- // Copyright (c) 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/touch/touch_observer_hud.h"
- #include "ash/constants/ash_switches.h"
- #include "ash/root_window_controller.h"
- #include "ash/shell.h"
- #include "ash/test/ash_test_base.h"
- #include "ash/touch/touch_devices_controller.h"
- #include "ash/touch/touch_hud_debug.h"
- #include "ash/touch/touch_hud_projection.h"
- #include "ash/touch/touch_hud_renderer.h"
- #include "base/command_line.h"
- #include "base/format_macros.h"
- #include "base/strings/stringprintf.h"
- #include "base/time/time.h"
- #include "ui/aura/window.h"
- #include "ui/display/manager/display_manager.h"
- #include "ui/display/test/display_manager_test_api.h"
- #include "ui/views/widget/widget.h"
- namespace ash {
- class TouchHudTestBase : public AshTestBase {
- public:
- TouchHudTestBase() = default;
- TouchHudTestBase(const TouchHudTestBase&) = delete;
- TouchHudTestBase& operator=(const TouchHudTestBase&) = delete;
- ~TouchHudTestBase() override = default;
- void SetUp() override {
- AshTestBase::SetUp();
- // Initialize display infos. They should be initialized after Ash
- // environment is set up, i.e., after AshTestBase::SetUp().
- internal_display_id_ =
- display::test::DisplayManagerTestApi(Shell::Get()->display_manager())
- .SetFirstDisplayAsInternalDisplay();
- external_display_id_ = 10;
- mirrored_display_id_ = 11;
- internal_display_info_ =
- CreateDisplayInfo(internal_display_id_, gfx::Rect(0, 0, 600, 500));
- external_display_info_ =
- CreateDisplayInfo(external_display_id_, gfx::Rect(1, 1, 200, 100));
- mirrored_display_info_ =
- CreateDisplayInfo(mirrored_display_id_, gfx::Rect(0, 0, 200, 100));
- }
- display::Display GetPrimaryDisplay() {
- return display::Screen::GetScreen()->GetPrimaryDisplay();
- }
- void SetupSingleDisplay() {
- display_info_list_.clear();
- display_info_list_.push_back(internal_display_info_);
- display_manager()->OnNativeDisplaysChanged(display_info_list_);
- }
- void SetupDualDisplays() {
- display_info_list_.clear();
- display_info_list_.push_back(internal_display_info_);
- display_info_list_.push_back(external_display_info_);
- display_manager()->OnNativeDisplaysChanged(display_info_list_);
- }
- void SetInternalAsPrimary() {
- GetWindowTreeHostManager()->SetPrimaryDisplayId(internal_display_id_);
- }
- void SetExternalAsPrimary() {
- GetWindowTreeHostManager()->SetPrimaryDisplayId(external_display_id_);
- }
- void MirrorDisplays() {
- DCHECK_EQ(2U, display_info_list_.size());
- DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
- DCHECK_EQ(external_display_id_, display_info_list_[1].id());
- display_info_list_[1] = mirrored_display_info_;
- display_manager()->OnNativeDisplaysChanged(display_info_list_);
- }
- void UnmirrorDisplays() {
- DCHECK_EQ(2U, display_info_list_.size());
- DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
- DCHECK_EQ(mirrored_display_id_, display_info_list_[1].id());
- display_info_list_[1] = external_display_info_;
- display_manager()->OnNativeDisplaysChanged(display_info_list_);
- }
- void RemoveInternalDisplay() {
- DCHECK_LT(0U, display_info_list_.size());
- DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
- display_info_list_.erase(display_info_list_.begin());
- display_manager()->OnNativeDisplaysChanged(display_info_list_);
- }
- void RemoveExternalDisplay() {
- DCHECK_EQ(2U, display_info_list_.size());
- display_info_list_.pop_back();
- display_manager()->OnNativeDisplaysChanged(display_info_list_);
- }
- void AddInternalDisplay() {
- DCHECK_EQ(0U, display_info_list_.size());
- display_info_list_.push_back(internal_display_info_);
- display_manager()->OnNativeDisplaysChanged(display_info_list_);
- }
- void AddExternalDisplay() {
- DCHECK_EQ(1U, display_info_list_.size());
- display_info_list_.push_back(external_display_info_);
- display_manager()->OnNativeDisplaysChanged(display_info_list_);
- }
- int64_t internal_display_id() const { return internal_display_id_; }
- int64_t external_display_id() const { return external_display_id_; }
- protected:
- WindowTreeHostManager* GetWindowTreeHostManager() {
- return Shell::Get()->window_tree_host_manager();
- }
- const display::Display& GetInternalDisplay() {
- return display_manager()->GetDisplayForId(internal_display_id_);
- }
- const display::Display& GetExternalDisplay() {
- return display_manager()->GetDisplayForId(external_display_id_);
- }
- aura::Window* GetInternalRootWindow() {
- return Shell::GetRootWindowForDisplayId(internal_display_id_);
- }
- aura::Window* GetExternalRootWindow() {
- return Shell::GetRootWindowForDisplayId(external_display_id_);
- }
- aura::Window* GetPrimaryRootWindow() {
- const display::Display& display = GetPrimaryDisplay();
- return Shell::GetRootWindowForDisplayId(display.id());
- }
- aura::Window* GetSecondaryRootWindow() {
- const display::Display& display =
- display::test::DisplayManagerTestApi(display_manager())
- .GetSecondaryDisplay();
- return Shell::GetRootWindowForDisplayId(display.id());
- }
- RootWindowController* GetInternalRootController() {
- aura::Window* root = GetInternalRootWindow();
- return RootWindowController::ForWindow(root);
- }
- RootWindowController* GetExternalRootController() {
- aura::Window* root = GetExternalRootWindow();
- return RootWindowController::ForWindow(root);
- }
- RootWindowController* GetPrimaryRootController() {
- aura::Window* root = GetPrimaryRootWindow();
- return RootWindowController::ForWindow(root);
- }
- RootWindowController* GetSecondaryRootController() {
- aura::Window* root = GetSecondaryRootWindow();
- return RootWindowController::ForWindow(root);
- }
- display::ManagedDisplayInfo CreateDisplayInfo(int64_t id,
- const gfx::Rect& bounds) {
- display::ManagedDisplayInfo info(id, base::StringPrintf("x-%" PRId64, id),
- false);
- info.SetBounds(bounds);
- return info;
- }
- aura::Window* GetRootWindowForTouchHud(TouchObserverHud* hud) {
- return hud->root_window_;
- }
- views::Widget* GetWidgetForTouchHud(TouchObserverHud* hud) {
- return hud->widget_;
- }
- int64_t internal_display_id_;
- int64_t external_display_id_;
- int64_t mirrored_display_id_;
- display::ManagedDisplayInfo internal_display_info_;
- display::ManagedDisplayInfo external_display_info_;
- display::ManagedDisplayInfo mirrored_display_info_;
- std::vector<display::ManagedDisplayInfo> display_info_list_;
- };
- class TouchHudDebugTest : public TouchHudTestBase {
- public:
- TouchHudDebugTest() = default;
- TouchHudDebugTest(const TouchHudDebugTest&) = delete;
- TouchHudDebugTest& operator=(const TouchHudDebugTest&) = delete;
- ~TouchHudDebugTest() override = default;
- void SetUp() override {
- // Add ash-touch-hud flag to enable debug touch HUD. This flag should be set
- // before Ash environment is set up, i.e., before TouchHudTestBase::SetUp().
- base::CommandLine::ForCurrentProcess()->AppendSwitch(
- switches::kAshTouchHud);
- TouchHudTestBase::SetUp();
- }
- void CheckInternalDisplay() {
- EXPECT_NE(nullptr, GetInternalTouchHudDebug());
- EXPECT_EQ(internal_display_id(), GetInternalTouchHudDebug()->display_id());
- EXPECT_EQ(GetInternalRootWindow(),
- GetRootWindowForTouchHud(GetInternalTouchHudDebug()));
- EXPECT_EQ(GetInternalRootWindow(),
- GetWidgetForTouchHud(GetInternalTouchHudDebug())
- ->GetNativeView()
- ->GetRootWindow());
- EXPECT_EQ(GetInternalDisplay().size(),
- GetWidgetForTouchHud(GetInternalTouchHudDebug())
- ->GetWindowBoundsInScreen()
- .size());
- }
- void CheckExternalDisplay() {
- EXPECT_NE(nullptr, GetExternalTouchHudDebug());
- EXPECT_EQ(external_display_id(), GetExternalTouchHudDebug()->display_id());
- EXPECT_EQ(GetExternalRootWindow(),
- GetRootWindowForTouchHud(GetExternalTouchHudDebug()));
- EXPECT_EQ(GetExternalRootWindow(),
- GetWidgetForTouchHud(GetExternalTouchHudDebug())
- ->GetNativeView()
- ->GetRootWindow());
- EXPECT_EQ(GetExternalDisplay().size(),
- GetWidgetForTouchHud(GetExternalTouchHudDebug())
- ->GetWindowBoundsInScreen()
- .size());
- }
- private:
- TouchHudDebug* GetInternalTouchHudDebug() {
- return GetInternalRootController()->touch_hud_debug();
- }
- TouchHudDebug* GetExternalTouchHudDebug() {
- return GetExternalRootController()->touch_hud_debug();
- }
- TouchHudDebug* GetPrimaryTouchHudDebug() {
- return GetPrimaryRootController()->touch_hud_debug();
- }
- TouchHudDebug* GetSecondaryTouchHudDebug() {
- return GetSecondaryRootController()->touch_hud_debug();
- }
- };
- class TouchHudProjectionTest : public TouchHudTestBase {
- public:
- TouchHudProjectionTest() = default;
- TouchHudProjectionTest(const TouchHudProjectionTest&) = delete;
- TouchHudProjectionTest& operator=(const TouchHudProjectionTest&) = delete;
- ~TouchHudProjectionTest() override = default;
- // testing::Test:
- void SetUp() override {
- base::CommandLine::ForCurrentProcess()->AppendSwitch(switches::kShowTaps);
- TouchHudTestBase::SetUp();
- }
- TouchHudProjection* GetInternalTouchHudProjection() {
- return GetInternalRootController()->touch_hud_projection();
- }
- int GetInternalTouchPointsCount() {
- return GetInternalTouchHudProjection()->touch_hud_renderer_->points_.size();
- }
- void SendTouchEventToInternalHud(ui::EventType type,
- const gfx::Point& location,
- int touch_id) {
- ui::TouchEvent event(
- type, location, event_time,
- ui::PointerDetails(ui::EventPointerType::kTouch, touch_id));
- GetInternalTouchHudProjection()->OnTouchEvent(&event);
- // Advance time for next event.
- event_time += base::Milliseconds(100);
- }
- private:
- base::TimeTicks event_time;
- };
- // Checks if debug touch HUD is correctly initialized for a single display.
- TEST_F(TouchHudDebugTest, SingleDisplay) {
- // Setup a single display setting.
- SetupSingleDisplay();
- // Check if touch HUD is set correctly and associated with appropriate
- // display.
- CheckInternalDisplay();
- }
- // Checks if debug touch HUDs are correctly initialized for two displays.
- TEST_F(TouchHudDebugTest, DualDisplays) {
- // Setup a dual display setting.
- SetupDualDisplays();
- // Check if touch HUDs are set correctly and associated with appropriate
- // displays.
- CheckInternalDisplay();
- CheckExternalDisplay();
- }
- // Checks if debug touch HUDs are correctly handled when primary display is
- // changed.
- TEST_F(TouchHudDebugTest, SwapPrimaryDisplay) {
- // Setup a dual display setting.
- SetupDualDisplays();
- // Set the primary display to the external one.
- SetExternalAsPrimary();
- display::test::DisplayManagerTestApi display_manager_test(display_manager());
- // Check if displays' touch HUDs are not swapped as root windows are.
- EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
- EXPECT_EQ(internal_display_id(),
- display_manager_test.GetSecondaryDisplay().id());
- CheckInternalDisplay();
- CheckExternalDisplay();
- // Set the primary display back to the internal one.
- SetInternalAsPrimary();
- // Check if displays' touch HUDs are not swapped back as root windows are.
- EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
- EXPECT_EQ(external_display_id(),
- display_manager_test.GetSecondaryDisplay().id());
- CheckInternalDisplay();
- CheckExternalDisplay();
- }
- // Checks if debug touch HUDs are correctly handled when displays are mirrored.
- TEST_F(TouchHudDebugTest, MirrorDisplays) {
- // Disable restoring mirror mode to prevent interference from previous
- // display configuration.
- display_manager()->set_disable_restoring_mirror_mode_for_test(true);
- // Setup a dual display setting.
- SetupDualDisplays();
- // Mirror displays.
- MirrorDisplays();
- // Check if the internal display is intact.
- EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
- CheckInternalDisplay();
- // Unmirror displays.
- UnmirrorDisplays();
- // Check if external display is added back correctly.
- EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
- EXPECT_EQ(external_display_id(),
- display::test::DisplayManagerTestApi(display_manager())
- .GetSecondaryDisplay()
- .id());
- CheckInternalDisplay();
- CheckExternalDisplay();
- display_manager()->set_disable_restoring_mirror_mode_for_test(false);
- }
- // Checks if debug touch HUDs are correctly handled when displays are mirrored
- // after setting the external display as the primary one.
- TEST_F(TouchHudDebugTest, SwapPrimaryThenMirrorDisplays) {
- display_manager()->set_disable_restoring_mirror_mode_for_test(true);
- // Setup a dual display setting.
- SetupDualDisplays();
- // Set the primary display to the external one.
- SetExternalAsPrimary();
- // Mirror displays.
- MirrorDisplays();
- // Check if the internal display is set as the primary one.
- EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
- CheckInternalDisplay();
- // Unmirror displays.
- UnmirrorDisplays();
- // Check if the external display is added back as the primary display and
- // touch HUDs are set correctly.
- EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
- EXPECT_EQ(internal_display_id(),
- display::test::DisplayManagerTestApi(display_manager())
- .GetSecondaryDisplay()
- .id());
- CheckInternalDisplay();
- CheckExternalDisplay();
- display_manager()->set_disable_restoring_mirror_mode_for_test(false);
- }
- // Checks if debug touch HUDs are correctly handled when the external display,
- // which is the secondary one, is removed.
- TEST_F(TouchHudDebugTest, RemoveSecondaryDisplay) {
- // Setup a dual display setting.
- SetupDualDisplays();
- // Remove external display which is the secondary one.
- RemoveExternalDisplay();
- // Check if the internal display is intact.
- EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
- CheckInternalDisplay();
- // Add external display back.
- AddExternalDisplay();
- // Check if displays' touch HUDs are set correctly.
- EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
- EXPECT_EQ(external_display_id(),
- display::test::DisplayManagerTestApi(display_manager())
- .GetSecondaryDisplay()
- .id());
- CheckInternalDisplay();
- CheckExternalDisplay();
- }
- // Checks if debug touch HUDs are correctly handled when the external display,
- // which is set as the primary display, is removed.
- TEST_F(TouchHudDebugTest, RemovePrimaryDisplay) {
- // Setup a dual display setting.
- SetupDualDisplays();
- // Set the primary display to the external one.
- SetExternalAsPrimary();
- // Remove the external display which is the primary display.
- RemoveExternalDisplay();
- // Check if the internal display is set as the primary one.
- EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
- CheckInternalDisplay();
- // Add the external display back.
- AddExternalDisplay();
- // Check if the external display is set as primary and touch HUDs are set
- // correctly.
- EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
- EXPECT_EQ(internal_display_id(),
- display::test::DisplayManagerTestApi(display_manager())
- .GetSecondaryDisplay()
- .id());
- CheckInternalDisplay();
- CheckExternalDisplay();
- }
- // Checks if debug touch HUDs are correctly handled when all displays are
- // removed.
- TEST_F(TouchHudDebugTest, Headless) {
- // Setup a single display setting.
- SetupSingleDisplay();
- // Remove the only display which is the internal one.
- RemoveInternalDisplay();
- // Add the internal display back.
- AddInternalDisplay();
- // Check if the display's touch HUD is set correctly.
- EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
- CheckInternalDisplay();
- }
- // Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
- // and touch-released events.
- // Test if the WM sets correct work area under different density.
- TEST_F(TouchHudProjectionTest, TouchMoveRelease) {
- SetupSingleDisplay();
- EXPECT_NE(nullptr, GetInternalTouchHudProjection());
- EXPECT_EQ(0, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
- EXPECT_EQ(1, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
- EXPECT_EQ(1, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
- EXPECT_EQ(0, GetInternalTouchPointsCount());
- }
- // Checks projection touch HUD with a sequence of touch-pressed, touch-moved,
- // and touch-cancelled events.
- TEST_F(TouchHudProjectionTest, TouchMoveCancel) {
- SetupSingleDisplay();
- EXPECT_NE(nullptr, GetInternalTouchHudProjection());
- EXPECT_EQ(0, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
- EXPECT_EQ(1, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
- EXPECT_EQ(1, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_CANCELLED, gfx::Point(10, 20), 1);
- EXPECT_EQ(0, GetInternalTouchPointsCount());
- }
- // Checks projection touch HUD with two simultaneous touches.
- TEST_F(TouchHudProjectionTest, DoubleTouch) {
- SetupSingleDisplay();
- EXPECT_NE(nullptr, GetInternalTouchHudProjection());
- EXPECT_EQ(0, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(10, 10), 1);
- EXPECT_EQ(1, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_PRESSED, gfx::Point(20, 10), 2);
- EXPECT_EQ(2, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(10, 20), 1);
- EXPECT_EQ(2, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_MOVED, gfx::Point(20, 20), 2);
- EXPECT_EQ(2, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(10, 20), 1);
- EXPECT_EQ(1, GetInternalTouchPointsCount());
- SendTouchEventToInternalHud(ui::ET_TOUCH_RELEASED, gfx::Point(20, 20), 2);
- EXPECT_EQ(0, GetInternalTouchPointsCount());
- }
- } // namespace ash
|