Tests added for user-listing on sign-in screen.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / screens / user_selection_screen.cc
blobe80dfaff606a8e486597af4936ea6574be1eea35
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.
5 #include "chrome/browser/chromeos/login/screens/user_selection_screen.h"
7 #include "ash/shell.h"
8 #include "base/logging.h"
9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
12 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
13 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
14 #include "chrome/browser/signin/screenlock_bridge.h"
15 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
16 #include "chrome/common/pref_names.h"
17 #include "components/user_manager/user_type.h"
18 #include "ui/wm/core/user_activity_detector.h"
20 namespace chromeos {
22 namespace {
24 // User dictionary keys.
25 const char kKeyUsername[] = "username";
26 const char kKeyDisplayName[] = "displayName";
27 const char kKeyEmailAddress[] = "emailAddress";
28 const char kKeyEnterpriseDomain[] = "enterpriseDomain";
29 const char kKeyPublicAccount[] = "publicAccount";
30 const char kKeyLocallyManagedUser[] = "locallyManagedUser";
31 const char kKeySignedIn[] = "signedIn";
32 const char kKeyCanRemove[] = "canRemove";
33 const char kKeyIsOwner[] = "isOwner";
34 const char kKeyInitialAuthType[] = "initialAuthType";
35 const char kKeyMultiProfilesAllowed[] = "isMultiProfilesAllowed";
36 const char kKeyMultiProfilesPolicy[] = "multiProfilesPolicy";
38 // Max number of users to show.
39 // Please keep synced with one in signin_userlist_unittest.cc.
40 const size_t kMaxUsers = 18;
42 const int kPasswordClearTimeoutSec = 60;
44 } // namespace
46 UserSelectionScreen::UserSelectionScreen() : handler_(NULL) {
49 UserSelectionScreen::~UserSelectionScreen() {
50 wm::UserActivityDetector* activity_detector =
51 ash::Shell::GetInstance()->user_activity_detector();
52 if (activity_detector->HasObserver(this))
53 activity_detector->RemoveObserver(this);
56 // static
57 void UserSelectionScreen::FillUserDictionary(
58 User* user,
59 bool is_owner,
60 bool is_signin_to_add,
61 ScreenlockBridge::LockHandler::AuthType auth_type,
62 base::DictionaryValue* user_dict) {
63 const std::string& user_id = user->email();
64 const bool is_public_account =
65 user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT;
66 const bool is_locally_managed_user =
67 user->GetType() == user_manager::USER_TYPE_LOCALLY_MANAGED;
69 user_dict->SetString(kKeyUsername, user_id);
70 user_dict->SetString(kKeyEmailAddress, user->display_email());
71 user_dict->SetString(kKeyDisplayName, user->GetDisplayName());
72 user_dict->SetBoolean(kKeyPublicAccount, is_public_account);
73 user_dict->SetBoolean(kKeyLocallyManagedUser, is_locally_managed_user);
74 user_dict->SetInteger(kKeyInitialAuthType, auth_type);
75 user_dict->SetBoolean(kKeySignedIn, user->is_logged_in());
76 user_dict->SetBoolean(kKeyIsOwner, is_owner);
78 // Fill in multi-profiles related fields.
79 if (is_signin_to_add) {
80 MultiProfileUserController* multi_profile_user_controller =
81 UserManager::Get()->GetMultiProfileUserController();
82 std::string behavior =
83 multi_profile_user_controller->GetCachedValue(user_id);
84 user_dict->SetBoolean(kKeyMultiProfilesAllowed,
85 multi_profile_user_controller->IsUserAllowedInSession(
86 user_id) == MultiProfileUserController::ALLOWED);
87 user_dict->SetString(kKeyMultiProfilesPolicy, behavior);
88 } else {
89 user_dict->SetBoolean(kKeyMultiProfilesAllowed, true);
92 if (is_public_account) {
93 policy::BrowserPolicyConnectorChromeOS* policy_connector =
94 g_browser_process->platform_part()->browser_policy_connector_chromeos();
96 if (policy_connector->IsEnterpriseManaged()) {
97 user_dict->SetString(kKeyEnterpriseDomain,
98 policy_connector->GetEnterpriseDomain());
103 // static
104 bool UserSelectionScreen::ShouldForceOnlineSignIn(const User* user) {
105 // Public sessions are always allowed to log in offline.
106 // Supervised user are allowed to log in offline if their OAuth token status
107 // is unknown or valid.
108 // For all other users, force online sign in if:
109 // * The flag to force online sign-in is set for the user.
110 // * The user's OAuth token is invalid.
111 // * The user's OAuth token status is unknown (except supervised users,
112 // see above).
113 if (user->is_logged_in())
114 return false;
116 const User::OAuthTokenStatus token_status = user->oauth_token_status();
117 const bool is_locally_managed_user =
118 user->GetType() == user_manager::USER_TYPE_LOCALLY_MANAGED;
119 const bool is_public_session =
120 user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT;
122 if (is_locally_managed_user &&
123 token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN) {
124 return false;
127 if (is_public_session)
128 return false;
130 return user->force_online_signin() ||
131 (token_status == User::OAUTH2_TOKEN_STATUS_INVALID) ||
132 (token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN);
135 void UserSelectionScreen::SetHandler(LoginDisplayWebUIHandler* handler) {
136 handler_ = handler;
139 void UserSelectionScreen::Init(const UserList& users, bool show_guest) {
140 users_ = users;
141 show_guest_ = show_guest;
143 wm::UserActivityDetector* activity_detector =
144 ash::Shell::GetInstance()->user_activity_detector();
145 if (!activity_detector->HasObserver(this))
146 activity_detector->AddObserver(this);
149 void UserSelectionScreen::OnBeforeUserRemoved(const std::string& username) {
150 for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) {
151 if ((*it)->email() == username) {
152 users_.erase(it);
153 break;
158 void UserSelectionScreen::OnUserRemoved(const std::string& username) {
159 if (!handler_)
160 return;
162 handler_->OnUserRemoved(username);
165 void UserSelectionScreen::OnUserImageChanged(const User& user) {
166 if (!handler_)
167 return;
168 handler_->OnUserImageChanged(user);
169 // TODO(antrim) : updateUserImage(user.email())
172 const UserList& UserSelectionScreen::GetUsers() const {
173 return users_;
176 void UserSelectionScreen::OnPasswordClearTimerExpired() {
177 if (handler_)
178 handler_->ClearUserPodPassword();
181 void UserSelectionScreen::OnUserActivity(const ui::Event* event) {
182 if (!password_clear_timer_.IsRunning()) {
183 password_clear_timer_.Start(
184 FROM_HERE,
185 base::TimeDelta::FromSeconds(kPasswordClearTimeoutSec),
186 this,
187 &UserSelectionScreen::OnPasswordClearTimerExpired);
189 password_clear_timer_.Reset();
192 // static
193 const UserList UserSelectionScreen::PrepareUserListForSending(
194 const UserList& users,
195 std::string owner,
196 bool is_signin_to_add) {
198 UserList users_to_send;
199 bool has_owner = owner.size() > 0;
200 size_t max_non_owner_users = has_owner ? kMaxUsers - 1 : kMaxUsers;
201 size_t non_owner_count = 0;
203 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
204 const std::string& user_id = (*it)->email();
205 bool is_owner = (user_id == owner);
206 bool is_public_account =
207 ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT);
209 if ((is_public_account && !is_signin_to_add) || is_owner ||
210 (!is_public_account && non_owner_count < max_non_owner_users)) {
212 if (!is_owner)
213 ++non_owner_count;
214 if (is_owner && users_to_send.size() > kMaxUsers) {
215 // Owner is always in the list.
216 users_to_send.insert(users_to_send.begin() + (kMaxUsers - 1), *it);
217 while (users_to_send.size() > kMaxUsers)
218 users_to_send.erase(users_to_send.begin() + kMaxUsers);
219 } else if (users_to_send.size() < kMaxUsers) {
220 users_to_send.push_back(*it);
224 return users_to_send;
227 void UserSelectionScreen::SendUserList() {
228 base::ListValue users_list;
229 const UserList& users = GetUsers();
231 // TODO(nkostylev): Move to a separate method in UserManager.
232 // http://crbug.com/230852
233 bool single_user = users.size() == 1;
234 bool is_signin_to_add = LoginDisplayHostImpl::default_host() &&
235 UserManager::Get()->IsUserLoggedIn();
236 std::string owner;
237 chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner);
239 policy::BrowserPolicyConnectorChromeOS* connector =
240 g_browser_process->platform_part()->browser_policy_connector_chromeos();
241 bool is_enterprise_managed = connector->IsEnterpriseManaged();
243 const UserList users_to_send = PrepareUserListForSending(users,
244 owner,
245 is_signin_to_add);
247 user_auth_type_map_.clear();
249 for (UserList::const_iterator it = users_to_send.begin();
250 it != users_to_send.end();
251 ++it) {
252 const std::string& user_id = (*it)->email();
253 bool is_owner = (user_id == owner);
254 const bool is_public_account =
255 ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT);
256 const ScreenlockBridge::LockHandler::AuthType initial_auth_type =
257 is_public_account
258 ? ScreenlockBridge::LockHandler::EXPAND_THEN_USER_CLICK
259 : (ShouldForceOnlineSignIn(*it)
260 ? ScreenlockBridge::LockHandler::ONLINE_SIGN_IN
261 : ScreenlockBridge::LockHandler::OFFLINE_PASSWORD);
262 user_auth_type_map_[user_id] = initial_auth_type;
264 base::DictionaryValue* user_dict = new base::DictionaryValue();
265 FillUserDictionary(
266 *it, is_owner, is_signin_to_add, initial_auth_type, user_dict);
267 bool signed_in = (*it)->is_logged_in();
268 // Single user check here is necessary because owner info might not be
269 // available when running into login screen on first boot.
270 // See http://crosbug.com/12723
271 bool can_remove_user =
272 ((!single_user || is_enterprise_managed) && !user_id.empty() &&
273 !is_owner && !is_public_account && !signed_in && !is_signin_to_add);
274 user_dict->SetBoolean(kKeyCanRemove, can_remove_user);
275 users_list.Append(user_dict);
278 handler_->LoadUsers(users_list, show_guest_);
281 void UserSelectionScreen::HandleGetUsers() {
282 SendUserList();
285 void UserSelectionScreen::SetAuthType(
286 const std::string& username,
287 ScreenlockBridge::LockHandler::AuthType auth_type) {
288 user_auth_type_map_[username] = auth_type;
291 ScreenlockBridge::LockHandler::AuthType UserSelectionScreen::GetAuthType(
292 const std::string& username) const {
293 if (user_auth_type_map_.find(username) == user_auth_type_map_.end())
294 return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
295 return user_auth_type_map_.find(username)->second;
298 } // namespace chromeos