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