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/window_state.h"
12 #include "ash/wm/wm_event.h"
13 #include "base/command_line.h"
14 #include "base/compiler_specific.h"
15 #include "base/logging.h"
16 #include "base/strings/string_util.h"
17 #include "base/time/time.h"
18 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
19 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
20 #include "chrome/browser/ui/ash/multi_user/user_switch_animator_chromeos.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/test/base/testing_profile.h"
23 #include "ui/aura/client/aura_constants.h"
24 #include "ui/aura/window_event_dispatcher.h"
25 #include "ui/base/ui_base_types.h"
26 #include "ui/wm/core/window_util.h"
27 #include "ui/wm/public/activation_client.h"
32 // A test class for preparing the chrome::MultiUserWindowManager. It creates
33 // various windows and instantiates the chrome::MultiUserWindowManager.
34 class MultiUserWindowManagerChromeOSTest : public AshTestBase {
36 MultiUserWindowManagerChromeOSTest()
37 : multi_user_window_manager_(NULL),
38 session_state_delegate_(NULL) {}
40 virtual void SetUp() OVERRIDE;
41 virtual void TearDown() OVERRIDE;
44 // Set up the test environment for this many windows.
45 void SetUpForThisManyWindows(int windows);
47 // Switch the user and wait until the animation is finished.
48 void SwitchUserAndWaitForAnimation(const std::string& user_id) {
49 multi_user_window_manager_->ActiveUserChanged(user_id);
50 base::TimeTicks now = base::TimeTicks::Now();
51 while (multi_user_window_manager_->IsAnimationRunningForTest()) {
52 // This should never take longer then a second.
53 ASSERT_GE(1000, (base::TimeTicks::Now() - now).InMilliseconds());
54 base::MessageLoop::current()->RunUntilIdle();
58 // Return the window with the given index.
59 aura::Window* window(size_t index) {
60 DCHECK(index < window_.size());
61 return window_[index];
64 // Delete the window at the given index, and set the referefence to NULL.
65 void delete_window_at(size_t index) {
66 delete window_[index];
67 window_[index] = NULL;
70 // The accessor to the MultiWindowManager.
71 chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager() {
72 return multi_user_window_manager_;
75 // Returns a list of all open windows in the following form:
76 // "<H(idden)/S(hown)/D(eleted)>[<Owner>[,<shownForUser>]], .."
77 // Like: "S[B], .." would mean that window#0 is shown and belongs to user B.
78 // or "S[B,A], .." would mean that window#0 is shown, belongs to B but is
79 // shown by A, and "D,..." would mean that window#0 is deleted.
80 std::string GetStatus();
82 // Returns a test-friendly string format of GetOwnersOfVisibleWindows().
83 std::string GetOwnersOfVisibleWindowsAsString();
85 TestSessionStateDelegate* session_state_delegate() {
86 return session_state_delegate_;
89 // Make a window system modal.
90 void MakeWindowSystemModal(aura::Window* window) {
91 aura::Window* system_modal_container =
92 window->GetRootWindow()->GetChildById(
93 ash::kShellWindowId_SystemModalContainer);
94 system_modal_container->AddChild(window);
97 void ShowWindowForUserNoUserTransition(aura::Window* window,
98 const std::string& user_id) {
99 multi_user_window_manager_->ShowWindowForUserIntern(window, user_id);
102 // The test session state observer does not automatically call the window
103 // manager. This function gets the current user from it and also sets it to
104 // the multi user window manager.
105 std::string GetAndValidateCurrentUserFromSessionStateObserver() {
106 const std::string& user =
107 session_state_delegate()->GetActiveUserInfo()->GetUserID();
108 if (user != multi_user_window_manager_->GetCurrentUserForTest())
109 multi_user_window_manager()->ActiveUserChanged(user);
113 // Initiate a user transition.
114 void StartUserTransitionAnimation(const std::string& user_id) {
115 multi_user_window_manager_->ActiveUserChanged(user_id);
118 // Call next animation step.
119 void AdvanceUserTransitionAnimation() {
120 multi_user_window_manager_->animation_->AdvanceUserTransitionAnimation();
123 // Return the user id of the wallpaper which is currently set.
124 const std::string& GetWallaperUserIdForTest() {
125 return multi_user_window_manager_->animation_->wallpaper_user_id_for_test();
128 // Returns true if the given window covers the screen.
129 bool CoversScreen(aura::Window* window) {
130 return chrome::UserSwichAnimatorChromeOS::CoversScreen(
135 // These get created for each session.
136 std::vector<aura::Window*> window_;
138 // The instance of the MultiUserWindowManager.
139 chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager_;
141 // The session state delegate.
142 ash::test::TestSessionStateDelegate* session_state_delegate_;
144 DISALLOW_COPY_AND_ASSIGN(MultiUserWindowManagerChromeOSTest);
147 void MultiUserWindowManagerChromeOSTest::SetUp() {
148 CommandLine::ForCurrentProcess()->AppendSwitch(switches::kMultiProfiles);
149 AshTestBase::SetUp();
150 session_state_delegate_ =
151 static_cast<TestSessionStateDelegate*> (
152 ash::Shell::GetInstance()->session_state_delegate());
153 session_state_delegate_->AddUser("a");
154 session_state_delegate_->AddUser("b");
155 session_state_delegate_->AddUser("c");
158 void MultiUserWindowManagerChromeOSTest::SetUpForThisManyWindows(int windows) {
159 DCHECK(!window_.size());
160 for (int i = 0; i < windows; i++) {
161 window_.push_back(CreateTestWindowInShellWithId(i));
164 multi_user_window_manager_ = new chrome::MultiUserWindowManagerChromeOS("A");
165 multi_user_window_manager_->SetAnimationSpeedForTest(
166 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_DISABLED);
167 chrome::MultiUserWindowManager::SetInstanceForTest(multi_user_window_manager_,
168 chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED);
169 EXPECT_TRUE(multi_user_window_manager_);
172 void MultiUserWindowManagerChromeOSTest::TearDown() {
173 // Since the AuraTestBase is needed to create our assets, we have to
174 // also delete them before we tear it down.
175 while (!window_.empty()) {
176 delete *(window_.begin());
177 window_.erase(window_.begin());
180 chrome::MultiUserWindowManager::DeleteInstance();
181 AshTestBase::TearDown();
184 std::string MultiUserWindowManagerChromeOSTest::GetStatus() {
186 for (size_t i = 0; i < window_.size(); i++) {
193 s += window(i)->IsVisible() ? "S[" : "H[";
194 const std::string& owner =
195 multi_user_window_manager_->GetWindowOwner(window(i));
197 const std::string& presenter =
198 multi_user_window_manager_->GetUserPresentingWindow(window(i));
199 if (!owner.empty() && owner != presenter) {
209 MultiUserWindowManagerChromeOSTest::GetOwnersOfVisibleWindowsAsString() {
210 std::set<std::string> owners;
211 multi_user_window_manager_->GetOwnersOfVisibleWindows(&owners);
213 std::vector<std::string> owner_list;
214 owner_list.insert(owner_list.begin(), owners.begin(), owners.end());
215 return JoinString(owner_list, ' ');
218 // Testing basic assumptions like default state and existence of manager.
219 TEST_F(MultiUserWindowManagerChromeOSTest, BasicTests) {
220 SetUpForThisManyWindows(3);
221 // Check the basic assumptions: All windows are visible and there is no owner.
222 EXPECT_EQ("S[], S[], S[]", GetStatus());
223 EXPECT_TRUE(multi_user_window_manager());
224 EXPECT_EQ(multi_user_window_manager(),
225 chrome::MultiUserWindowManager::GetInstance());
226 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
228 // The owner of an unowned window should be empty and it should be shown on
230 EXPECT_EQ("", multi_user_window_manager()->GetWindowOwner(window(0)));
232 multi_user_window_manager()->GetUserPresentingWindow(window(0)));
234 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A"));
236 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B"));
238 // Set the owner of one window should remember it as such. It should only be
239 // drawn on the owners desktop - not on any other.
240 multi_user_window_manager()->SetWindowOwner(window(0), "A");
241 EXPECT_EQ("A", multi_user_window_manager()->GetWindowOwner(window(0)));
243 multi_user_window_manager()->GetUserPresentingWindow(window(0)));
245 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A"));
247 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B"));
249 // Overriding it with another state should show it on the other user's
251 ShowWindowForUserNoUserTransition(window(0), "B");
252 EXPECT_EQ("A", multi_user_window_manager()->GetWindowOwner(window(0)));
254 multi_user_window_manager()->GetUserPresentingWindow(window(0)));
256 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "A"));
258 multi_user_window_manager()->IsWindowOnDesktopOfUser(window(0), "B"));
261 // Testing simple owner changes.
262 TEST_F(MultiUserWindowManagerChromeOSTest, OwnerTests) {
263 SetUpForThisManyWindows(5);
264 // Set some windows to the active owner.
265 multi_user_window_manager()->SetWindowOwner(window(0), "A");
266 EXPECT_EQ("S[A], S[], S[], S[], S[]", GetStatus());
267 multi_user_window_manager()->SetWindowOwner(window(2), "A");
268 EXPECT_EQ("S[A], S[], S[A], S[], S[]", GetStatus());
270 // Set some windows to an inactive owner. Note that the windows should hide.
271 multi_user_window_manager()->SetWindowOwner(window(1), "B");
272 EXPECT_EQ("S[A], H[B], S[A], S[], S[]", GetStatus());
273 multi_user_window_manager()->SetWindowOwner(window(3), "B");
274 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
276 // Assume that the user has now changed to C - which should show / hide
278 multi_user_window_manager()->ActiveUserChanged("C");
279 EXPECT_EQ("H[A], H[B], H[A], H[B], S[]", GetStatus());
281 // If someone tries to show an inactive window it should only work if it can
282 // be shown / hidden.
283 multi_user_window_manager()->ActiveUserChanged("A");
284 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
286 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
288 EXPECT_EQ("S[A], H[B], H[A], H[B], S[]", GetStatus());
290 EXPECT_EQ("S[A], H[B], S[A], H[B], S[]", GetStatus());
293 TEST_F(MultiUserWindowManagerChromeOSTest, CloseWindowTests) {
294 SetUpForThisManyWindows(1);
295 multi_user_window_manager()->SetWindowOwner(window(0), "B");
296 EXPECT_EQ("H[B]", GetStatus());
297 ShowWindowForUserNoUserTransition(window(0), "A");
298 EXPECT_EQ("S[B,A]", GetStatus());
299 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
300 EXPECT_EQ("B", GetOwnersOfVisibleWindowsAsString());
302 aura::Window* to_be_deleted = window(0);
304 EXPECT_EQ(std::string("A"),
305 multi_user_window_manager()->GetUserPresentingWindow(
307 EXPECT_EQ(std::string("B"),
308 multi_user_window_manager()->GetWindowOwner(
314 EXPECT_EQ("D", GetStatus());
315 EXPECT_EQ("", GetOwnersOfVisibleWindowsAsString());
316 // There should be no owner anymore for that window and the shared windows
317 // should be gone as well.
318 EXPECT_EQ(std::string(),
319 multi_user_window_manager()->GetUserPresentingWindow(
321 EXPECT_EQ(std::string(),
322 multi_user_window_manager()->GetWindowOwner(
326 TEST_F(MultiUserWindowManagerChromeOSTest, SharedWindowTests) {
327 SetUpForThisManyWindows(5);
328 // Set some owners and make sure we got what we asked for.
329 multi_user_window_manager()->SetWindowOwner(window(0), "A");
330 multi_user_window_manager()->SetWindowOwner(window(1), "A");
331 multi_user_window_manager()->SetWindowOwner(window(2), "B");
332 multi_user_window_manager()->SetWindowOwner(window(3), "B");
333 multi_user_window_manager()->SetWindowOwner(window(4), "C");
334 EXPECT_EQ("S[A], S[A], H[B], H[B], H[C]", GetStatus());
335 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
336 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
338 // For all following tests we override window 2 to be shown by user B.
339 ShowWindowForUserNoUserTransition(window(1), "B");
341 // Change window 3 between two users and see that it changes
342 // accordingly (or not).
343 ShowWindowForUserNoUserTransition(window(2), "A");
344 EXPECT_EQ("S[A], H[A,B], S[B,A], H[B], H[C]", GetStatus());
345 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
346 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString());
347 ShowWindowForUserNoUserTransition(window(2), "C");
348 EXPECT_EQ("S[A], H[A,B], H[B,C], H[B], H[C]", GetStatus());
349 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
350 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
352 // Switch the users and see that the results are correct.
353 multi_user_window_manager()->ActiveUserChanged("B");
354 EXPECT_EQ("H[A], S[A,B], H[B,C], S[B], H[C]", GetStatus());
355 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString());
356 multi_user_window_manager()->ActiveUserChanged("C");
357 EXPECT_EQ("H[A], H[A,B], S[B,C], H[B], S[C]", GetStatus());
358 EXPECT_EQ("B C", GetOwnersOfVisibleWindowsAsString());
360 // Showing on the desktop of the already owning user should have no impact.
361 ShowWindowForUserNoUserTransition(window(4), "C");
362 EXPECT_EQ("H[A], H[A,B], S[B,C], H[B], S[C]", GetStatus());
363 EXPECT_EQ("B C", GetOwnersOfVisibleWindowsAsString());
365 // Changing however a shown window back to the original owner should hide it.
366 ShowWindowForUserNoUserTransition(window(2), "B");
367 EXPECT_EQ("H[A], H[A,B], H[B], H[B], S[C]", GetStatus());
368 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
369 EXPECT_EQ("C", GetOwnersOfVisibleWindowsAsString());
371 // And the change should be "permanent" - switching somewhere else and coming
373 multi_user_window_manager()->ActiveUserChanged("B");
374 EXPECT_EQ("H[A], S[A,B], S[B], S[B], H[C]", GetStatus());
375 EXPECT_EQ("A B", GetOwnersOfVisibleWindowsAsString());
376 multi_user_window_manager()->ActiveUserChanged("C");
377 EXPECT_EQ("H[A], H[A,B], H[B], H[B], S[C]", GetStatus());
378 EXPECT_EQ("C", GetOwnersOfVisibleWindowsAsString());
380 // After switching window 2 back to its original desktop, all desktops should
382 ShowWindowForUserNoUserTransition(window(1), "A");
383 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
386 // Make sure that adding a window to another desktop does not cause harm.
387 TEST_F(MultiUserWindowManagerChromeOSTest, DoubleSharedWindowTests) {
388 SetUpForThisManyWindows(1);
389 multi_user_window_manager()->SetWindowOwner(window(0), "B");
391 // Add two references to the same window.
392 ShowWindowForUserNoUserTransition(window(0), "A");
393 ShowWindowForUserNoUserTransition(window(0), "A");
394 EXPECT_TRUE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
399 EXPECT_EQ("D", GetStatus());
400 // There should be no shares anymore open.
401 EXPECT_FALSE(multi_user_window_manager()->AreWindowsSharedAmongUsers());
404 // Tests that the user's desktop visibility changes get respected. These tests
405 // are required to make sure that our usage of the same feature for showing and
406 // hiding does not interfere with the "normal operation".
407 TEST_F(MultiUserWindowManagerChromeOSTest, PreserveWindowVisibilityTests) {
408 SetUpForThisManyWindows(5);
409 // Set some owners and make sure we got what we asked for.
410 // Note that we try to cover all combinations in one go.
411 multi_user_window_manager()->SetWindowOwner(window(0), "A");
412 multi_user_window_manager()->SetWindowOwner(window(1), "A");
413 multi_user_window_manager()->SetWindowOwner(window(2), "B");
414 multi_user_window_manager()->SetWindowOwner(window(3), "B");
415 ShowWindowForUserNoUserTransition(window(2), "A");
416 ShowWindowForUserNoUserTransition(window(3), "A");
417 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
419 // Hiding a window should be respected - no matter if it is owned by that user
420 // owned by someone else but shown on that desktop - or not owned.
424 EXPECT_EQ("H[A], S[A], H[B,A], S[B,A], H[]", GetStatus());
426 // Flipping to another user and back should preserve all show / hide states.
427 multi_user_window_manager()->ActiveUserChanged("B");
428 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], H[]", GetStatus());
430 multi_user_window_manager()->ActiveUserChanged("A");
431 EXPECT_EQ("H[A], S[A], H[B,A], S[B,A], H[]", GetStatus());
433 // After making them visible and switching fore and back everything should be
438 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
440 multi_user_window_manager()->ActiveUserChanged("B");
441 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus());
443 multi_user_window_manager()->ActiveUserChanged("A");
444 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
446 // Now test that making windows visible through "normal operation" while the
447 // user's desktop is hidden leads to the correct result.
448 multi_user_window_manager()->ActiveUserChanged("B");
449 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus());
453 EXPECT_EQ("H[A], H[A], H[B,A], H[B,A], S[]", GetStatus());
454 multi_user_window_manager()->ActiveUserChanged("A");
455 EXPECT_EQ("S[A], S[A], S[B,A], S[B,A], S[]", GetStatus());
458 // Check that minimizing a window which is owned by another user will move it
459 // back and gets restored upon switching back to the original user.
460 TEST_F(MultiUserWindowManagerChromeOSTest, MinimizeChangesOwnershipBack) {
461 SetUpForThisManyWindows(4);
462 multi_user_window_manager()->SetWindowOwner(window(0), "A");
463 multi_user_window_manager()->SetWindowOwner(window(1), "B");
464 multi_user_window_manager()->SetWindowOwner(window(2), "B");
465 ShowWindowForUserNoUserTransition(window(1), "A");
466 EXPECT_EQ("S[A], S[B,A], H[B], S[]", GetStatus());
467 EXPECT_TRUE(multi_user_window_manager()->IsWindowOnDesktopOfUser(window(1),
469 wm::GetWindowState(window(1))->Minimize();
470 // At this time the window is still on the desktop of that user, but the user
471 // does not have a way to get to it.
472 EXPECT_EQ("S[A], H[B,A], H[B], S[]", GetStatus());
473 EXPECT_TRUE(multi_user_window_manager()->IsWindowOnDesktopOfUser(window(1),
475 EXPECT_TRUE(wm::GetWindowState(window(1))->IsMinimized());
476 // Change to user B and make sure that minimizing does not change anything.
477 multi_user_window_manager()->ActiveUserChanged("B");
478 EXPECT_EQ("H[A], S[B], S[B], S[]", GetStatus());
479 EXPECT_FALSE(wm::GetWindowState(window(1))->IsMinimized());
482 // Check that we cannot transfer the ownership of a minimized window.
483 TEST_F(MultiUserWindowManagerChromeOSTest, MinimizeSuppressesViewTransfer) {
484 SetUpForThisManyWindows(1);
485 multi_user_window_manager()->SetWindowOwner(window(0), "A");
486 wm::GetWindowState(window(0))->Minimize();
487 EXPECT_EQ("H[A]", GetStatus());
489 // Try to transfer the window to user B - which should get ignored.
490 ShowWindowForUserNoUserTransition(window(0), "B");
491 EXPECT_EQ("H[A]", GetStatus());
494 // Testing that the activation state changes to the active window.
495 TEST_F(MultiUserWindowManagerChromeOSTest, ActiveWindowTests) {
496 SetUpForThisManyWindows(4);
498 aura::client::ActivationClient* activation_client =
499 aura::client::GetActivationClient(window(0)->GetRootWindow());
501 // Set some windows to the active owner.
502 multi_user_window_manager()->SetWindowOwner(window(0), "A");
503 multi_user_window_manager()->SetWindowOwner(window(1), "A");
504 multi_user_window_manager()->SetWindowOwner(window(2), "B");
505 multi_user_window_manager()->SetWindowOwner(window(3), "B");
506 EXPECT_EQ("S[A], S[A], H[B], H[B]", GetStatus());
508 // Set the active window for user A to be #1
509 activation_client->ActivateWindow(window(1));
511 // Change to user B and make sure that one of its windows is active.
512 multi_user_window_manager()->ActiveUserChanged("B");
513 EXPECT_EQ("H[A], H[A], S[B], S[B]", GetStatus());
514 EXPECT_TRUE(window(3) == activation_client->GetActiveWindow() ||
515 window(2) == activation_client->GetActiveWindow());
516 // Set the active window for user B now to be #2
517 activation_client->ActivateWindow(window(2));
519 multi_user_window_manager()->ActiveUserChanged("A");
520 EXPECT_EQ(window(1), activation_client->GetActiveWindow());
522 multi_user_window_manager()->ActiveUserChanged("B");
523 EXPECT_EQ(window(2), activation_client->GetActiveWindow());
525 multi_user_window_manager()->ActiveUserChanged("C");
526 EXPECT_EQ(NULL, activation_client->GetActiveWindow());
528 // Now test that a minimized window stays minimized upon switch and back.
529 multi_user_window_manager()->ActiveUserChanged("A");
530 wm::GetWindowState(window(0))->Minimize();
532 multi_user_window_manager()->ActiveUserChanged("B");
533 multi_user_window_manager()->ActiveUserChanged("A");
534 EXPECT_TRUE(wm::GetWindowState(window(0))->IsMinimized());
535 EXPECT_EQ(window(1), activation_client->GetActiveWindow());
538 // Test that Transient windows are handled properly.
539 TEST_F(MultiUserWindowManagerChromeOSTest, TransientWindows) {
540 SetUpForThisManyWindows(10);
542 // We create a hierarchy like this:
543 // 0 (A) 4 (B) 7 (-) - The top level owned/not owned windows
545 // 1 5 - 6 8 - Transient child of the owned windows.
547 // 2 9 - A transtient child of a transient child.
550 multi_user_window_manager()->SetWindowOwner(window(0), "A");
551 multi_user_window_manager()->SetWindowOwner(window(4), "B");
552 ::wm::AddTransientChild(window(0), window(1));
553 // We first attach 2->3 and then 1->2 to see that the ownership gets
554 // properly propagated through the sub tree upon assigning.
555 ::wm::AddTransientChild(window(2), window(3));
556 ::wm::AddTransientChild(window(1), window(2));
557 ::wm::AddTransientChild(window(4), window(5));
558 ::wm::AddTransientChild(window(4), window(6));
559 ::wm::AddTransientChild(window(7), window(8));
560 ::wm::AddTransientChild(window(7), window(9));
562 // By now the hierarchy should have updated itself to show all windows of A
563 // and hide all windows of B. Unowned windows should remain in what ever state
565 EXPECT_EQ("S[A], S[], S[], S[], H[B], H[], H[], S[], S[], S[]", GetStatus());
567 // Trying to show a hidden transient window shouldn't change anything for now.
570 EXPECT_EQ("S[A], S[], S[], S[], H[B], H[], H[], S[], S[], S[]", GetStatus());
572 // Hiding on the other hand a shown window should work and hide also its
573 // children. Note that hide will have an immediate impact on itself and all
574 // transient children. It furthermore should remember this state when the
575 // transient children are removed from its owner later on.
578 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], H[], S[], S[], H[]", GetStatus());
580 // Switching users and switch back should return to the previous state.
581 multi_user_window_manager()->ActiveUserChanged("B");
582 EXPECT_EQ("H[A], H[], H[], H[], S[B], S[], S[], S[], S[], H[]", GetStatus());
583 multi_user_window_manager()->ActiveUserChanged("A");
584 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], H[], S[], S[], H[]", GetStatus());
586 // Removing a window from its transient parent should return to the previously
587 // set visibility state.
588 // Note: Window2 was explicitly hidden above and that state should remain.
589 // Note furthermore that Window3 should also be hidden since it was hidden
590 // implicitly by hiding Window2.
591 // set hidden above).
592 // 0 (A) 4 (B) 7 (-) 2(-) 3 (-) 6(-)
597 ::wm::RemoveTransientChild(window(2), window(3));
598 ::wm::RemoveTransientChild(window(4), window(6));
599 EXPECT_EQ("S[A], S[], H[], H[], H[B], H[], S[], S[], S[], H[]", GetStatus());
600 // Before we leave we need to reverse all transient window ownerships.
601 ::wm::RemoveTransientChild(window(0), window(1));
602 ::wm::RemoveTransientChild(window(1), window(2));
603 ::wm::RemoveTransientChild(window(4), window(5));
604 ::wm::RemoveTransientChild(window(7), window(8));
605 ::wm::RemoveTransientChild(window(7), window(9));
608 // Test that the initial visibility state gets remembered.
609 TEST_F(MultiUserWindowManagerChromeOSTest, PreserveInitialVisibility) {
610 SetUpForThisManyWindows(4);
612 // Set our initial show state before we assign an owner.
617 EXPECT_EQ("S[], H[], S[], H[]", GetStatus());
619 // First test: The show state gets preserved upon user switch.
620 multi_user_window_manager()->SetWindowOwner(window(0), "A");
621 multi_user_window_manager()->SetWindowOwner(window(1), "A");
622 multi_user_window_manager()->SetWindowOwner(window(2), "B");
623 multi_user_window_manager()->SetWindowOwner(window(3), "B");
624 EXPECT_EQ("S[A], H[A], H[B], H[B]", GetStatus());
625 multi_user_window_manager()->ActiveUserChanged("B");
626 EXPECT_EQ("H[A], H[A], S[B], H[B]", GetStatus());
627 multi_user_window_manager()->ActiveUserChanged("A");
628 EXPECT_EQ("S[A], H[A], H[B], H[B]", GetStatus());
630 // Second test: Transferring the window to another desktop preserves the
632 ShowWindowForUserNoUserTransition(window(0), "B");
633 ShowWindowForUserNoUserTransition(window(1), "B");
634 ShowWindowForUserNoUserTransition(window(2), "A");
635 ShowWindowForUserNoUserTransition(window(3), "A");
636 EXPECT_EQ("H[A,B], H[A,B], S[B,A], H[B,A]", GetStatus());
637 multi_user_window_manager()->ActiveUserChanged("B");
638 EXPECT_EQ("S[A,B], H[A,B], H[B,A], H[B,A]", GetStatus());
639 multi_user_window_manager()->ActiveUserChanged("A");
640 EXPECT_EQ("H[A,B], H[A,B], S[B,A], H[B,A]", GetStatus());
643 // Test that a system modal dialog will switch to the desktop of the owning
645 TEST_F(MultiUserWindowManagerChromeOSTest, SwitchUsersUponModalityChange) {
646 SetUpForThisManyWindows(1);
647 session_state_delegate()->SwitchActiveUser("a");
649 // Making the window system modal should not change anything.
650 MakeWindowSystemModal(window(0));
651 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
653 // Making the window owned by user B should switch users.
654 multi_user_window_manager()->SetWindowOwner(window(0), "b");
655 EXPECT_EQ("b", session_state_delegate()->GetActiveUserInfo()->GetUserID());
658 // Test that a system modal dialog will not switch desktop if active user has
660 TEST_F(MultiUserWindowManagerChromeOSTest, DontSwitchUsersUponModalityChange) {
661 SetUpForThisManyWindows(1);
662 session_state_delegate()->SwitchActiveUser("a");
664 // Making the window system modal should not change anything.
665 MakeWindowSystemModal(window(0));
666 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
668 // Making the window owned by user a should not switch users.
669 multi_user_window_manager()->SetWindowOwner(window(0), "a");
670 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
673 // Test that a system modal dialog will not switch if shown on correct desktop
674 // but owned by another user.
675 TEST_F(MultiUserWindowManagerChromeOSTest,
676 DontSwitchUsersUponModalityChangeWhenShownButNotOwned) {
677 SetUpForThisManyWindows(1);
678 session_state_delegate()->SwitchActiveUser("a");
681 multi_user_window_manager()->SetWindowOwner(window(0), "b");
682 ShowWindowForUserNoUserTransition(window(0), "a");
683 MakeWindowSystemModal(window(0));
684 // Showing the window should trigger no user switch.
686 EXPECT_EQ("a", session_state_delegate()->GetActiveUserInfo()->GetUserID());
689 // Test that a system modal dialog will switch if shown on incorrect desktop but
690 // even if owned by current user.
691 TEST_F(MultiUserWindowManagerChromeOSTest,
692 SwitchUsersUponModalityChangeWhenShownButNotOwned) {
693 SetUpForThisManyWindows(1);
694 session_state_delegate()->SwitchActiveUser("a");
697 multi_user_window_manager()->SetWindowOwner(window(0), "a");
698 ShowWindowForUserNoUserTransition(window(0), "b");
699 MakeWindowSystemModal(window(0));
700 // Showing the window should trigger a user switch.
702 EXPECT_EQ("b", session_state_delegate()->GetActiveUserInfo()->GetUserID());
705 // Test that using the full user switch animations are working as expected.
706 TEST_F(MultiUserWindowManagerChromeOSTest, FullUserSwitchAnimationTests) {
707 SetUpForThisManyWindows(3);
708 // Turn the use of delays and animation on.
709 multi_user_window_manager()->SetAnimationSpeedForTest(
710 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
711 // Set some owners and make sure we got what we asked for.
712 multi_user_window_manager()->SetWindowOwner(window(0), "A");
713 multi_user_window_manager()->SetWindowOwner(window(1), "B");
714 multi_user_window_manager()->SetWindowOwner(window(2), "C");
715 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
716 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
718 // Switch the user fore and back and see that the results are correct.
719 SwitchUserAndWaitForAnimation("B");
721 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
722 EXPECT_EQ("B", GetOwnersOfVisibleWindowsAsString());
724 SwitchUserAndWaitForAnimation("A");
726 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
728 // Switch the user quickly to another user and before the animation is done
729 // switch back and see that this works.
730 multi_user_window_manager()->ActiveUserChanged("B");
731 // With the start of the animation B should become visible.
732 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
733 // Check that after switching to C, C is fully visible.
734 SwitchUserAndWaitForAnimation("C");
735 EXPECT_EQ("H[A], H[B], S[C]", GetStatus());
738 // Make sure that we do not crash upon shutdown when an animation is pending and
739 // a shutdown happens.
740 TEST_F(MultiUserWindowManagerChromeOSTest, SystemShutdownWithActiveAnimation) {
741 SetUpForThisManyWindows(2);
742 // Turn the use of delays and animation on.
743 multi_user_window_manager()->SetAnimationSpeedForTest(
744 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
745 // Set some owners and make sure we got what we asked for.
746 multi_user_window_manager()->SetWindowOwner(window(0), "A");
747 multi_user_window_manager()->SetWindowOwner(window(1), "B");
748 StartUserTransitionAnimation("B");
749 // We don't do anything more here - the animations are pending and with the
750 // shutdown of the framework the animations should get cancelled. If not a
751 // crash would happen.
754 // Test that using the full user switch, the animations are transitioning as
755 // we expect them to in all animation steps.
756 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationSteps) {
757 SetUpForThisManyWindows(3);
758 // Turn the use of delays and animation on.
759 multi_user_window_manager()->SetAnimationSpeedForTest(
760 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
761 // Set some owners and make sure we got what we asked for.
762 multi_user_window_manager()->SetWindowOwner(window(0), "A");
763 multi_user_window_manager()->SetWindowOwner(window(1), "B");
764 multi_user_window_manager()->SetWindowOwner(window(2), "C");
765 EXPECT_FALSE(CoversScreen(window(0)));
766 EXPECT_FALSE(CoversScreen(window(1)));
767 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
768 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
769 EXPECT_NE(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
770 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(
771 window(0)->GetRootWindow()));
772 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
774 // Start the animation and see that the old window is becoming invisible, the
775 // new one visible, the background starts transitionining and the shelf hides.
776 StartUserTransitionAnimation("B");
777 EXPECT_EQ("->B", GetWallaperUserIdForTest());
778 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
779 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
780 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
781 EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
782 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(
783 window(0)->GetRootWindow()));
785 // Staring the next step should show the shelf again, but there are many
786 // subsystems missing (preferences system, ChromeLauncherController, ...)
787 // which should set the shelf to its users state. Since that isn't there we
788 // can only make sure that it stays where it is.
789 AdvanceUserTransitionAnimation();
790 EXPECT_EQ("->B", GetWallaperUserIdForTest());
791 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
792 EXPECT_EQ(ash::SHELF_AUTO_HIDE_ALWAYS_HIDDEN,
793 ash::Shell::GetInstance()->GetShelfAutoHideBehavior(
794 window(0)->GetRootWindow()));
796 // After the finalize the animation of the wallpaper should be finished.
797 AdvanceUserTransitionAnimation();
798 EXPECT_EQ("B", GetWallaperUserIdForTest());
801 // Test that the screen coverage is properly determined.
802 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsScreenCoverage) {
803 SetUpForThisManyWindows(3);
804 // Maximizing, fully covering the screen by bounds or fullscreen mode should
805 // make CoversScreen return true.
806 wm::GetWindowState(window(0))->Maximize();
807 window(1)->SetBounds(gfx::Rect(0, 0, 3000, 3000));
809 EXPECT_TRUE(CoversScreen(window(0)));
810 EXPECT_TRUE(CoversScreen(window(1)));
811 EXPECT_FALSE(CoversScreen(window(2)));
813 ash::wm::WMEvent event(ash::wm::WM_EVENT_FULLSCREEN);
814 wm::GetWindowState(window(2))->OnWMEvent(&event);
815 EXPECT_TRUE(CoversScreen(window(2)));
818 // Test that switching from a desktop which has a maximized window to a desktop
819 // which has no maximized window will produce the proper animation.
820 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsMaximizeToNormal) {
821 SetUpForThisManyWindows(3);
822 // Turn the use of delays and animation on.
823 multi_user_window_manager()->SetAnimationSpeedForTest(
824 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
825 // Set some owners and make sure we got what we asked for.
826 multi_user_window_manager()->SetWindowOwner(window(0), "A");
827 wm::GetWindowState(window(0))->Maximize();
828 multi_user_window_manager()->SetWindowOwner(window(1), "B");
829 multi_user_window_manager()->SetWindowOwner(window(2), "C");
830 EXPECT_TRUE(CoversScreen(window(0)));
831 EXPECT_FALSE(CoversScreen(window(1)));
832 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
833 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
834 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
836 // Start the animation and see that the new background is immediately set.
837 StartUserTransitionAnimation("B");
838 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
839 EXPECT_EQ("B", GetWallaperUserIdForTest());
840 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
841 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
843 // The next step will not change anything.
844 AdvanceUserTransitionAnimation();
845 EXPECT_EQ("B", GetWallaperUserIdForTest());
846 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
847 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
849 // The final step will also not have any visible impact.
850 AdvanceUserTransitionAnimation();
851 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
852 EXPECT_EQ("B", GetWallaperUserIdForTest());
853 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
854 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
857 // Test that switching from a desktop which has a normal window to a desktop
858 // which has a maximized window will produce the proper animation.
859 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsNormalToMaximized) {
860 SetUpForThisManyWindows(3);
861 // Turn the use of delays and animation on.
862 multi_user_window_manager()->SetAnimationSpeedForTest(
863 chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_FAST);
864 // Set some owners and make sure we got what we asked for.
865 multi_user_window_manager()->SetWindowOwner(window(0), "A");
866 multi_user_window_manager()->SetWindowOwner(window(1), "B");
867 wm::GetWindowState(window(1))->Maximize();
868 multi_user_window_manager()->SetWindowOwner(window(2), "C");
869 EXPECT_FALSE(CoversScreen(window(0)));
870 EXPECT_TRUE(CoversScreen(window(1)));
871 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
872 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
873 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
875 // Start the animation and see that the old window is becoming invisible, the
876 // new one visible and the background remains as is.
877 StartUserTransitionAnimation("B");
878 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
879 EXPECT_EQ("", 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("", GetWallaperUserIdForTest());
886 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
887 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
889 // The final step however will switch the background.
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 maximized window to a desktop
898 // which has a maximized window will produce the proper animation.
899 TEST_F(MultiUserWindowManagerChromeOSTest, AnimationStepsMaximizedToMaximized) {
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 wm::GetWindowState(window(0))->Maximize();
907 multi_user_window_manager()->SetWindowOwner(window(1), "B");
908 wm::GetWindowState(window(1))->Maximize();
909 multi_user_window_manager()->SetWindowOwner(window(2), "C");
910 EXPECT_TRUE(CoversScreen(window(0)));
911 EXPECT_TRUE(CoversScreen(window(1)));
912 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
913 EXPECT_EQ("A", GetOwnersOfVisibleWindowsAsString());
914 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
916 // Start the animation and see that the old window is staying visible, the
917 // new one slowly visible and the background changes immediately.
918 StartUserTransitionAnimation("B");
919 EXPECT_EQ("S[A], S[B], H[C]", GetStatus());
920 EXPECT_EQ("B", GetWallaperUserIdForTest());
921 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
922 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
924 // The next step will not change anything.
925 AdvanceUserTransitionAnimation();
926 EXPECT_EQ("B", GetWallaperUserIdForTest());
927 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
928 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
930 // The final step however will hide the old window.
931 AdvanceUserTransitionAnimation();
932 EXPECT_EQ("H[A], S[B], H[C]", GetStatus());
933 EXPECT_EQ("B", GetWallaperUserIdForTest());
934 EXPECT_EQ(0.0f, window(0)->layer()->GetTargetOpacity());
935 EXPECT_EQ(1.0f, window(1)->layer()->GetTargetOpacity());
937 // Switching back will preserve the z-order by instantly showing the new
938 // window, hiding the layer above it and switching instantly the wallpaper.
939 StartUserTransitionAnimation("A");
940 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
941 EXPECT_EQ("A", GetWallaperUserIdForTest());
942 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
943 EXPECT_EQ(0.0f, window(1)->layer()->GetTargetOpacity());
945 // The next step will not change anything.
946 AdvanceUserTransitionAnimation();
947 EXPECT_EQ("A", GetWallaperUserIdForTest());
948 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
949 EXPECT_EQ(0.0f, window(1)->layer()->GetTargetOpacity());
951 // The final step is also not changing anything to the status.
952 AdvanceUserTransitionAnimation();
953 EXPECT_EQ("S[A], H[B], H[C]", GetStatus());
954 EXPECT_EQ("A", GetWallaperUserIdForTest());
955 EXPECT_EQ(1.0f, window(0)->layer()->GetTargetOpacity());
956 EXPECT_EQ(0.0f, window(1)->layer()->GetTargetOpacity());
959 // Test that showing a window for another user also switches the desktop.
960 TEST_F(MultiUserWindowManagerChromeOSTest, ShowForUserSwitchesDesktop) {
961 SetUpForThisManyWindows(3);
962 multi_user_window_manager()->ActiveUserChanged("a");
963 session_state_delegate()->SwitchActiveUser("a");
965 // Set some owners and make sure we got what we asked for.
966 multi_user_window_manager()->SetWindowOwner(window(0), "a");
967 multi_user_window_manager()->SetWindowOwner(window(1), "b");
968 multi_user_window_manager()->SetWindowOwner(window(2), "c");
969 EXPECT_EQ("S[a], H[b], H[c]", GetStatus());
971 // SetWindowOwner should not have changed the active user.
972 EXPECT_EQ("a", GetAndValidateCurrentUserFromSessionStateObserver());
974 // Check that teleporting the window of the currently active user will
975 // teleport to the new desktop.
976 multi_user_window_manager()->ShowWindowForUser(window(0), "b");
977 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
978 EXPECT_EQ("S[a,b], S[b], H[c]", GetStatus());
980 // Check that teleporting a window from a currently inactive user will not
982 multi_user_window_manager()->ShowWindowForUser(window(2), "a");
983 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
984 EXPECT_EQ("S[a,b], S[b], H[c,a]", GetStatus());
985 multi_user_window_manager()->ShowWindowForUser(window(2), "b");
986 EXPECT_EQ("b", GetAndValidateCurrentUserFromSessionStateObserver());
987 EXPECT_EQ("S[a,b], S[b], S[c,b]", GetStatus());
989 // Check that teleporting back will also change the desktop.
990 multi_user_window_manager()->ShowWindowForUser(window(2), "c");
991 EXPECT_EQ("c", GetAndValidateCurrentUserFromSessionStateObserver());
992 EXPECT_EQ("H[a,b], H[b], S[c]", GetStatus());