user_selection_screen.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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 "chrome/browser/chromeos/login/screens/user_selection_screen.h" 6 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" 19 20namespace chromeos { 21 22namespace { 23 24// User dictionary keys. 25const char kKeyUsername[] = "username"; 26const char kKeyDisplayName[] = "displayName"; 27const char kKeyEmailAddress[] = "emailAddress"; 28const char kKeyEnterpriseDomain[] = "enterpriseDomain"; 29const char kKeyPublicAccount[] = "publicAccount"; 30const char kKeyLocallyManagedUser[] = "locallyManagedUser"; 31const char kKeySignedIn[] = "signedIn"; 32const char kKeyCanRemove[] = "canRemove"; 33const char kKeyIsOwner[] = "isOwner"; 34const char kKeyInitialAuthType[] = "initialAuthType"; 35const char kKeyMultiProfilesAllowed[] = "isMultiProfilesAllowed"; 36const char kKeyMultiProfilesPolicy[] = "multiProfilesPolicy"; 37 38// Max number of users to show. 39// Please keep synced with one in signin_userlist_unittest.cc. 40const size_t kMaxUsers = 18; 41 42const int kPasswordClearTimeoutSec = 60; 43 44} // namespace 45 46UserSelectionScreen::UserSelectionScreen() : handler_(NULL) { 47} 48 49UserSelectionScreen::~UserSelectionScreen() { 50 wm::UserActivityDetector* activity_detector = 51 ash::Shell::GetInstance()->user_activity_detector(); 52 if (activity_detector->HasObserver(this)) 53 activity_detector->RemoveObserver(this); 54} 55 56// static 57void 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; 68 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); 77 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); 90 } 91 92 if (is_public_account) { 93 policy::BrowserPolicyConnectorChromeOS* policy_connector = 94 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 95 96 if (policy_connector->IsEnterpriseManaged()) { 97 user_dict->SetString(kKeyEnterpriseDomain, 98 policy_connector->GetEnterpriseDomain()); 99 } 100 } 101} 102 103// static 104bool 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; 115 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; 121 122 if (is_locally_managed_user && 123 token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN) { 124 return false; 125 } 126 127 if (is_public_session) 128 return false; 129 130 return user->force_online_signin() || 131 (token_status == User::OAUTH2_TOKEN_STATUS_INVALID) || 132 (token_status == User::OAUTH_TOKEN_STATUS_UNKNOWN); 133} 134 135void UserSelectionScreen::SetHandler(LoginDisplayWebUIHandler* handler) { 136 handler_ = handler; 137} 138 139void UserSelectionScreen::Init(const UserList& users, bool show_guest) { 140 users_ = users; 141 show_guest_ = show_guest; 142 143 wm::UserActivityDetector* activity_detector = 144 ash::Shell::GetInstance()->user_activity_detector(); 145 if (!activity_detector->HasObserver(this)) 146 activity_detector->AddObserver(this); 147} 148 149void 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; 154 } 155 } 156} 157 158void UserSelectionScreen::OnUserRemoved(const std::string& username) { 159 if (!handler_) 160 return; 161 162 handler_->OnUserRemoved(username); 163} 164 165void UserSelectionScreen::OnUserImageChanged(const User& user) { 166 if (!handler_) 167 return; 168 handler_->OnUserImageChanged(user); 169 // TODO(antrim) : updateUserImage(user.email()) 170} 171 172const UserList& UserSelectionScreen::GetUsers() const { 173 return users_; 174} 175 176void UserSelectionScreen::OnPasswordClearTimerExpired() { 177 if (handler_) 178 handler_->ClearUserPodPassword(); 179} 180 181void 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); 188 } 189 password_clear_timer_.Reset(); 190} 191 192// static 193const UserList UserSelectionScreen::PrepareUserListForSending( 194 const UserList& users, 195 std::string owner, 196 bool is_signin_to_add) { 197 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; 202 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); 208 209 if ((is_public_account && !is_signin_to_add) || is_owner || 210 (!is_public_account && non_owner_count < max_non_owner_users)) { 211 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); 221 } 222 } 223 } 224 return users_to_send; 225} 226 227void UserSelectionScreen::SendUserList() { 228 base::ListValue users_list; 229 const UserList& users = GetUsers(); 230 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); 238 239 policy::BrowserPolicyConnectorChromeOS* connector = 240 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 241 bool is_enterprise_managed = connector->IsEnterpriseManaged(); 242 243 const UserList users_to_send = PrepareUserListForSending(users, 244 owner, 245 is_signin_to_add); 246 247 user_auth_type_map_.clear(); 248 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; 263 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); 276 } 277 278 handler_->LoadUsers(users_list, show_guest_); 279} 280 281void UserSelectionScreen::HandleGetUsers() { 282 SendUserList(); 283} 284 285void UserSelectionScreen::SetAuthType( 286 const std::string& username, 287 ScreenlockBridge::LockHandler::AuthType auth_type) { 288 user_auth_type_map_[username] = auth_type; 289} 290 291ScreenlockBridge::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; 296} 297 298} // namespace chromeos 299