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