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