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