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"
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"
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;
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);
57 void UserSelectionScreen::FillUserDictionary(
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
);
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());
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,
113 if (user
->is_logged_in())
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
) {
127 if (is_public_session
)
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
) {
139 void UserSelectionScreen::Init(const UserList
& users
, bool show_guest
) {
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
) {
158 void UserSelectionScreen::OnUserRemoved(const std::string
& username
) {
162 handler_
->OnUserRemoved(username
);
165 void UserSelectionScreen::OnUserImageChanged(const User
& user
) {
168 handler_
->OnUserImageChanged(user
);
169 // TODO(antrim) : updateUserImage(user.email())
172 const UserList
& UserSelectionScreen::GetUsers() const {
176 void UserSelectionScreen::OnPasswordClearTimerExpired() {
178 handler_
->ClearUserPodPassword();
181 void UserSelectionScreen::OnUserActivity(const ui::Event
* event
) {
182 if (!password_clear_timer_
.IsRunning()) {
183 password_clear_timer_
.Start(
185 base::TimeDelta::FromSeconds(kPasswordClearTimeoutSec
),
187 &UserSelectionScreen::OnPasswordClearTimerExpired
);
189 password_clear_timer_
.Reset();
193 const UserList
UserSelectionScreen::PrepareUserListForSending(
194 const UserList
& users
,
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
)) {
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();
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
,
247 user_auth_type_map_
.clear();
249 for (UserList::const_iterator it
= users_to_send
.begin();
250 it
!= users_to_send
.end();
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
=
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();
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() {
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