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