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