user_selection_screen.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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 "ui/wm/core/user_activity_detector.h" 18 19namespace chromeos { 20 21namespace { 22 23// User dictionary keys. 24const char kKeyUsername[] = "username"; 25const char kKeyDisplayName[] = "displayName"; 26const char kKeyEmailAddress[] = "emailAddress"; 27const char kKeyEnterpriseDomain[] = "enterpriseDomain"; 28const char kKeyPublicAccount[] = "publicAccount"; 29const char kKeyLocallyManagedUser[] = "locallyManagedUser"; 30const char kKeySignedIn[] = "signedIn"; 31const char kKeyCanRemove[] = "canRemove"; 32const char kKeyIsOwner[] = "isOwner"; 33const char kKeyInitialAuthType[] = "initialAuthType"; 34const char kKeyMultiProfilesAllowed[] = "isMultiProfilesAllowed"; 35const char kKeyMultiProfilesPolicy[] = "multiProfilesPolicy"; 36 37// Max number of users to show. 38const size_t kMaxUsers = 18; 39 40const int kPasswordClearTimeoutSec = 60; 41 42} // namespace 43 44UserSelectionScreen::UserSelectionScreen() : handler_(NULL) { 45} 46 47UserSelectionScreen::~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 55void 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 102bool 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} 132 133void UserSelectionScreen::SetHandler(LoginDisplayWebUIHandler* handler) { 134 handler_ = handler; 135} 136 137void UserSelectionScreen::Init(const UserList& users, bool show_guest) { 138 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} 146 147void UserSelectionScreen::OnBeforeUserRemoved(const std::string& username) { 148 for (UserList::iterator it = users_.begin(); it != users_.end(); ++it) { 149 if ((*it)->email() == username) { 150 users_.erase(it); 151 break; 152 } 153 } 154} 155 156void UserSelectionScreen::OnUserRemoved(const std::string& username) { 157 if (!handler_) 158 return; 159 160 handler_->OnUserRemoved(username); 161} 162 163void UserSelectionScreen::OnUserImageChanged(const User& user) { 164 if (!handler_) 165 return; 166 handler_->OnUserImageChanged(user); 167 // TODO(antrim) : updateUserImage(user.email()) 168} 169 170const UserList& UserSelectionScreen::GetUsers() const { 171 return users_; 172} 173 174void UserSelectionScreen::OnPasswordClearTimerExpired() { 175 if (handler_) 176 handler_->ClearUserPodPassword(); 177} 178 179void 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 190void 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 255void UserSelectionScreen::HandleGetUsers() { 256 SendUserList(false); 257} 258 259void UserSelectionScreen::SetAuthType( 260 const std::string& username, 261 ScreenlockBridge::LockHandler::AuthType auth_type) { 262 user_auth_type_map_[username] = auth_type; 263} 264 265ScreenlockBridge::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 273