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.
6 #include "ash/shell_window_ids.h"
7 #include "ash/test/ash_test_base.h"
8 #include "ash/test/test_session_state_delegate.h"
9 #include "ash/test/test_shell_delegate.h"
10 #include "ash/wm/window_state.h"
11 #include "base/command_line.h"
12 #include "base/compiler_specific.h"
13 #include "base/logging.h"
14 #include "base/strings/string_util.h"
15 #include "base/time/time.h"
16 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
17 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/test/base/testing_profile.h"
20 #include "ui/aura/client/activation_client.h"
21 #include "ui/aura/client/aura_constants.h"
22 #include "ui/aura/root_window.h"
23 #include "ui/base/ui_base_types.h"
24 #include "ui/views/corewm/window_util.h"
29 // A test class for preparing the chrome::MultiUserWindowManager. It creates
30 // various windows and instantiates the chrome::MultiUserWindowManager.
31 class MultiUserWindowManagerChromeOSTest : public AshTestBase {
33 MultiUserWindowManagerChromeOSTest()
34 : multi_user_window_manager_(NULL),
35 session_state_delegate_(NULL) {}
37 virtual void SetUp() OVERRIDE;
38 virtual void TearDown() OVERRIDE;
41 // Set up the test environment for this many windows.
42 void SetUpForThisManyWindows(int windows);
44 // Switch the user and wait until the animation is finished.
45 void SwitchUserAndWaitForAnimation(const std::string& user_id) {
46 multi_user_window_manager_->ActiveUserChanged(user_id);
47 base::TimeTicks now = base::TimeTicks::Now();
48 while (multi_user_window_manager_->IsAnimationRunningForTest()) {
49 // This should never take longer then a second.
50 ASSERT_GE(1000, (base::TimeTicks::Now() - now).InMilliseconds());
51 base::MessageLoop::current()->RunUntilIdle();
55 // Return the window with the given index.
56 aura::Window* window(size_t index) {
57 DCHECK(index < window_.size());
58 return window_[index];
61 // Delete the window at the given index, and set the referefence to NULL.
62 void delete_window_at(size_t index) {
63 delete window_[index];
64 window_[index] = NULL;
67 // The accessor to the MultiWindowManager.
68 chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager() {
69 return multi_user_window_manager_;
72 // Returns a list of all open windows in the following form:
73 // "<H(idden)/S(hown)/D(eleted)>[<Owner>[,<shownForUser>]], .."
74 // Like: "S[B], .." would mean that window#0 is shown and belongs to user B.
75 // or "S[B,A], .." would mean that window#0 is shown, belongs to B but is
76 // shown by A, and "D,..." would mean that window#0 is deleted.
77 std::string GetStatus();
79 // Returns a test-friendly string format of GetOwnersOfVisibleWindows().
80 std::string GetOwnersOfVisibleWindowsAsString();
82 TestSessionStateDelegate* session_state_delegate() {
83 return session_state_delegate_;
86 // Make a window system modal.
87 void MakeWindowSystemModal(aura::Window* window) {
88 aura::Window* system_modal_container =
89 window->GetRootWindow()->GetChildById(
90 ash::internal::kShellWindowId_SystemModalContainer);
91 system_modal_container->AddChild(window);
94 void ShowWindowForUserNoUserTransition(aura::Window* window,
95 const std::string& user_id) {
96 multi_user_window_manager_->ShowWindowForUserIntern(window, user_id);
99 // The test session state observer does not automatically call the window
100 // manager. This function gets the current user from it and also sets it to
101 // the multi user window manager.
102 std::string GetAndValidateCurrentUserFromSessionStateObserver() {
103 const std::string& user = session_state_delegate()->get_activated_user();
104 if (user != multi_user_window_manager_->GetCurrentUserForTest())
105 multi_user_window_manager()->ActiveUserChanged(user);
110 // These get created for each session.
111 std::vector<aura::Window*> window_;
113 // The instance of the MultiUserWindowManager.
114 chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager_;
116 // The session state delegate.
117 ash::test::TestSessionStateDelegate* session_state_delegate_;
119 DISALLOW_COPY_AND_ASSIGN(MultiUserWindowManagerChromeOSTest);
122 void MultiUserWindowManagerChromeOSTest::SetUp() {
123 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kMultiProfiles);
124 AshTestBase::SetUp();
125 session_state_delegate_ =
126 static_cast<TestSessionStateDelegate*> (
127 ash::Shell::GetInstance()->session_state_delegate());
130 void MultiUserWindowManagerChromeOSTest::SetUpForThisManyWindows(int windows) {
131 DCHECK(!window_.size());
132 for (int i = 0; i < windows; i++) {
133 window_.push_back(CreateTestWindowInShellWithId(i));
136 multi_user_window_manager_ = new chrome::MultiUserWindowManagerChromeOS("A");
137 multi_user_window_manager_->SetAnimationsForTest(true);
138 chrome::MultiUserWindowManager::SetInstanceForTest(multi_user_window_manager_,
139 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED);
140 EXPECT_TRUE(multi_user_window_manager_);
143 void MultiUserWindowManagerChromeOSTest::TearDown() {
144 // Since the AuraTestBase is needed to create our assets, we have to
145 // also delete them before we tear it down.
146 while (!window_.empty()) {
147 delete *(window_.begin());
148 window_.erase(window_.begin());
151 chrome::MultiUserWindowManager::DeleteInstance();
152 AshTestBase::TearDown();
155 std::string MultiUserWindowManagerChromeOSTest::GetStatus() {
157 for (size_t i = 0; i < window_.size(); i++) {
164 s += window(i)->IsVisible() ? "S[" : "H[";
165 const std::string& owner =
166 multi_user_window_manager_->GetWindowOwner(window(i));
168 const std::string& presenter =
169 multi_user_window_manager_->GetUserPresentingWindow(window(i));
170 if (!owner.empty() && owner != presenter) {
180 MultiUserWindowManagerChromeOSTest::GetOwnersOfVisibleWindowsAsString() {
181 std::set<std::string> owners;
182 multi_user_window_manager_->GetOwnersOfVisibleWindows(&owners);
184 std::vector<std::string> owner_list;
185 owner_list.insert(owner_list.begin(), owners.begin(), owners.end());
186 return JoinString(owner_list, ' ');
189 // Testing basic assumptions like default state and existence of manager.
190 TEST_F(MultiUserWindowManagerChromeOSTest, BasicTests) {
191 SetUpForThisManyWindows(3);
192 // Check the basic assumptions: All windows are visible and there is no owner.
193 EXPECT_EQ("S[], S[], S[]", GetStatus());
194 EXPECT_TRUE(multi_user_window_manager());
195 EXPECT_EQ(multi_user_window_manager(),
196 chrome::MultiUserWindowManager::GetInstance());
197 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
199 // The owner of an unowned window should be empty and it should be shown on
201 EXPECT_EQ("", multi_user_window_manager()->GetWindowOwner(window(0)));
203 multi_user_window_manager()->GetUserPresentingWindow(window(0)));
205 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A"));
207 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B"));
209 // Set the owner of one window should remember it as such. It should only be
210 // drawn on the owners desktop - not on any other.
211 multi_user_window_manager()->SetWindowOwner(window(0), "A");
212 EXPECT_EQ("A", multi_user_window_manager()->GetWindowOwner(window(0)));
214 multi_user_window_manager()->GetUserPresentingWindow(window(0)));
216 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A"));
218 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B"));
220 // Overriding it with another state should show it on the other user's
222 ShowWindowForUserNoUserTransition(window(0), "B");
223 EXPECT_EQ("A", multi_user_window_manager()->GetWindowOwner(window(0)));
225 multi_user_window_manager()->GetUserPresentingWindow(window(0)));
227 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A"));
229 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B"));
232 // Testing simple owner changes.
233 TEST_F(MultiUserWindowManagerChromeOSTest, OwnerTests) {
234 SetUpForThisManyWindows(5);
235 // Set some windows to the active owner.
236 multi_user_window_manager()->SetWindowOwner(window(0), "A");
237 EXPECT_EQ("S[A], S[], S[], S[], S[]", GetStatus());
238 multi_user_window_manager()->SetWindowOwner(window(2), "A");
239 EXPECT_EQ("S[A], S[], S[A], S[], S[]", GetStatus());
241 // Set some windows to an inactive owner. Note that the windows should hide.
242 multi_user_window_manager()->SetWindowOwner(window(1), "B");
243 EXPECT_EQ("S[A], H[B], S[A], S[], S[]", GetStatus());
244 multi_user_window_manager()->SetWindowOwner(window(3), "B");
245 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
247 // Assume that the user has now changed to C - which should show / hide
249 multi_user_window_manager()->ActiveUserChanged("C");
250 EXPECT_EQ("H[A], H[B], H[A], H[B], S[]", GetStatus());
252 // If someone tries to show an inactive window it should only work if it can
253 // be shown / hidden.
254 multi_user_window_manager()->ActiveUserChanged("A");
255 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
257 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
259 EXPECT_EQ("S[A], H[B], H[A], H[B], S[]", GetStatus());
261 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
264 TEST_F(MultiUserWindowManagerChromeOSTest, CloseWindowTests) {
265 SetUpForThisManyWindows(1);
266 multi_user_window_manager()->SetWindowOwner(window(0), "B");
267 EXPECT_EQ("H[B]", GetStatus());
268 ShowWindowForUserNoUserTransition(window(0), "A");
269 EXPECT_EQ("S[B,A]", GetStatus());
270 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
271 EXPECT_EQ("B", GetOwnersOfVisibleWindowsAsString());
273 aura::Window* to_be_deleted = window(0);
275 EXPECT_EQ(std::string("A"),
276 multi_user_window_manager()->GetUserPresentingWindow(
278 EXPECT_EQ(std::string("B"),
279 multi_user_window_manager()->GetWindowOwner(
285 EXPECT_EQ("D", GetStatus());
286 EXPECT_EQ("", GetOwnersOfVisibleWindowsAsString());
287 // There should be no owner anymore for that window and the shared windows
288 // should be gone as well.
289 EXPECT_EQ(std::string(),
290 multi_user_window_manager()->GetUserPresentingWindow(
292 EXPECT_EQ(std::string(),
293 multi_user_window_manager()->GetWindowOwner(
297 TEST_F(MultiUserWindowManagerChromeOSTest, SharedWindowTests) {
298 SetUpForThisManyWindows(5);
299 // Set some owners and make sure we got what we asked for.
300 multi_user_window_manager()->SetWindowOwner(window(0), "A");
301 multi_user_window_manager()->SetWindowOwner(window(1), "A");
302 multi_user_window_manager()->SetWindowOwner(window(2), "B");
303 multi_user_window_manager()->SetWindowOwner(window(3), "B");
304 multi_user_window_manager()->SetWindowOwner(window(4), "C");
305 EXPECT_EQ("S[A], S[A], H[B], H[B], H[C]", GetStatus());
306 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
307 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
309 // For all following tests we override window 2 to be shown by user B.
310 ShowWindowForUserNoUserTransition(window(1), "B");
312 // Change window 3 between two users and see that it changes
313 // accordingly (or not).
314 ShowWindowForUserNoUserTransition(window(2), "A");
315 EXPECT_EQ("S[A], H[A,B], S[B,A], H[B], H[C]", GetStatus());
316 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
317 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString());
318 ShowWindowForUserNoUserTransition(window(2), "C");
319 EXPECT_EQ("S[A], H[A,B], H[B,C], H[B], H[C]", GetStatus());
320 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
321 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
323 // Switch the users and see that the results are correct.
324 multi_user_window_manager()->ActiveUserChanged("B");
325 EXPECT_EQ("H[A], S[A,B], H[B,C], S[B], H[C]", GetStatus());
326 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString());
327 multi_user_window_manager()->ActiveUserChanged("C");
328 EXPECT_EQ("H[A], H[A,B], S[B,C], H[B], S[C]", GetStatus());
329 EXPECT_EQ("B C", GetOwnersOfVisibleWindowsAsString());
331 // Showing on the desktop of the already owning user should have no impact.
332 ShowWindowForUserNoUserTransition(window(4), "C");
333 EXPECT_EQ("H[A], H[A,B], S[B,C], H[B], S[C]", GetStatus());
334 EXPECT_EQ("B C", GetOwnersOfVisibleWindowsAsString());
336 // Changing however a shown window back to the original owner should hide it.
337 ShowWindowForUserNoUserTransition(window(2), "B");
338 EXPECT_EQ("H[A], H[A,B], H[B], H[B], S[C]", GetStatus());
339 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
340 EXPECT_EQ("C", GetOwnersOfVisibleWindowsAsString());
342 // And the change should be "permanent" - switching somewhere else and coming
344 multi_user_window_manager()->ActiveUserChanged("B");
345 EXPECT_EQ("H[A], S[A,B], S[B], S[B], H[C]", GetStatus());
346 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString());
347 multi_user_window_manager()->ActiveUserChanged("C");
348 EXPECT_EQ("H[A], H[A,B], H[B], H[B], S[C]", GetStatus());
349 EXPECT_EQ("C", GetOwnersOfVisibleWindowsAsString());
351 // After switching window 2 back to its original desktop, all desktops should
353 ShowWindowForUserNoUserTransition(window(1), "A");
354 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
357 // Make sure that adding a window to another desktop does not cause harm.
358 TEST_F(MultiUserWindowManagerChromeOSTest, DoubleSharedWindowTests) {
359 SetUpForThisManyWindows(1);
360 multi_user_window_manager()->SetWindowOwner(window(0), "B");
362 // Add two references to the same window.
363 ShowWindowForUserNoUserTransition(window(0), "A");
364 ShowWindowForUserNoUserTransition(window(0), "A");
365 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
370 EXPECT_EQ("D", GetStatus());
371 // There should be no shares anymore open.
372 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
375 // Tests that the user's desktop visibility changes get respected. These tests
376 // are required to make sure that our usage of the same feature for showing and
377 // hiding does not interfere with the "normal operation".
378 TEST_F(MultiUserWindowManagerChromeOSTest, PreserveWindowVisibilityTests) {
379 SetUpForThisManyWindows(5);
380 // Set some owners and make sure we got what we asked for.
381 // Note that we try to cover all combinations in one go.
382 multi_user_window_manager()->SetWindowOwner(window(0), "A");
383 multi_user_window_manager()->SetWindowOwner(window(1), "A");
384 multi_user_window_manager()->SetWindowOwner(window(2), "B");
385 multi_user_window_manager()->SetWindowOwner(window(3), "B");
386 ShowWindowForUserNoUserTransition(window(2), "A");
387 ShowWindowForUserNoUserTransition(window(3), "A");
388 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
390 // Hiding a window should be respected - no matter if it is owned by that user
391 // owned by someone else but shown on that desktop - or not owned.
395 EXPECT_EQ("H[A], S[A], H[B,A], S[B,A], H[]", GetStatus());
397 // Flipping to another user and back should preserve all show / hide states.
398 multi_user_window_manager()->ActiveUserChanged("B");
399 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], H[]", GetStatus());
401 multi_user_window_manager()->ActiveUserChanged("A");
402 EXPECT_EQ("H[A], S[A], H[B,A], S[B,A], H[]", GetStatus());
404 // After making them visible and switching fore and back everything should be
409 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
411 multi_user_window_manager()->ActiveUserChanged("B");
412 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus());
414 multi_user_window_manager()->ActiveUserChanged("A");
415 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
417 // Now test that making windows visible through "normal operation" while the
418 // user's desktop is hidden leads to the correct result.
419 multi_user_window_manager()->ActiveUserChanged("B");
420 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus());
424 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus());
425 multi_user_window_manager()->ActiveUserChanged("A");
426 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
429 // Check that minimizing a window which is owned by another user will move it
430 // back and gets restored upon switching back to the original user.
431 TEST_F(MultiUserWindowManagerChromeOSTest, MinimizeChangesOwnershipBack) {
432 SetUpForThisManyWindows(4);
433 multi_user_window_manager()->SetWindowOwner(window(0), "A");
434 multi_user_window_manager()->SetWindowOwner(window(1), "B");
435 multi_user_window_manager()->SetWindowOwner(window(2), "B");
436 ShowWindowForUserNoUserTransition(window(1), "A");
437 EXPECT_EQ("S[A], S[B,A], H[B], S[]", GetStatus());
438 EXPECT_TRUE(multi_user_window_manager()->IsWindowOnDesktopOfUser(window(1),
440 wm::GetWindowState(window(1))->Minimize();
441 // At this time the window is still on the desktop of that user, but the user
442 // does not have a way to get to it.
443 EXPECT_EQ("S[A], H[B,A], H[B], S[]", GetStatus());
444 EXPECT_TRUE(multi_user_window_manager()->IsWindowOnDesktopOfUser(window(1),
446 EXPECT_TRUE(wm::GetWindowState(window(1))->IsMinimized());
447 // Change to user B and make sure that minimizing does not change anything.
448 multi_user_window_manager()->ActiveUserChanged("B");
449 EXPECT_EQ("H[A], S[B], S[B], S[]", GetStatus());
450 EXPECT_FALSE(wm::GetWindowState(window(1))->IsMinimized());
453 // Check that we cannot transfer the ownership of a minimized window.
454 TEST_F(MultiUserWindowManagerChromeOSTest, MinimizeSuppressesViewTransfer) {
455 SetUpForThisManyWindows(1);
456 multi_user_window_manager()->SetWindowOwner(window(0), "A");
457 wm::GetWindowState(window(0))->Minimize();
458 EXPECT_EQ("H[A]", GetStatus());
460 // Try to transfer the window to user B - which should get ignored.
461 ShowWindowForUserNoUserTransition(window(0), "B");
462 EXPECT_EQ("H[A]", GetStatus());
465 // Testing that the activation state changes to the active window.
466 TEST_F(MultiUserWindowManagerChromeOSTest, ActiveWindowTests) {
467 SetUpForThisManyWindows(4);
469 aura::client::ActivationClient* activation_client =
470 aura::client::GetActivationClient(window(0)->GetRootWindow());
472 // Set some windows to the active owner.
473 multi_user_window_manager()->SetWindowOwner(window(0), "A");
474 multi_user_window_manager()->SetWindowOwner(window(1), "A");
475 multi_user_window_manager()->SetWindowOwner(window(2), "B");
476 multi_user_window_manager()->SetWindowOwner(window(3), "B");
477 EXPECT_EQ("S[A], S[A], H[B], H[B]", GetStatus());
479 // Set the active window for user A to be #1
480 activation_client->ActivateWindow(window(1));
482 // Change to user B and make sure that one of its windows is active.
483 multi_user_window_manager()->ActiveUserChanged("B");
484 EXPECT_EQ("H[A], H[A], S[B], S[B]", GetStatus());
485 EXPECT_TRUE(window(3) == activation_client->GetActiveWindow() ||
486 window(2) == activation_client->GetActiveWindow());
487 // Set the active window for user B now to be #2
488 activation_client->ActivateWindow(window(2));
490 multi_user_window_manager()->ActiveUserChanged("A");
491 EXPECT_EQ(window(1), activation_client->GetActiveWindow());
493 multi_user_window_manager()->ActiveUserChanged("B");
494 EXPECT_EQ(window(2), activation_client->GetActiveWindow());
496 multi_user_window_manager()->ActiveUserChanged("C");
497 EXPECT_EQ(NULL, activation_client->GetActiveWindow());
499 // Now test that a minimized window stays minimized upon switch and back.
500 multi_user_window_manager()->ActiveUserChanged("A");
501 wm::GetWindowState(window(0))->Minimize();
503 multi_user_window_manager()->ActiveUserChanged("B");
504 multi_user_window_manager()->ActiveUserChanged("A");
505 EXPECT_TRUE(wm::GetWindowState(window(0))->IsMinimized());
506 EXPECT_EQ(window(1), activation_client->GetActiveWindow());
509 // Test that Transient windows are handled properly.
510 TEST_F(MultiUserWindowManagerChromeOSTest, TransientWindows) {
511 SetUpForThisManyWindows(10);
513 // We create a hierarchy like this:
514 // 0 (A) 4 (B) 7 (-) - The top level owned/not owned windows
516 // 1 5 - 6 8 - Transient child of the owned windows.
518 // 2 9 - A transtient child of a transient child.
521 multi_user_window_manager()->SetWindowOwner(window(0), "A");
522 multi_user_window_manager()->SetWindowOwner(window(4), "B");
523 views::corewm::AddTransientChild(window(0), window(1));
524 // We first attach 2->3 and then 1->2 to see that the ownership gets
525 // properly propagated through the sub tree upon assigning.
526 views::corewm::AddTransientChild(window(2), window(3));
527 views::corewm::AddTransientChild(window(1), window(2));
528 views::corewm::AddTransientChild(window(4), window(5));
529 views::corewm::AddTransientChild(window(4), window(6));
530 views::corewm::AddTransientChild(window(7), window(8));
531 views::corewm::AddTransientChild(window(7), window(9));
533 // By now the hierarchy should have updated itself to show all windows of A
534 // and hide all windows of B. Unowned windows should remain in what ever state
536 EXPECT_EQ("S[A], S[], S[], S[], H[B], H[], H[], S[], S[], S[]", GetStatus());
538 // Trying to show a hidden transient window shouldn't change anything for now.
541 EXPECT_EQ("S[A], S[], S[], S[], H[B], H[], H[], S[], S[], S[]", GetStatus());
543 // Hiding on the other hand a shown window should work and hide also its
544 // children. Note that hide will have an immediate impact on itself and all
545 // transient children. It furthermore should remember this state when the
546 // transient children are removed from its owner later on.
549 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], H[], S[], S[], H[]", GetStatus());
551 // Switching users and switch back should return to the previous state.
552 multi_user_window_manager()->ActiveUserChanged("B");
553 EXPECT_EQ("H[A], H[], H[], H[], S[B], S[], S[], S[], S[], H[]", GetStatus());
554 multi_user_window_manager()->ActiveUserChanged("A");
555 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], H[], S[], S[], H[]", GetStatus());
557 // Removing a window from its transient parent should return to the previously
558 // set visibility state.
559 // Note: Window2 was explicitly hidden above and that state should remain.
560 // Note furthermore that Window3 should also be hidden since it was hidden
561 // implicitly by hiding Window2.
562 // set hidden above).
563 // 0 (A) 4 (B) 7 (-) 2(-) 3 (-) 6(-)
568 views::corewm::RemoveTransientChild(window(2), window(3));
569 views::corewm::RemoveTransientChild(window(4), window(6));
570 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], S[], S[], S[], H[]", GetStatus());
571 // Before we leave we need to reverse all transient window ownerships.
572 views::corewm::RemoveTransientChild(window(0), window(1));
573 views::corewm::RemoveTransientChild(window(1), window(2));
574 views::corewm::RemoveTransientChild(window(4), window(5));
575 views::corewm::RemoveTransientChild(window(7), window(8));
576 views::corewm::RemoveTransientChild(window(7), window(9));
579 // Test that the initial visibility state gets remembered.
580 TEST_F(MultiUserWindowManagerChromeOSTest, PreserveInitialVisibility) {
581 SetUpForThisManyWindows(4);
583 // Set our initial show state before we assign an owner.
588 EXPECT_EQ("S[], H[], S[], H[]", GetStatus());
590 // First test: The show state gets preserved upon user switch.
591 multi_user_window_manager()->SetWindowOwner(window(0), "A");
592 multi_user_window_manager()->SetWindowOwner(window(1), "A");
593 multi_user_window_manager()->SetWindowOwner(window(2), "B");
594 multi_user_window_manager()->SetWindowOwner(window(3), "B");
595 EXPECT_EQ("S[A], H[A], H[B], H[B]", GetStatus());
596 multi_user_window_manager()->ActiveUserChanged("B");
597 EXPECT_EQ("H[A], H[A], S[B], H[B]", GetStatus());
598 multi_user_window_manager()->ActiveUserChanged("A");
599 EXPECT_EQ("S[A], H[A], H[B], H[B]", GetStatus());
601 // Second test: Transferring the window to another desktop preserves the
603 ShowWindowForUserNoUserTransition(window(0), "B");
604 ShowWindowForUserNoUserTransition(window(1), "B");
605 ShowWindowForUserNoUserTransition(window(2), "A");
606 ShowWindowForUserNoUserTransition(window(3), "A");
607 EXPECT_EQ("H[A,B], H[A,B], S[B,A], H[B,A]", GetStatus());
608 multi_user_window_manager()->ActiveUserChanged("B");
609 EXPECT_EQ("S[A,B], H[A,B], H[B,A], H[B,A]", GetStatus());
610 multi_user_window_manager()->ActiveUserChanged("A");
611 EXPECT_EQ("H[A,B], H[A,B], S[B,A], H[B,A]", GetStatus());
614 // Test that a system modal dialog will switch to the desktop of the owning
616 TEST_F(MultiUserWindowManagerChromeOSTest, SwitchUsersUponModalityChange) {
617 SetUpForThisManyWindows(1);
618 session_state_delegate()->SwitchActiveUser("a");
620 // Making the window system modal should not change anything.
621 MakeWindowSystemModal(window(0));
622 EXPECT_EQ("a", session_state_delegate()->get_activated_user());
624 // Making the window owned by user B should switch users.
625 multi_user_window_manager()->SetWindowOwner(window(0), "b");
626 EXPECT_EQ("b", session_state_delegate()->get_activated_user());
629 // Test that a system modal dialog will not switch desktop if active user has
631 TEST_F(MultiUserWindowManagerChromeOSTest, DontSwitchUsersUponModalityChange) {
632 SetUpForThisManyWindows(1);
633 session_state_delegate()->SwitchActiveUser("a");
635 // Making the window system modal should not change anything.
636 MakeWindowSystemModal(window(0));
637 EXPECT_EQ("a", session_state_delegate()->get_activated_user());
639 // Making the window owned by user a should not switch users.
640 multi_user_window_manager()->SetWindowOwner(window(0), "a");
641 EXPECT_EQ("a", session_state_delegate()->get_activated_user());
644 // Test that a system modal dialog will not switch if shown on correct desktop
645 // but owned by another user.
646 TEST_F(MultiUserWindowManagerChromeOSTest,
647 DontSwitchUsersUponModalityChangeWhenShownButNotOwned) {
648 SetUpForThisManyWindows(1);
649 session_state_delegate()->SwitchActiveUser("a");
652 multi_user_window_manager()->SetWindowOwner(window(0), "b");
653 ShowWindowForUserNoUserTransition(window(0), "a");
654 MakeWindowSystemModal(window(0));
655 // Showing the window should trigger no user switch.
657 EXPECT_EQ("a", session_state_delegate()->get_activated_user());
660 // Test that a system modal dialog will switch if shown on incorrect desktop but
661 // even if owned by current user.
662 TEST_F(MultiUserWindowManagerChromeOSTest,
663 SwitchUsersUponModalityChangeWhenShownButNotOwned) {
664 SetUpForThisManyWindows(1);
665 session_state_delegate()->SwitchActiveUser("a");
668 multi_user_window_manager()->SetWindowOwner(window(0), "a");
669 ShowWindowForUserNoUserTransition(window(0), "b");
670 MakeWindowSystemModal(window(0));
671 // Showing the window should trigger a user switch.
673 EXPECT_EQ("b", session_state_delegate()->get_activated_user());
676 // Test that using the full user switch animations are working as expected.
677 TEST_F(MultiUserWindowManagerChromeOSTest, FullUserSwitchAnimationTests) {
678 SetUpForThisManyWindows(3);
679 // Turn the use of delays and animation on.
680 multi_user_window_manager()->SetAnimationsForTest(false);
681 // Set some owners and make sure we got what we asked for.
682 multi_user_window_manager()->SetWindowOwner(window(0), "A");
683 multi_user_window_manager()->SetWindowOwner(window(1), "B");
684 multi_user_window_manager()->SetWindowOwner(window(2), "C");
685 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
686 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
688 // Switch the user fore and back and see that the results are correct.
689 SwitchUserAndWaitForAnimation("B");
691 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
692 EXPECT_EQ("B", GetOwnersOfVisibleWindowsAsString());
694 SwitchUserAndWaitForAnimation("A");
696 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
698 // Switch the user quickly to another user and before the animation is done
699 // switch back and see that this works.
700 multi_user_window_manager()->ActiveUserChanged("B");
701 // Check that at this time we have nothing visible (in the middle of the
703 EXPECT_EQ("H[A], H[B], H[C]", GetStatus());
704 // Check that after switching to C, C is fully visible.
705 SwitchUserAndWaitForAnimation("C");
706 EXPECT_EQ("H[A], H[B], S[C]", GetStatus());
709 // Test that showing a window for another user also switches the desktop.
710 TEST_F(MultiUserWindowManagerChromeOSTest, ShowForUserSwitchesDesktop) {
711 SetUpForThisManyWindows(3);
712 multi_user_window_manager()->ActiveUserChanged("a");
713 session_state_delegate()->SwitchActiveUser("a");
715 // Set some owners and make sure we got what we asked for.
716 multi_user_window_manager()->SetWindowOwner(window(0), "a");
717 multi_user_window_manager()->SetWindowOwner(window(1), "b");
718 multi_user_window_manager()->SetWindowOwner(window(2), "c");
719 EXPECT_EQ("S[a], H[b], H[c]", GetStatus());
721 // SetWindowOwner should not have changed the active user.
722 EXPECT_EQ("a", GetAndValidateCurrentUserFromSessionStateObserver());
724 // Check that teleporting the window of the currently active user will
725 // teleport to the new desktop.
726 multi_user_window_manager()->ShowWindowForUser(window(0), "b");
727 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
728 EXPECT_EQ("S[a,b], S[b], H[c]", GetStatus());
730 // Check that teleporting a window from a currently inactive user will not
732 multi_user_window_manager()->ShowWindowForUser(window(2), "a");
733 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
734 EXPECT_EQ("S[a,b], S[b], H[c,a]", GetStatus());
735 multi_user_window_manager()->ShowWindowForUser(window(2), "b");
736 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
737 EXPECT_EQ("S[a,b], S[b], S[c,b]", GetStatus());
739 // Check that teleporting back will also change the desktop.
740 multi_user_window_manager()->ShowWindowForUser(window(2), "c");
741 EXPECT_EQ("c", GetAndValidateCurrentUserFromSessionStateObserver());
742 EXPECT_EQ("H[a,b], H[b], S[c]", GetStatus());