Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / ui / webui / signin / user_manager_screen_handler.cc
blob594aff0a8af69417162fe5c15201ac3aef0771c8
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.
5 #include "chrome/browser/ui/webui/signin/user_manager_screen_handler.h"
7 #include "base/bind.h"
8 #include "base/value_conversions.h"
9 #include "base/values.h"
10 #include "chrome/browser/browser_process.h"
11 #include "chrome/browser/profiles/profile.h"
12 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
13 #include "chrome/browser/profiles/profile_info_cache.h"
14 #include "chrome/browser/profiles/profile_info_cache_observer.h"
15 #include "chrome/browser/profiles/profile_manager.h"
16 #include "chrome/browser/profiles/profile_window.h"
17 #include "chrome/browser/profiles/profiles_state.h"
18 #include "chrome/browser/signin/local_auth.h"
19 #include "chrome/browser/ui/browser_dialogs.h"
20 #include "chrome/browser/ui/browser_finder.h"
21 #include "chrome/browser/ui/singleton_tabs.h"
22 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_ui.h"
24 #include "google_apis/gaia/gaia_auth_fetcher.h"
25 #include "google_apis/gaia/gaia_constants.h"
26 #include "grit/browser_resources.h"
27 #include "grit/chromium_strings.h"
28 #include "grit/generated_resources.h"
29 #include "grit/theme_resources.h"
30 #include "third_party/skia/include/core/SkBitmap.h"
31 #include "ui/base/l10n/l10n_util.h"
32 #include "ui/base/resource/resource_bundle.h"
33 #include "ui/base/webui/web_ui_util.h"
34 #include "ui/gfx/image/image_util.h"
36 #if defined(ENABLE_MANAGED_USERS)
37 #include "chrome/browser/managed_mode/managed_user_service.h"
38 #endif
40 namespace {
41 // User dictionary keys.
42 const char kKeyUsername[] = "username";
43 const char kKeyDisplayName[]= "displayName";
44 const char kKeyEmailAddress[] = "emailAddress";
45 const char kKeyProfilePath[] = "profilePath";
46 const char kKeyPublicAccount[] = "publicAccount";
47 const char kKeyLocallyManagedUser[] = "locallyManagedUser";
48 const char kKeySignedIn[] = "signedIn";
49 const char kKeyCanRemove[] = "canRemove";
50 const char kKeyIsOwner[] = "isOwner";
51 const char kKeyIsDesktop[] = "isDesktopUser";
52 const char kKeyAvatarUrl[] = "userImage";
53 const char kKeyNeedsSignin[] = "needsSignin";
55 // JS API callback names.
56 const char kJsApiUserManagerInitialize[] = "userManagerInitialize";
57 const char kJsApiUserManagerAddUser[] = "addUser";
58 const char kJsApiUserManagerAuthLaunchUser[] = "authenticatedLaunchUser";
59 const char kJsApiUserManagerLaunchGuest[] = "launchGuest";
60 const char kJsApiUserManagerLaunchUser[] = "launchUser";
61 const char kJsApiUserManagerRemoveUser[] = "removeUser";
63 const size_t kAvatarIconSize = 180;
65 void HandleAndDoNothing(const base::ListValue* args) {
68 // This callback is run if the only profile has been deleted, and a new
69 // profile has been created to replace it.
70 void OpenNewWindowForProfile(
71 chrome::HostDesktopType desktop_type,
72 Profile* profile,
73 Profile::CreateStatus status) {
74 if (status != Profile::CREATE_STATUS_INITIALIZED)
75 return;
76 profiles::FindOrCreateNewWindowForProfile(
77 profile,
78 chrome::startup::IS_PROCESS_STARTUP,
79 chrome::startup::IS_FIRST_RUN,
80 desktop_type,
81 false);
84 // This callback is run after switching to a new profile has finished. This
85 // means either a new browser window has been opened, or an existing one
86 // has been found, which means we can safely close the User Manager without
87 // accidentally terminating the browser process. The task needs to be posted,
88 // as HideUserManager will end up destroying its WebContents, which will
89 // destruct the UserManagerScreenHandler as well.
90 void OnSwitchToProfileComplete() {
91 base::MessageLoop::current()->PostTask(
92 FROM_HERE,
93 base::Bind(&chrome::HideUserManager));
96 std::string GetAvatarImageAtIndex(
97 size_t index, const ProfileInfoCache& info_cache) {
98 bool is_gaia_picture =
99 info_cache.IsUsingGAIAPictureOfProfileAtIndex(index) &&
100 info_cache.GetGAIAPictureOfProfileAtIndex(index);
102 // If the avatar is too small (i.e. the old-style low resolution avatar),
103 // it will be pixelated when displayed in the User Manager, so we should
104 // return the placeholder avatar instead.
105 gfx::Image avatar_image = info_cache.GetAvatarIconOfProfileAtIndex(index);
106 if (avatar_image.Width() <= profiles::kAvatarIconWidth ||
107 avatar_image.Height() <= profiles::kAvatarIconHeight ) {
108 avatar_image = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
109 profiles::GetPlaceholderAvatarIconResourceID());
111 gfx::Image resized_image = profiles::GetSizedAvatarIcon(
112 avatar_image, is_gaia_picture, kAvatarIconSize, kAvatarIconSize);
113 return webui::GetBitmapDataUrl(resized_image.AsBitmap());
116 size_t GetIndexOfProfileWithEmailAndName(const ProfileInfoCache& info_cache,
117 const base::string16& email,
118 const base::string16& name) {
119 for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) {
120 if (info_cache.GetUserNameOfProfileAtIndex(i) == email &&
121 info_cache.GetNameOfProfileAtIndex(i) == name) {
122 return i;
125 return std::string::npos;
128 } // namespace
130 // ProfileUpdateObserver ------------------------------------------------------
132 class UserManagerScreenHandler::ProfileUpdateObserver
133 : public ProfileInfoCacheObserver {
134 public:
135 ProfileUpdateObserver(
136 ProfileManager* profile_manager, UserManagerScreenHandler* handler)
137 : profile_manager_(profile_manager),
138 user_manager_handler_(handler) {
139 DCHECK(profile_manager_);
140 DCHECK(user_manager_handler_);
141 profile_manager_->GetProfileInfoCache().AddObserver(this);
144 virtual ~ProfileUpdateObserver() {
145 DCHECK(profile_manager_);
146 profile_manager_->GetProfileInfoCache().RemoveObserver(this);
149 private:
150 // ProfileInfoCacheObserver implementation:
151 // If any change has been made to a profile, propagate it to all the
152 // visible user manager screens.
153 virtual void OnProfileAdded(const base::FilePath& profile_path) OVERRIDE {
154 user_manager_handler_->SendUserList();
157 virtual void OnProfileWasRemoved(
158 const base::FilePath& profile_path,
159 const base::string16& profile_name) OVERRIDE {
160 // TODO(noms): Change 'SendUserList' to 'removeUser' JS-call when
161 // UserManager is able to find pod belonging to removed user.
162 user_manager_handler_->SendUserList();
165 virtual void OnProfileNameChanged(
166 const base::FilePath& profile_path,
167 const base::string16& old_profile_name) OVERRIDE {
168 user_manager_handler_->SendUserList();
171 virtual void OnProfileAvatarChanged(
172 const base::FilePath& profile_path) OVERRIDE {
173 user_manager_handler_->SendUserList();
176 virtual void OnProfileSigninRequiredChanged(
177 const base::FilePath& profile_path) OVERRIDE {
178 user_manager_handler_->SendUserList();
181 ProfileManager* profile_manager_;
183 UserManagerScreenHandler* user_manager_handler_; // Weak; owns us.
185 DISALLOW_COPY_AND_ASSIGN(ProfileUpdateObserver);
188 // UserManagerScreenHandler ---------------------------------------------------
190 UserManagerScreenHandler::UserManagerScreenHandler()
191 : desktop_type_(chrome::GetActiveDesktop()) {
192 profileInfoCacheObserver_.reset(
193 new UserManagerScreenHandler::ProfileUpdateObserver(
194 g_browser_process->profile_manager(), this));
197 UserManagerScreenHandler::~UserManagerScreenHandler() {
200 void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) {
201 SendUserList();
202 web_ui()->CallJavascriptFunction("cr.ui.Oobe.showUserManagerScreen");
203 desktop_type_ = chrome::GetHostDesktopTypeForNativeView(
204 web_ui()->GetWebContents()->GetNativeView());
207 void UserManagerScreenHandler::HandleAddUser(const base::ListValue* args) {
208 profiles::CreateAndSwitchToNewProfile(desktop_type_,
209 base::Bind(&OnSwitchToProfileComplete),
210 ProfileMetrics::ADD_NEW_USER_MANAGER);
213 void UserManagerScreenHandler::HandleAuthenticatedLaunchUser(
214 const base::ListValue* args) {
215 base::string16 email_address;
216 if (!args->GetString(0, &email_address))
217 return;
219 base::string16 display_name;
220 if (!args->GetString(1, &display_name))
221 return;
223 std::string password;
224 if (!args->GetString(2, &password))
225 return;
227 ProfileInfoCache& info_cache =
228 g_browser_process->profile_manager()->GetProfileInfoCache();
229 size_t profile_index = GetIndexOfProfileWithEmailAndName(
230 info_cache, email_address, display_name);
231 if (profile_index >= info_cache.GetNumberOfProfiles()) {
232 NOTREACHED();
233 return;
236 authenticating_profile_index_ = profile_index;
237 if (!chrome::ValidateLocalAuthCredentials(profile_index, password)) {
238 // Make a second attempt via an on-line authentication call. This handles
239 // profiles that are missing sign-in credentials and also cases where the
240 // password has been changed externally.
241 client_login_.reset(new GaiaAuthFetcher(
242 this,
243 GaiaConstants::kChromeSource,
244 web_ui()->GetWebContents()->GetBrowserContext()->GetRequestContext()));
245 std::string email_string;
246 args->GetString(0, &email_string);
247 client_login_->StartClientLogin(
248 email_string,
249 password,
250 GaiaConstants::kSyncService,
251 std::string(),
252 std::string(),
253 GaiaAuthFetcher::HostedAccountsAllowed);
254 password_attempt_ = password;
255 return;
258 ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL);
261 void UserManagerScreenHandler::HandleRemoveUser(const base::ListValue* args) {
262 DCHECK(args);
263 const base::Value* profile_path_value;
264 if (!args->Get(0, &profile_path_value))
265 return;
267 base::FilePath profile_path;
268 if (!base::GetValueAsFilePath(*profile_path_value, &profile_path))
269 return;
271 // This handler could have been called in managed mode, for example because
272 // the user fiddled with the web inspector. Silently return in this case.
273 if (Profile::FromWebUI(web_ui())->IsManaged())
274 return;
276 if (!profiles::IsMultipleProfilesEnabled())
277 return;
279 g_browser_process->profile_manager()->ScheduleProfileForDeletion(
280 profile_path,
281 base::Bind(&OpenNewWindowForProfile, desktop_type_));
282 ProfileMetrics::LogProfileDeleteUser(ProfileMetrics::PROFILE_DELETED);
285 void UserManagerScreenHandler::HandleLaunchGuest(const base::ListValue* args) {
286 profiles::SwitchToGuestProfile(desktop_type_,
287 base::Bind(&OnSwitchToProfileComplete));
288 ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::SWITCH_PROFILE_GUEST);
291 void UserManagerScreenHandler::HandleLaunchUser(const base::ListValue* args) {
292 base::string16 email_address;
293 base::string16 display_name;
295 if (!args->GetString(0, &email_address) ||
296 !args->GetString(1, &display_name)) {
297 NOTREACHED();
298 return;
301 ProfileInfoCache& info_cache =
302 g_browser_process->profile_manager()->GetProfileInfoCache();
303 size_t profile_index = GetIndexOfProfileWithEmailAndName(
304 info_cache, email_address, display_name);
306 if (profile_index >= info_cache.GetNumberOfProfiles()) {
307 NOTREACHED();
308 return;
311 // It's possible that a user breaks into the user-manager page using the
312 // JavaScript Inspector and causes a "locked" profile to call this
313 // unauthenticated version of "launch" instead of the proper one. Thus,
314 // we have to validate in (secure) C++ code that it really is a profile
315 // not needing authentication. If it is, just ignore the "launch" request.
316 if (info_cache.ProfileIsSigninRequiredAtIndex(profile_index))
317 return;
318 ProfileMetrics::LogProfileAuthResult(ProfileMetrics::AUTH_UNNECESSARY);
320 base::FilePath path = info_cache.GetPathOfProfileAtIndex(profile_index);
321 profiles::SwitchToProfile(path,
322 desktop_type_,
323 false, /* reuse any existing windows */
324 base::Bind(&OnSwitchToProfileComplete),
325 ProfileMetrics::SWITCH_PROFILE_MANAGER);
328 void UserManagerScreenHandler::OnClientLoginSuccess(
329 const ClientLoginResult& result) {
330 chrome::SetLocalAuthCredentials(authenticating_profile_index_,
331 password_attempt_);
332 ReportAuthenticationResult(true, ProfileMetrics::AUTH_ONLINE);
335 void UserManagerScreenHandler::OnClientLoginFailure(
336 const GoogleServiceAuthError& error) {
337 const GoogleServiceAuthError::State state = error.state();
338 // Some "error" results mean the password was correct but some other action
339 // should be taken. For our purposes, we only care that the password was
340 // correct so count those as a success.
341 bool success = (state == GoogleServiceAuthError::NONE ||
342 state == GoogleServiceAuthError::CAPTCHA_REQUIRED ||
343 state == GoogleServiceAuthError::TWO_FACTOR ||
344 state == GoogleServiceAuthError::ACCOUNT_DELETED ||
345 state == GoogleServiceAuthError::ACCOUNT_DISABLED);
346 ReportAuthenticationResult(success,
347 success ? ProfileMetrics::AUTH_ONLINE
348 : ProfileMetrics::AUTH_FAILED);
351 void UserManagerScreenHandler::RegisterMessages() {
352 web_ui()->RegisterMessageCallback(kJsApiUserManagerInitialize,
353 base::Bind(&UserManagerScreenHandler::HandleInitialize,
354 base::Unretained(this)));
355 web_ui()->RegisterMessageCallback(kJsApiUserManagerAddUser,
356 base::Bind(&UserManagerScreenHandler::HandleAddUser,
357 base::Unretained(this)));
358 web_ui()->RegisterMessageCallback(kJsApiUserManagerAuthLaunchUser,
359 base::Bind(&UserManagerScreenHandler::HandleAuthenticatedLaunchUser,
360 base::Unretained(this)));
361 web_ui()->RegisterMessageCallback(kJsApiUserManagerLaunchGuest,
362 base::Bind(&UserManagerScreenHandler::HandleLaunchGuest,
363 base::Unretained(this)));
364 web_ui()->RegisterMessageCallback(kJsApiUserManagerLaunchUser,
365 base::Bind(&UserManagerScreenHandler::HandleLaunchUser,
366 base::Unretained(this)));
367 web_ui()->RegisterMessageCallback(kJsApiUserManagerRemoveUser,
368 base::Bind(&UserManagerScreenHandler::HandleRemoveUser,
369 base::Unretained(this)));
371 const content::WebUI::MessageCallback& kDoNothingCallback =
372 base::Bind(&HandleAndDoNothing);
374 // Unused callbacks from screen_account_picker.js
375 web_ui()->RegisterMessageCallback("accountPickerReady", kDoNothingCallback);
376 web_ui()->RegisterMessageCallback("loginUIStateChanged", kDoNothingCallback);
377 web_ui()->RegisterMessageCallback("hideCaptivePortal", kDoNothingCallback);
378 // Unused callbacks from display_manager.js
379 web_ui()->RegisterMessageCallback("showAddUser", kDoNothingCallback);
380 web_ui()->RegisterMessageCallback("loadWallpaper", kDoNothingCallback);
381 web_ui()->RegisterMessageCallback("updateCurrentScreen", kDoNothingCallback);
382 web_ui()->RegisterMessageCallback("loginVisible", kDoNothingCallback);
383 // Unused callbacks from user_pod_row.js
384 web_ui()->RegisterMessageCallback("focusPod", kDoNothingCallback);
387 void UserManagerScreenHandler::GetLocalizedValues(
388 base::DictionaryValue* localized_strings) {
389 // For Control Bar.
390 localized_strings->SetString("signedIn",
391 l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_ACTIVE_USER));
392 localized_strings->SetString("signinButton",
393 l10n_util::GetStringUTF16(IDS_LOGIN_BUTTON));
394 localized_strings->SetString("addUser",
395 l10n_util::GetStringUTF16(IDS_ADD_USER_BUTTON));
396 localized_strings->SetString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL));
397 localized_strings->SetString("browseAsGuest",
398 l10n_util::GetStringUTF16(IDS_GO_INCOGNITO_BUTTON));
399 localized_strings->SetString("signOutUser",
400 l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_SIGN_OUT));
402 // For AccountPickerScreen.
403 localized_strings->SetString("screenType", "login-add-user");
404 localized_strings->SetString("highlightStrength", "normal");
405 localized_strings->SetString("title",
406 l10n_util::GetStringUTF16(IDS_USER_MANAGER_SCREEN_TITLE));
407 localized_strings->SetString("passwordHint",
408 l10n_util::GetStringUTF16(IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT));
409 localized_strings->SetString("podMenuButtonAccessibleName",
410 l10n_util::GetStringUTF16(IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME));
411 localized_strings->SetString("podMenuRemoveItemAccessibleName",
412 l10n_util::GetStringUTF16(
413 IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME));
414 localized_strings->SetString("removeUser",
415 l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON));
416 localized_strings->SetString("passwordFieldAccessibleName",
417 l10n_util::GetStringUTF16(IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME));
418 localized_strings->SetString("bootIntoWallpaper", "off");
420 // For AccountPickerScreen, the remove user warning overlay.
421 localized_strings->SetString("removeUserWarningButtonTitle",
422 l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON));
423 localized_strings->SetString("removeUserWarningText",
424 l10n_util::GetStringUTF16(
425 IDS_LOGIN_POD_USER_REMOVE_WARNING));
427 // Strings needed for the User Manager tutorial slides.
428 localized_strings->SetString("tutorialStart",
429 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_START));
430 localized_strings->SetString("tutorialSkip",
431 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SKIP));
432 localized_strings->SetString("tutorialNext",
433 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_NEXT));
434 localized_strings->SetString("tutorialDone",
435 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_DONE));
436 localized_strings->SetString("slideWelcomeTitle",
437 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_INTRO_TITLE));
438 localized_strings->SetString("slideWelcomeText",
439 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_INTRO_TEXT));
440 localized_strings->SetString("slideYourChromeTitle",
441 l10n_util::GetStringUTF16(
442 IDS_USER_MANAGER_TUTORIAL_SLIDE_YOUR_CHROME_TITLE));
443 localized_strings->SetString("slideYourChromeText", l10n_util::GetStringUTF16(
444 IDS_USER_MANAGER_TUTORIAL_SLIDE_YOUR_CHROME_TEXT));
445 localized_strings->SetString("slideGuestsTitle",
446 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_GUEST_TITLE));
447 localized_strings->SetString("slideGuestsText",
448 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_GUEST_TEXT));
449 localized_strings->SetString("slideFriendsTitle",
450 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_FRIENDS_TITLE));
451 localized_strings->SetString("slideFriendsText",
452 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_FRIENDS_TEXT));
453 localized_strings->SetString("slideCompleteTitle",
454 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_TITLE));
455 localized_strings->SetString("slideCompleteText",
456 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_TEXT));
457 localized_strings->SetString("slideCompleteUserNotFound",
458 l10n_util::GetStringUTF16(
459 IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_USER_NOT_FOUND));
460 localized_strings->SetString("slideCompleteAddUser",
461 l10n_util::GetStringUTF16(
462 IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_ADD_USER));
464 // Strings needed for the user_pod_template public account div, but not ever
465 // actually displayed for desktop users.
466 localized_strings->SetString("publicAccountReminder", base::string16());
467 localized_strings->SetString("publicAccountEnter", base::string16());
468 localized_strings->SetString("publicAccountEnterAccessibleName",
469 base::string16());
470 localized_strings->SetString("multiple-signin-banner-text",
471 base::string16());
472 localized_strings->SetString("signinBannerText", base::string16());
473 localized_strings->SetString("launchAppButton", base::string16());
474 localized_strings->SetString("multiProfilesRestrictedPolicyTitle",
475 base::string16());
476 localized_strings->SetString("multiProfilesNotAllowedPolicyMsg",
477 base::string16());
478 localized_strings->SetString("multiProfilesPrimaryOnlyPolicyMsg",
479 base::string16());
482 void UserManagerScreenHandler::SendUserList() {
483 base::ListValue users_list;
484 base::FilePath active_profile_path =
485 web_ui()->GetWebContents()->GetBrowserContext()->GetPath();
486 const ProfileInfoCache& info_cache =
487 g_browser_process->profile_manager()->GetProfileInfoCache();
489 // If the active user is a managed user, then they may not perform
490 // certain actions (i.e. delete another user).
491 bool active_user_is_managed = Profile::FromWebUI(web_ui())->IsManaged();
492 for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) {
493 base::DictionaryValue* profile_value = new base::DictionaryValue();
495 base::FilePath profile_path = info_cache.GetPathOfProfileAtIndex(i);
496 bool is_active_user = (profile_path == active_profile_path);
498 profile_value->SetString(
499 kKeyUsername, info_cache.GetUserNameOfProfileAtIndex(i));
500 profile_value->SetString(
501 kKeyEmailAddress, info_cache.GetUserNameOfProfileAtIndex(i));
502 profile_value->SetString(
503 kKeyDisplayName, info_cache.GetNameOfProfileAtIndex(i));
504 profile_value->SetString(kKeyProfilePath, profile_path.MaybeAsASCII());
505 profile_value->SetBoolean(kKeyPublicAccount, false);
506 profile_value->SetBoolean(kKeyLocallyManagedUser, false);
507 profile_value->SetBoolean(kKeySignedIn, is_active_user);
508 profile_value->SetBoolean(
509 kKeyNeedsSignin, info_cache.ProfileIsSigninRequiredAtIndex(i));
510 profile_value->SetBoolean(kKeyIsOwner, false);
511 profile_value->SetBoolean(kKeyCanRemove, !active_user_is_managed);
512 profile_value->SetBoolean(kKeyIsDesktop, true);
513 profile_value->SetString(
514 kKeyAvatarUrl, GetAvatarImageAtIndex(i, info_cache));
516 // The row of user pods should display the active user first.
517 if (is_active_user)
518 users_list.Insert(0, profile_value);
519 else
520 users_list.Append(profile_value);
523 web_ui()->CallJavascriptFunction("login.AccountPickerScreen.loadUsers",
524 users_list, base::FundamentalValue(false), base::FundamentalValue(true));
527 void UserManagerScreenHandler::ReportAuthenticationResult(
528 bool success,
529 ProfileMetrics::ProfileAuth auth) {
530 ProfileMetrics::LogProfileAuthResult(auth);
531 password_attempt_.clear();
533 if (success) {
534 ProfileInfoCache& info_cache =
535 g_browser_process->profile_manager()->GetProfileInfoCache();
536 info_cache.SetProfileSigninRequiredAtIndex(
537 authenticating_profile_index_, false);
538 base::FilePath path = info_cache.GetPathOfProfileAtIndex(
539 authenticating_profile_index_);
540 profiles::SwitchToProfile(path, desktop_type_, true,
541 base::Bind(&OnSwitchToProfileComplete),
542 ProfileMetrics::SWITCH_PROFILE_UNLOCK);
543 } else {
544 web_ui()->CallJavascriptFunction(
545 "cr.ui.Oobe.showSignInError",
546 base::FundamentalValue(0),
547 base::StringValue(
548 l10n_util::GetStringUTF8(IDS_LOGIN_ERROR_AUTHENTICATING)),
549 base::StringValue(""),
550 base::FundamentalValue(0));