OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/login/screens/user_selection_screen.h" | 5 #include "chrome/browser/chromeos/login/screens/user_selection_screen.h" |
6 | 6 |
7 #include "ash/shell.h" | |
8 #include "base/logging.h" | 7 #include "base/logging.h" |
9 #include "base/prefs/pref_service.h" | 8 #include "chrome/browser/chromeos/login/screens/screen_observer.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" | 9 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" |
16 #include "chrome/common/pref_names.h" | |
17 #include "ui/wm/core/user_activity_detector.h" | |
18 | 10 |
19 namespace chromeos { | 11 namespace chromeos { |
20 | 12 |
21 namespace { | |
22 | |
23 // User dictionary keys. | |
24 const char kKeyUsername[] = "username"; | |
25 const char kKeyDisplayName[] = "displayName"; | |
26 const char kKeyEmailAddress[] = "emailAddress"; | |
27 const char kKeyEnterpriseDomain[] = "enterpriseDomain"; | |
28 const char kKeyPublicAccount[] = "publicAccount"; | |
29 const char kKeyLocallyManagedUser[] = "locallyManagedUser"; | |
30 const char kKeySignedIn[] = "signedIn"; | |
31 const char kKeyCanRemove[] = "canRemove"; | |
32 const char kKeyIsOwner[] = "isOwner"; | |
33 const char kKeyInitialAuthType[] = "initialAuthType"; | |
34 const char kKeyMultiProfilesAllowed[] = "isMultiProfilesAllowed"; | |
35 const char kKeyMultiProfilesPolicy[] = "multiProfilesPolicy"; | |
36 | |
37 // Max number of users to show. | |
38 const size_t kMaxUsers = 18; | |
39 | |
40 const int kPasswordClearTimeoutSec = 60; | |
41 | |
42 } // namespace | |
43 | |
44 UserSelectionScreen::UserSelectionScreen() : handler_(NULL) { | 13 UserSelectionScreen::UserSelectionScreen() : handler_(NULL) { |
45 } | 14 } |
46 | 15 |
47 UserSelectionScreen::~UserSelectionScreen() { | 16 UserSelectionScreen::~UserSelectionScreen() { |
48 wm::UserActivityDetector* activity_detector = | |
49 ash::Shell::GetInstance()->user_activity_detector(); | |
50 if (activity_detector->HasObserver(this)) | |
51 activity_detector->RemoveObserver(this); | |
52 } | |
53 | |
54 // static | |
55 void UserSelectionScreen::FillUserDictionary( | |
56 User* user, | |
57 bool is_owner, | |
58 bool is_signin_to_add, | |
59 ScreenlockBridge::LockHandler::AuthType auth_type, | |
60 base::DictionaryValue* user_dict) { | |
61 const std::string& user_id = user->email(); | |
62 const bool is_public_account = | |
63 user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT; | |
64 const bool is_locally_managed_user = | |
65 user->GetType() == User::USER_TYPE_LOCALLY_MANAGED; | |
66 | |
67 user_dict->SetString(kKeyUsername, user_id); | |
68 user_dict->SetString(kKeyEmailAddress, user->display_email()); | |
69 user_dict->SetString(kKeyDisplayName, user->GetDisplayName()); | |
70 user_dict->SetBoolean(kKeyPublicAccount, is_public_account); | |
71 user_dict->SetBoolean(kKeyLocallyManagedUser, is_locally_managed_user); | |
72 user_dict->SetInteger(kKeyInitialAuthType, auth_type); | |
73 user_dict->SetBoolean(kKeySignedIn, user->is_logged_in()); | |
74 user_dict->SetBoolean(kKeyIsOwner, is_owner); | |
75 | |
76 // Fill in multi-profiles related fields. | |
77 if (is_signin_to_add) { | |
78 MultiProfileUserController* multi_profile_user_controller = | |
79 UserManager::Get()->GetMultiProfileUserController(); | |
80 std::string behavior = | |
81 multi_profile_user_controller->GetCachedValue(user_id); | |
82 user_dict->SetBoolean(kKeyMultiProfilesAllowed, | |
83 multi_profile_user_controller->IsUserAllowedInSession( | |
84 user_id) == MultiProfileUserController::ALLOWED); | |
85 user_dict->SetString(kKeyMultiProfilesPolicy, behavior); | |
86 } else { | |
87 user_dict->SetBoolean(kKeyMultiProfilesAllowed, true); | |
88 } | |
89 | |
90 if (is_public_account) { | |
91 policy::BrowserPolicyConnectorChromeOS* policy_connector = | |
92 g_browser_process->platform_part()->browser_policy_connector_chromeos(); | |
93 | |
94 if (policy_connector->IsEnterpriseManaged()) { | |
95 user_dict->SetString(kKeyEnterpriseDomain, | |
96 policy_connector->GetEnterpriseDomain()); | |
97 } | |
98 } | |
99 } | |
100 | |
101 // static | |
102 bool UserSelectionScreen::ShouldForceOnlineSignIn(const User* user) { | |
103 // Public sessions are always allowed to log in offline. | |
104 // Supervised user are allowed to log in offline if their OAuth token status | |
105 // is unknown or valid. | |
106 // For all other users, force online sign in if: | |
107 // * The flag to force online sign-in is set for the user. | |
108 // * The user's OAuth token is invalid. | |
109 // * The user's OAuth token status is unknown (except supervised users, | |
110 // see above). | |
111 if (user->is_logged_in()) | |
112 return false; | |
113 | |
114 const User::OAuthTokenStatus token_status = user->oauth_token_status(); | |
115 const bool is_locally_managed_user = | |
116 user->GetType() == User::USER_TYPE_LOCALLY_MANAGED; | |
117 const bool is_public_session = | |
118 user->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT; | |
119 | |
120 if (is_locally_managed_user && | |
121 token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN) { | |
122 return false; | |
123 } | |
124 | |
125 if (is_public_session) | |
126 return false; | |
127 | |
128 return user->force_online_signin() || | |
129 (token_status == User::OAUTH2_TOKEN_STATUS_INVALID) || | |
130 (token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN); | |
131 } | 17 } |
132 | 18 |
133 void UserSelectionScreen::SetHandler(LoginDisplayWebUIHandler* handler) { | 19 void UserSelectionScreen::SetHandler(LoginDisplayWebUIHandler* handler) { |
134 handler_ = handler; | 20 handler_ = handler; |
135 } | 21 } |
136 | 22 |
137 void UserSelectionScreen::Init(const UserList& users, bool show_guest) { | 23 void UserSelectionScreen::Init(const UserList& users) { |
138 users_ = users; | 24 users_ = users; |
139 show_guest_ = show_guest; | |
140 | |
141 wm::UserActivityDetector* activity_detector = | |
142 ash::Shell::GetInstance()->user_activity_detector(); | |
143 if (!activity_detector->HasObserver(this)) | |
144 activity_detector->AddObserver(this); | |
145 } | 25 } |
146 | 26 |
147 void UserSelectionScreen::OnBeforeUserRemoved(const std::string& username) { | 27 void UserSelectionScreen::OnBeforeUserRemoved(const std::string& username) { |
148 for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) { | 28 for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) { |
149 if ((*it)->email() == username) { | 29 if ((*it)->email() == username) { |
150 users_.erase(it); | 30 users_.erase(it); |
151 break; | 31 break; |
152 } | 32 } |
153 } | 33 } |
154 } | 34 } |
155 | 35 |
156 void UserSelectionScreen::OnUserRemoved(const std::string& username) { | 36 void UserSelectionScreen::OnUserRemoved(const std::string& username) { |
157 if (!handler_) | 37 if (!handler_) |
158 return; | 38 return; |
159 | 39 |
160 handler_->OnUserRemoved(username); | 40 handler_->OnUserRemoved(username); |
161 } | 41 } |
162 | 42 |
163 void UserSelectionScreen::OnUserImageChanged(const User& user) { | 43 void UserSelectionScreen::OnUserImageChanged(const User& user) { |
164 if (!handler_) | 44 if (!handler_) |
165 return; | 45 return; |
166 handler_->OnUserImageChanged(user); | 46 handler_->OnUserImageChanged(user); |
167 // TODO(antrim) : updateUserImage(user.email()) | 47 // TODO(antrim) : updateUserImage(user.email()) |
168 } | 48 } |
169 | 49 |
170 const UserList& UserSelectionScreen::GetUsers() const { | 50 const UserList& UserSelectionScreen::GetUsers() const { |
171 return users_; | 51 return users_; |
172 } | 52 } |
173 | 53 |
174 void UserSelectionScreen::OnPasswordClearTimerExpired() { | |
175 if (handler_) | |
176 handler_->ClearUserPodPassword(); | |
177 } | |
178 | |
179 void UserSelectionScreen::OnUserActivity(const ui::Event* event) { | |
180 if (!password_clear_timer_.IsRunning()) { | |
181 password_clear_timer_.Start( | |
182 FROM_HERE, | |
183 base::TimeDelta::FromSeconds(kPasswordClearTimeoutSec), | |
184 this, | |
185 &UserSelectionScreen::OnPasswordClearTimerExpired); | |
186 } | |
187 password_clear_timer_.Reset(); | |
188 } | |
189 | |
190 void UserSelectionScreen::SendUserList(bool animated) { | |
191 base::ListValue users_list; | |
192 const UserList& users = GetUsers(); | |
193 | |
194 // TODO(nkostylev): Move to a separate method in UserManager. | |
195 // http://crbug.com/230852 | |
196 bool is_signin_to_add = LoginDisplayHostImpl::default_host() && | |
197 UserManager::Get()->IsUserLoggedIn(); | |
198 | |
199 user_auth_type_map_.clear(); | |
200 | |
201 bool single_user = users.size() == 1; | |
202 std::string owner; | |
203 chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner); | |
204 bool has_owner = owner.size() > 0; | |
205 size_t max_non_owner_users = has_owner ? kMaxUsers - 1 : kMaxUsers; | |
206 size_t non_owner_count = 0; | |
207 | |
208 policy::BrowserPolicyConnectorChromeOS* connector = | |
209 g_browser_process->platform_part()->browser_policy_connector_chromeos(); | |
210 | |
211 bool is_enterprise_managed = connector->IsEnterpriseManaged(); | |
212 | |
213 for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) { | |
214 const std::string& user_id = (*it)->email(); | |
215 bool is_owner = (user_id == owner); | |
216 bool is_public_account = | |
217 ((*it)->GetType() == User::USER_TYPE_PUBLIC_ACCOUNT); | |
218 | |
219 if ((is_public_account && !is_signin_to_add) || is_owner || | |
220 (!is_public_account && non_owner_count < max_non_owner_users)) { | |
221 ScreenlockBridge::LockHandler::AuthType initial_auth_type = | |
222 ShouldForceOnlineSignIn(*it) | |
223 ? ScreenlockBridge::LockHandler::ONLINE_SIGN_IN | |
224 : ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; | |
225 user_auth_type_map_[user_id] = initial_auth_type; | |
226 | |
227 base::DictionaryValue* user_dict = new base::DictionaryValue(); | |
228 FillUserDictionary( | |
229 *it, is_owner, is_signin_to_add, initial_auth_type, user_dict); | |
230 bool signed_in = (*it)->is_logged_in(); | |
231 // Single user check here is necessary because owner info might not be | |
232 // available when running into login screen on first boot. | |
233 // See http://crosbug.com/12723 | |
234 bool can_remove_user = | |
235 ((!single_user || is_enterprise_managed) && !user_id.empty() && | |
236 !is_owner && !is_public_account && !signed_in && !is_signin_to_add); | |
237 user_dict->SetBoolean(kKeyCanRemove, can_remove_user); | |
238 | |
239 if (!is_owner) | |
240 ++non_owner_count; | |
241 if (is_owner && users_list.GetSize() > kMaxUsers) { | |
242 // Owner is always in the list. | |
243 users_list.Insert(kMaxUsers - 1, user_dict); | |
244 while (users_list.GetSize() > kMaxUsers) | |
245 users_list.Remove(kMaxUsers, NULL); | |
246 } else if (users_list.GetSize() < kMaxUsers) { | |
247 users_list.Append(user_dict); | |
248 } | |
249 } | |
250 } | |
251 | |
252 handler_->LoadUsers(users_list, animated, show_guest_); | |
253 } | |
254 | |
255 void UserSelectionScreen::HandleGetUsers() { | |
256 SendUserList(false); | |
257 } | |
258 | |
259 void UserSelectionScreen::SetAuthType( | |
260 const std::string& username, | |
261 ScreenlockBridge::LockHandler::AuthType auth_type) { | |
262 user_auth_type_map_[username] = auth_type; | |
263 } | |
264 | |
265 ScreenlockBridge::LockHandler::AuthType UserSelectionScreen::GetAuthType( | |
266 const std::string& username) const { | |
267 if (user_auth_type_map_.find(username) == user_auth_type_map_.end()) | |
268 return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; | |
269 return user_auth_type_map_.find(username)->second; | |
270 } | |
271 | |
272 } // namespace chromeos | 54 } // namespace chromeos |
OLD | NEW |