diff options
author | mohsen@chromium.org <mohsen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-24 21:08:27 +0000 |
---|---|---|
committer | mohsen@chromium.org <mohsen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-24 21:08:27 +0000 |
commit | 4aa0d84f4864b284ab93b2c5af9d9d96e5d3a4ac (patch) | |
tree | b374508e859ee348527ac75b111d161a96a5af4e | |
parent | cc384b25fb73e9e3b5c44b9e9051c90229697ca5 (diff) | |
download | chromium_src-4aa0d84f4864b284ab93b2c5af9d9d96e5d3a4ac.zip chromium_src-4aa0d84f4864b284ab93b2c5af9d9d96e5d3a4ac.tar.gz chromium_src-4aa0d84f4864b284ab93b2c5af9d9d96e5d3a4ac.tar.bz2 |
Swap touch HUD when switching primary display
When a display is set as the primary display, its root window (and all
its children, including the widget showing the touch HUD) is replaced
with the old one's. But, the touch HUD widget is bound to display and
should not be swapped between the two displays. So, after swapping the
root windows, touch HUDs are swapped back to their own display.
BUG=172237
Review URL: https://chromiumcodereview.appspot.com/13460017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196235 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | ash/ash.gyp | 1 | ||||
-rw-r--r-- | ash/root_window_controller.cc | 22 | ||||
-rw-r--r-- | ash/root_window_controller.h | 17 | ||||
-rw-r--r-- | ash/touch/touch_observer_hud.cc | 92 | ||||
-rw-r--r-- | ash/touch/touch_observer_hud.h | 38 | ||||
-rw-r--r-- | ash/touch/touch_observer_hud_unittest.cc | 394 |
6 files changed, 515 insertions, 49 deletions
diff --git a/ash/ash.gyp b/ash/ash.gyp index 156e0e0..c99f041 100644 --- a/ash/ash.gyp +++ b/ash/ash.gyp @@ -664,6 +664,7 @@ 'system/web_notification/web_notification_tray_unittest.cc', 'test/ash_unittests.cc', 'tooltips/tooltip_controller_unittest.cc', + 'touch/touch_observer_hud_unittest.cc', 'wm/activation_controller_unittest.cc', 'wm/ash_activation_controller_unittest.cc', 'wm/ash_native_cursor_manager_unittest.cc', diff --git a/ash/root_window_controller.cc b/ash/root_window_controller.cc index 991f1eb..e4472e0d 100644 --- a/ash/root_window_controller.cc +++ b/ash/root_window_controller.cc @@ -166,7 +166,8 @@ RootWindowController::RootWindowController(aura::RootWindow* root_window) : root_window_(root_window), root_window_layout_(NULL), shelf_(NULL), - panel_layout_manager_(NULL) { + panel_layout_manager_(NULL), + touch_observer_hud_(NULL) { SetRootWindowController(root_window, this); screen_dimmer_.reset(new ScreenDimmer(root_window)); @@ -199,9 +200,6 @@ RootWindowController* RootWindowController::ForActiveRootWindow() { } void RootWindowController::Shutdown() { - // Remove touch observer HUD. - SetTouchObserverHUD(NULL); - CloseChildWindows(); if (Shell::GetActiveRootWindow() == root_window_) { Shell::GetInstance()->set_active_root_window( @@ -299,12 +297,8 @@ void RootWindowController::CreateContainers() { // Create touch observer HUD if needed. HUD should be created after the // containers have been created, so that its widget can be added to them. CommandLine* command_line = CommandLine::ForCurrentProcess(); - if (command_line->HasSwitch(switches::kAshTouchHud)) { - int64 id = root_window_->GetProperty(kDisplayIdKey); - const gfx::Display& display = Shell::GetInstance()->display_manager()-> - GetDisplayForId(id); - SetTouchObserverHUD(new TouchObserverHUD(display)); - } + if (command_line->HasSwitch(switches::kAshTouchHud)) + touch_observer_hud_ = new TouchObserverHUD(root_window_.get()); } void RootWindowController::CreateSystemBackground( @@ -408,14 +402,6 @@ void RootWindowController::MoveWindowsTo(aura::RootWindow* dst) { ReparentAllWindows(root_window_.get(), dst); } -void RootWindowController::SetTouchObserverHUD(TouchObserverHUD* hud) { - if (touch_observer_hud_) - root_window_->RemovePreTargetHandler(touch_observer_hud_.get()); - if (hud) - root_window_->AddPreTargetHandler(hud); - touch_observer_hud_.reset(hud); -} - ShelfLayoutManager* RootWindowController::GetShelfLayoutManager() { return shelf_.get() ? shelf_->shelf_layout_manager() : NULL; } diff --git a/ash/root_window_controller.h b/ash/root_window_controller.h index 1bd6ae8..45c2807 100644 --- a/ash/root_window_controller.h +++ b/ash/root_window_controller.h @@ -89,13 +89,13 @@ class ASH_EXPORT RootWindowController { // NULL if no such shelf exists. ShelfWidget* shelf() { return shelf_.get(); } - TouchObserverHUD* touch_observer_hud() { return touch_observer_hud_.get(); } - - // Sets the touch HUD for this root window controller and adds it as a - // pre-target handler to the root window. Also, removes the previous touch - // HUD, if any, from pre-target handlers. - void SetTouchObserverHUD(TouchObserverHUD* hud); + TouchObserverHUD* touch_observer_hud() { return touch_observer_hud_; } + // Sets the touch HUD. The RootWindowController will not own this HUD; its + // lifetime is managed by itself. + void set_touch_observer_hud(TouchObserverHUD* hud) { + touch_observer_hud_ = hud; + } // Access the shelf layout manager associated with this root // window controller, NULL if no such shelf exists. ShelfLayoutManager* GetShelfLayoutManager(); @@ -200,8 +200,9 @@ class ASH_EXPORT RootWindowController { scoped_ptr<ScreenDimmer> screen_dimmer_; scoped_ptr<WorkspaceController> workspace_controller_; - // Heads-up display for touch events. - scoped_ptr<TouchObserverHUD> touch_observer_hud_; + // Heads-up display for touch events. The RootWindowController does not own + // this HUD; its lifetime is managed by itself. + TouchObserverHUD* touch_observer_hud_; // We need to own event handlers for various containers. scoped_ptr<ToplevelWindowEventHandler> default_container_handler_; diff --git a/ash/touch/touch_observer_hud.cc b/ash/touch/touch_observer_hud.cc index 28b0a38..ab87c66 100644 --- a/ash/touch/touch_observer_hud.cc +++ b/ash/touch/touch_observer_hud.cc @@ -276,8 +276,12 @@ class TouchHudCanvas : public views::View { DISALLOW_COPY_AND_ASSIGN(TouchHudCanvas); }; -TouchObserverHUD::TouchObserverHUD(const gfx::Display& display) - : display_id_(display.id()) { +TouchObserverHUD::TouchObserverHUD(aura::RootWindow* initial_root) + : display_id_(initial_root->GetProperty(kDisplayIdKey)), + root_window_(initial_root) { + const gfx::Display& display = + Shell::GetInstance()->display_manager()->GetDisplayForId(display_id_); + views::View* content = new views::View; canvas_ = new TouchHudCanvas(this); @@ -314,26 +318,34 @@ TouchObserverHUD::TouchObserverHUD(const gfx::Display& display) params.accept_events = false; params.bounds = gfx::Rect(display_size); params.parent = Shell::GetContainer( - Shell::GetInstance()->display_controller()->GetRootWindowForDisplayId( - display_id_), + root_window_, internal::kShellWindowId_OverlayContainer); widget_->Init(params); widget_->SetContentsView(content); widget_->StackAtTop(); widget_->Show(); - // The TouchObserverHUD's lifetime is always more than |widget_|. The - // |widget_| is unset from the OnWidgetDestroying callback. widget_->AddObserver(this); - // Observe display changes to handle changes in display size. + // Observe changes in display size and mode to update touch HUD. Shell::GetScreen()->AddObserver(this); +#if defined(OS_CHROMEOS) + Shell::GetInstance()->output_configurator()->AddObserver(this); +#endif // defined(OS_CHROMEOS) + + Shell::GetInstance()->display_controller()->AddObserver(this); + root_window_->AddPreTargetHandler(this); } TouchObserverHUD::~TouchObserverHUD() { - // The widget should have already been destroyed. - DCHECK(!widget_); + Shell::GetInstance()->display_controller()->RemoveObserver(this); + +#if defined(OS_CHROMEOS) + Shell::GetInstance()->output_configurator()->RemoveObserver(this); +#endif // defined(OS_CHROMEOS) Shell::GetScreen()->RemoveObserver(this); + + widget_->RemoveObserver(this); } // static @@ -408,20 +420,68 @@ void TouchObserverHUD::OnTouchEvent(ui::TouchEvent* event) { void TouchObserverHUD::OnWidgetDestroying(views::Widget* widget) { DCHECK_EQ(widget, widget_); - widget_ = NULL; + delete this; } void TouchObserverHUD::OnDisplayBoundsChanged(const gfx::Display& display) { + if (display.id() != display_id_) + return; const gfx::Size& size = display.size(); - if (display.id() == display_id_) { - widget_->SetSize(size); - canvas_->SetSize(size); - label_container_->SetY(size.height() / kReducedScale); - } + widget_->SetSize(size); + canvas_->SetSize(size); + label_container_->SetY(size.height() / kReducedScale); } void TouchObserverHUD::OnDisplayAdded(const gfx::Display& new_display) {} -void TouchObserverHUD::OnDisplayRemoved(const gfx::Display& old_display) {} + +void TouchObserverHUD::OnDisplayRemoved(const gfx::Display& old_display) { + if (old_display.id() != display_id_) + return; + widget_->CloseNow(); +} + +#if defined(OS_CHROMEOS) +void TouchObserverHUD::OnDisplayModeChanged() { + // Clear touch HUD for any change in display mode (single, dual extended, dual + // mirrored, ...). + Clear(); +} +#endif // defined(OS_CHROMEOS) + +void TouchObserverHUD::OnDisplayConfigurationChanging() { + if (!root_window_) + return; + + root_window_->RemovePreTargetHandler(this); + + RootWindowController* controller = GetRootWindowController(root_window_); + controller->set_touch_observer_hud(NULL); + + views::Widget::ReparentNativeView( + widget_->GetNativeView(), + Shell::GetContainer(root_window_, + internal::kShellWindowId_UnparentedControlContainer)); + + root_window_ = NULL; +} + +void TouchObserverHUD::OnDisplayConfigurationChanged() { + if (root_window_) + return; + + root_window_ = Shell::GetInstance()->display_controller()-> + GetRootWindowForDisplayId(display_id_); + + views::Widget::ReparentNativeView( + widget_->GetNativeView(), + Shell::GetContainer(root_window_, + internal::kShellWindowId_OverlayContainer)); + + RootWindowController* controller = GetRootWindowController(root_window_); + controller->set_touch_observer_hud(this); + + root_window_->AddPreTargetHandler(this); +} } // namespace internal } // namespace ash diff --git a/ash/touch/touch_observer_hud.h b/ash/touch/touch_observer_hud.h index 1728112..1a79015 100644 --- a/ash/touch/touch_observer_hud.h +++ b/ash/touch/touch_observer_hud.h @@ -6,6 +6,7 @@ #define ASH_TOUCH_TOUCH_OBSERVER_HUD_H_ #include "ash/ash_export.h" +#include "ash/display/display_controller.h" #include "ash/shell.h" #include "base/values.h" #include "ui/base/events/event_handler.h" @@ -13,6 +14,10 @@ #include "ui/gfx/point.h" #include "ui/views/widget/widget_observer.h" +#if defined(OS_CHROMEOS) +#include "chromeos/display/output_configurator.h" +#endif // defined(OS_CHROMEOS) + namespace aura { class Window; } @@ -32,13 +37,18 @@ namespace internal { class TouchHudCanvas; -// An event filter which handles system level gesture events. -class ASH_EXPORT TouchObserverHUD : public ui::EventHandler, - public views::WidgetObserver, - public gfx::DisplayObserver { +// An event filter which handles system level gesture events. Objects of this +// class manage their own lifetime. +class ASH_EXPORT TouchObserverHUD + : public ui::EventHandler, + public views::WidgetObserver, + public gfx::DisplayObserver, +#if defined(OS_CHROMEOS) + public chromeos::OutputConfigurator::Observer, +#endif // defined(OS_CHROMEOS) + public DisplayController::Observer { public: - explicit TouchObserverHUD(const gfx::Display& display); - virtual ~TouchObserverHUD(); + explicit TouchObserverHUD(aura::RootWindow* initial_root); // Returns the log of touch events as a dictionary mapping id of each display // to its touch log. @@ -57,6 +67,10 @@ class ASH_EXPORT TouchObserverHUD : public ui::EventHandler, scoped_ptr<ListValue> GetLogAsList() const; private: + friend class TouchHudTest; + + virtual ~TouchObserverHUD(); + void UpdateTouchPointLabel(int index); // Overriden from ui::EventHandler: @@ -65,14 +79,24 @@ class ASH_EXPORT TouchObserverHUD : public ui::EventHandler, // Overridden from views::WidgetObserver: virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE; - // Overridden from gfx::DisplayObserver. + // Overridden from gfx::DisplayObserver: virtual void OnDisplayBoundsChanged(const gfx::Display& display) OVERRIDE; virtual void OnDisplayAdded(const gfx::Display& new_display) OVERRIDE; virtual void OnDisplayRemoved(const gfx::Display& old_display) OVERRIDE; +#if defined(OS_CHROMEOS) + // Overriden from chromeos::OutputConfigurator::Observer: + virtual void OnDisplayModeChanged() OVERRIDE; +#endif // defined(OS_CHROMEOS) + + // Overriden form DisplayController::Observer: + virtual void OnDisplayConfigurationChanging() OVERRIDE; + virtual void OnDisplayConfigurationChanged() OVERRIDE; + static const int kMaxTouchPoints = 32; const int64 display_id_; + aura::RootWindow* root_window_; views::Widget* widget_; TouchHudCanvas* canvas_; diff --git a/ash/touch/touch_observer_hud_unittest.cc b/ash/touch/touch_observer_hud_unittest.cc new file mode 100644 index 0000000..6dfae8a --- /dev/null +++ b/ash/touch/touch_observer_hud_unittest.cc @@ -0,0 +1,394 @@ +// 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/ash_switches.h" +#include "ash/display/display_manager.h" +#include "ash/root_window_controller.h" +#include "ash/test/ash_test_base.h" +#include "ash/test/display_manager_test_api.h" +#include "ash/wm/property_util.h" +#include "base/command_line.h" +#include "base/stringprintf.h" + +namespace ash { +namespace internal { + +class TouchHudTest : public test::AshTestBase { + public: + TouchHudTest() {} + virtual ~TouchHudTest() {} + + virtual void SetUp() OVERRIDE { + // Add ash-touch-hud flag to enable touch HUD. This flag should be set + // before Ash environment is set up, i.e., before + // test::AshTestBase::SetUp(). + CommandLine::ForCurrentProcess()->AppendSwitch( + ash::switches::kAshTouchHud); + + test::AshTestBase::SetUp(); + + // Initialize display infos. They should be initialized after Ash + // environment is set up, i.e., after test::AshTestBase::SetUp(). + internal_display_id_ = test::DisplayManagerTestApi(GetDisplayManager()). + SetFirstDisplayAsInternalDisplay(); + external_display_id_ = 10; + mirrored_display_id_ = 11; + + internal_display_info_ = + CreateDisplayInfo(internal_display_id_, gfx::Rect(0, 0, 500, 500)); + external_display_info_ = + CreateDisplayInfo(external_display_id_, gfx::Rect(1, 1, 100, 100)); + mirrored_display_info_ = + CreateDisplayInfo(mirrored_display_id_, gfx::Rect(0, 0, 100, 100)); + } + + const gfx::Display& GetPrimaryDisplay() { + return GetDisplayController()->GetPrimaryDisplay(); + } + + const gfx::Display& GetSecondaryDisplay() { + return *GetDisplayController()->GetSecondaryDisplay(); + } + + void SetupSingleDisplay() { + display_info_list_.clear(); + display_info_list_.push_back(internal_display_info_); + GetDisplayManager()->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_); + GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_); + } + + void SetInternalAsPrimary() { + const gfx::Display& internal_display = + GetDisplayManager()->GetDisplayForId(internal_display_id_); + GetDisplayController()->SetPrimaryDisplay(internal_display); + } + + void SetExternalAsPrimary() { + const gfx::Display& external_display = + GetDisplayManager()->GetDisplayForId(external_display_id_); + GetDisplayController()->SetPrimaryDisplay(external_display); + } + + 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_; + GetDisplayManager()->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_; + GetDisplayManager()->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()); + GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_); + } + + void RemoveExternalDisplay() { + DCHECK_EQ(2U, display_info_list_.size()); + display_info_list_.pop_back(); + GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_); + } + + void AddInternalDisplay() { + DCHECK_EQ(0U, display_info_list_.size()); + display_info_list_.push_back(internal_display_info_); + GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_); + } + + void AddExternalDisplay() { + DCHECK_EQ(1U, display_info_list_.size()); + display_info_list_.push_back(external_display_info_); + GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_); + } + + int64 internal_display_id() const { + return internal_display_id_; + } + + int64 external_display_id() const { + return external_display_id_; + } + + void CheckInternalDisplay() { + EXPECT_NE(static_cast<internal::TouchObserverHUD*>(NULL), + GetInternalTouchHud()); + EXPECT_EQ(internal_display_id(), GetInternalTouchHud()->display_id_); + EXPECT_EQ(GetInternalRootWindow(), GetInternalTouchHud()->root_window_); + EXPECT_EQ(GetInternalRootWindow(), + GetInternalTouchHud()->widget_->GetNativeView()->GetRootWindow()); + EXPECT_EQ(GetInternalDisplay().size(), + GetInternalTouchHud()->widget_->GetWindowBoundsInScreen().size()); + } + + void CheckExternalDisplay() { + EXPECT_NE(static_cast<internal::TouchObserverHUD*>(NULL), + GetExternalTouchHud()); + EXPECT_EQ(external_display_id(), GetExternalTouchHud()->display_id_); + EXPECT_EQ(GetExternalRootWindow(), GetExternalTouchHud()->root_window_); + EXPECT_EQ(GetExternalRootWindow(), + GetExternalTouchHud()->widget_->GetNativeView()->GetRootWindow()); + EXPECT_EQ(GetExternalDisplay().size(), + GetExternalTouchHud()->widget_->GetWindowBoundsInScreen().size()); + } + + private: + DisplayManager* GetDisplayManager() { + return Shell::GetInstance()->display_manager(); + } + + DisplayController* GetDisplayController() { + return Shell::GetInstance()->display_controller(); + } + + const gfx::Display& GetInternalDisplay() { + return GetDisplayManager()->GetDisplayForId(internal_display_id_); + } + + const gfx::Display& GetExternalDisplay() { + return GetDisplayManager()->GetDisplayForId(external_display_id_); + } + + aura::RootWindow* GetInternalRootWindow() { + return GetDisplayController()->GetRootWindowForDisplayId( + internal_display_id_); + } + + aura::RootWindow* GetExternalRootWindow() { + return GetDisplayController()->GetRootWindowForDisplayId( + external_display_id_); + } + + aura::RootWindow* GetPrimaryRootWindow() { + const gfx::Display& display = GetPrimaryDisplay(); + return GetDisplayController()->GetRootWindowForDisplayId(display.id()); + } + + aura::RootWindow* GetSecondaryRootWindow() { + const gfx::Display& display = GetSecondaryDisplay(); + return GetDisplayController()->GetRootWindowForDisplayId(display.id()); + } + + internal::RootWindowController* GetInternalRootController() { + aura::RootWindow* root = GetInternalRootWindow(); + return GetRootWindowController(root); + } + + internal::RootWindowController* GetExternalRootController() { + aura::RootWindow* root = GetExternalRootWindow(); + return GetRootWindowController(root); + } + + internal::RootWindowController* GetPrimaryRootController() { + aura::RootWindow* root = GetPrimaryRootWindow(); + return GetRootWindowController(root); + } + + internal::RootWindowController* GetSecondaryRootController() { + aura::RootWindow* root = GetSecondaryRootWindow(); + return GetRootWindowController(root); + } + + internal::TouchObserverHUD* GetInternalTouchHud() { + return GetInternalRootController()->touch_observer_hud(); + } + + internal::TouchObserverHUD* GetExternalTouchHud() { + return GetExternalRootController()->touch_observer_hud(); + } + + internal::TouchObserverHUD* GetPrimaryTouchHud() { + return GetPrimaryRootController()->touch_observer_hud(); + } + + internal::TouchObserverHUD* GetSecondaryTouchHud() { + return GetSecondaryRootController()->touch_observer_hud(); + } + + DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) { + DisplayInfo info(id, base::StringPrintf("x-%ld", id), false); + info.SetBounds(bounds); + return info; + } + + int64 internal_display_id_; + int64 external_display_id_; + int64 mirrored_display_id_; + DisplayInfo internal_display_info_; + DisplayInfo external_display_info_; + DisplayInfo mirrored_display_info_; + + std::vector<DisplayInfo> display_info_list_; + + DISALLOW_COPY_AND_ASSIGN(TouchHudTest); +}; + +// Checks if touch HUDs are correctly initialized for displays. +TEST_F(TouchHudTest, Basic) { + // Setup a dual display setting. + SetupDualDisplays(); + + // Check if touch HUDs are set correctly and associated with appropriate + // displays. + CheckInternalDisplay(); + CheckExternalDisplay(); +} + +// Checks if touch HUDs are correctly handled when primary display is changed. +TEST_F(TouchHudTest, SwapPrimaryDisplay) { + // Setup a dual display setting. + SetupDualDisplays(); + + // Set the primary display to the external one. + SetExternalAsPrimary(); + + // Check if displays' touch HUDs are not swapped as root windows are. + EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id()); + EXPECT_EQ(internal_display_id(), 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(), GetSecondaryDisplay().id()); + CheckInternalDisplay(); + CheckExternalDisplay(); +} + +// Checks if touch HUDs are correctly handled when displays are mirrored. +TEST_F(TouchHudTest, MirrorDisplays) { + // 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(), GetSecondaryDisplay().id()); + CheckInternalDisplay(); + CheckExternalDisplay(); +} + +// Checks if touch HUDs are correctly handled when displays are mirrored after +// setting the external display as the primary one. +TEST_F(TouchHudTest, SwapPrimaryThenMirrorDisplays) { + // 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(), GetSecondaryDisplay().id()); + CheckInternalDisplay(); + CheckExternalDisplay(); +} + +// Checks if touch HUDs are correctly handled when the external display, which +// is the secondary one, is removed. +TEST_F(TouchHudTest, 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(), GetSecondaryDisplay().id()); + CheckInternalDisplay(); + CheckExternalDisplay(); +} + +// Checks if touch HUDs are correctly handled when the external display, which +// is set as the primary display, is removed. +TEST_F(TouchHudTest, 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(), GetSecondaryDisplay().id()); + CheckInternalDisplay(); + CheckExternalDisplay(); +} + +// Checks if touch HUDs are correctly handled when all displays are removed. +TEST_F(TouchHudTest, 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(); +} + +} // namespace internal +} // namespace ash |