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" 24namespace chromeos { 25namespace { 26 27const char* kTestAccount1 = "user1@test.com"; 28const char* kTestAccount2 = "user2@test.com"; 29 30class 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 49class 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 62class 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 76TEST_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. 129TEST_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 182class 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 210void 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 219void WallpaperPrivateApiMultiUserUnittest::TearDown() { 220 chrome::MultiUserWindowManager::DeleteInstance(); 221 AshTestBase::TearDown(); 222} 223 224void 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 237void 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. 246TEST_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. 346TEST_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