Home | History | Annotate | Download | only in extensions
      1 // Copyright (c) 2012 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/test/ash_test_base.h"
      7 #include "ash/test/test_session_state_delegate.h"
      8 #include "ash/test/test_shell_delegate.h"
      9 #include "ash/wm/window_state.h"
     10 #include "base/command_line.h"
     11 #include "base/memory/scoped_ptr.h"
     12 #include "chrome/browser/chromeos/extensions/wallpaper_private_api.h"
     13 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
     14 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
     15 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
     16 #include "chrome/browser/ui/ash/multi_user/multi_user_window_manager_chromeos.h"
     17 #include "ui/aura/test/test_windows.h"
     18 #include "ui/aura/window.h"
     19 #include "ui/aura/window_event_dispatcher.h"
     20 
     21 //#include "base/compiler_specific.h"
     22 //#include "base/logging.h"
     23 //#include "chrome/browser/ui/ash/multi_user/multi_user_window_manager.h"
     24 namespace chromeos {
     25 namespace {
     26 
     27 const char* kTestAccount1 = "user1 (at) test.com";
     28 const char* kTestAccount2 = "user2 (at) test.com";
     29 
     30 class WallpaperPrivateApiUnittest : public ash::test::AshTestBase {
     31  public:
     32   WallpaperPrivateApiUnittest()
     33       : fake_user_manager_(new FakeUserManager()),
     34         scoped_user_manager_(fake_user_manager_) {
     35   }
     36 
     37  protected:
     38   FakeUserManager* fake_user_manager() {
     39     return fake_user_manager_;
     40   }
     41 
     42  private:
     43   FakeUserManager* fake_user_manager_;
     44   ScopedUserManagerEnabler scoped_user_manager_;
     45 
     46   DISALLOW_COPY_AND_ASSIGN(WallpaperPrivateApiUnittest);
     47 };
     48 
     49 class TestMinimizeFunction
     50     : public WallpaperPrivateMinimizeInactiveWindowsFunction {
     51  public:
     52   TestMinimizeFunction() {}
     53 
     54   virtual bool RunAsync() OVERRIDE {
     55     return WallpaperPrivateMinimizeInactiveWindowsFunction::RunAsync();
     56   }
     57 
     58  protected:
     59   virtual ~TestMinimizeFunction() {}
     60 };
     61 
     62 class TestRestoreFunction
     63     : public WallpaperPrivateRestoreMinimizedWindowsFunction {
     64  public:
     65   TestRestoreFunction() {}
     66 
     67   virtual bool RunAsync() OVERRIDE {
     68     return WallpaperPrivateRestoreMinimizedWindowsFunction::RunAsync();
     69   }
     70  protected:
     71   virtual ~TestRestoreFunction() {}
     72 };
     73 
     74 }  // namespace
     75 
     76 TEST_F(WallpaperPrivateApiUnittest, HideAndRestoreWindows) {
     77   fake_user_manager()->AddUser(kTestAccount1);
     78   scoped_ptr<aura::Window> window3(CreateTestWindowInShellWithId(3));
     79   scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
     80   scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
     81   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
     82 
     83   ash::wm::WindowState* window0_state = ash::wm::GetWindowState(window0.get());
     84   ash::wm::WindowState* window1_state = ash::wm::GetWindowState(window1.get());
     85   ash::wm::WindowState* window2_state = ash::wm::GetWindowState(window2.get());
     86   ash::wm::WindowState* window3_state = ash::wm::GetWindowState(window3.get());
     87 
     88   window3_state->Minimize();
     89   window1_state->Maximize();
     90 
     91   // Window 3 starts minimized, window 1 starts maximized.
     92   EXPECT_FALSE(window0_state->IsMinimized());
     93   EXPECT_FALSE(window1_state->IsMinimized());
     94   EXPECT_FALSE(window2_state->IsMinimized());
     95   EXPECT_TRUE(window3_state->IsMinimized());
     96 
     97   // We then activate window 0 (i.e. wallpaper picker) and call the minimize
     98   // function.
     99   window0_state->Activate();
    100   EXPECT_TRUE(window0_state->IsActive());
    101   scoped_refptr<TestMinimizeFunction> minimize_function(
    102       new TestMinimizeFunction());
    103   EXPECT_TRUE(minimize_function->RunAsync());
    104 
    105   // All windows except window 0 should be minimized.
    106   EXPECT_FALSE(window0_state->IsMinimized());
    107   EXPECT_TRUE(window1_state->IsMinimized());
    108   EXPECT_TRUE(window2_state->IsMinimized());
    109   EXPECT_TRUE(window3_state->IsMinimized());
    110 
    111   // Then we destroy window 0 and call the restore function.
    112   window0.reset();
    113   scoped_refptr<TestRestoreFunction> restore_function(
    114       new TestRestoreFunction());
    115   EXPECT_TRUE(restore_function->RunAsync());
    116 
    117   // Windows 1 and 2 should no longer be minimized. Window 1 should again
    118   // be maximized. Window 3 should still be minimized.
    119   EXPECT_TRUE(window1_state->IsMaximized());
    120   EXPECT_FALSE(window2_state->IsMinimized());
    121   EXPECT_TRUE(window3_state->IsMinimized());
    122 }
    123 
    124 // Test for multiple calls to |MinimizeInactiveWindows| before call
    125 // |RestoreWindows|:
    126 // 1. If all window hasn't change their states, the following calls are noops.
    127 // 2. If some windows are manually unminimized, the following call will minimize
    128 // all the unminimized windows.
    129 TEST_F(WallpaperPrivateApiUnittest, HideAndManualUnminimizeWindows) {
    130   fake_user_manager()->AddUser(kTestAccount1);
    131   scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
    132   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
    133 
    134   ash::wm::WindowState* window0_state = ash::wm::GetWindowState(window0.get());
    135   ash::wm::WindowState* window1_state = ash::wm::GetWindowState(window1.get());
    136 
    137   // We then activate window 0 (i.e. wallpaper picker) and call the minimize
    138   // function.
    139   window0_state->Activate();
    140   EXPECT_TRUE(window0_state->IsActive());
    141   scoped_refptr<TestMinimizeFunction> minimize_function_0(
    142       new TestMinimizeFunction());
    143   EXPECT_TRUE(minimize_function_0->RunAsync());
    144 
    145   // All windows except window 0 should be minimized.
    146   EXPECT_FALSE(window0_state->IsMinimized());
    147   EXPECT_TRUE(window1_state->IsMinimized());
    148 
    149   // Calls minimize function again should be an noop if window state didn't
    150   // change.
    151   scoped_refptr<TestMinimizeFunction> minimize_function_1(
    152       new TestMinimizeFunction());
    153   EXPECT_TRUE(minimize_function_1->RunAsync());
    154 
    155   // All windows except window 0 should be minimized.
    156   EXPECT_FALSE(window0_state->IsMinimized());
    157   EXPECT_TRUE(window1_state->IsMinimized());
    158 
    159   // Manually unminimize window 1.
    160   window1_state->Unminimize();
    161   EXPECT_FALSE(window1_state->IsMinimized());
    162   window0_state->Activate();
    163 
    164   scoped_refptr<TestMinimizeFunction> minimize_function_2(
    165       new TestMinimizeFunction());
    166   EXPECT_TRUE(minimize_function_2->RunAsync());
    167 
    168   // Window 1 should be minimized again.
    169   EXPECT_FALSE(window0_state->IsMinimized());
    170   EXPECT_TRUE(window1_state->IsMinimized());
    171 
    172   // Then we destroy window 0 and call the restore function.
    173   window0.reset();
    174   scoped_refptr<TestRestoreFunction> restore_function(
    175       new TestRestoreFunction());
    176   EXPECT_TRUE(restore_function->RunAsync());
    177 
    178   // Windows 1 should no longer be minimized.
    179   EXPECT_FALSE(window1_state->IsMinimized());
    180 }
    181 
    182 class WallpaperPrivateApiMultiUserUnittest
    183     : public WallpaperPrivateApiUnittest {
    184  public:
    185   WallpaperPrivateApiMultiUserUnittest()
    186       : multi_user_window_manager_(NULL),
    187         session_state_delegate_(NULL) {}
    188 
    189   virtual void SetUp() OVERRIDE;
    190   virtual void TearDown() OVERRIDE;
    191 
    192  protected:
    193   void SetUpMultiUserWindowManager(
    194       const std::string& active_user_id,
    195       chrome::MultiUserWindowManager::MultiProfileMode mode);
    196 
    197   void SwitchActiveUser(const std::string& active_user_id);
    198 
    199   chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager() {
    200     return multi_user_window_manager_;
    201   }
    202 
    203  private:
    204   chrome::MultiUserWindowManagerChromeOS* multi_user_window_manager_;
    205   ash::test::TestSessionStateDelegate* session_state_delegate_;
    206 
    207   DISALLOW_COPY_AND_ASSIGN(WallpaperPrivateApiMultiUserUnittest);
    208 };
    209 
    210 void WallpaperPrivateApiMultiUserUnittest::SetUp() {
    211   AshTestBase::SetUp();
    212   session_state_delegate_ =
    213       static_cast<ash::test::TestSessionStateDelegate*> (
    214           ash::Shell::GetInstance()->session_state_delegate());
    215   fake_user_manager()->AddUser(kTestAccount1);
    216   fake_user_manager()->AddUser(kTestAccount2);
    217 }
    218 
    219 void WallpaperPrivateApiMultiUserUnittest::TearDown() {
    220   chrome::MultiUserWindowManager::DeleteInstance();
    221   AshTestBase::TearDown();
    222 }
    223 
    224 void WallpaperPrivateApiMultiUserUnittest::SetUpMultiUserWindowManager(
    225     const std::string& active_user_id,
    226     chrome::MultiUserWindowManager::MultiProfileMode mode) {
    227   multi_user_window_manager_ =
    228       new chrome::MultiUserWindowManagerChromeOS(active_user_id);
    229   chrome::MultiUserWindowManager::SetInstanceForTest(
    230       multi_user_window_manager_, mode);
    231   // We do not want animations while the test is going on.
    232   multi_user_window_manager_->SetAnimationSpeedForTest(
    233       chrome::MultiUserWindowManagerChromeOS::ANIMATION_SPEED_DISABLED);
    234   EXPECT_TRUE(multi_user_window_manager_);
    235 }
    236 
    237 void WallpaperPrivateApiMultiUserUnittest::SwitchActiveUser(
    238     const std::string& active_user_id) {
    239   fake_user_manager()->SwitchActiveUser(active_user_id);
    240   multi_user_window_manager_->ActiveUserChanged(active_user_id);
    241 }
    242 
    243 // In multi profile mode, user may open wallpaper picker in one profile and
    244 // then switch to a different profile and open another wallpaper picker
    245 // without closing the first one.
    246 TEST_F(WallpaperPrivateApiMultiUserUnittest, HideAndRestoreWindowsTwoUsers) {
    247   SetUpMultiUserWindowManager(kTestAccount1,
    248       chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_SEPARATED);
    249 
    250   scoped_ptr<aura::Window> window4(CreateTestWindowInShellWithId(4));
    251   scoped_ptr<aura::Window> window3(CreateTestWindowInShellWithId(3));
    252   scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
    253   scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
    254   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
    255 
    256   ash::wm::WindowState* window0_state = ash::wm::GetWindowState(window0.get());
    257   ash::wm::WindowState* window1_state = ash::wm::GetWindowState(window1.get());
    258   ash::wm::WindowState* window2_state = ash::wm::GetWindowState(window2.get());
    259   ash::wm::WindowState* window3_state = ash::wm::GetWindowState(window3.get());
    260   ash::wm::WindowState* window4_state = ash::wm::GetWindowState(window4.get());
    261 
    262   multi_user_window_manager()->SetWindowOwner(window0.get(), kTestAccount1);
    263   multi_user_window_manager()->SetWindowOwner(window1.get(), kTestAccount1);
    264 
    265   // Set some windows to an inactive owner.
    266   multi_user_window_manager()->SetWindowOwner(window2.get(), kTestAccount2);
    267   multi_user_window_manager()->SetWindowOwner(window3.get(), kTestAccount2);
    268   multi_user_window_manager()->SetWindowOwner(window4.get(), kTestAccount2);
    269 
    270   EXPECT_FALSE(window0_state->IsMinimized());
    271   EXPECT_FALSE(window1_state->IsMinimized());
    272   EXPECT_FALSE(window2_state->IsMinimized());
    273   EXPECT_FALSE(window3_state->IsMinimized());
    274   EXPECT_FALSE(window4_state->IsMinimized());
    275 
    276   // We then activate window 0 (i.e. wallpaper picker) and call the minimize
    277   // function.
    278   window0_state->Activate();
    279   EXPECT_TRUE(window0_state->IsActive());
    280   scoped_refptr<TestMinimizeFunction> minimize_function_0(
    281       new TestMinimizeFunction());
    282   EXPECT_TRUE(minimize_function_0->RunAsync());
    283 
    284   // All windows except window 0 should be minimized.
    285   EXPECT_FALSE(window0_state->IsMinimized());
    286   EXPECT_TRUE(window1_state->IsMinimized());
    287 
    288   // All windows that belong to inactive user should not be affected.
    289   EXPECT_FALSE(window2_state->IsMinimized());
    290   EXPECT_FALSE(window3_state->IsMinimized());
    291   EXPECT_FALSE(window4_state->IsMinimized());
    292 
    293   // Activate kTestAccount2. kTestAccount1 becomes inactive user.
    294   SwitchActiveUser(kTestAccount2);
    295 
    296   window2_state->Activate();
    297   EXPECT_TRUE(window2_state->IsActive());
    298   scoped_refptr<TestMinimizeFunction> minimize_function_1(
    299       new TestMinimizeFunction());
    300   EXPECT_TRUE(minimize_function_1->RunAsync());
    301 
    302   // All windows except window 2 should be minimized.
    303   EXPECT_FALSE(window2_state->IsMinimized());
    304   EXPECT_TRUE(window3_state->IsMinimized());
    305   EXPECT_TRUE(window4_state->IsMinimized());
    306 
    307   // All windows that belong to inactive user should not be affected.
    308   EXPECT_FALSE(window0_state->IsMinimized());
    309   EXPECT_TRUE(window1_state->IsMinimized());
    310 
    311   // Destroy window 4. Nothing should happen to other windows.
    312   window4_state->Unminimize();
    313   window4.reset();
    314 
    315   EXPECT_FALSE(window2_state->IsMinimized());
    316   EXPECT_TRUE(window3_state->IsMinimized());
    317   EXPECT_FALSE(window0_state->IsMinimized());
    318   EXPECT_TRUE(window1_state->IsMinimized());
    319 
    320   // Then we destroy window 2 and call the restore function.
    321   window2.reset();
    322   scoped_refptr<TestRestoreFunction> restore_function_0(
    323       new TestRestoreFunction());
    324   EXPECT_TRUE(restore_function_0->RunAsync());
    325 
    326   EXPECT_FALSE(window3_state->IsMinimized());
    327 
    328   // All windows that belong to inactive user should not be affected.
    329   EXPECT_FALSE(window0_state->IsMinimized());
    330   EXPECT_TRUE(window1_state->IsMinimized());
    331 
    332   SwitchActiveUser(kTestAccount1);
    333 
    334   // Then we destroy window 0 and call the restore function.
    335   window0.reset();
    336   scoped_refptr<TestRestoreFunction> restore_function_1(
    337       new TestRestoreFunction());
    338   EXPECT_TRUE(restore_function_1->RunAsync());
    339 
    340   EXPECT_FALSE(window1_state->IsMinimized());
    341   EXPECT_FALSE(window3_state->IsMinimized());
    342 }
    343 
    344 // In multi profile mode, user may teleport windows. Teleported window should
    345 // also be minimized when open wallpaper picker.
    346 TEST_F(WallpaperPrivateApiMultiUserUnittest, HideTeleportedWindow) {
    347   SetUpMultiUserWindowManager(kTestAccount1,
    348       chrome::MultiUserWindowManager::MULTI_PROFILE_MODE_MIXED);
    349 
    350   scoped_ptr<aura::Window> window3(CreateTestWindowInShellWithId(3));
    351   scoped_ptr<aura::Window> window2(CreateTestWindowInShellWithId(2));
    352   scoped_ptr<aura::Window> window1(CreateTestWindowInShellWithId(1));
    353   scoped_ptr<aura::Window> window0(CreateTestWindowInShellWithId(0));
    354 
    355   ash::wm::WindowState* window0_state = ash::wm::GetWindowState(window0.get());
    356   ash::wm::WindowState* window1_state = ash::wm::GetWindowState(window1.get());
    357   ash::wm::WindowState* window2_state = ash::wm::GetWindowState(window2.get());
    358   ash::wm::WindowState* window3_state = ash::wm::GetWindowState(window3.get());
    359 
    360   multi_user_window_manager()->SetWindowOwner(window0.get(), kTestAccount1);
    361   multi_user_window_manager()->SetWindowOwner(window1.get(), kTestAccount1);
    362 
    363   // Set some windows to an inactive owner.
    364   multi_user_window_manager()->SetWindowOwner(window2.get(), kTestAccount2);
    365   multi_user_window_manager()->SetWindowOwner(window3.get(), kTestAccount2);
    366 
    367   // Teleport window2 to kTestAccount1.
    368   multi_user_window_manager()->ShowWindowForUser(window2.get(), kTestAccount1);
    369 
    370   // Initial window state. All windows shouldn't be minimized.
    371   EXPECT_FALSE(window0_state->IsMinimized());
    372   EXPECT_FALSE(window1_state->IsMinimized());
    373   EXPECT_FALSE(window2_state->IsMinimized());
    374   EXPECT_FALSE(window3_state->IsMinimized());
    375 
    376   // We then activate window 0 (i.e. wallpaper picker) and call the minimize
    377   // function.
    378   window0_state->Activate();
    379   EXPECT_TRUE(window0_state->IsActive());
    380   scoped_refptr<TestMinimizeFunction> minimize_function_0(
    381       new TestMinimizeFunction());
    382   EXPECT_TRUE(minimize_function_0->RunAsync());
    383 
    384   // All windows except window 0 should be minimized.
    385   EXPECT_FALSE(window0_state->IsMinimized());
    386   EXPECT_TRUE(window1_state->IsMinimized());
    387 
    388   // Teleported window should also be minimized.
    389   EXPECT_TRUE(window2_state->IsMinimized());
    390   // Other window should remain the same.
    391   EXPECT_FALSE(window3_state->IsMinimized());
    392 
    393   // Then we destroy window 0 and call the restore function.
    394   window0.reset();
    395   scoped_refptr<TestRestoreFunction> restore_function_1(
    396       new TestRestoreFunction());
    397   EXPECT_TRUE(restore_function_1->RunAsync());
    398 
    399   EXPECT_FALSE(window1_state->IsMinimized());
    400   EXPECT_FALSE(window2_state->IsMinimized());
    401   EXPECT_FALSE(window3_state->IsMinimized());
    402 }
    403 
    404 }  // namespace chromeos
    405