Home | History | Annotate | Download | only in touch
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "ash/touch/touch_observer_hud.h"
      6 
      7 #include "ash/ash_switches.h"
      8 #include "ash/display/display_manager.h"
      9 #include "ash/root_window_controller.h"
     10 #include "ash/screen_ash.h"
     11 #include "ash/shell.h"
     12 #include "ash/test/ash_test_base.h"
     13 #include "ash/test/display_manager_test_api.h"
     14 #include "ash/touch/touch_hud_debug.h"
     15 #include "ash/wm/property_util.h"
     16 #include "base/command_line.h"
     17 #include "base/format_macros.h"
     18 #include "base/strings/stringprintf.h"
     19 #include "ui/aura/window.h"
     20 
     21 namespace ash {
     22 namespace internal {
     23 
     24 class TouchHudTest : public test::AshTestBase {
     25  public:
     26   TouchHudTest() {}
     27   virtual ~TouchHudTest() {}
     28 
     29   virtual void SetUp() OVERRIDE {
     30     // Add ash-touch-hud flag to enable touch HUD. This flag should be set
     31     // before Ash environment is set up, i.e., before
     32     // test::AshTestBase::SetUp().
     33     CommandLine::ForCurrentProcess()->AppendSwitch(
     34         ash::switches::kAshTouchHud);
     35 
     36     test::AshTestBase::SetUp();
     37 
     38     // Initialize display infos. They should be initialized after Ash
     39     // environment is set up, i.e., after test::AshTestBase::SetUp().
     40     internal_display_id_ = test::DisplayManagerTestApi(GetDisplayManager()).
     41         SetFirstDisplayAsInternalDisplay();
     42     external_display_id_ = 10;
     43     mirrored_display_id_ = 11;
     44 
     45     internal_display_info_ =
     46         CreateDisplayInfo(internal_display_id_, gfx::Rect(0, 0, 500, 500));
     47     external_display_info_ =
     48         CreateDisplayInfo(external_display_id_, gfx::Rect(1, 1, 100, 100));
     49     mirrored_display_info_ =
     50         CreateDisplayInfo(mirrored_display_id_, gfx::Rect(0, 0, 100, 100));
     51   }
     52 
     53   gfx::Display GetPrimaryDisplay() {
     54     return Shell::GetScreen()->GetPrimaryDisplay();
     55   }
     56 
     57   const gfx::Display& GetSecondaryDisplay() {
     58     return ScreenAsh::GetSecondaryDisplay();
     59   }
     60 
     61   void SetupSingleDisplay() {
     62     display_info_list_.clear();
     63     display_info_list_.push_back(internal_display_info_);
     64     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
     65   }
     66 
     67   void SetupDualDisplays() {
     68     display_info_list_.clear();
     69     display_info_list_.push_back(internal_display_info_);
     70     display_info_list_.push_back(external_display_info_);
     71     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
     72   }
     73 
     74   void SetInternalAsPrimary() {
     75     const gfx::Display& internal_display =
     76         GetDisplayManager()->GetDisplayForId(internal_display_id_);
     77     GetDisplayController()->SetPrimaryDisplay(internal_display);
     78   }
     79 
     80   void SetExternalAsPrimary() {
     81     const gfx::Display& external_display =
     82         GetDisplayManager()->GetDisplayForId(external_display_id_);
     83     GetDisplayController()->SetPrimaryDisplay(external_display);
     84   }
     85 
     86   void MirrorDisplays() {
     87     DCHECK_EQ(2U, display_info_list_.size());
     88     DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
     89     DCHECK_EQ(external_display_id_, display_info_list_[1].id());
     90     display_info_list_[1] = mirrored_display_info_;
     91     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
     92   }
     93 
     94   void UnmirrorDisplays() {
     95     DCHECK_EQ(2U, display_info_list_.size());
     96     DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
     97     DCHECK_EQ(mirrored_display_id_, display_info_list_[1].id());
     98     display_info_list_[1] = external_display_info_;
     99     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
    100   }
    101 
    102   void RemoveInternalDisplay() {
    103     DCHECK_LT(0U, display_info_list_.size());
    104     DCHECK_EQ(internal_display_id_, display_info_list_[0].id());
    105     display_info_list_.erase(display_info_list_.begin());
    106     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
    107   }
    108 
    109   void RemoveExternalDisplay() {
    110     DCHECK_EQ(2U, display_info_list_.size());
    111     display_info_list_.pop_back();
    112     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
    113   }
    114 
    115   void AddInternalDisplay() {
    116     DCHECK_EQ(0U, display_info_list_.size());
    117     display_info_list_.push_back(internal_display_info_);
    118     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
    119   }
    120 
    121   void AddExternalDisplay() {
    122     DCHECK_EQ(1U, display_info_list_.size());
    123     display_info_list_.push_back(external_display_info_);
    124     GetDisplayManager()->OnNativeDisplaysChanged(display_info_list_);
    125   }
    126 
    127   int64 internal_display_id() const {
    128     return internal_display_id_;
    129   }
    130 
    131   int64 external_display_id() const {
    132     return external_display_id_;
    133   }
    134 
    135   void CheckInternalDisplay() {
    136     EXPECT_NE(static_cast<internal::TouchObserverHUD*>(NULL),
    137               GetInternalTouchHud());
    138     EXPECT_EQ(internal_display_id(), GetInternalTouchHud()->display_id_);
    139     EXPECT_EQ(GetInternalRootWindow(), GetInternalTouchHud()->root_window_);
    140     EXPECT_EQ(GetInternalRootWindow(),
    141               GetInternalTouchHud()->widget_->GetNativeView()->GetRootWindow());
    142     EXPECT_EQ(GetInternalDisplay().size(),
    143               GetInternalTouchHud()->widget_->GetWindowBoundsInScreen().size());
    144   }
    145 
    146   void CheckExternalDisplay() {
    147     EXPECT_NE(static_cast<internal::TouchObserverHUD*>(NULL),
    148               GetExternalTouchHud());
    149     EXPECT_EQ(external_display_id(), GetExternalTouchHud()->display_id_);
    150     EXPECT_EQ(GetExternalRootWindow(), GetExternalTouchHud()->root_window_);
    151     EXPECT_EQ(GetExternalRootWindow(),
    152               GetExternalTouchHud()->widget_->GetNativeView()->GetRootWindow());
    153     EXPECT_EQ(GetExternalDisplay().size(),
    154               GetExternalTouchHud()->widget_->GetWindowBoundsInScreen().size());
    155   }
    156 
    157  private:
    158   DisplayManager* GetDisplayManager() {
    159     return Shell::GetInstance()->display_manager();
    160   }
    161 
    162   DisplayController* GetDisplayController() {
    163     return Shell::GetInstance()->display_controller();
    164   }
    165 
    166   const gfx::Display& GetInternalDisplay() {
    167     return GetDisplayManager()->GetDisplayForId(internal_display_id_);
    168   }
    169 
    170   const gfx::Display& GetExternalDisplay() {
    171     return GetDisplayManager()->GetDisplayForId(external_display_id_);
    172   }
    173 
    174   aura::RootWindow* GetInternalRootWindow() {
    175     return GetDisplayController()->GetRootWindowForDisplayId(
    176         internal_display_id_);
    177   }
    178 
    179   aura::RootWindow* GetExternalRootWindow() {
    180     return GetDisplayController()->GetRootWindowForDisplayId(
    181         external_display_id_);
    182   }
    183 
    184   aura::RootWindow* GetPrimaryRootWindow() {
    185     const gfx::Display& display = GetPrimaryDisplay();
    186     return GetDisplayController()->GetRootWindowForDisplayId(display.id());
    187   }
    188 
    189   aura::RootWindow* GetSecondaryRootWindow() {
    190     const gfx::Display& display = GetSecondaryDisplay();
    191     return GetDisplayController()->GetRootWindowForDisplayId(display.id());
    192   }
    193 
    194   internal::RootWindowController* GetInternalRootController() {
    195     aura::RootWindow* root = GetInternalRootWindow();
    196     return GetRootWindowController(root);
    197   }
    198 
    199   internal::RootWindowController* GetExternalRootController() {
    200     aura::RootWindow* root = GetExternalRootWindow();
    201     return GetRootWindowController(root);
    202   }
    203 
    204   internal::RootWindowController* GetPrimaryRootController() {
    205     aura::RootWindow* root = GetPrimaryRootWindow();
    206     return GetRootWindowController(root);
    207   }
    208 
    209   internal::RootWindowController* GetSecondaryRootController() {
    210     aura::RootWindow* root = GetSecondaryRootWindow();
    211     return GetRootWindowController(root);
    212   }
    213 
    214   internal::TouchObserverHUD* GetInternalTouchHud() {
    215     return GetInternalRootController()->touch_hud_debug();
    216   }
    217 
    218   internal::TouchObserverHUD* GetExternalTouchHud() {
    219     return GetExternalRootController()->touch_hud_debug();
    220   }
    221 
    222   internal::TouchObserverHUD* GetPrimaryTouchHud() {
    223     return GetPrimaryRootController()->touch_hud_debug();
    224   }
    225 
    226   internal::TouchObserverHUD* GetSecondaryTouchHud() {
    227     return GetSecondaryRootController()->touch_hud_debug();
    228   }
    229 
    230   DisplayInfo CreateDisplayInfo(int64 id, const gfx::Rect& bounds) {
    231     DisplayInfo info(id, base::StringPrintf("x-%" PRId64, id), false);
    232     info.SetBounds(bounds);
    233     return info;
    234   }
    235 
    236   int64 internal_display_id_;
    237   int64 external_display_id_;
    238   int64 mirrored_display_id_;
    239   DisplayInfo internal_display_info_;
    240   DisplayInfo external_display_info_;
    241   DisplayInfo mirrored_display_info_;
    242 
    243   std::vector<DisplayInfo> display_info_list_;
    244 
    245   DISALLOW_COPY_AND_ASSIGN(TouchHudTest);
    246 };
    247 
    248 // Checks if touch HUDs are correctly initialized for displays.
    249 TEST_F(TouchHudTest, Basic) {
    250   if (!SupportsMultipleDisplays())
    251     return;
    252 
    253   // Setup a dual display setting.
    254   SetupDualDisplays();
    255 
    256   // Check if touch HUDs are set correctly and associated with appropriate
    257   // displays.
    258   CheckInternalDisplay();
    259   CheckExternalDisplay();
    260 }
    261 
    262 // Checks if touch HUDs are correctly handled when primary display is changed.
    263 TEST_F(TouchHudTest, SwapPrimaryDisplay) {
    264   if (!SupportsMultipleDisplays())
    265     return;
    266 
    267   // Setup a dual display setting.
    268   SetupDualDisplays();
    269 
    270   // Set the primary display to the external one.
    271   SetExternalAsPrimary();
    272 
    273   // Check if displays' touch HUDs are not swapped as root windows are.
    274   EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
    275   EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
    276   CheckInternalDisplay();
    277   CheckExternalDisplay();
    278 
    279   // Set the primary display back to the internal one.
    280   SetInternalAsPrimary();
    281 
    282   // Check if displays' touch HUDs are not swapped back as root windows are.
    283   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
    284   EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
    285   CheckInternalDisplay();
    286   CheckExternalDisplay();
    287 }
    288 
    289 // Checks if touch HUDs are correctly handled when displays are mirrored.
    290 TEST_F(TouchHudTest, MirrorDisplays) {
    291   if (!SupportsMultipleDisplays())
    292     return;
    293 
    294   // Setup a dual display setting.
    295   SetupDualDisplays();
    296 
    297   // Mirror displays.
    298   MirrorDisplays();
    299 
    300   // Check if the internal display is intact.
    301   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
    302   CheckInternalDisplay();
    303 
    304   // Unmirror displays.
    305   UnmirrorDisplays();
    306 
    307   // Check if external display is added back correctly.
    308   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
    309   EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
    310   CheckInternalDisplay();
    311   CheckExternalDisplay();
    312 }
    313 
    314 // Checks if touch HUDs are correctly handled when displays are mirrored after
    315 // setting the external display as the primary one.
    316 TEST_F(TouchHudTest, SwapPrimaryThenMirrorDisplays) {
    317   if (!SupportsMultipleDisplays())
    318     return;
    319 
    320   // Setup a dual display setting.
    321   SetupDualDisplays();
    322 
    323   // Set the primary display to the external one.
    324   SetExternalAsPrimary();
    325 
    326   // Mirror displays.
    327   MirrorDisplays();
    328 
    329   // Check if the internal display is set as the primary one.
    330   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
    331   CheckInternalDisplay();
    332 
    333   // Unmirror displays.
    334   UnmirrorDisplays();
    335 
    336   // Check if the external display is added back as the primary display and
    337   // touch HUDs are set correctly.
    338   EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
    339   EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
    340   CheckInternalDisplay();
    341   CheckExternalDisplay();
    342 }
    343 
    344 // Checks if touch HUDs are correctly handled when the external display, which
    345 // is the secondary one, is removed.
    346 TEST_F(TouchHudTest, RemoveSecondaryDisplay) {
    347   if (!SupportsMultipleDisplays())
    348     return;
    349 
    350   // Setup a dual display setting.
    351   SetupDualDisplays();
    352 
    353   // Remove external display which is the secondary one.
    354   RemoveExternalDisplay();
    355 
    356   // Check if the internal display is intact.
    357   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
    358   CheckInternalDisplay();
    359 
    360   // Add external display back.
    361   AddExternalDisplay();
    362 
    363   // Check if displays' touch HUDs are set correctly.
    364   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
    365   EXPECT_EQ(external_display_id(), GetSecondaryDisplay().id());
    366   CheckInternalDisplay();
    367   CheckExternalDisplay();
    368 }
    369 
    370 // Checks if touch HUDs are correctly handled when the external display, which
    371 // is set as the primary display, is removed.
    372 TEST_F(TouchHudTest, RemovePrimaryDisplay) {
    373   if (!SupportsMultipleDisplays())
    374     return;
    375 
    376   // Setup a dual display setting.
    377   SetupDualDisplays();
    378 
    379   // Set the primary display to the external one.
    380   SetExternalAsPrimary();
    381 
    382   // Remove the external display which is the primary display.
    383   RemoveExternalDisplay();
    384 
    385   // Check if the internal display is set as the primary one.
    386   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
    387   CheckInternalDisplay();
    388 
    389   // Add the external display back.
    390   AddExternalDisplay();
    391 
    392   // Check if the external display is set as primary and touch HUDs are set
    393   // correctly.
    394   EXPECT_EQ(external_display_id(), GetPrimaryDisplay().id());
    395   EXPECT_EQ(internal_display_id(), GetSecondaryDisplay().id());
    396   CheckInternalDisplay();
    397   CheckExternalDisplay();
    398 }
    399 
    400 // Checks if touch HUDs are correctly handled when all displays are removed.
    401 TEST_F(TouchHudTest, Headless) {
    402   if (!SupportsMultipleDisplays())
    403     return;
    404 
    405   // Setup a single display setting.
    406   SetupSingleDisplay();
    407 
    408   // Remove the only display which is the internal one.
    409   RemoveInternalDisplay();
    410 
    411   // Add the internal display back.
    412   AddInternalDisplay();
    413 
    414   // Check if the display's touch HUD is set correctly.
    415   EXPECT_EQ(internal_display_id(), GetPrimaryDisplay().id());
    416   CheckInternalDisplay();
    417 }
    418 
    419 }  // namespace internal
    420 }  // namespace ash
    421