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.
5 #include "ash/session/user_info.h"
7 #include "ash/shell_window_ids.h"
8 #include "ash/test/ash_test_base.h"
9 #include "ash/test/test_session_state_delegate.h"
10 #include "ash/test/test_shell_delegate.h"
11 #include "ash/wm/maximize_mode/maximize_mode_controller.h"
12 #include "ash/wm/maximize_mode/maximize_mode_window_manager.h"
13 #include "ash/wm/window_state.h"
14 #include "ash/wm/wm_event.h"
15 #include "base/command_line.h"
16 #include "base/compiler_specific.h"
17 #include "base/logging.h"
18 #include "base/strings/string_util.h"
19 #include "base/time/time.h"
20 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
21 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
22 #include "chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.h"
23 #include "chrome/test/base/testing_profile.h"
24 #include "ui/aura/client/aura_constants.h"
25 #include "ui/aura/window_event_dispatcher.h"
26 #include "ui/base/ui_base_types.h"
27 #include "ui/wm/core/window_util.h"
28 #include "ui/wm/public/activation_client.h"
33 // A test class for preparing the chrome::MultiUserWindowManager. It creates
34 // various windows and instantiates the chrome::MultiUserWindowManager.
35 class MultiUserWindowManagerChromeOSTest : public AshTestBase {
37 MultiUserWindowManagerChromeOSTest()
38 : multi_user_window_manager_(NULL),
39 session_state_delegate_(NULL) {}
41 virtual void SetUp() OVERRIDE;
42 virtual void TearDown() OVERRIDE;
45 // Set up the test environment for this many windows.
46 void SetUpForThisManyWindows(int windows);
48 // Switch the user and wait until the animation is finished.
49 void SwitchUserAndWaitForAnimation(const std::string& user_id) {
50 multi_user_window_manager_->ActiveUserChanged(user_id);
51 base::TimeTicks now = base::TimeTicks::Now();
52 while (multi_user_window_manager_->IsAnimationRunningForTest()) {
53 // This should never take longer then a second.
54 ASSERT_GE(1000, (base::TimeTicks::Now() - now).InMilliseconds());
55 base::MessageLoop::current()->RunUntilIdle();
59 // Return the window with the given index.
60 aura::Window* window(size_t index) {
61 DCHECK(index < window_.size());
62 return window_[index];
65 // Delete the window at the given index, and set the referefence to NULL.
66 void delete_window_at(size_t index) {
67 delete window_[index];
68 window_[index] = NULL;
71 // The accessor to the MultiWindowManager.
72 chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager() {
73 return multi_user_window_manager_;
76 // Returns a list of all open windows in the following form:
77 // "<H(idden)/S(hown)/D(eleted)>[<Owner>[,<shownForUser>]], .."
78 // Like: "S[B], .." would mean that window#0 is shown and belongs to user B.
79 // or "S[B,A], .." would mean that window#0 is shown, belongs to B but is
80 // shown by A, and "D,..." would mean that window#0 is deleted.
81 std::string GetStatus();
83 // Returns a test-friendly string format of GetOwnersOfVisibleWindows().
84 std::string GetOwnersOfVisibleWindowsAsString();
86 TestSessionStateDelegate* session_state_delegate() {
87 return session_state_delegate_;
90 // Make a window system modal.
91 void MakeWindowSystemModal(aura::Window* window) {
92 aura::Window* system_modal_container =
93 window->GetRootWindow()->GetChildById(
94 ash::kShellWindowId_SystemModalContainer);
95 system_modal_container->AddChild(window);
98 void ShowWindowForUserNoUserTransition(aura::Window* window,
99 const std::string& user_id) {
100 multi_user_window_manager_->ShowWindowForUserIntern(window, user_id);
103 // The test session state observer does not automatically call the window
104 // manager. This function gets the current user from it and also sets it to
105 // the multi user window manager.
106 std::string GetAndValidateCurrentUserFromSessionStateObserver() {
107 const std::string& user =
108 session_state_delegate()->GetActiveUserInfo()->GetUserID();
109 if (user != multi_user_window_manager_->GetCurrentUserForTest())
110 multi_user_window_manager()->ActiveUserChanged(user);
114 // Initiate a user transition.
115 void StartUserTransitionAnimation(const std::string& user_id) {
116 multi_user_window_manager_->ActiveUserChanged(user_id);
119 // Call next animation step.
120 void AdvanceUserTransitionAnimation() {
121 multi_user_window_manager_->animation_->AdvanceUserTransitionAnimation();
124 // Return the user id of the wallpaper which is currently set.
125 const std::string& GetWallaperUserIdForTest() {
126 return multi_user_window_manager_->animation_->wallpaper_user_id_for_test();
129 // Returns true if the given window covers the screen.
130 bool CoversScreen(aura::Window* window) {
131 return chrome::UserSwichAnimatorChromeOS::CoversScreen(
135 // Create a maximize mode window manager.
136 ash::MaximizeModeWindowManager* CreateMaximizeModeWindowManager() {
137 EXPECT_FALSE(maximize_mode_window_manager());
138 Shell::GetInstance()->maximize_mode_controller()->
139 EnableMaximizeModeWindowManager(true);
140 return maximize_mode_window_manager();
143 ash::MaximizeModeWindowManager* maximize_mode_window_manager() {
144 return Shell::GetInstance()->maximize_mode_controller()->
145 maximize_mode_window_manager_.get();
149 // These get created for each session.
150 std::vector<aura::Window*> window_;
152 // The instance of the MultiUserWindowManager.
153 chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager_;
155 // The session state delegate.
156 ash::test::TestSessionStateDelegate* session_state_delegate_;
158 // The maximized window manager (if enabled).
159 scoped_ptr<MaximizeModeWindowManager> maximize_mode_window_manager_;
161 DISALLOW_COPY_AND_ASSIGN(MultiUserWindowManagerChromeOSTest);
164 void MultiUserWindowManagerChromeOSTest::SetUp() {
165 AshTestBase::SetUp();
166 session_state_delegate_ =
167 static_cast<TestSessionStateDelegate*> (
168 ash::Shell::GetInstance()->session_state_delegate());
169 session_state_delegate_->AddUser("a");
170 session_state_delegate_->AddUser("b");
171 session_state_delegate_->AddUser("c");
174 void MultiUserWindowManagerChromeOSTest::SetUpForThisManyWindows(int windows) {
175 DCHECK(!window_.size());
176 for (int i = 0; i < windows; i++) {
177 window_.push_back(CreateTestWindowInShellWithId(i));
180 multi_user_window_manager_ = new chrome::MultiUserWindowManagerChromeOS("A");
181 multi_user_window_manager_->SetAnimationSpeedForTest(
182 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_DISABLED);
183 chrome::MultiUserWindowManager::SetInstanceForTest(multi_user_window_manager_,
184 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED);
185 EXPECT_TRUE(multi_user_window_manager_);
188 void MultiUserWindowManagerChromeOSTest::TearDown() {
189 // Since the AuraTestBase is needed to create our assets, we have to
190 // also delete them before we tear it down.
191 while (!window_.empty()) {
192 delete *(window_.begin());
193 window_.erase(window_.begin());
196 chrome::MultiUserWindowManager::DeleteInstance();
197 AshTestBase::TearDown();
200 std::string MultiUserWindowManagerChromeOSTest::GetStatus() {
202 for (size_t i = 0; i < window_.size(); i++) {
209 s += window(i)->IsVisible() ? "S[" : "H[";
210 const std::string& owner =
211 multi_user_window_manager_->GetWindowOwner(window(i));
213 const std::string& presenter =
214 multi_user_window_manager_->GetUserPresentingWindow(window(i));
215 if (!owner.empty() && owner != presenter) {
225 MultiUserWindowManagerChromeOSTest::GetOwnersOfVisibleWindowsAsString() {
226 std::set<std::string> owners;
227 multi_user_window_manager_->GetOwnersOfVisibleWindows(&owners);
229 std::vector<std::string> owner_list;
230 owner_list.insert(owner_list.begin(), owners.begin(), owners.end());
231 return JoinString(owner_list, ' ');
234 // Testing basic assumptions like default state and existence of manager.
235 TEST_F(MultiUserWindowManagerChromeOSTest, BasicTests) {
236 SetUpForThisManyWindows(3);
237 // Check the basic assumptions: All windows are visible and there is no owner.
238 EXPECT_EQ("S[], S[], S[]", GetStatus());
239 EXPECT_TRUE(multi_user_window_manager());
240 EXPECT_EQ(multi_user_window_manager(),
241 chrome::MultiUserWindowManager::GetInstance());
242 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
244 // The owner of an unowned window should be empty and it should be shown on
246 EXPECT_EQ("", multi_user_window_manager()->GetWindowOwner(window(0)));
248 multi_user_window_manager()->GetUserPresentingWindow(window(0)));
250 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A"));
252 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B"));
254 // Set the owner of one window should remember it as such. It should only be
255 // drawn on the owners desktop - not on any other.
256 multi_user_window_manager()->SetWindowOwner(window(0), "A");
257 EXPECT_EQ("A", multi_user_window_manager()->GetWindowOwner(window(0)));
259 multi_user_window_manager()->GetUserPresentingWindow(window(0)));
261 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A"));
263 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B"));
265 // Overriding it with another state should show it on the other user's
267 ShowWindowForUserNoUserTransition(window(0), "B");
268 EXPECT_EQ("A", multi_user_window_manager()->GetWindowOwner(window(0)));
270 multi_user_window_manager()->GetUserPresentingWindow(window(0)));
272 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A"));
274 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B"));
277 // Testing simple owner changes.
278 TEST_F(MultiUserWindowManagerChromeOSTest, OwnerTests) {
279 SetUpForThisManyWindows(5);
280 // Set some windows to the active owner.
281 multi_user_window_manager()->SetWindowOwner(window(0), "A");
282 EXPECT_EQ("S[A], S[], S[], S[], S[]", GetStatus());
283 multi_user_window_manager()->SetWindowOwner(window(2), "A");
284 EXPECT_EQ("S[A], S[], S[A], S[], S[]", GetStatus());
286 // Set some windows to an inactive owner. Note that the windows should hide.
287 multi_user_window_manager()->SetWindowOwner(window(1), "B");
288 EXPECT_EQ("S[A], H[B], S[A], S[], S[]", GetStatus());
289 multi_user_window_manager()->SetWindowOwner(window(3), "B");
290 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
292 // Assume that the user has now changed to C - which should show / hide
294 multi_user_window_manager()->ActiveUserChanged("C");
295 EXPECT_EQ("H[A], H[B], H[A], H[B], S[]", GetStatus());
297 // If someone tries to show an inactive window it should only work if it can
298 // be shown / hidden.
299 multi_user_window_manager()->ActiveUserChanged("A");
300 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
302 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
304 EXPECT_EQ("S[A], H[B], H[A], H[B], S[]", GetStatus());
306 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
309 TEST_F(MultiUserWindowManagerChromeOSTest, CloseWindowTests) {
310 SetUpForThisManyWindows(1);
311 multi_user_window_manager()->SetWindowOwner(window(0), "B");
312 EXPECT_EQ("H[B]", GetStatus());
313 ShowWindowForUserNoUserTransition(window(0), "A");
314 EXPECT_EQ("S[B,A]", GetStatus());
315 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
316 EXPECT_EQ("B", GetOwnersOfVisibleWindowsAsString());
318 aura::Window* to_be_deleted = window(0);
320 EXPECT_EQ(std::string("A"),
321 multi_user_window_manager()->GetUserPresentingWindow(
323 EXPECT_EQ(std::string("B"),
324 multi_user_window_manager()->GetWindowOwner(
330 EXPECT_EQ("D", GetStatus());
331 EXPECT_EQ("", GetOwnersOfVisibleWindowsAsString());
332 // There should be no owner anymore for that window and the shared windows
333 // should be gone as well.
334 EXPECT_EQ(std::string(),
335 multi_user_window_manager()->GetUserPresentingWindow(
337 EXPECT_EQ(std::string(),
338 multi_user_window_manager()->GetWindowOwner(
342 TEST_F(MultiUserWindowManagerChromeOSTest, SharedWindowTests) {
343 SetUpForThisManyWindows(5);
344 // Set some owners and make sure we got what we asked for.
345 multi_user_window_manager()->SetWindowOwner(window(0), "A");
346 multi_user_window_manager()->SetWindowOwner(window(1), "A");
347 multi_user_window_manager()->SetWindowOwner(window(2), "B");
348 multi_user_window_manager()->SetWindowOwner(window(3), "B");
349 multi_user_window_manager()->SetWindowOwner(window(4), "C");
350 EXPECT_EQ("S[A], S[A], H[B], H[B], H[C]", GetStatus());
351 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
352 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
354 // For all following tests we override window 2 to be shown by user B.
355 ShowWindowForUserNoUserTransition(window(1), "B");
357 // Change window 3 between two users and see that it changes
358 // accordingly (or not).
359 ShowWindowForUserNoUserTransition(window(2), "A");
360 EXPECT_EQ("S[A], H[A,B], S[B,A], H[B], H[C]", GetStatus());
361 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
362 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString());
363 ShowWindowForUserNoUserTransition(window(2), "C");
364 EXPECT_EQ("S[A], H[A,B], H[B,C], H[B], H[C]", GetStatus());
365 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
366 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
368 // Switch the users and see that the results are correct.
369 multi_user_window_manager()->ActiveUserChanged("B");
370 EXPECT_EQ("H[A], S[A,B], H[B,C], S[B], H[C]", GetStatus());
371 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString());
372 multi_user_window_manager()->ActiveUserChanged("C");
373 EXPECT_EQ("H[A], H[A,B], S[B,C], H[B], S[C]", GetStatus());
374 EXPECT_EQ("B C", GetOwnersOfVisibleWindowsAsString());
376 // Showing on the desktop of the already owning user should have no impact.
377 ShowWindowForUserNoUserTransition(window(4), "C");
378 EXPECT_EQ("H[A], H[A,B], S[B,C], H[B], S[C]", GetStatus());
379 EXPECT_EQ("B C", GetOwnersOfVisibleWindowsAsString());
381 // Changing however a shown window back to the original owner should hide it.
382 ShowWindowForUserNoUserTransition(window(2), "B");
383 EXPECT_EQ("H[A], H[A,B], H[B], H[B], S[C]", GetStatus());
384 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
385 EXPECT_EQ("C", GetOwnersOfVisibleWindowsAsString());
387 // And the change should be "permanent" - switching somewhere else and coming
389 multi_user_window_manager()->ActiveUserChanged("B");
390 EXPECT_EQ("H[A], S[A,B], S[B], S[B], H[C]", GetStatus());
391 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString());
392 multi_user_window_manager()->ActiveUserChanged("C");
393 EXPECT_EQ("H[A], H[A,B], H[B], H[B], S[C]", GetStatus());
394 EXPECT_EQ("C", GetOwnersOfVisibleWindowsAsString());
396 // After switching window 2 back to its original desktop, all desktops should
398 ShowWindowForUserNoUserTransition(window(1), "A");
399 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
402 // Make sure that adding a window to another desktop does not cause harm.
403 TEST_F(MultiUserWindowManagerChromeOSTest, DoubleSharedWindowTests) {
404 SetUpForThisManyWindows(1);
405 multi_user_window_manager()->SetWindowOwner(window(0), "B");
407 // Add two references to the same window.
408 ShowWindowForUserNoUserTransition(window(0), "A");
409 ShowWindowForUserNoUserTransition(window(0), "A");
410 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
415 EXPECT_EQ("D", GetStatus());
416 // There should be no shares anymore open.
417 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
420 // Tests that the user's desktop visibility changes get respected. These tests
421 // are required to make sure that our usage of the same feature for showing and
422 // hiding does not interfere with the "normal operation".
423 TEST_F(MultiUserWindowManagerChromeOSTest, PreserveWindowVisibilityTests) {
424 SetUpForThisManyWindows(5);
425 // Set some owners and make sure we got what we asked for.
426 // Note that we try to cover all combinations in one go.
427 multi_user_window_manager()->SetWindowOwner(window(0), "A");
428 multi_user_window_manager()->SetWindowOwner(window(1), "A");
429 multi_user_window_manager()->SetWindowOwner(window(2), "B");
430 multi_user_window_manager()->SetWindowOwner(window(3), "B");
431 ShowWindowForUserNoUserTransition(window(2), "A");
432 ShowWindowForUserNoUserTransition(window(3), "A");
433 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
435 // Hiding a window should be respected - no matter if it is owned by that user
436 // owned by someone else but shown on that desktop - or not owned.
440 EXPECT_EQ("H[A], S[A], H[B,A], S[B,A], H[]", GetStatus());
442 // Flipping to another user and back should preserve all show / hide states.
443 multi_user_window_manager()->ActiveUserChanged("B");
444 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], H[]", GetStatus());
446 multi_user_window_manager()->ActiveUserChanged("A");
447 EXPECT_EQ("H[A], S[A], H[B,A], S[B,A], H[]", GetStatus());
449 // After making them visible and switching fore and back everything should be
454 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
456 multi_user_window_manager()->ActiveUserChanged("B");
457 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus());
459 multi_user_window_manager()->ActiveUserChanged("A");
460 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
462 // Now test that making windows visible through "normal operation" while the
463 // user's desktop is hidden leads to the correct result.
464 multi_user_window_manager()->ActiveUserChanged("B");
465 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus());
469 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus());
470 multi_user_window_manager()->ActiveUserChanged("A");
471 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
474 // Check that minimizing a window which is owned by another user will move it
475 // back and gets restored upon switching back to the original user.
476 TEST_F(MultiUserWindowManagerChromeOSTest, MinimizeChangesOwnershipBack) {
477 SetUpForThisManyWindows(4);
478 multi_user_window_manager()->SetWindowOwner(window(0), "A");
479 multi_user_window_manager()->SetWindowOwner(window(1), "B");
480 multi_user_window_manager()->SetWindowOwner(window(2), "B");
481 ShowWindowForUserNoUserTransition(window(1), "A");
482 EXPECT_EQ("S[A], S[B,A], H[B], S[]", GetStatus());
483 EXPECT_TRUE(multi_user_window_manager()->IsWindowOnDesktopOfUser(window(1),
485 wm::GetWindowState(window(1))->Minimize();
486 // At this time the window is still on the desktop of that user, but the user
487 // does not have a way to get to it.
488 EXPECT_EQ("S[A], H[B,A], H[B], S[]", GetStatus());
489 EXPECT_TRUE(multi_user_window_manager()->IsWindowOnDesktopOfUser(window(1),
491 EXPECT_TRUE(wm::GetWindowState(window(1))->IsMinimized());
492 // Change to user B and make sure that minimizing does not change anything.
493 multi_user_window_manager()->ActiveUserChanged("B");
494 EXPECT_EQ("H[A], S[B], S[B], S[]", GetStatus());
495 EXPECT_FALSE(wm::GetWindowState(window(1))->IsMinimized());
498 // Check that we cannot transfer the ownership of a minimized window.
499 TEST_F(MultiUserWindowManagerChromeOSTest, MinimizeSuppressesViewTransfer) {
500 SetUpForThisManyWindows(1);
501 multi_user_window_manager()->SetWindowOwner(window(0), "A");
502 wm::GetWindowState(window(0))->Minimize();
503 EXPECT_EQ("H[A]", GetStatus());
505 // Try to transfer the window to user B - which should get ignored.
506 ShowWindowForUserNoUserTransition(window(0), "B");
507 EXPECT_EQ("H[A]", GetStatus());
510 // Testing that the activation state changes to the active window.
511 TEST_F(MultiUserWindowManagerChromeOSTest, ActiveWindowTests) {
512 SetUpForThisManyWindows(4);
514 aura::client::ActivationClient* activation_client =
515 aura::client::GetActivationClient(window(0)->GetRootWindow());
517 // Set some windows to the active owner.
518 multi_user_window_manager()->SetWindowOwner(window(0), "A");
519 multi_user_window_manager()->SetWindowOwner(window(1), "A");
520 multi_user_window_manager()->SetWindowOwner(window(2), "B");
521 multi_user_window_manager()->SetWindowOwner(window(3), "B");
522 EXPECT_EQ("S[A], S[A], H[B], H[B]", GetStatus());
524 // Set the active window for user A to be #1
525 activation_client->ActivateWindow(window(1));
527 // Change to user B and make sure that one of its windows is active.
528 multi_user_window_manager()->ActiveUserChanged("B");
529 EXPECT_EQ("H[A], H[A], S[B], S[B]", GetStatus());
530 EXPECT_TRUE(window(3) == activation_client->GetActiveWindow() ||
531 window(2) == activation_client->GetActiveWindow());
532 // Set the active window for user B now to be #2
533 activation_client->ActivateWindow(window(2));
535 multi_user_window_manager()->ActiveUserChanged("A");
536 EXPECT_EQ(window(1), activation_client->GetActiveWindow());
538 multi_user_window_manager()->ActiveUserChanged("B");
539 EXPECT_EQ(window(2), activation_client->GetActiveWindow());
541 multi_user_window_manager()->ActiveUserChanged("C");
542 EXPECT_EQ(NULL, activation_client->GetActiveWindow());
544 // Now test that a minimized window stays minimized upon switch and back.
545 multi_user_window_manager()->ActiveUserChanged("A");
546 wm::GetWindowState(window(0))->Minimize();
548 multi_user_window_manager()->ActiveUserChanged("B");
549 multi_user_window_manager()->ActiveUserChanged("A");
550 EXPECT_TRUE(wm::GetWindowState(window(0))->IsMinimized());
551 EXPECT_EQ(window(1), activation_client->GetActiveWindow());
554 // Test that Transient windows are handled properly.
555 TEST_F(MultiUserWindowManagerChromeOSTest, TransientWindows) {
556 SetUpForThisManyWindows(10);
558 // We create a hierarchy like this:
559 // 0 (A) 4 (B) 7 (-) - The top level owned/not owned windows
561 // 1 5 - 6 8 - Transient child of the owned windows.
563 // 2 9 - A transtient child of a transient child.
566 multi_user_window_manager()->SetWindowOwner(window(0), "A");
567 multi_user_window_manager()->SetWindowOwner(window(4), "B");
568 ::wm::AddTransientChild(window(0), window(1));
569 // We first attach 2->3 and then 1->2 to see that the ownership gets
570 // properly propagated through the sub tree upon assigning.
571 ::wm::AddTransientChild(window(2), window(3));
572 ::wm::AddTransientChild(window(1), window(2));
573 ::wm::AddTransientChild(window(4), window(5));
574 ::wm::AddTransientChild(window(4), window(6));
575 ::wm::AddTransientChild(window(7), window(8));
576 ::wm::AddTransientChild(window(7), window(9));
578 // By now the hierarchy should have updated itself to show all windows of A
579 // and hide all windows of B. Unowned windows should remain in what ever state
581 EXPECT_EQ("S[A], S[], S[], S[], H[B], H[], H[], S[], S[], S[]", GetStatus());
583 // Trying to show a hidden transient window shouldn't change anything for now.
586 EXPECT_EQ("S[A], S[], S[], S[], H[B], H[], H[], S[], S[], S[]", GetStatus());
588 // Hiding on the other hand a shown window should work and hide also its
589 // children. Note that hide will have an immediate impact on itself and all
590 // transient children. It furthermore should remember this state when the
591 // transient children are removed from its owner later on.
594 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], H[], S[], S[], H[]", GetStatus());
596 // Switching users and switch back should return to the previous state.
597 multi_user_window_manager()->ActiveUserChanged("B");
598 EXPECT_EQ("H[A], H[], H[], H[], S[B], S[], S[], S[], S[], H[]", GetStatus());
599 multi_user_window_manager()->ActiveUserChanged("A");
600 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], H[], S[], S[], H[]", GetStatus());
602 // Removing a window from its transient parent should return to the previously
603 // set visibility state.
604 // Note: Window2 was explicitly hidden above and that state should remain.
605 // Note furthermore that Window3 should also be hidden since it was hidden
606 // implicitly by hiding Window2.
607 // set hidden above).
608 // 0 (A) 4 (B) 7 (-) 2(-) 3 (-) 6(-)
613 ::wm::RemoveTransientChild(window(2), window(3));
614 ::wm::RemoveTransientChild(window(4), window(6));
615 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], S[], S[], S[], H[]", GetStatus());
616 // Before we leave we need to reverse all transient window ownerships.
617 ::wm::RemoveTransientChild(window(0), window(1));
618 ::wm::RemoveTransientChild(window(1), window(2));
619 ::wm::RemoveTransientChild(window(4), window(5));
620 ::wm::RemoveTransientChild(window(7), window(8));
621 ::wm::RemoveTransientChild(window(7), window(9));
624 // Test that the initial visibility state gets remembered.
625 TEST_F(MultiUserWindowManagerChromeOSTest, PreserveInitialVisibility) {
626 SetUpForThisManyWindows(4);
628 // Set our initial show state before we assign an owner.
633 EXPECT_EQ("S[], H[], S[], H[]", GetStatus());
635 // First test: The show state gets preserved upon user switch.
636 multi_user_window_manager()->SetWindowOwner(window(0), "A");
637 multi_user_window_manager()->SetWindowOwner(window(1), "A");
638 multi_user_window_manager()->SetWindowOwner(window(2), "B");
639 multi_user_window_manager()->SetWindowOwner(window(3), "B");
640 EXPECT_EQ("S[A], H[A], H[B], H[B]", GetStatus());
641 multi_user_window_manager()->ActiveUserChanged("B");
642 EXPECT_EQ("H[A], H[A], S[B], H[B]", GetStatus());
643 multi_user_window_manager()->ActiveUserChanged("A");
644 EXPECT_EQ("S[A], H[A], H[B], H[B]", GetStatus());
646 // Second test: Transferring the window to another desktop preserves the
648 ShowWindowForUserNoUserTransition(window(0), "B");
649 ShowWindowForUserNoUserTransition(window(1), "B");
650 ShowWindowForUserNoUserTransition(window(2), "A");
651 ShowWindowForUserNoUserTransition(window(3), "A");
652 EXPECT_EQ("H[A,B], H[A,B], S[B,A], H[B,A]", GetStatus());
653 multi_user_window_manager()->ActiveUserChanged("B");
654 EXPECT_EQ("S[A,B], H[A,B], H[B,A], H[B,A]", GetStatus());
655 multi_user_window_manager()->ActiveUserChanged("A");
656 EXPECT_EQ("H[A,B], H[A,B], S[B,A], H[B,A]", GetStatus());
659 // Test that in case of an activated maximize mode, windows from other users get
660 // maximized after a user switch.
661 TEST_F(MultiUserWindowManagerChromeOSTest, MaximizeModeInteraction) {
662 SetUpForThisManyWindows(2);
664 multi_user_window_manager()->SetWindowOwner(window(0), "A");
665 multi_user_window_manager()->SetWindowOwner(window(1), "B");
667 EXPECT_FALSE(wm::GetWindowState(window(0))->IsMaximized());
668 EXPECT_FALSE(wm::GetWindowState(window(1))->IsMaximized());
670 ash::MaximizeModeWindowManager* manager = CreateMaximizeModeWindowManager();
671 ASSERT_TRUE(manager);
673 EXPECT_TRUE(wm::GetWindowState(window(0))->IsMaximized());
674 EXPECT_FALSE(wm::GetWindowState(window(1))->IsMaximized());
676 // After we start switching to B, the windows of user B should maximize.
677 StartUserTransitionAnimation("B");
679 EXPECT_TRUE(wm::GetWindowState(window(0))->IsMaximized());
680 EXPECT_TRUE(wm::GetWindowState(window(1))->IsMaximized());
683 // Test that a system modal dialog will switch to the desktop of the owning
685 TEST_F(MultiUserWindowManagerChromeOSTest, SwitchUsersUponModalityChange) {
686 SetUpForThisManyWindows(1);
687 session_state_delegate()->SwitchActiveUser("a");
689 // Making the window system modal should not change anything.
690 MakeWindowSystemModal(window(0));
691 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
693 // Making the window owned by user B should switch users.
694 multi_user_window_manager()->SetWindowOwner(window(0), "b");
695 EXPECT_EQ("b", session_state_delegate()->GetActiveUserInfo()->GetUserID());
698 // Test that a system modal dialog will not switch desktop if active user has
700 TEST_F(MultiUserWindowManagerChromeOSTest, DontSwitchUsersUponModalityChange) {
701 SetUpForThisManyWindows(1);
702 session_state_delegate()->SwitchActiveUser("a");
704 // Making the window system modal should not change anything.
705 MakeWindowSystemModal(window(0));
706 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
708 // Making the window owned by user a should not switch users.
709 multi_user_window_manager()->SetWindowOwner(window(0), "a");
710 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
713 // Test that a system modal dialog will not switch if shown on correct desktop
714 // but owned by another user.
715 TEST_F(MultiUserWindowManagerChromeOSTest,
716 DontSwitchUsersUponModalityChangeWhenShownButNotOwned) {
717 SetUpForThisManyWindows(1);
718 session_state_delegate()->SwitchActiveUser("a");
721 multi_user_window_manager()->SetWindowOwner(window(0), "b");
722 ShowWindowForUserNoUserTransition(window(0), "a");
723 MakeWindowSystemModal(window(0));
724 // Showing the window should trigger no user switch.
726 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
729 // Test that a system modal dialog will switch if shown on incorrect desktop but
730 // even if owned by current user.
731 TEST_F(MultiUserWindowManagerChromeOSTest,
732 SwitchUsersUponModalityChangeWhenShownButNotOwned) {
733 SetUpForThisManyWindows(1);
734 session_state_delegate()->SwitchActiveUser("a");
737 multi_user_window_manager()->SetWindowOwner(window(0), "a");
738 ShowWindowForUserNoUserTransition(window(0), "b");
739 MakeWindowSystemModal(window(0));
740 // Showing the window should trigger a user switch.
742 EXPECT_EQ("b", session_state_delegate()->GetActiveUserInfo()->GetUserID());
745 // Test that using the full user switch animations are working as expected.
746 TEST_F(MultiUserWindowManagerChromeOSTest, FullUserSwitchAnimationTests) {
747 SetUpForThisManyWindows(3);
748 // Turn the use of delays and animation on.
749 multi_user_window_manager()->SetAnimationSpeedForTest(
750 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
751 // Set some owners and make sure we got what we asked for.
752 multi_user_window_manager()->SetWindowOwner(window(0), "A");
753 multi_user_window_manager()->SetWindowOwner(window(1), "B");
754 multi_user_window_manager()->SetWindowOwner(window(2), "C");
755 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
756 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
758 // Switch the user fore and back and see that the results are correct.
759 SwitchUserAndWaitForAnimation("B");
761 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
762 EXPECT_EQ("B", GetOwnersOfVisibleWindowsAsString());
764 SwitchUserAndWaitForAnimation("A");
766 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
768 // Switch the user quickly to another user and before the animation is done
769 // switch back and see that this works.
770 multi_user_window_manager()->ActiveUserChanged("B");
771 // With the start of the animation B should become visible.
772 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
773 // Check that after switching to C, C is fully visible.
774 SwitchUserAndWaitForAnimation("C");
775 EXPECT_EQ("H[A], H[B], S[C]", GetStatus());
778 // Make sure that we do not crash upon shutdown when an animation is pending and
779 // a shutdown happens.
780 TEST_F(MultiUserWindowManagerChromeOSTest, SystemShutdownWithActiveAnimation) {
781 SetUpForThisManyWindows(2);
782 // Turn the use of delays and animation on.
783 multi_user_window_manager()->SetAnimationSpeedForTest(
784 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
785 // Set some owners and make sure we got what we asked for.
786 multi_user_window_manager()->SetWindowOwner(window(0), "A");
787 multi_user_window_manager()->SetWindowOwner(window(1), "B");
788 StartUserTransitionAnimation("B");
789 // We don't do anything more here - the animations are pending and with the
790 // shutdown of the framework the animations should get cancelled. If not a
791 // crash would happen.
794 // Test that using the full user switch, the animations are transitioning as
795 // we expect them to in all animation steps.
796 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationSteps) {
797 SetUpForThisManyWindows(3);
798 // Turn the use of delays and animation on.
799 multi_user_window_manager()->SetAnimationSpeedForTest(
800 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
801 // Set some owners and make sure we got what we asked for.
802 multi_user_window_manager()->SetWindowOwner(window(0), "A");
803 multi_user_window_manager()->SetWindowOwner(window(1), "B");
804 multi_user_window_manager()->SetWindowOwner(window(2), "C");
805 EXPECT_FALSE(CoversScreen(window(0)));
806 EXPECT_FALSE(CoversScreen(window(1)));
807 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
808 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
809 EXPECT_NE(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
810 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(
811 window(0)->GetRootWindow()));
812 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
814 // Start the animation and see that the old window is becoming invisible, the
815 // new one visible, the background starts transitionining and the shelf hides.
816 StartUserTransitionAnimation("B");
817 EXPECT_EQ("->B", GetWallaperUserIdForTest());
818 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
819 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
820 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
821 EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
822 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(
823 window(0)->GetRootWindow()));
825 // Staring the next step should show the shelf again, but there are many
826 // subsystems missing (preferences system, ChromeLauncherController, ...)
827 // which should set the shelf to its users state. Since that isn't there we
828 // can only make sure that it stays where it is.
829 AdvanceUserTransitionAnimation();
830 EXPECT_EQ("->B", GetWallaperUserIdForTest());
831 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
832 EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
833 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(
834 window(0)->GetRootWindow()));
836 // After the finalize the animation of the wallpaper should be finished.
837 AdvanceUserTransitionAnimation();
838 EXPECT_EQ("B", GetWallaperUserIdForTest());
841 // Test that the screen coverage is properly determined.
842 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsScreenCoverage) {
843 SetUpForThisManyWindows(3);
844 // Maximizing, fully covering the screen by bounds or fullscreen mode should
845 // make CoversScreen return true.
846 wm::GetWindowState(window(0))->Maximize();
847 window(1)->SetBounds(gfx::Rect(0, 0, 3000, 3000));
849 EXPECT_TRUE(CoversScreen(window(0)));
850 EXPECT_TRUE(CoversScreen(window(1)));
851 EXPECT_FALSE(CoversScreen(window(2)));
853 ash::wm::WMEvent event(ash::wm::WM_EVENT_FULLSCREEN);
854 wm::GetWindowState(window(2))->OnWMEvent(&event);
855 EXPECT_TRUE(CoversScreen(window(2)));
858 // Test that switching from a desktop which has a maximized window to a desktop
859 // which has no maximized window will produce the proper animation.
860 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsMaximizeToNormal) {
861 SetUpForThisManyWindows(3);
862 // Turn the use of delays and animation on.
863 multi_user_window_manager()->SetAnimationSpeedForTest(
864 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
865 // Set some owners and make sure we got what we asked for.
866 multi_user_window_manager()->SetWindowOwner(window(0), "A");
867 wm::GetWindowState(window(0))->Maximize();
868 multi_user_window_manager()->SetWindowOwner(window(1), "B");
869 multi_user_window_manager()->SetWindowOwner(window(2), "C");
870 EXPECT_TRUE(CoversScreen(window(0)));
871 EXPECT_FALSE(CoversScreen(window(1)));
872 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
873 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
874 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
876 // Start the animation and see that the new background is immediately set.
877 StartUserTransitionAnimation("B");
878 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
879 EXPECT_EQ("B", GetWallaperUserIdForTest());
880 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
881 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
883 // The next step will not change anything.
884 AdvanceUserTransitionAnimation();
885 EXPECT_EQ("B", GetWallaperUserIdForTest());
886 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
887 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
889 // The final step will also not have any visible impact.
890 AdvanceUserTransitionAnimation();
891 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
892 EXPECT_EQ("B", GetWallaperUserIdForTest());
893 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
894 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
897 // Test that switching from a desktop which has a normal window to a desktop
898 // which has a maximized window will produce the proper animation.
899 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsNormalToMaximized) {
900 SetUpForThisManyWindows(3);
901 // Turn the use of delays and animation on.
902 multi_user_window_manager()->SetAnimationSpeedForTest(
903 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
904 // Set some owners and make sure we got what we asked for.
905 multi_user_window_manager()->SetWindowOwner(window(0), "A");
906 multi_user_window_manager()->SetWindowOwner(window(1), "B");
907 wm::GetWindowState(window(1))->Maximize();
908 multi_user_window_manager()->SetWindowOwner(window(2), "C");
909 EXPECT_FALSE(CoversScreen(window(0)));
910 EXPECT_TRUE(CoversScreen(window(1)));
911 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
912 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
913 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
915 // Start the animation and see that the old window is becoming invisible, the
916 // new one visible and the background remains as is.
917 StartUserTransitionAnimation("B");
918 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
919 EXPECT_EQ("", GetWallaperUserIdForTest());
920 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
921 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
923 // The next step will not change anything.
924 AdvanceUserTransitionAnimation();
925 EXPECT_EQ("", GetWallaperUserIdForTest());
926 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
927 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
929 // The final step however will switch the background.
930 AdvanceUserTransitionAnimation();
931 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
932 EXPECT_EQ("B", GetWallaperUserIdForTest());
933 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
934 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
937 // Test that switching from a desktop which has a maximized window to a desktop
938 // which has a maximized window will produce the proper animation.
939 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsMaximizedToMaximized) {
940 SetUpForThisManyWindows(3);
941 // Turn the use of delays and animation on.
942 multi_user_window_manager()->SetAnimationSpeedForTest(
943 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
944 // Set some owners and make sure we got what we asked for.
945 multi_user_window_manager()->SetWindowOwner(window(0), "A");
946 wm::GetWindowState(window(0))->Maximize();
947 multi_user_window_manager()->SetWindowOwner(window(1), "B");
948 wm::GetWindowState(window(1))->Maximize();
949 multi_user_window_manager()->SetWindowOwner(window(2), "C");
950 EXPECT_TRUE(CoversScreen(window(0)));
951 EXPECT_TRUE(CoversScreen(window(1)));
952 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
953 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
954 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
956 // Start the animation and see that the old window is staying visible, the
957 // new one slowly visible and the background changes immediately.
958 StartUserTransitionAnimation("B");
959 EXPECT_EQ("S[A], S[B], H[C]", GetStatus());
960 EXPECT_EQ("B", GetWallaperUserIdForTest());
961 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
962 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
964 // The next step will not change anything.
965 AdvanceUserTransitionAnimation();
966 EXPECT_EQ("B", GetWallaperUserIdForTest());
967 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
968 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
970 // The final step however will hide the old window.
971 AdvanceUserTransitionAnimation();
972 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
973 EXPECT_EQ("B", GetWallaperUserIdForTest());
974 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
975 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
977 // Switching back will preserve the z-order by instantly showing the new
978 // window, hiding the layer above it and switching instantly the wallpaper.
979 StartUserTransitionAnimation("A");
980 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
981 EXPECT_EQ("A", GetWallaperUserIdForTest());
982 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
983 EXPECT_EQ(0.0f, window(1)->layer()->GetTargetOpacity());
985 // The next step will not change anything.
986 AdvanceUserTransitionAnimation();
987 EXPECT_EQ("A", GetWallaperUserIdForTest());
988 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
989 EXPECT_EQ(0.0f, window(1)->layer()->GetTargetOpacity());
991 // The final step is also not changing anything to the status.
992 AdvanceUserTransitionAnimation();
993 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
994 EXPECT_EQ("A", GetWallaperUserIdForTest());
995 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
996 EXPECT_EQ(0.0f, window(1)->layer()->GetTargetOpacity());
999 // Test that showing a window for another user also switches the desktop.
1000 TEST_F(MultiUserWindowManagerChromeOSTest, ShowForUserSwitchesDesktop) {
1001 SetUpForThisManyWindows(3);
1002 multi_user_window_manager()->ActiveUserChanged("a");
1003 session_state_delegate()->SwitchActiveUser("a");
1005 // Set some owners and make sure we got what we asked for.
1006 multi_user_window_manager()->SetWindowOwner(window(0), "a");
1007 multi_user_window_manager()->SetWindowOwner(window(1), "b");
1008 multi_user_window_manager()->SetWindowOwner(window(2), "c");
1009 EXPECT_EQ("S[a], H[b], H[c]", GetStatus());
1011 // SetWindowOwner should not have changed the active user.
1012 EXPECT_EQ("a", GetAndValidateCurrentUserFromSessionStateObserver());
1014 // Check that teleporting the window of the currently active user will
1015 // teleport to the new desktop.
1016 multi_user_window_manager()->ShowWindowForUser(window(0), "b");
1017 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
1018 EXPECT_EQ("S[a,b], S[b], H[c]", GetStatus());
1020 // Check that teleporting a window from a currently inactive user will not
1021 // trigger a switch.
1022 multi_user_window_manager()->ShowWindowForUser(window(2), "a");
1023 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
1024 EXPECT_EQ("S[a,b], S[b], H[c,a]", GetStatus());
1025 multi_user_window_manager()->ShowWindowForUser(window(2), "b");
1026 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
1027 EXPECT_EQ("S[a,b], S[b], S[c,b]", GetStatus());
1029 // Check that teleporting back will also change the desktop.
1030 multi_user_window_manager()->ShowWindowForUser(window(2), "c");
1031 EXPECT_EQ("c", GetAndValidateCurrentUserFromSessionStateObserver());
1032 EXPECT_EQ("H[a,b], H[b], S[c]", GetStatus());