user_manager_screen_handler.cc revision 03b57e008b61dfcb1fbad3aea950ae0e001748b0
1// Copyright 2013 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/ui/webui/signin/user_manager_screen_handler.h" 6 7#include "base/bind.h" 8#include "base/prefs/pref_service.h" 9#include "base/strings/utf_string_conversions.h" 10#include "base/value_conversions.h" 11#include "base/values.h" 12#include "chrome/browser/browser_process.h" 13#include "chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h" 14#include "chrome/browser/profiles/profile.h" 15#include "chrome/browser/profiles/profile_avatar_icon_util.h" 16#include "chrome/browser/profiles/profile_info_cache.h" 17#include "chrome/browser/profiles/profile_info_cache_observer.h" 18#include "chrome/browser/profiles/profile_manager.h" 19#include "chrome/browser/profiles/profile_metrics.h" 20#include "chrome/browser/profiles/profile_window.h" 21#include "chrome/browser/profiles/profiles_state.h" 22#include "chrome/browser/signin/local_auth.h" 23#include "chrome/browser/ui/browser_dialogs.h" 24#include "chrome/browser/ui/browser_finder.h" 25#include "chrome/browser/ui/singleton_tabs.h" 26#include "chrome/common/pref_names.h" 27#include "chrome/common/url_constants.h" 28#include "content/public/browser/web_contents.h" 29#include "content/public/browser/web_ui.h" 30#include "google_apis/gaia/gaia_auth_fetcher.h" 31#include "google_apis/gaia/gaia_constants.h" 32#include "grit/browser_resources.h" 33#include "grit/chromium_strings.h" 34#include "grit/generated_resources.h" 35#include "grit/theme_resources.h" 36#include "third_party/skia/include/core/SkBitmap.h" 37#include "ui/base/l10n/l10n_util.h" 38#include "ui/base/resource/resource_bundle.h" 39#include "ui/base/webui/web_ui_util.h" 40#include "ui/gfx/image/image.h" 41#include "ui/gfx/image/image_skia.h" 42#include "ui/gfx/image/image_util.h" 43 44namespace { 45// User dictionary keys. 46const char kKeyUsername[] = "username"; 47const char kKeyDisplayName[]= "displayName"; 48const char kKeyEmailAddress[] = "emailAddress"; 49const char kKeyProfilePath[] = "profilePath"; 50const char kKeyPublicAccount[] = "publicAccount"; 51const char kKeySupervisedUser[] = "supervisedUser"; 52const char kKeySignedIn[] = "signedIn"; 53const char kKeyCanRemove[] = "canRemove"; 54const char kKeyIsOwner[] = "isOwner"; 55const char kKeyIsDesktop[] = "isDesktopUser"; 56const char kKeyAvatarUrl[] = "userImage"; 57const char kKeyNeedsSignin[] = "needsSignin"; 58 59// JS API callback names. 60const char kJsApiUserManagerInitialize[] = "userManagerInitialize"; 61const char kJsApiUserManagerAddUser[] = "addUser"; 62const char kJsApiUserManagerAuthLaunchUser[] = "authenticatedLaunchUser"; 63const char kJsApiUserManagerLaunchGuest[] = "launchGuest"; 64const char kJsApiUserManagerLaunchUser[] = "launchUser"; 65const char kJsApiUserManagerRemoveUser[] = "removeUser"; 66const char kJsApiUserManagerAttemptUnlock[] = "attemptUnlock"; 67 68const size_t kAvatarIconSize = 180; 69 70void HandleAndDoNothing(const base::ListValue* args) { 71} 72 73// This callback is run if the only profile has been deleted, and a new 74// profile has been created to replace it. 75void OpenNewWindowForProfile( 76 chrome::HostDesktopType desktop_type, 77 Profile* profile, 78 Profile::CreateStatus status) { 79 if (status != Profile::CREATE_STATUS_INITIALIZED) 80 return; 81 profiles::FindOrCreateNewWindowForProfile( 82 profile, 83 chrome::startup::IS_PROCESS_STARTUP, 84 chrome::startup::IS_FIRST_RUN, 85 desktop_type, 86 false); 87} 88 89// This callback is run after switching to a new profile has finished. This 90// means either a new browser window has been opened, or an existing one 91// has been found, which means we can safely close the User Manager without 92// accidentally terminating the browser process. The task needs to be posted, 93// as HideUserManager will end up destroying its WebContents, which will 94// destruct the UserManagerScreenHandler as well. 95void OnSwitchToProfileComplete() { 96 base::MessageLoop::current()->PostTask( 97 FROM_HERE, 98 base::Bind(&chrome::HideUserManager)); 99} 100 101std::string GetAvatarImageAtIndex( 102 size_t index, const ProfileInfoCache& info_cache) { 103 bool is_gaia_picture = 104 info_cache.IsUsingGAIAPictureOfProfileAtIndex(index) && 105 info_cache.GetGAIAPictureOfProfileAtIndex(index); 106 107 // If the avatar is too small (i.e. the old-style low resolution avatar), 108 // it will be pixelated when displayed in the User Manager, so we should 109 // return the placeholder avatar instead. 110 gfx::Image avatar_image = info_cache.GetAvatarIconOfProfileAtIndex(index); 111 if (avatar_image.Width() <= profiles::kAvatarIconWidth || 112 avatar_image.Height() <= profiles::kAvatarIconHeight ) { 113 avatar_image = ui::ResourceBundle::GetSharedInstance().GetImageNamed( 114 profiles::GetPlaceholderAvatarIconResourceID()); 115 } 116 gfx::Image resized_image = profiles::GetSizedAvatarIcon( 117 avatar_image, is_gaia_picture, kAvatarIconSize, kAvatarIconSize); 118 return webui::GetBitmapDataUrl(resized_image.AsBitmap()); 119} 120 121size_t GetIndexOfProfileWithEmailAndName(const ProfileInfoCache& info_cache, 122 const base::string16& email, 123 const base::string16& name) { 124 for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) { 125 if (info_cache.GetUserNameOfProfileAtIndex(i) == email && 126 (name.empty() || 127 profiles::GetAvatarNameForProfile( 128 info_cache.GetPathOfProfileAtIndex(i)) == name)) { 129 return i; 130 } 131 } 132 return std::string::npos; 133} 134 135extensions::ScreenlockPrivateEventRouter* GetScreenlockRouter( 136 const std::string& email) { 137 ProfileInfoCache& info_cache = 138 g_browser_process->profile_manager()->GetProfileInfoCache(); 139 const size_t profile_index = GetIndexOfProfileWithEmailAndName( 140 info_cache, base::UTF8ToUTF16(email), base::string16()); 141 Profile* profile = g_browser_process->profile_manager() 142 ->GetProfileByPath(info_cache.GetPathOfProfileAtIndex(profile_index)); 143 return extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()->Get( 144 profile); 145} 146 147bool IsGuestModeEnabled() { 148 PrefService* service = g_browser_process->local_state(); 149 DCHECK(service); 150 return service->GetBoolean(prefs::kBrowserGuestModeEnabled); 151} 152 153} // namespace 154 155// ProfileUpdateObserver ------------------------------------------------------ 156 157class UserManagerScreenHandler::ProfileUpdateObserver 158 : public ProfileInfoCacheObserver { 159 public: 160 ProfileUpdateObserver( 161 ProfileManager* profile_manager, UserManagerScreenHandler* handler) 162 : profile_manager_(profile_manager), 163 user_manager_handler_(handler) { 164 DCHECK(profile_manager_); 165 DCHECK(user_manager_handler_); 166 profile_manager_->GetProfileInfoCache().AddObserver(this); 167 } 168 169 virtual ~ProfileUpdateObserver() { 170 DCHECK(profile_manager_); 171 profile_manager_->GetProfileInfoCache().RemoveObserver(this); 172 } 173 174 private: 175 // ProfileInfoCacheObserver implementation: 176 // If any change has been made to a profile, propagate it to all the 177 // visible user manager screens. 178 virtual void OnProfileAdded(const base::FilePath& profile_path) OVERRIDE { 179 user_manager_handler_->SendUserList(); 180 } 181 182 virtual void OnProfileWasRemoved( 183 const base::FilePath& profile_path, 184 const base::string16& profile_name) OVERRIDE { 185 // TODO(noms): Change 'SendUserList' to 'removeUser' JS-call when 186 // UserManager is able to find pod belonging to removed user. 187 user_manager_handler_->SendUserList(); 188 } 189 190 virtual void OnProfileNameChanged( 191 const base::FilePath& profile_path, 192 const base::string16& old_profile_name) OVERRIDE { 193 user_manager_handler_->SendUserList(); 194 } 195 196 virtual void OnProfileAvatarChanged( 197 const base::FilePath& profile_path) OVERRIDE { 198 user_manager_handler_->SendUserList(); 199 } 200 201 virtual void OnProfileSigninRequiredChanged( 202 const base::FilePath& profile_path) OVERRIDE { 203 user_manager_handler_->SendUserList(); 204 } 205 206 ProfileManager* profile_manager_; 207 208 UserManagerScreenHandler* user_manager_handler_; // Weak; owns us. 209 210 DISALLOW_COPY_AND_ASSIGN(ProfileUpdateObserver); 211}; 212 213// UserManagerScreenHandler --------------------------------------------------- 214 215UserManagerScreenHandler::UserManagerScreenHandler() 216 : desktop_type_(chrome::GetActiveDesktop()) { 217 profileInfoCacheObserver_.reset( 218 new UserManagerScreenHandler::ProfileUpdateObserver( 219 g_browser_process->profile_manager(), this)); 220} 221 222UserManagerScreenHandler::~UserManagerScreenHandler() { 223 ScreenlockBridge::Get()->SetLockHandler(NULL); 224} 225 226void UserManagerScreenHandler::ShowBannerMessage( 227 const base::string16& message) { 228 web_ui()->CallJavascriptFunction( 229 "login.AccountPickerScreen.showBannerMessage", 230 base::StringValue(message)); 231} 232 233void UserManagerScreenHandler::ShowUserPodCustomIcon( 234 const std::string& user_email, 235 const ScreenlockBridge::UserPodCustomIconOptions& icon_options) { 236 scoped_ptr<base::DictionaryValue> icon = icon_options.ToDictionaryValue(); 237 if (!icon || icon->empty()) 238 return; 239 web_ui()->CallJavascriptFunction( 240 "login.AccountPickerScreen.showUserPodCustomIcon", 241 base::StringValue(user_email), 242 *icon); 243} 244 245void UserManagerScreenHandler::HideUserPodCustomIcon( 246 const std::string& user_email) { 247 web_ui()->CallJavascriptFunction( 248 "login.AccountPickerScreen.hideUserPodCustomIcon", 249 base::StringValue(user_email)); 250} 251 252void UserManagerScreenHandler::EnableInput() { 253 // Nothing here because UI is not disabled when starting to authenticate. 254} 255 256void UserManagerScreenHandler::SetAuthType( 257 const std::string& user_email, 258 ScreenlockBridge::LockHandler::AuthType auth_type, 259 const base::string16& auth_value) { 260 if (GetAuthType(user_email) == 261 ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD) 262 return; 263 264 user_auth_type_map_[user_email] = auth_type; 265 web_ui()->CallJavascriptFunction( 266 "login.AccountPickerScreen.setAuthType", 267 base::StringValue(user_email), 268 base::FundamentalValue(auth_type), 269 base::StringValue(auth_value)); 270} 271 272ScreenlockBridge::LockHandler::AuthType UserManagerScreenHandler::GetAuthType( 273 const std::string& user_email) const { 274 UserAuthTypeMap::const_iterator it = user_auth_type_map_.find(user_email); 275 if (it == user_auth_type_map_.end()) 276 return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; 277 return it->second; 278} 279 280void UserManagerScreenHandler::Unlock(const std::string& user_email) { 281 ProfileInfoCache& info_cache = 282 g_browser_process->profile_manager()->GetProfileInfoCache(); 283 const size_t profile_index = GetIndexOfProfileWithEmailAndName( 284 info_cache, base::UTF8ToUTF16(user_email), base::string16()); 285 DCHECK_LT(profile_index, info_cache.GetNumberOfProfiles()); 286 287 authenticating_profile_index_ = profile_index; 288 ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL); 289} 290 291void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) { 292 SendUserList(); 293 web_ui()->CallJavascriptFunction("cr.ui.Oobe.showUserManagerScreen", 294 base::FundamentalValue(IsGuestModeEnabled())); 295 desktop_type_ = chrome::GetHostDesktopTypeForNativeView( 296 web_ui()->GetWebContents()->GetNativeView()); 297 298 ScreenlockBridge::Get()->SetLockHandler(this); 299} 300 301void UserManagerScreenHandler::HandleAddUser(const base::ListValue* args) { 302 profiles::CreateAndSwitchToNewProfile(desktop_type_, 303 base::Bind(&OnSwitchToProfileComplete), 304 ProfileMetrics::ADD_NEW_USER_MANAGER); 305} 306 307void UserManagerScreenHandler::HandleAuthenticatedLaunchUser( 308 const base::ListValue* args) { 309 base::string16 email_address; 310 if (!args->GetString(0, &email_address)) 311 return; 312 313 base::string16 display_name; 314 if (!args->GetString(1, &display_name)) 315 return; 316 317 std::string password; 318 if (!args->GetString(2, &password)) 319 return; 320 321 ProfileInfoCache& info_cache = 322 g_browser_process->profile_manager()->GetProfileInfoCache(); 323 size_t profile_index = GetIndexOfProfileWithEmailAndName( 324 info_cache, email_address, display_name); 325 if (profile_index >= info_cache.GetNumberOfProfiles()) { 326 NOTREACHED(); 327 return; 328 } 329 330 authenticating_profile_index_ = profile_index; 331 if (!chrome::ValidateLocalAuthCredentials(profile_index, password)) { 332 // Make a second attempt via an on-line authentication call. This handles 333 // profiles that are missing sign-in credentials and also cases where the 334 // password has been changed externally. 335 client_login_.reset(new GaiaAuthFetcher( 336 this, 337 GaiaConstants::kChromeSource, 338 web_ui()->GetWebContents()->GetBrowserContext()->GetRequestContext())); 339 std::string email_string; 340 args->GetString(0, &email_string); 341 client_login_->StartClientLogin( 342 email_string, 343 password, 344 GaiaConstants::kSyncService, 345 std::string(), 346 std::string(), 347 GaiaAuthFetcher::HostedAccountsAllowed); 348 password_attempt_ = password; 349 return; 350 } 351 352 ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL); 353} 354 355void UserManagerScreenHandler::HandleRemoveUser(const base::ListValue* args) { 356 DCHECK(args); 357 const base::Value* profile_path_value; 358 if (!args->Get(0, &profile_path_value)) 359 return; 360 361 base::FilePath profile_path; 362 if (!base::GetValueAsFilePath(*profile_path_value, &profile_path)) 363 return; 364 365 // This handler could have been called for a supervised user, for example 366 // because the user fiddled with the web inspector. Silently return in this 367 // case. 368 if (Profile::FromWebUI(web_ui())->IsSupervised()) 369 return; 370 371 if (!profiles::IsMultipleProfilesEnabled()) 372 return; 373 374 g_browser_process->profile_manager()->ScheduleProfileForDeletion( 375 profile_path, 376 base::Bind(&OpenNewWindowForProfile, desktop_type_)); 377 ProfileMetrics::LogProfileDeleteUser( 378 ProfileMetrics::DELETE_PROFILE_USER_MANAGER); 379} 380 381void UserManagerScreenHandler::HandleLaunchGuest(const base::ListValue* args) { 382 if (IsGuestModeEnabled()) { 383 profiles::SwitchToGuestProfile(desktop_type_, 384 base::Bind(&OnSwitchToProfileComplete)); 385 ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::SWITCH_PROFILE_GUEST); 386 } else { 387 // The UI should have prevented the user from allowing the selection of 388 // guest mode. 389 NOTREACHED(); 390 } 391} 392 393void UserManagerScreenHandler::HandleLaunchUser(const base::ListValue* args) { 394 base::string16 email_address; 395 base::string16 display_name; 396 397 if (!args->GetString(0, &email_address) || 398 !args->GetString(1, &display_name)) { 399 NOTREACHED(); 400 return; 401 } 402 403 ProfileInfoCache& info_cache = 404 g_browser_process->profile_manager()->GetProfileInfoCache(); 405 size_t profile_index = GetIndexOfProfileWithEmailAndName( 406 info_cache, email_address, display_name); 407 408 if (profile_index >= info_cache.GetNumberOfProfiles()) { 409 NOTREACHED(); 410 return; 411 } 412 413 // It's possible that a user breaks into the user-manager page using the 414 // JavaScript Inspector and causes a "locked" profile to call this 415 // unauthenticated version of "launch" instead of the proper one. Thus, 416 // we have to validate in (secure) C++ code that it really is a profile 417 // not needing authentication. If it is, just ignore the "launch" request. 418 if (info_cache.ProfileIsSigninRequiredAtIndex(profile_index)) 419 return; 420 ProfileMetrics::LogProfileAuthResult(ProfileMetrics::AUTH_UNNECESSARY); 421 422 base::FilePath path = info_cache.GetPathOfProfileAtIndex(profile_index); 423 profiles::SwitchToProfile(path, 424 desktop_type_, 425 false, /* reuse any existing windows */ 426 base::Bind(&OnSwitchToProfileComplete), 427 ProfileMetrics::SWITCH_PROFILE_MANAGER); 428} 429 430void UserManagerScreenHandler::HandleAttemptUnlock( 431 const base::ListValue* args) { 432 std::string email; 433 CHECK(args->GetString(0, &email)); 434 GetScreenlockRouter(email)->OnAuthAttempted(GetAuthType(email), ""); 435} 436 437void UserManagerScreenHandler::HandleHardlockUserPod( 438 const base::ListValue* args) { 439 std::string email; 440 CHECK(args->GetString(0, &email)); 441 SetAuthType(email, 442 ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD, 443 base::string16()); 444 HideUserPodCustomIcon(email); 445} 446 447void UserManagerScreenHandler::OnClientLoginSuccess( 448 const ClientLoginResult& result) { 449 chrome::SetLocalAuthCredentials(authenticating_profile_index_, 450 password_attempt_); 451 ReportAuthenticationResult(true, ProfileMetrics::AUTH_ONLINE); 452} 453 454void UserManagerScreenHandler::OnClientLoginFailure( 455 const GoogleServiceAuthError& error) { 456 const GoogleServiceAuthError::State state = error.state(); 457 // Some "error" results mean the password was correct but some other action 458 // should be taken. For our purposes, we only care that the password was 459 // correct so count those as a success. 460 bool success = (state == GoogleServiceAuthError::NONE || 461 state == GoogleServiceAuthError::CAPTCHA_REQUIRED || 462 state == GoogleServiceAuthError::TWO_FACTOR || 463 state == GoogleServiceAuthError::ACCOUNT_DELETED || 464 state == GoogleServiceAuthError::ACCOUNT_DISABLED); 465 ReportAuthenticationResult(success, 466 success ? ProfileMetrics::AUTH_ONLINE 467 : ProfileMetrics::AUTH_FAILED); 468} 469 470void UserManagerScreenHandler::RegisterMessages() { 471 web_ui()->RegisterMessageCallback(kJsApiUserManagerInitialize, 472 base::Bind(&UserManagerScreenHandler::HandleInitialize, 473 base::Unretained(this))); 474 web_ui()->RegisterMessageCallback(kJsApiUserManagerAddUser, 475 base::Bind(&UserManagerScreenHandler::HandleAddUser, 476 base::Unretained(this))); 477 web_ui()->RegisterMessageCallback(kJsApiUserManagerAuthLaunchUser, 478 base::Bind(&UserManagerScreenHandler::HandleAuthenticatedLaunchUser, 479 base::Unretained(this))); 480 web_ui()->RegisterMessageCallback(kJsApiUserManagerLaunchGuest, 481 base::Bind(&UserManagerScreenHandler::HandleLaunchGuest, 482 base::Unretained(this))); 483 web_ui()->RegisterMessageCallback(kJsApiUserManagerLaunchUser, 484 base::Bind(&UserManagerScreenHandler::HandleLaunchUser, 485 base::Unretained(this))); 486 web_ui()->RegisterMessageCallback(kJsApiUserManagerRemoveUser, 487 base::Bind(&UserManagerScreenHandler::HandleRemoveUser, 488 base::Unretained(this))); 489 web_ui()->RegisterMessageCallback(kJsApiUserManagerAttemptUnlock, 490 base::Bind(&UserManagerScreenHandler::HandleAttemptUnlock, 491 base::Unretained(this))); 492 493 const content::WebUI::MessageCallback& kDoNothingCallback = 494 base::Bind(&HandleAndDoNothing); 495 496 // Unused callbacks from screen_account_picker.js 497 web_ui()->RegisterMessageCallback("accountPickerReady", kDoNothingCallback); 498 web_ui()->RegisterMessageCallback("loginUIStateChanged", kDoNothingCallback); 499 web_ui()->RegisterMessageCallback("hideCaptivePortal", kDoNothingCallback); 500 // Unused callbacks from display_manager.js 501 web_ui()->RegisterMessageCallback("showAddUser", kDoNothingCallback); 502 web_ui()->RegisterMessageCallback("loadWallpaper", kDoNothingCallback); 503 web_ui()->RegisterMessageCallback("updateCurrentScreen", kDoNothingCallback); 504 web_ui()->RegisterMessageCallback("loginVisible", kDoNothingCallback); 505 // Unused callbacks from user_pod_row.js 506 web_ui()->RegisterMessageCallback("focusPod", kDoNothingCallback); 507} 508 509void UserManagerScreenHandler::GetLocalizedValues( 510 base::DictionaryValue* localized_strings) { 511 // For Control Bar. 512 localized_strings->SetString("signedIn", 513 l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_ACTIVE_USER)); 514 localized_strings->SetString("signinButton", 515 l10n_util::GetStringUTF16(IDS_LOGIN_BUTTON)); 516 localized_strings->SetString("addUser", 517 l10n_util::GetStringUTF16(IDS_ADD_USER_BUTTON)); 518 localized_strings->SetString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL)); 519 localized_strings->SetString("browseAsGuest", 520 l10n_util::GetStringUTF16(IDS_GO_INCOGNITO_BUTTON)); 521 localized_strings->SetString("signOutUser", 522 l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_SIGN_OUT)); 523 524 // For AccountPickerScreen. 525 localized_strings->SetString("screenType", "login-add-user"); 526 localized_strings->SetString("highlightStrength", "normal"); 527 localized_strings->SetString("title", 528 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)); 529 localized_strings->SetString("passwordHint", 530 l10n_util::GetStringUTF16(IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT)); 531 localized_strings->SetString("podMenuButtonAccessibleName", 532 l10n_util::GetStringUTF16(IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME)); 533 localized_strings->SetString("podMenuRemoveItemAccessibleName", 534 l10n_util::GetStringUTF16( 535 IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME)); 536 localized_strings->SetString("removeUser", 537 l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON)); 538 localized_strings->SetString("passwordFieldAccessibleName", 539 l10n_util::GetStringUTF16(IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME)); 540 localized_strings->SetString("bootIntoWallpaper", "off"); 541 542 // For AccountPickerScreen, the remove user warning overlay. 543 localized_strings->SetString("removeUserWarningButtonTitle", 544 l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON)); 545 localized_strings->SetString("removeUserWarningText", 546 l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING)); 547 localized_strings->SetString("removeSupervisedUserWarningText", 548 l10n_util::GetStringFUTF16( 549 IDS_LOGIN_POD_SUPERVISED_USER_REMOVE_WARNING, 550 base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL))); 551 552 // Strings needed for the User Manager tutorial slides. 553 localized_strings->SetString("tutorialNext", 554 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_NEXT)); 555 localized_strings->SetString("tutorialDone", 556 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_DONE)); 557 localized_strings->SetString("slideWelcomeTitle", 558 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_INTRO_TITLE)); 559 localized_strings->SetString("slideWelcomeText", 560 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_INTRO_TEXT)); 561 localized_strings->SetString("slideYourChromeTitle", 562 l10n_util::GetStringUTF16( 563 IDS_USER_MANAGER_TUTORIAL_SLIDE_YOUR_CHROME_TITLE)); 564 localized_strings->SetString("slideYourChromeText", l10n_util::GetStringUTF16( 565 IDS_USER_MANAGER_TUTORIAL_SLIDE_YOUR_CHROME_TEXT)); 566 localized_strings->SetString("slideGuestsTitle", 567 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_GUEST_TITLE)); 568 localized_strings->SetString("slideGuestsText", 569 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_GUEST_TEXT)); 570 localized_strings->SetString("slideFriendsTitle", 571 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_FRIENDS_TITLE)); 572 localized_strings->SetString("slideFriendsText", 573 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_FRIENDS_TEXT)); 574 localized_strings->SetString("slideCompleteTitle", 575 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_TITLE)); 576 localized_strings->SetString("slideCompleteText", 577 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_TEXT)); 578 localized_strings->SetString("slideCompleteUserNotFound", 579 l10n_util::GetStringUTF16( 580 IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_USER_NOT_FOUND)); 581 localized_strings->SetString("slideCompleteAddUser", 582 l10n_util::GetStringUTF16( 583 IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_ADD_USER)); 584 585 // Strings needed for the user_pod_template public account div, but not ever 586 // actually displayed for desktop users. 587 localized_strings->SetString("publicAccountReminder", base::string16()); 588 localized_strings->SetString("publicSessionLanguageAndInput", 589 base::string16()); 590 localized_strings->SetString("publicAccountEnter", base::string16()); 591 localized_strings->SetString("publicAccountEnterAccessibleName", 592 base::string16()); 593 localized_strings->SetString("publicSessionSelectLanguage", base::string16()); 594 localized_strings->SetString("publicSessionSelectKeyboard", base::string16()); 595 localized_strings->SetString("signinBannerText", base::string16()); 596 localized_strings->SetString("launchAppButton", base::string16()); 597 localized_strings->SetString("multiProfilesRestrictedPolicyTitle", 598 base::string16()); 599 localized_strings->SetString("multiProfilesNotAllowedPolicyMsg", 600 base::string16()); 601 localized_strings->SetString("multiProfilesPrimaryOnlyPolicyMsg", 602 base::string16()); 603 localized_strings->SetString("multiProfilesOwnerPrimaryOnlyMsg", 604 base::string16()); 605} 606 607void UserManagerScreenHandler::SendUserList() { 608 base::ListValue users_list; 609 base::FilePath active_profile_path = 610 web_ui()->GetWebContents()->GetBrowserContext()->GetPath(); 611 const ProfileInfoCache& info_cache = 612 g_browser_process->profile_manager()->GetProfileInfoCache(); 613 614 user_auth_type_map_.clear(); 615 616 // If the active user is a supervised user, then they may not perform 617 // certain actions (i.e. delete another user). 618 bool active_user_is_supervised = Profile::FromWebUI(web_ui())->IsSupervised(); 619 for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) { 620 base::DictionaryValue* profile_value = new base::DictionaryValue(); 621 622 base::FilePath profile_path = info_cache.GetPathOfProfileAtIndex(i); 623 bool is_active_user = (profile_path == active_profile_path); 624 625 profile_value->SetString( 626 kKeyUsername, info_cache.GetUserNameOfProfileAtIndex(i)); 627 profile_value->SetString( 628 kKeyEmailAddress, info_cache.GetUserNameOfProfileAtIndex(i)); 629 // The profiles displayed in the User Manager are never guest profiles. 630 profile_value->SetString( 631 kKeyDisplayName, 632 profiles::GetAvatarNameForProfile(profile_path)); 633 profile_value->SetString(kKeyProfilePath, profile_path.MaybeAsASCII()); 634 profile_value->SetBoolean(kKeyPublicAccount, false); 635 profile_value->SetBoolean( 636 kKeySupervisedUser, info_cache.ProfileIsSupervisedAtIndex(i)); 637 profile_value->SetBoolean(kKeySignedIn, is_active_user); 638 profile_value->SetBoolean( 639 kKeyNeedsSignin, info_cache.ProfileIsSigninRequiredAtIndex(i)); 640 profile_value->SetBoolean(kKeyIsOwner, false); 641 profile_value->SetBoolean(kKeyCanRemove, !active_user_is_supervised); 642 profile_value->SetBoolean(kKeyIsDesktop, true); 643 profile_value->SetString( 644 kKeyAvatarUrl, GetAvatarImageAtIndex(i, info_cache)); 645 646 // The row of user pods should display the active user first. 647 if (is_active_user) 648 users_list.Insert(0, profile_value); 649 else 650 users_list.Append(profile_value); 651 } 652 653 web_ui()->CallJavascriptFunction("login.AccountPickerScreen.loadUsers", 654 users_list, base::FundamentalValue(IsGuestModeEnabled())); 655} 656 657void UserManagerScreenHandler::ReportAuthenticationResult( 658 bool success, 659 ProfileMetrics::ProfileAuth auth) { 660 ProfileMetrics::LogProfileAuthResult(auth); 661 password_attempt_.clear(); 662 663 if (success) { 664 ProfileInfoCache& info_cache = 665 g_browser_process->profile_manager()->GetProfileInfoCache(); 666 info_cache.SetProfileSigninRequiredAtIndex( 667 authenticating_profile_index_, false); 668 base::FilePath path = info_cache.GetPathOfProfileAtIndex( 669 authenticating_profile_index_); 670 profiles::SwitchToProfile(path, desktop_type_, true, 671 base::Bind(&OnSwitchToProfileComplete), 672 ProfileMetrics::SWITCH_PROFILE_UNLOCK); 673 } else { 674 web_ui()->CallJavascriptFunction( 675 "cr.ui.Oobe.showSignInError", 676 base::FundamentalValue(0), 677 base::StringValue( 678 l10n_util::GetStringUTF8(IDS_LOGIN_ERROR_AUTHENTICATING)), 679 base::StringValue(""), 680 base::FundamentalValue(0)); 681 } 682} 683