1// Copyright 2014 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/session/session_state_delegate.h"
6#include "ash/shell.h"
7#include "base/prefs/pref_service.h"
8#include "chrome/browser/chrome_notification_types.h"
9#include "chrome/browser/chromeos/login/lock/screen_locker.h"
10#include "chrome/browser/chromeos/login/lock/screen_locker_tester.h"
11#include "chrome/browser/chromeos/login/login_manager_test.h"
12#include "chrome/browser/chromeos/login/startup_utils.h"
13#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
14#include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
15#include "chrome/browser/chromeos/login/ui/webui_login_view.h"
16#include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
17#include "chrome/browser/chromeos/profiles/profile_helper.h"
18#include "chrome/common/pref_names.h"
19#include "chrome/test/base/in_process_browser_test.h"
20#include "components/user_manager/user_manager.h"
21#include "content/public/test/test_utils.h"
22#include "testing/gtest/include/gtest/gtest.h"
23
24using namespace testing;
25
26namespace {
27
28const char* kTestUsers[] = {"test-user1@gmail.com",
29                            "test-user2@gmail.com",
30                            "test-user3@gmail.com"};
31
32}  // anonymous namespace
33
34namespace chromeos {
35
36class UserAddingScreenTest : public LoginManagerTest,
37                             public UserAddingScreen::Observer {
38 public:
39  UserAddingScreenTest() : LoginManagerTest(false),
40                           user_adding_started_(0),
41                           user_adding_finished_(0) {
42  }
43
44  virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
45    LoginManagerTest::SetUpInProcessBrowserTestFixture();
46    UserAddingScreen::Get()->AddObserver(this);
47  }
48
49  virtual void OnUserAddingFinished() OVERRIDE { ++user_adding_finished_; }
50
51  virtual void OnUserAddingStarted() OVERRIDE { ++user_adding_started_; }
52
53  void SetUserCanLock(user_manager::User* user, bool can_lock) {
54    user->set_can_lock(can_lock);
55  }
56
57  void CheckScreenIsVisible() {
58    views::View* web_view =
59        LoginDisplayHostImpl::default_host()->GetWebUILoginView()->child_at(0);
60    for (views::View* current_view = web_view;
61         current_view;
62         current_view = current_view->parent()) {
63      EXPECT_TRUE(current_view->visible());
64      if (current_view->layer())
65        EXPECT_EQ(current_view->layer()->GetCombinedOpacity(), 1.f);
66    }
67    for (aura::Window* window = web_view->GetWidget()->GetNativeWindow();
68         window;
69         window = window->parent()) {
70      EXPECT_TRUE(window->IsVisible());
71      EXPECT_EQ(window->layer()->GetCombinedOpacity(), 1.f);
72    }
73  }
74
75  int user_adding_started() { return user_adding_started_; }
76
77  int user_adding_finished() { return user_adding_finished_; }
78
79 private:
80  int user_adding_started_;
81  int user_adding_finished_;
82
83  DISALLOW_COPY_AND_ASSIGN(UserAddingScreenTest);
84};
85
86IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, PRE_CancelAdding) {
87  RegisterUser(kTestUsers[0]);
88  RegisterUser(kTestUsers[1]);
89  RegisterUser(kTestUsers[2]);
90  StartupUtils::MarkOobeCompleted();
91}
92
93IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, CancelAdding) {
94  EXPECT_CALL(login_utils(), DoBrowserLaunch(_, _)).Times(1);
95  EXPECT_EQ(3u, user_manager::UserManager::Get()->GetUsers().size());
96  EXPECT_EQ(0u, user_manager::UserManager::Get()->GetLoggedInUsers().size());
97
98  EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_LOGIN_PRIMARY,
99            ash::Shell::GetInstance()->session_state_delegate()->
100                GetSessionState());
101
102  LoginUser(kTestUsers[0]);
103  EXPECT_EQ(1u, user_manager::UserManager::Get()->GetLoggedInUsers().size());
104  EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_ACTIVE,
105            ash::Shell::GetInstance()->session_state_delegate()->
106                GetSessionState());
107
108  UserAddingScreen::Get()->Start();
109  content::RunAllPendingInMessageLoop();
110  EXPECT_EQ(1, user_adding_started());
111  EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_LOGIN_SECONDARY,
112            ash::Shell::GetInstance()->session_state_delegate()->
113                GetSessionState());
114
115  UserAddingScreen::Get()->Cancel();
116  content::RunAllPendingInMessageLoop();
117  EXPECT_EQ(1, user_adding_finished());
118  EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_ACTIVE,
119            ash::Shell::GetInstance()->session_state_delegate()->
120                GetSessionState());
121
122  EXPECT_TRUE(LoginDisplayHostImpl::default_host() == NULL);
123  EXPECT_EQ(1u, user_manager::UserManager::Get()->GetLoggedInUsers().size());
124  EXPECT_EQ(kTestUsers[0],
125            user_manager::UserManager::Get()->GetActiveUser()->email());
126}
127
128IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, PRE_AddingSeveralUsers) {
129  RegisterUser(kTestUsers[0]);
130  RegisterUser(kTestUsers[1]);
131  RegisterUser(kTestUsers[2]);
132  StartupUtils::MarkOobeCompleted();
133}
134
135IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, AddingSeveralUsers) {
136  EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_LOGIN_PRIMARY,
137            ash::Shell::GetInstance()->session_state_delegate()->
138                GetSessionState());
139  EXPECT_CALL(login_utils(), DoBrowserLaunch(_, _)).Times(3);
140  LoginUser(kTestUsers[0]);
141  EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_ACTIVE,
142            ash::Shell::GetInstance()->session_state_delegate()->
143                GetSessionState());
144
145  user_manager::UserManager* user_manager = user_manager::UserManager::Get();
146
147  for (int i = 1; i < 3; ++i) {
148    UserAddingScreen::Get()->Start();
149    content::RunAllPendingInMessageLoop();
150    EXPECT_EQ(i, user_adding_started());
151    EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_LOGIN_SECONDARY,
152              ash::Shell::GetInstance()->session_state_delegate()->
153                  GetSessionState());
154    AddUser(kTestUsers[i]);
155    EXPECT_EQ(i, user_adding_finished());
156    EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_ACTIVE,
157              ash::Shell::GetInstance()->session_state_delegate()->
158                  GetSessionState());
159    EXPECT_TRUE(LoginDisplayHostImpl::default_host() == NULL);
160    ASSERT_EQ(unsigned(i + 1), user_manager->GetLoggedInUsers().size());
161  }
162
163  EXPECT_EQ(ash::SessionStateDelegate::SESSION_STATE_ACTIVE,
164            ash::Shell::GetInstance()->session_state_delegate()->
165                GetSessionState());
166
167  // Now check how unlock policy works for these users.
168  PrefService* prefs1 =
169      ProfileHelper::Get()
170          ->GetProfileByUserUnsafe(user_manager->GetLoggedInUsers()[0])
171          ->GetPrefs();
172  PrefService* prefs2 =
173      ProfileHelper::Get()
174          ->GetProfileByUserUnsafe(user_manager->GetLoggedInUsers()[1])
175          ->GetPrefs();
176  PrefService* prefs3 =
177      ProfileHelper::Get()
178          ->GetProfileByUserUnsafe(user_manager->GetLoggedInUsers()[2])
179          ->GetPrefs();
180  ASSERT_TRUE(prefs1 != NULL);
181  ASSERT_TRUE(prefs2 != NULL);
182  ASSERT_TRUE(prefs3 != NULL);
183  prefs1->SetBoolean(prefs::kEnableAutoScreenLock, false);
184  prefs2->SetBoolean(prefs::kEnableAutoScreenLock, false);
185  prefs3->SetBoolean(prefs::kEnableAutoScreenLock, false);
186
187  // One of the users has the primary-only policy.
188  // List of unlock users doesn't depend on kEnableLockScreen preference.
189  prefs1->SetBoolean(prefs::kEnableAutoScreenLock, true);
190  prefs1->SetString(prefs::kMultiProfileUserBehavior,
191                    MultiProfileUserController::kBehaviorPrimaryOnly);
192  prefs2->SetString(prefs::kMultiProfileUserBehavior,
193                    MultiProfileUserController::kBehaviorUnrestricted);
194  prefs3->SetString(prefs::kMultiProfileUserBehavior,
195                    MultiProfileUserController::kBehaviorUnrestricted);
196  user_manager::UserList unlock_users = user_manager->GetUnlockUsers();
197  ASSERT_EQ(1UL, unlock_users.size());
198  EXPECT_EQ(kTestUsers[0], unlock_users[0]->email());
199
200  prefs1->SetBoolean(prefs::kEnableAutoScreenLock, false);
201  unlock_users = user_manager->GetUnlockUsers();
202  ASSERT_EQ(1UL, unlock_users.size());
203  EXPECT_EQ(kTestUsers[0], unlock_users[0]->email());
204
205  // If all users have unrestricted policy then anyone can perform unlock.
206  prefs1->SetString(prefs::kMultiProfileUserBehavior,
207                    MultiProfileUserController::kBehaviorUnrestricted);
208  unlock_users = user_manager->GetUnlockUsers();
209  ASSERT_EQ(3UL, unlock_users.size());
210  for (int i = 0; i < 3; ++i)
211    EXPECT_EQ(kTestUsers[i], unlock_users[i]->email());
212
213  // This preference doesn't affect list of unlock users.
214  prefs2->SetBoolean(prefs::kEnableAutoScreenLock, true);
215  unlock_users = user_manager->GetUnlockUsers();
216  ASSERT_EQ(3UL, unlock_users.size());
217  for (int i = 0; i < 3; ++i)
218    EXPECT_EQ(kTestUsers[i], unlock_users[i]->email());
219
220  // Now one of the users is unable to unlock.
221  SetUserCanLock(user_manager->GetLoggedInUsers()[2], false);
222  unlock_users = user_manager->GetUnlockUsers();
223  ASSERT_EQ(2UL, unlock_users.size());
224  for (int i = 0; i < 2; ++i)
225    EXPECT_EQ(kTestUsers[i], unlock_users[i]->email());
226  SetUserCanLock(user_manager->GetLoggedInUsers()[2], true);
227
228  // Now one of the users has not-allowed policy.
229  // In this scenario this user is not allowed in multi-profile session but
230  // if that user happened to still be part of multi-profile session it should
231  // not be listed on screen lock.
232  prefs3->SetString(prefs::kMultiProfileUserBehavior,
233                    MultiProfileUserController::kBehaviorNotAllowed);
234  unlock_users = user_manager->GetUnlockUsers();
235  ASSERT_EQ(2UL, unlock_users.size());
236  for (int i = 0; i < 2; ++i)
237    EXPECT_EQ(kTestUsers[i], unlock_users[i]->email());
238}
239
240IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, PRE_ScreenVisibility) {
241  RegisterUser(kTestUsers[0]);
242  RegisterUser(kTestUsers[1]);
243  StartupUtils::MarkOobeCompleted();
244}
245
246// Trying to catch http://crbug.com/362153.
247IN_PROC_BROWSER_TEST_F(UserAddingScreenTest, ScreenVisibility) {
248  LoginUser(kTestUsers[0]);
249
250  UserAddingScreen::Get()->Start();
251  content::RunAllPendingInMessageLoop();
252  CheckScreenIsVisible();
253  UserAddingScreen::Get()->Cancel();
254  content::RunAllPendingInMessageLoop();
255
256  ScreenLocker::Show();
257  content::WindowedNotificationObserver(
258      chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
259      content::NotificationService::AllSources()).Wait();
260
261  ScreenLocker::Hide();
262  content::WindowedNotificationObserver(
263      chrome::NOTIFICATION_SCREEN_LOCK_STATE_CHANGED,
264      content::NotificationService::AllSources()).Wait();
265
266  UserAddingScreen::Get()->Start();
267  content::RunAllPendingInMessageLoop();
268  CheckScreenIsVisible();
269  UserAddingScreen::Get()->Cancel();
270  content::RunAllPendingInMessageLoop();
271}
272
273}  // namespace chromeos
274