1 // Copyright 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/root_window_controller.h" 6 #include "ash/shelf/shelf_widget.h" 7 #include "ash/shell.h" 8 #include "ash/shell_window_ids.h" 9 #include "ash/test/ash_test_base.h" 10 #include "ash/test/test_session_state_delegate.h" 11 #include "ash/test/test_shell_delegate.h" 12 #include "ash/wm/maximize_mode/maximize_mode_controller.h" 13 #include "ash/wm/maximize_mode/maximize_mode_window_manager.h" 14 #include "ash/wm/window_state.h" 15 #include "ash/wm/wm_event.h" 16 #include "base/command_line.h" 17 #include "base/compiler_specific.h" 18 #include "base/logging.h" 19 #include "base/strings/string_util.h" 20 #include "base/time/time.h" 21 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h" 22 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h" 23 #include "chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.h" 24 #include "chrome/test/base/testing_profile.h" 25 #include "components/user_manager/user_info.h" 26 #include "ui/aura/client/aura_constants.h" 27 #include "ui/aura/window_event_dispatcher.h" 28 #include "ui/base/ui_base_types.h" 29 #include "ui/wm/core/window_util.h" 30 #include "ui/wm/public/activation_client.h" 31 32 namespace ash { 33 namespace test { 34 35 // A test class for preparing the chrome::MultiUserWindowManager. It creates 36 // various windows and instantiates the chrome::MultiUserWindowManager. 37 class MultiUserWindowManagerChromeOSTest : public AshTestBase { 38 public: 39 MultiUserWindowManagerChromeOSTest() 40 : multi_user_window_manager_(NULL), 41 session_state_delegate_(NULL) {} 42 43 virtual void SetUp() OVERRIDE; 44 virtual void TearDown() OVERRIDE; 45 46 protected: 47 // Set up the test environment for this many windows. 48 void SetUpForThisManyWindows(int windows); 49 50 // Switch the user and wait until the animation is finished. 51 void SwitchUserAndWaitForAnimation(const std::string& user_id) { 52 multi_user_window_manager_->ActiveUserChanged(user_id); 53 base::TimeTicks now = base::TimeTicks::Now(); 54 while (multi_user_window_manager_->IsAnimationRunningForTest()) { 55 // This should never take longer then a second. 56 ASSERT_GE(1000, (base::TimeTicks::Now() - now).InMilliseconds()); 57 base::MessageLoop::current()->RunUntilIdle(); 58 } 59 } 60 61 // Return the window with the given index. 62 aura::Window* window(size_t index) { 63 DCHECK(index < window_.size()); 64 return window_[index]; 65 } 66 67 // Delete the window at the given index, and set the referefence to NULL. 68 void delete_window_at(size_t index) { 69 delete window_[index]; 70 window_[index] = NULL; 71 } 72 73 // The accessor to the MultiWindowManager. 74 chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager() { 75 return multi_user_window_manager_; 76 } 77 78 // Returns a list of all open windows in the following form: 79 // "<H(idden)/S(hown)/D(eleted)>[<Owner>[,<shownForUser>]], .." 80 // Like: "S[B], .." would mean that window#0 is shown and belongs to user B. 81 // or "S[B,A], .." would mean that window#0 is shown, belongs to B but is 82 // shown by A, and "D,..." would mean that window#0 is deleted. 83 std::string GetStatus(); 84 85 // Returns a test-friendly string format of GetOwnersOfVisibleWindows(). 86 std::string GetOwnersOfVisibleWindowsAsString(); 87 88 TestSessionStateDelegate* session_state_delegate() { 89 return session_state_delegate_; 90 } 91 92 // Make a window system modal. 93 void MakeWindowSystemModal(aura::Window* window) { 94 aura::Window* system_modal_container = 95 window->GetRootWindow()->GetChildById( 96 ash::kShellWindowId_SystemModalContainer); 97 system_modal_container->AddChild(window); 98 } 99 100 void ShowWindowForUserNoUserTransition(aura::Window* window, 101 const std::string& user_id) { 102 multi_user_window_manager_->ShowWindowForUserIntern(window, user_id); 103 } 104 105 // The test session state observer does not automatically call the window 106 // manager. This function gets the current user from it and also sets it to 107 // the multi user window manager. 108 std::string GetAndValidateCurrentUserFromSessionStateObserver() { 109 const std::string& user = 110 session_state_delegate()->GetActiveUserInfo()->GetUserID(); 111 if (user != multi_user_window_manager_->GetCurrentUserForTest()) 112 multi_user_window_manager()->ActiveUserChanged(user); 113 return user; 114 } 115 116 // Initiate a user transition. 117 void StartUserTransitionAnimation(const std::string& user_id) { 118 multi_user_window_manager_->ActiveUserChanged(user_id); 119 } 120 121 // Call next animation step. 122 void AdvanceUserTransitionAnimation() { 123 multi_user_window_manager_->animation_->AdvanceUserTransitionAnimation(); 124 } 125 126 // Return the user id of the wallpaper which is currently set. 127 const std::string& GetWallaperUserIdForTest() { 128 return multi_user_window_manager_->animation_->wallpaper_user_id_for_test(); 129 } 130 131 // Returns true if the given window covers the screen. 132 bool CoversScreen(aura::Window* window) { 133 return chrome::UserSwichAnimatorChromeOS::CoversScreen( 134 window); 135 } 136 137 // Create a maximize mode window manager. 138 ash::MaximizeModeWindowManager* CreateMaximizeModeWindowManager() { 139 EXPECT_FALSE(maximize_mode_window_manager()); 140 Shell::GetInstance()->maximize_mode_controller()-> 141 EnableMaximizeModeWindowManager(true); 142 return maximize_mode_window_manager(); 143 } 144 145 ash::MaximizeModeWindowManager* maximize_mode_window_manager() { 146 return Shell::GetInstance()->maximize_mode_controller()-> 147 maximize_mode_window_manager_.get(); 148 } 149 150 private: 151 // These get created for each session. 152 std::vector<aura::Window*> window_; 153 154 // The instance of the MultiUserWindowManager. 155 chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager_; 156 157 // The session state delegate. 158 ash::test::TestSessionStateDelegate* session_state_delegate_; 159 160 // The maximized window manager (if enabled). 161 scoped_ptr<MaximizeModeWindowManager> maximize_mode_window_manager_; 162 163 DISALLOW_COPY_AND_ASSIGN(MultiUserWindowManagerChromeOSTest); 164 }; 165 166 void MultiUserWindowManagerChromeOSTest::SetUp() { 167 AshTestBase::SetUp(); 168 session_state_delegate_ = 169 static_cast<TestSessionStateDelegate*> ( 170 ash::Shell::GetInstance()->session_state_delegate()); 171 session_state_delegate_->AddUser("a"); 172 session_state_delegate_->AddUser("b"); 173 session_state_delegate_->AddUser("c"); 174 } 175 176 void MultiUserWindowManagerChromeOSTest::SetUpForThisManyWindows(int windows) { 177 DCHECK(!window_.size()); 178 for (int i = 0; i < windows; i++) { 179 window_.push_back(CreateTestWindowInShellWithId(i)); 180 window_[i]->Show(); 181 } 182 multi_user_window_manager_ = new chrome::MultiUserWindowManagerChromeOS("A"); 183 multi_user_window_manager_->SetAnimationSpeedForTest( 184 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_DISABLED); 185 chrome::MultiUserWindowManager::SetInstanceForTest(multi_user_window_manager_, 186 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED); 187 EXPECT_TRUE(multi_user_window_manager_); 188 } 189 190 void MultiUserWindowManagerChromeOSTest::TearDown() { 191 // Since the AuraTestBase is needed to create our assets, we have to 192 // also delete them before we tear it down. 193 while (!window_.empty()) { 194 delete *(window_.begin()); 195 window_.erase(window_.begin()); 196 } 197 198 chrome::MultiUserWindowManager::DeleteInstance(); 199 AshTestBase::TearDown(); 200 } 201 202 std::string MultiUserWindowManagerChromeOSTest::GetStatus() { 203 std::string s; 204 for (size_t i = 0; i < window_.size(); i++) { 205 if (i) 206 s += ", "; 207 if (!window(i)) { 208 s += "D"; 209 continue; 210 } 211 s += window(i)->IsVisible() ? "S[" : "H["; 212 const std::string& owner = 213 multi_user_window_manager_->GetWindowOwner(window(i)); 214 s += owner; 215 const std::string& presenter = 216 multi_user_window_manager_->GetUserPresentingWindow(window(i)); 217 if (!owner.empty() && owner != presenter) { 218 s += ","; 219 s += presenter; 220 } 221 s += "]"; 222 } 223 return s; 224 } 225 226 std::string 227 MultiUserWindowManagerChromeOSTest::GetOwnersOfVisibleWindowsAsString() { 228 std::set<std::string> owners; 229 multi_user_window_manager_->GetOwnersOfVisibleWindows(&owners); 230 231 std::vector<std::string> owner_list; 232 owner_list.insert(owner_list.begin(), owners.begin(), owners.end()); 233 return JoinString(owner_list, ' '); 234 } 235 236 // Testing basic assumptions like default state and existence of manager. 237 TEST_F(MultiUserWindowManagerChromeOSTest, BasicTests) { 238 SetUpForThisManyWindows(3); 239 // Check the basic assumptions: All windows are visible and there is no owner. 240 EXPECT_EQ("S[], S[], S[]", GetStatus()); 241 EXPECT_TRUE(multi_user_window_manager()); 242 EXPECT_EQ(multi_user_window_manager(), 243 chrome::MultiUserWindowManager::GetInstance()); 244 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers()); 245 246 // The owner of an unowned window should be empty and it should be shown on 247 // all windows. 248 EXPECT_EQ("", multi_user_window_manager()->GetWindowOwner(window(0))); 249 EXPECT_EQ("", 250 multi_user_window_manager()->GetUserPresentingWindow(window(0))); 251 EXPECT_TRUE( 252 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A")); 253 EXPECT_TRUE( 254 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B")); 255 256 // Set the owner of one window should remember it as such. It should only be 257 // drawn on the owners desktop - not on any other. 258 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 259 EXPECT_EQ("A", multi_user_window_manager()->GetWindowOwner(window(0))); 260 EXPECT_EQ("A", 261 multi_user_window_manager()->GetUserPresentingWindow(window(0))); 262 EXPECT_TRUE( 263 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A")); 264 EXPECT_FALSE( 265 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B")); 266 267 // Overriding it with another state should show it on the other user's 268 // desktop. 269 ShowWindowForUserNoUserTransition(window(0), "B"); 270 EXPECT_EQ("A", multi_user_window_manager()->GetWindowOwner(window(0))); 271 EXPECT_EQ("B", 272 multi_user_window_manager()->GetUserPresentingWindow(window(0))); 273 EXPECT_FALSE( 274 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A")); 275 EXPECT_TRUE( 276 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B")); 277 } 278 279 // Testing simple owner changes. 280 TEST_F(MultiUserWindowManagerChromeOSTest, OwnerTests) { 281 SetUpForThisManyWindows(5); 282 // Set some windows to the active owner. 283 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 284 EXPECT_EQ("S[A], S[], S[], S[], S[]", GetStatus()); 285 multi_user_window_manager()->SetWindowOwner(window(2), "A"); 286 EXPECT_EQ("S[A], S[], S[A], S[], S[]", GetStatus()); 287 288 // Set some windows to an inactive owner. Note that the windows should hide. 289 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 290 EXPECT_EQ("S[A], H[B], S[A], S[], S[]", GetStatus()); 291 multi_user_window_manager()->SetWindowOwner(window(3), "B"); 292 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus()); 293 294 // Assume that the user has now changed to C - which should show / hide 295 // accordingly. 296 multi_user_window_manager()->ActiveUserChanged("C"); 297 EXPECT_EQ("H[A], H[B], H[A], H[B], S[]", GetStatus()); 298 299 // If someone tries to show an inactive window it should only work if it can 300 // be shown / hidden. 301 multi_user_window_manager()->ActiveUserChanged("A"); 302 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus()); 303 window(3)->Show(); 304 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus()); 305 window(2)->Hide(); 306 EXPECT_EQ("S[A], H[B], H[A], H[B], S[]", GetStatus()); 307 window(2)->Show(); 308 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus()); 309 } 310 311 TEST_F(MultiUserWindowManagerChromeOSTest, CloseWindowTests) { 312 SetUpForThisManyWindows(1); 313 multi_user_window_manager()->SetWindowOwner(window(0), "B"); 314 EXPECT_EQ("H[B]", GetStatus()); 315 ShowWindowForUserNoUserTransition(window(0), "A"); 316 EXPECT_EQ("S[B,A]", GetStatus()); 317 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers()); 318 EXPECT_EQ("B", GetOwnersOfVisibleWindowsAsString()); 319 320 aura::Window* to_be_deleted = window(0); 321 322 EXPECT_EQ(std::string("A"), 323 multi_user_window_manager()->GetUserPresentingWindow( 324 to_be_deleted)); 325 EXPECT_EQ(std::string("B"), 326 multi_user_window_manager()->GetWindowOwner( 327 to_be_deleted)); 328 329 // Close the window. 330 delete_window_at(0); 331 332 EXPECT_EQ("D", GetStatus()); 333 EXPECT_EQ("", GetOwnersOfVisibleWindowsAsString()); 334 // There should be no owner anymore for that window and the shared windows 335 // should be gone as well. 336 EXPECT_EQ(std::string(), 337 multi_user_window_manager()->GetUserPresentingWindow( 338 to_be_deleted)); 339 EXPECT_EQ(std::string(), 340 multi_user_window_manager()->GetWindowOwner( 341 to_be_deleted)); 342 } 343 344 TEST_F(MultiUserWindowManagerChromeOSTest, SharedWindowTests) { 345 SetUpForThisManyWindows(5); 346 // Set some owners and make sure we got what we asked for. 347 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 348 multi_user_window_manager()->SetWindowOwner(window(1), "A"); 349 multi_user_window_manager()->SetWindowOwner(window(2), "B"); 350 multi_user_window_manager()->SetWindowOwner(window(3), "B"); 351 multi_user_window_manager()->SetWindowOwner(window(4), "C"); 352 EXPECT_EQ("S[A], S[A], H[B], H[B], H[C]", GetStatus()); 353 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers()); 354 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString()); 355 356 // For all following tests we override window 2 to be shown by user B. 357 ShowWindowForUserNoUserTransition(window(1), "B"); 358 359 // Change window 3 between two users and see that it changes 360 // accordingly (or not). 361 ShowWindowForUserNoUserTransition(window(2), "A"); 362 EXPECT_EQ("S[A], H[A,B], S[B,A], H[B], H[C]", GetStatus()); 363 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers()); 364 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString()); 365 ShowWindowForUserNoUserTransition(window(2), "C"); 366 EXPECT_EQ("S[A], H[A,B], H[B,C], H[B], H[C]", GetStatus()); 367 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers()); 368 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString()); 369 370 // Switch the users and see that the results are correct. 371 multi_user_window_manager()->ActiveUserChanged("B"); 372 EXPECT_EQ("H[A], S[A,B], H[B,C], S[B], H[C]", GetStatus()); 373 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString()); 374 multi_user_window_manager()->ActiveUserChanged("C"); 375 EXPECT_EQ("H[A], H[A,B], S[B,C], H[B], S[C]", GetStatus()); 376 EXPECT_EQ("B C", GetOwnersOfVisibleWindowsAsString()); 377 378 // Showing on the desktop of the already owning user should have no impact. 379 ShowWindowForUserNoUserTransition(window(4), "C"); 380 EXPECT_EQ("H[A], H[A,B], S[B,C], H[B], S[C]", GetStatus()); 381 EXPECT_EQ("B C", GetOwnersOfVisibleWindowsAsString()); 382 383 // Changing however a shown window back to the original owner should hide it. 384 ShowWindowForUserNoUserTransition(window(2), "B"); 385 EXPECT_EQ("H[A], H[A,B], H[B], H[B], S[C]", GetStatus()); 386 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers()); 387 EXPECT_EQ("C", GetOwnersOfVisibleWindowsAsString()); 388 389 // And the change should be "permanent" - switching somewhere else and coming 390 // back. 391 multi_user_window_manager()->ActiveUserChanged("B"); 392 EXPECT_EQ("H[A], S[A,B], S[B], S[B], H[C]", GetStatus()); 393 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString()); 394 multi_user_window_manager()->ActiveUserChanged("C"); 395 EXPECT_EQ("H[A], H[A,B], H[B], H[B], S[C]", GetStatus()); 396 EXPECT_EQ("C", GetOwnersOfVisibleWindowsAsString()); 397 398 // After switching window 2 back to its original desktop, all desktops should 399 // be "clean" again. 400 ShowWindowForUserNoUserTransition(window(1), "A"); 401 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers()); 402 } 403 404 // Make sure that adding a window to another desktop does not cause harm. 405 TEST_F(MultiUserWindowManagerChromeOSTest, DoubleSharedWindowTests) { 406 SetUpForThisManyWindows(1); 407 multi_user_window_manager()->SetWindowOwner(window(0), "B"); 408 409 // Add two references to the same window. 410 ShowWindowForUserNoUserTransition(window(0), "A"); 411 ShowWindowForUserNoUserTransition(window(0), "A"); 412 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers()); 413 414 // Close the window. 415 delete_window_at(0); 416 417 EXPECT_EQ("D", GetStatus()); 418 // There should be no shares anymore open. 419 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers()); 420 } 421 422 // Tests that the user's desktop visibility changes get respected. These tests 423 // are required to make sure that our usage of the same feature for showing and 424 // hiding does not interfere with the "normal operation". 425 TEST_F(MultiUserWindowManagerChromeOSTest, PreserveWindowVisibilityTests) { 426 SetUpForThisManyWindows(5); 427 // Set some owners and make sure we got what we asked for. 428 // Note that we try to cover all combinations in one go. 429 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 430 multi_user_window_manager()->SetWindowOwner(window(1), "A"); 431 multi_user_window_manager()->SetWindowOwner(window(2), "B"); 432 multi_user_window_manager()->SetWindowOwner(window(3), "B"); 433 ShowWindowForUserNoUserTransition(window(2), "A"); 434 ShowWindowForUserNoUserTransition(window(3), "A"); 435 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus()); 436 437 // Hiding a window should be respected - no matter if it is owned by that user 438 // owned by someone else but shown on that desktop - or not owned. 439 window(0)->Hide(); 440 window(2)->Hide(); 441 window(4)->Hide(); 442 EXPECT_EQ("H[A], S[A], H[B,A], S[B,A], H[]", GetStatus()); 443 444 // Flipping to another user and back should preserve all show / hide states. 445 multi_user_window_manager()->ActiveUserChanged("B"); 446 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], H[]", GetStatus()); 447 448 multi_user_window_manager()->ActiveUserChanged("A"); 449 EXPECT_EQ("H[A], S[A], H[B,A], S[B,A], H[]", GetStatus()); 450 451 // After making them visible and switching fore and back everything should be 452 // visible. 453 window(0)->Show(); 454 window(2)->Show(); 455 window(4)->Show(); 456 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus()); 457 458 multi_user_window_manager()->ActiveUserChanged("B"); 459 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus()); 460 461 multi_user_window_manager()->ActiveUserChanged("A"); 462 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus()); 463 464 // Now test that making windows visible through "normal operation" while the 465 // user's desktop is hidden leads to the correct result. 466 multi_user_window_manager()->ActiveUserChanged("B"); 467 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus()); 468 window(0)->Show(); 469 window(2)->Show(); 470 window(4)->Show(); 471 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus()); 472 multi_user_window_manager()->ActiveUserChanged("A"); 473 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus()); 474 } 475 476 // Check that minimizing a window which is owned by another user will move it 477 // back and gets restored upon switching back to the original user. 478 TEST_F(MultiUserWindowManagerChromeOSTest, MinimizeChangesOwnershipBack) { 479 SetUpForThisManyWindows(4); 480 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 481 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 482 multi_user_window_manager()->SetWindowOwner(window(2), "B"); 483 ShowWindowForUserNoUserTransition(window(1), "A"); 484 EXPECT_EQ("S[A], S[B,A], H[B], S[]", GetStatus()); 485 EXPECT_TRUE(multi_user_window_manager()->IsWindowOnDesktopOfUser(window(1), 486 "A")); 487 wm::GetWindowState(window(1))->Minimize(); 488 // At this time the window is still on the desktop of that user, but the user 489 // does not have a way to get to it. 490 EXPECT_EQ("S[A], H[B,A], H[B], S[]", GetStatus()); 491 EXPECT_TRUE(multi_user_window_manager()->IsWindowOnDesktopOfUser(window(1), 492 "A")); 493 EXPECT_TRUE(wm::GetWindowState(window(1))->IsMinimized()); 494 // Change to user B and make sure that minimizing does not change anything. 495 multi_user_window_manager()->ActiveUserChanged("B"); 496 EXPECT_EQ("H[A], S[B], S[B], S[]", GetStatus()); 497 EXPECT_FALSE(wm::GetWindowState(window(1))->IsMinimized()); 498 } 499 500 // Check that we cannot transfer the ownership of a minimized window. 501 TEST_F(MultiUserWindowManagerChromeOSTest, MinimizeSuppressesViewTransfer) { 502 SetUpForThisManyWindows(1); 503 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 504 wm::GetWindowState(window(0))->Minimize(); 505 EXPECT_EQ("H[A]", GetStatus()); 506 507 // Try to transfer the window to user B - which should get ignored. 508 ShowWindowForUserNoUserTransition(window(0), "B"); 509 EXPECT_EQ("H[A]", GetStatus()); 510 } 511 512 // Testing that the activation state changes to the active window. 513 TEST_F(MultiUserWindowManagerChromeOSTest, ActiveWindowTests) { 514 SetUpForThisManyWindows(4); 515 516 aura::client::ActivationClient* activation_client = 517 aura::client::GetActivationClient(window(0)->GetRootWindow()); 518 519 // Set some windows to the active owner. 520 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 521 multi_user_window_manager()->SetWindowOwner(window(1), "A"); 522 multi_user_window_manager()->SetWindowOwner(window(2), "B"); 523 multi_user_window_manager()->SetWindowOwner(window(3), "B"); 524 EXPECT_EQ("S[A], S[A], H[B], H[B]", GetStatus()); 525 526 // Set the active window for user A to be #1 527 activation_client->ActivateWindow(window(1)); 528 529 // Change to user B and make sure that one of its windows is active. 530 multi_user_window_manager()->ActiveUserChanged("B"); 531 EXPECT_EQ("H[A], H[A], S[B], S[B]", GetStatus()); 532 EXPECT_TRUE(window(3) == activation_client->GetActiveWindow() || 533 window(2) == activation_client->GetActiveWindow()); 534 // Set the active window for user B now to be #2 535 activation_client->ActivateWindow(window(2)); 536 537 multi_user_window_manager()->ActiveUserChanged("A"); 538 EXPECT_EQ(window(1), activation_client->GetActiveWindow()); 539 540 multi_user_window_manager()->ActiveUserChanged("B"); 541 EXPECT_EQ(window(2), activation_client->GetActiveWindow()); 542 543 multi_user_window_manager()->ActiveUserChanged("C"); 544 EXPECT_EQ(NULL, activation_client->GetActiveWindow()); 545 546 // Now test that a minimized window stays minimized upon switch and back. 547 multi_user_window_manager()->ActiveUserChanged("A"); 548 wm::GetWindowState(window(0))->Minimize(); 549 550 multi_user_window_manager()->ActiveUserChanged("B"); 551 multi_user_window_manager()->ActiveUserChanged("A"); 552 EXPECT_TRUE(wm::GetWindowState(window(0))->IsMinimized()); 553 EXPECT_EQ(window(1), activation_client->GetActiveWindow()); 554 } 555 556 // Test that Transient windows are handled properly. 557 TEST_F(MultiUserWindowManagerChromeOSTest, TransientWindows) { 558 SetUpForThisManyWindows(10); 559 560 // We create a hierarchy like this: 561 // 0 (A) 4 (B) 7 (-) - The top level owned/not owned windows 562 // | | | 563 // 1 5 - 6 8 - Transient child of the owned windows. 564 // | | 565 // 2 9 - A transtient child of a transient child. 566 // | 567 // 3 - .. 568 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 569 multi_user_window_manager()->SetWindowOwner(window(4), "B"); 570 ::wm::AddTransientChild(window(0), window(1)); 571 // We first attach 2->3 and then 1->2 to see that the ownership gets 572 // properly propagated through the sub tree upon assigning. 573 ::wm::AddTransientChild(window(2), window(3)); 574 ::wm::AddTransientChild(window(1), window(2)); 575 ::wm::AddTransientChild(window(4), window(5)); 576 ::wm::AddTransientChild(window(4), window(6)); 577 ::wm::AddTransientChild(window(7), window(8)); 578 ::wm::AddTransientChild(window(7), window(9)); 579 580 // By now the hierarchy should have updated itself to show all windows of A 581 // and hide all windows of B. Unowned windows should remain in what ever state 582 // they are in. 583 EXPECT_EQ("S[A], S[], S[], S[], H[B], H[], H[], S[], S[], S[]", GetStatus()); 584 585 // Trying to show a hidden transient window shouldn't change anything for now. 586 window(5)->Show(); 587 window(6)->Show(); 588 EXPECT_EQ("S[A], S[], S[], S[], H[B], H[], H[], S[], S[], S[]", GetStatus()); 589 590 // Hiding on the other hand a shown window should work and hide also its 591 // children. Note that hide will have an immediate impact on itself and all 592 // transient children. It furthermore should remember this state when the 593 // transient children are removed from its owner later on. 594 window(2)->Hide(); 595 window(9)->Hide(); 596 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], H[], S[], S[], H[]", GetStatus()); 597 598 // Switching users and switch back should return to the previous state. 599 multi_user_window_manager()->ActiveUserChanged("B"); 600 EXPECT_EQ("H[A], H[], H[], H[], S[B], S[], S[], S[], S[], H[]", GetStatus()); 601 multi_user_window_manager()->ActiveUserChanged("A"); 602 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], H[], S[], S[], H[]", GetStatus()); 603 604 // Removing a window from its transient parent should return to the previously 605 // set visibility state. 606 // Note: Window2 was explicitly hidden above and that state should remain. 607 // Note furthermore that Window3 should also be hidden since it was hidden 608 // implicitly by hiding Window2. 609 // set hidden above). 610 // 0 (A) 4 (B) 7 (-) 2(-) 3 (-) 6(-) 611 // | | | 612 // 1 5 8 613 // | 614 // 9 615 ::wm::RemoveTransientChild(window(2), window(3)); 616 ::wm::RemoveTransientChild(window(4), window(6)); 617 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], S[], S[], S[], H[]", GetStatus()); 618 // Before we leave we need to reverse all transient window ownerships. 619 ::wm::RemoveTransientChild(window(0), window(1)); 620 ::wm::RemoveTransientChild(window(1), window(2)); 621 ::wm::RemoveTransientChild(window(4), window(5)); 622 ::wm::RemoveTransientChild(window(7), window(8)); 623 ::wm::RemoveTransientChild(window(7), window(9)); 624 } 625 626 // Test that the initial visibility state gets remembered. 627 TEST_F(MultiUserWindowManagerChromeOSTest, PreserveInitialVisibility) { 628 SetUpForThisManyWindows(4); 629 630 // Set our initial show state before we assign an owner. 631 window(0)->Show(); 632 window(1)->Hide(); 633 window(2)->Show(); 634 window(3)->Hide(); 635 EXPECT_EQ("S[], H[], S[], H[]", GetStatus()); 636 637 // First test: The show state gets preserved upon user switch. 638 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 639 multi_user_window_manager()->SetWindowOwner(window(1), "A"); 640 multi_user_window_manager()->SetWindowOwner(window(2), "B"); 641 multi_user_window_manager()->SetWindowOwner(window(3), "B"); 642 EXPECT_EQ("S[A], H[A], H[B], H[B]", GetStatus()); 643 multi_user_window_manager()->ActiveUserChanged("B"); 644 EXPECT_EQ("H[A], H[A], S[B], H[B]", GetStatus()); 645 multi_user_window_manager()->ActiveUserChanged("A"); 646 EXPECT_EQ("S[A], H[A], H[B], H[B]", GetStatus()); 647 648 // Second test: Transferring the window to another desktop preserves the 649 // show state. 650 ShowWindowForUserNoUserTransition(window(0), "B"); 651 ShowWindowForUserNoUserTransition(window(1), "B"); 652 ShowWindowForUserNoUserTransition(window(2), "A"); 653 ShowWindowForUserNoUserTransition(window(3), "A"); 654 EXPECT_EQ("H[A,B], H[A,B], S[B,A], H[B,A]", GetStatus()); 655 multi_user_window_manager()->ActiveUserChanged("B"); 656 EXPECT_EQ("S[A,B], H[A,B], H[B,A], H[B,A]", GetStatus()); 657 multi_user_window_manager()->ActiveUserChanged("A"); 658 EXPECT_EQ("H[A,B], H[A,B], S[B,A], H[B,A]", GetStatus()); 659 } 660 661 // Test that in case of an activated maximize mode, windows from other users get 662 // maximized after a user switch. 663 TEST_F(MultiUserWindowManagerChromeOSTest, MaximizeModeInteraction) { 664 SetUpForThisManyWindows(2); 665 666 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 667 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 668 669 EXPECT_FALSE(wm::GetWindowState(window(0))->IsMaximized()); 670 EXPECT_FALSE(wm::GetWindowState(window(1))->IsMaximized()); 671 672 ash::MaximizeModeWindowManager* manager = CreateMaximizeModeWindowManager(); 673 ASSERT_TRUE(manager); 674 675 EXPECT_TRUE(wm::GetWindowState(window(0))->IsMaximized()); 676 EXPECT_FALSE(wm::GetWindowState(window(1))->IsMaximized()); 677 678 // After we start switching to B, the windows of user B should maximize. 679 StartUserTransitionAnimation("B"); 680 681 EXPECT_TRUE(wm::GetWindowState(window(0))->IsMaximized()); 682 EXPECT_TRUE(wm::GetWindowState(window(1))->IsMaximized()); 683 } 684 685 // Test that a system modal dialog will switch to the desktop of the owning 686 // user. 687 TEST_F(MultiUserWindowManagerChromeOSTest, SwitchUsersUponModalityChange) { 688 SetUpForThisManyWindows(1); 689 session_state_delegate()->SwitchActiveUser("a"); 690 691 // Making the window system modal should not change anything. 692 MakeWindowSystemModal(window(0)); 693 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID()); 694 695 // Making the window owned by user B should switch users. 696 multi_user_window_manager()->SetWindowOwner(window(0), "b"); 697 EXPECT_EQ("b", session_state_delegate()->GetActiveUserInfo()->GetUserID()); 698 } 699 700 // Test that a system modal dialog will not switch desktop if active user has 701 // shows window. 702 TEST_F(MultiUserWindowManagerChromeOSTest, DontSwitchUsersUponModalityChange) { 703 SetUpForThisManyWindows(1); 704 session_state_delegate()->SwitchActiveUser("a"); 705 706 // Making the window system modal should not change anything. 707 MakeWindowSystemModal(window(0)); 708 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID()); 709 710 // Making the window owned by user a should not switch users. 711 multi_user_window_manager()->SetWindowOwner(window(0), "a"); 712 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID()); 713 } 714 715 // Test that a system modal dialog will not switch if shown on correct desktop 716 // but owned by another user. 717 TEST_F(MultiUserWindowManagerChromeOSTest, 718 DontSwitchUsersUponModalityChangeWhenShownButNotOwned) { 719 SetUpForThisManyWindows(1); 720 session_state_delegate()->SwitchActiveUser("a"); 721 722 window(0)->Hide(); 723 multi_user_window_manager()->SetWindowOwner(window(0), "b"); 724 ShowWindowForUserNoUserTransition(window(0), "a"); 725 MakeWindowSystemModal(window(0)); 726 // Showing the window should trigger no user switch. 727 window(0)->Show(); 728 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID()); 729 } 730 731 // Test that a system modal dialog will switch if shown on incorrect desktop but 732 // even if owned by current user. 733 TEST_F(MultiUserWindowManagerChromeOSTest, 734 SwitchUsersUponModalityChangeWhenShownButNotOwned) { 735 SetUpForThisManyWindows(1); 736 session_state_delegate()->SwitchActiveUser("a"); 737 738 window(0)->Hide(); 739 multi_user_window_manager()->SetWindowOwner(window(0), "a"); 740 ShowWindowForUserNoUserTransition(window(0), "b"); 741 MakeWindowSystemModal(window(0)); 742 // Showing the window should trigger a user switch. 743 window(0)->Show(); 744 EXPECT_EQ("b", session_state_delegate()->GetActiveUserInfo()->GetUserID()); 745 } 746 747 // Test that using the full user switch animations are working as expected. 748 TEST_F(MultiUserWindowManagerChromeOSTest, FullUserSwitchAnimationTests) { 749 SetUpForThisManyWindows(3); 750 // Turn the use of delays and animation on. 751 multi_user_window_manager()->SetAnimationSpeedForTest( 752 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST); 753 // Set some owners and make sure we got what we asked for. 754 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 755 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 756 multi_user_window_manager()->SetWindowOwner(window(2), "C"); 757 EXPECT_EQ("S[A], H[B], H[C]", GetStatus()); 758 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString()); 759 760 // Switch the user fore and back and see that the results are correct. 761 SwitchUserAndWaitForAnimation("B"); 762 763 EXPECT_EQ("H[A], S[B], H[C]", GetStatus()); 764 EXPECT_EQ("B", GetOwnersOfVisibleWindowsAsString()); 765 766 SwitchUserAndWaitForAnimation("A"); 767 768 EXPECT_EQ("S[A], H[B], H[C]", GetStatus()); 769 770 // Switch the user quickly to another user and before the animation is done 771 // switch back and see that this works. 772 multi_user_window_manager()->ActiveUserChanged("B"); 773 // With the start of the animation B should become visible. 774 EXPECT_EQ("H[A], S[B], H[C]", GetStatus()); 775 // Check that after switching to C, C is fully visible. 776 SwitchUserAndWaitForAnimation("C"); 777 EXPECT_EQ("H[A], H[B], S[C]", GetStatus()); 778 } 779 780 // Make sure that we do not crash upon shutdown when an animation is pending and 781 // a shutdown happens. 782 TEST_F(MultiUserWindowManagerChromeOSTest, SystemShutdownWithActiveAnimation) { 783 SetUpForThisManyWindows(2); 784 // Turn the use of delays and animation on. 785 multi_user_window_manager()->SetAnimationSpeedForTest( 786 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST); 787 // Set some owners and make sure we got what we asked for. 788 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 789 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 790 StartUserTransitionAnimation("B"); 791 // We don't do anything more here - the animations are pending and with the 792 // shutdown of the framework the animations should get cancelled. If not a 793 // crash would happen. 794 } 795 796 // Test that using the full user switch, the animations are transitioning as 797 // we expect them to in all animation steps. 798 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationSteps) { 799 SetUpForThisManyWindows(3); 800 // Turn the use of delays and animation on. 801 multi_user_window_manager()->SetAnimationSpeedForTest( 802 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST); 803 // Set some owners and make sure we got what we asked for. 804 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 805 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 806 multi_user_window_manager()->SetWindowOwner(window(2), "C"); 807 EXPECT_FALSE(CoversScreen(window(0))); 808 EXPECT_FALSE(CoversScreen(window(1))); 809 EXPECT_EQ("S[A], H[B], H[C]", GetStatus()); 810 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString()); 811 EXPECT_NE(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, 812 ash::Shell::GetInstance()->GetShelfAutoHideBehavior( 813 window(0)->GetRootWindow())); 814 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity()); 815 ash::ShelfWidget* shelf = ash::RootWindowController::ForWindow( 816 window(0))->shelf(); 817 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 818 819 // Start the animation and see that the old window is becoming invisible, the 820 // new one visible, the background starts transitionining and the shelf hides. 821 StartUserTransitionAnimation("B"); 822 EXPECT_EQ("->B", GetWallaperUserIdForTest()); 823 EXPECT_EQ("H[A], S[B], H[C]", GetStatus()); 824 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity()); 825 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 826 EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, 827 ash::Shell::GetInstance()->GetShelfAutoHideBehavior( 828 window(0)->GetRootWindow())); 829 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 830 831 // Staring the next step should show the shelf again, but there are many 832 // subsystems missing (preferences system, ChromeLauncherController, ...) 833 // which should set the shelf to its users state. Since that isn't there we 834 // can only make sure that it stays where it is. 835 AdvanceUserTransitionAnimation(); 836 EXPECT_EQ("->B", GetWallaperUserIdForTest()); 837 EXPECT_EQ("H[A], S[B], H[C]", GetStatus()); 838 EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, 839 ash::Shell::GetInstance()->GetShelfAutoHideBehavior( 840 window(0)->GetRootWindow())); 841 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 842 843 // After the finalize the animation of the wallpaper should be finished. 844 AdvanceUserTransitionAnimation(); 845 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 846 EXPECT_EQ("B", GetWallaperUserIdForTest()); 847 } 848 849 // Test that the screen coverage is properly determined. 850 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsScreenCoverage) { 851 SetUpForThisManyWindows(3); 852 // Maximizing, fully covering the screen by bounds or fullscreen mode should 853 // make CoversScreen return true. 854 wm::GetWindowState(window(0))->Maximize(); 855 window(1)->SetBounds(gfx::Rect(0, 0, 3000, 3000)); 856 857 EXPECT_TRUE(CoversScreen(window(0))); 858 EXPECT_TRUE(CoversScreen(window(1))); 859 EXPECT_FALSE(CoversScreen(window(2))); 860 861 ash::wm::WMEvent event(ash::wm::WM_EVENT_FULLSCREEN); 862 wm::GetWindowState(window(2))->OnWMEvent(&event); 863 EXPECT_TRUE(CoversScreen(window(2))); 864 } 865 866 // Test that switching from a desktop which has a maximized window to a desktop 867 // which has no maximized window will produce the proper animation. 868 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsMaximizeToNormal) { 869 SetUpForThisManyWindows(3); 870 // Turn the use of delays and animation on. 871 multi_user_window_manager()->SetAnimationSpeedForTest( 872 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST); 873 // Set some owners and make sure we got what we asked for. 874 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 875 wm::GetWindowState(window(0))->Maximize(); 876 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 877 multi_user_window_manager()->SetWindowOwner(window(2), "C"); 878 EXPECT_TRUE(CoversScreen(window(0))); 879 EXPECT_FALSE(CoversScreen(window(1))); 880 EXPECT_EQ("S[A], H[B], H[C]", GetStatus()); 881 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString()); 882 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity()); 883 884 // Start the animation and see that the new background is immediately set. 885 StartUserTransitionAnimation("B"); 886 EXPECT_EQ("H[A], S[B], H[C]", GetStatus()); 887 EXPECT_EQ("B", GetWallaperUserIdForTest()); 888 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity()); 889 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 890 891 // The next step will not change anything. 892 AdvanceUserTransitionAnimation(); 893 EXPECT_EQ("B", GetWallaperUserIdForTest()); 894 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity()); 895 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 896 897 // The final step will also not have any visible impact. 898 AdvanceUserTransitionAnimation(); 899 EXPECT_EQ("H[A], S[B], H[C]", GetStatus()); 900 EXPECT_EQ("B", GetWallaperUserIdForTest()); 901 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity()); 902 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 903 } 904 905 // Test that switching from a desktop which has a normal window to a desktop 906 // which has a maximized window will produce the proper animation. 907 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsNormalToMaximized) { 908 SetUpForThisManyWindows(3); 909 // Turn the use of delays and animation on. 910 multi_user_window_manager()->SetAnimationSpeedForTest( 911 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST); 912 // Set some owners and make sure we got what we asked for. 913 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 914 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 915 wm::GetWindowState(window(1))->Maximize(); 916 multi_user_window_manager()->SetWindowOwner(window(2), "C"); 917 EXPECT_FALSE(CoversScreen(window(0))); 918 EXPECT_TRUE(CoversScreen(window(1))); 919 EXPECT_EQ("S[A], H[B], H[C]", GetStatus()); 920 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString()); 921 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity()); 922 923 // Start the animation and see that the old window is becoming invisible, the 924 // new one visible and the background remains as is. 925 StartUserTransitionAnimation("B"); 926 EXPECT_EQ("H[A], S[B], H[C]", GetStatus()); 927 EXPECT_EQ("", GetWallaperUserIdForTest()); 928 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity()); 929 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 930 931 // The next step will not change anything. 932 AdvanceUserTransitionAnimation(); 933 EXPECT_EQ("", GetWallaperUserIdForTest()); 934 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity()); 935 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 936 937 // The final step however will switch the background. 938 AdvanceUserTransitionAnimation(); 939 EXPECT_EQ("H[A], S[B], H[C]", GetStatus()); 940 EXPECT_EQ("B", GetWallaperUserIdForTest()); 941 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity()); 942 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 943 } 944 945 // Test that switching from a desktop which has a maximized window to a desktop 946 // which has a maximized window will produce the proper animation. 947 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsMaximizedToMaximized) { 948 SetUpForThisManyWindows(3); 949 // Turn the use of delays and animation on. 950 multi_user_window_manager()->SetAnimationSpeedForTest( 951 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST); 952 // Set some owners and make sure we got what we asked for. 953 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 954 wm::GetWindowState(window(0))->Maximize(); 955 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 956 wm::GetWindowState(window(1))->Maximize(); 957 multi_user_window_manager()->SetWindowOwner(window(2), "C"); 958 EXPECT_TRUE(CoversScreen(window(0))); 959 EXPECT_TRUE(CoversScreen(window(1))); 960 EXPECT_EQ("S[A], H[B], H[C]", GetStatus()); 961 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString()); 962 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity()); 963 964 // Start the animation and see that the old window is staying visible, the 965 // new one slowly visible and the background changes immediately. 966 StartUserTransitionAnimation("B"); 967 EXPECT_EQ("S[A], S[B], H[C]", GetStatus()); 968 EXPECT_EQ("B", GetWallaperUserIdForTest()); 969 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity()); 970 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 971 972 // The next step will not change anything. 973 AdvanceUserTransitionAnimation(); 974 EXPECT_EQ("B", GetWallaperUserIdForTest()); 975 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity()); 976 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 977 978 // The final step however will hide the old window. 979 AdvanceUserTransitionAnimation(); 980 EXPECT_EQ("H[A], S[B], H[C]", GetStatus()); 981 EXPECT_EQ("B", GetWallaperUserIdForTest()); 982 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity()); 983 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity()); 984 985 // Switching back will preserve the z-order by instantly showing the new 986 // window, hiding the layer above it and switching instantly the wallpaper. 987 StartUserTransitionAnimation("A"); 988 EXPECT_EQ("S[A], H[B], H[C]", GetStatus()); 989 EXPECT_EQ("A", GetWallaperUserIdForTest()); 990 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity()); 991 EXPECT_EQ(0.0f, window(1)->layer()->GetTargetOpacity()); 992 993 // The next step will not change anything. 994 AdvanceUserTransitionAnimation(); 995 EXPECT_EQ("A", GetWallaperUserIdForTest()); 996 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity()); 997 EXPECT_EQ(0.0f, window(1)->layer()->GetTargetOpacity()); 998 999 // The final step is also not changing anything to the status. 1000 AdvanceUserTransitionAnimation(); 1001 EXPECT_EQ("S[A], H[B], H[C]", GetStatus()); 1002 EXPECT_EQ("A", GetWallaperUserIdForTest()); 1003 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity()); 1004 EXPECT_EQ(0.0f, window(1)->layer()->GetTargetOpacity()); 1005 } 1006 1007 // Test that showing a window for another user also switches the desktop. 1008 TEST_F(MultiUserWindowManagerChromeOSTest, ShowForUserSwitchesDesktop) { 1009 SetUpForThisManyWindows(3); 1010 multi_user_window_manager()->ActiveUserChanged("a"); 1011 session_state_delegate()->SwitchActiveUser("a"); 1012 1013 // Set some owners and make sure we got what we asked for. 1014 multi_user_window_manager()->SetWindowOwner(window(0), "a"); 1015 multi_user_window_manager()->SetWindowOwner(window(1), "b"); 1016 multi_user_window_manager()->SetWindowOwner(window(2), "c"); 1017 EXPECT_EQ("S[a], H[b], H[c]", GetStatus()); 1018 1019 // SetWindowOwner should not have changed the active user. 1020 EXPECT_EQ("a", GetAndValidateCurrentUserFromSessionStateObserver()); 1021 1022 // Check that teleporting the window of the currently active user will 1023 // teleport to the new desktop. 1024 multi_user_window_manager()->ShowWindowForUser(window(0), "b"); 1025 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver()); 1026 EXPECT_EQ("S[a,b], S[b], H[c]", GetStatus()); 1027 1028 // Check that teleporting a window from a currently inactive user will not 1029 // trigger a switch. 1030 multi_user_window_manager()->ShowWindowForUser(window(2), "a"); 1031 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver()); 1032 EXPECT_EQ("S[a,b], S[b], H[c,a]", GetStatus()); 1033 multi_user_window_manager()->ShowWindowForUser(window(2), "b"); 1034 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver()); 1035 EXPECT_EQ("S[a,b], S[b], S[c,b]", GetStatus()); 1036 1037 // Check that teleporting back will also change the desktop. 1038 multi_user_window_manager()->ShowWindowForUser(window(2), "c"); 1039 EXPECT_EQ("c", GetAndValidateCurrentUserFromSessionStateObserver()); 1040 EXPECT_EQ("H[a,b], H[b], S[c]", GetStatus()); 1041 } 1042 1043 class TestWindowObserver : public aura::WindowObserver { 1044 public: 1045 TestWindowObserver(): resize_calls_(0) {} 1046 virtual ~TestWindowObserver() {}; 1047 1048 virtual void OnWindowBoundsChanged(aura::Window* window, 1049 const gfx::Rect& old_bounds, 1050 const gfx::Rect& new_bounds) OVERRIDE { 1051 resize_calls_++; 1052 } 1053 1054 int resize_calls() { return resize_calls_; } 1055 1056 private: 1057 int resize_calls_; 1058 1059 DISALLOW_COPY_AND_ASSIGN(TestWindowObserver); 1060 }; 1061 1062 // Test that switching between users with the shelf in the same place, the shelf 1063 // will get covered with a black bar instead being hidden and re-shown. 1064 TEST_F(MultiUserWindowManagerChromeOSTest, TestBlackBarCover) { 1065 SetUpForThisManyWindows(2); 1066 multi_user_window_manager()->SetWindowOwner(window(0), "A"); 1067 multi_user_window_manager()->SetWindowOwner(window(1), "B"); 1068 aura::Window* root_window = ash::Shell::GetInstance()->GetPrimaryRootWindow(); 1069 1070 // Turn the use of delays and animation on. 1071 multi_user_window_manager()->SetAnimationSpeedForTest( 1072 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST); 1073 EXPECT_NE(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, 1074 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(root_window)); 1075 ash::ShelfWidget* shelf = ash::RootWindowController::ForWindow( 1076 root_window)->shelf(); 1077 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 1078 1079 // First test that with no maximized window we show/hide the shelf. 1080 StartUserTransitionAnimation("B"); 1081 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 1082 EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, 1083 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(root_window)); 1084 1085 // Staring the next step should show the shelf again. 1086 AdvanceUserTransitionAnimation(); 1087 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 1088 1089 AdvanceUserTransitionAnimation(); 1090 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 1091 ash::Shell::GetInstance()->SetShelfAutoHideBehavior( 1092 ash::SHELF_AUTO_HIDE_BEHAVIOR_NEVER, root_window); 1093 1094 // Now we maximize the windows which will cause the black overlay to show up. 1095 wm::GetWindowState(window(0))->Maximize(); 1096 wm::GetWindowState(window(1))->Maximize(); 1097 // We set a window observer on both windows to see that no resize is performed 1098 // on our test windows. 1099 TestWindowObserver window_observer; 1100 window(0)->AddObserver(&window_observer); 1101 window(1)->AddObserver(&window_observer); 1102 1103 // Start the animation and see that the shelf gets hidden by the black bar, 1104 // and the AutoHide behavior remains as it was. 1105 StartUserTransitionAnimation("A"); 1106 EXPECT_TRUE(shelf->IsShelfHiddenBehindBlackBar()); 1107 EXPECT_NE(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, 1108 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(root_window)); 1109 1110 // Staring the next step should show the shelf again. 1111 AdvanceUserTransitionAnimation(); 1112 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 1113 EXPECT_NE(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN, 1114 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(root_window)); 1115 1116 AdvanceUserTransitionAnimation(); 1117 EXPECT_FALSE(shelf->IsShelfHiddenBehindBlackBar()); 1118 window(0)->RemoveObserver(&window_observer); 1119 window(1)->RemoveObserver(&window_observer); 1120 // No resize should have been done to the window. 1121 EXPECT_EQ(0, window_observer.resize_calls()); 1122 } 1123 1124 } // namespace test 1125 } // namespace ash 1126