ProfilePolicyConnectorFactory: Refactoring from Profile to BrowserContext.
[chromium-blink-merge.git] / chrome / browser / ui / webui / signin / user_manager_screen_handler.cc
blobbc11d4dc4ea80081c79af33e33e5462411c75bd5
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/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/chrome_notification_types.h"
14 #include "chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/profiles/profile_avatar_icon_util.h"
17 #include "chrome/browser/profiles/profile_info_cache.h"
18 #include "chrome/browser/profiles/profile_info_cache_observer.h"
19 #include "chrome/browser/profiles/profile_manager.h"
20 #include "chrome/browser/profiles/profile_metrics.h"
21 #include "chrome/browser/profiles/profile_window.h"
22 #include "chrome/browser/profiles/profiles_state.h"
23 #include "chrome/browser/signin/local_auth.h"
24 #include "chrome/browser/ui/app_list/app_list_service.h"
25 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_dialogs.h"
27 #include "chrome/browser/ui/browser_finder.h"
28 #include "chrome/browser/ui/browser_list.h"
29 #include "chrome/browser/ui/browser_list_observer.h"
30 #include "chrome/browser/ui/chrome_pages.h"
31 #include "chrome/browser/ui/singleton_tabs.h"
32 #include "chrome/browser/ui/user_manager.h"
33 #include "chrome/common/pref_names.h"
34 #include "chrome/common/url_constants.h"
35 #include "chrome/grit/chromium_strings.h"
36 #include "chrome/grit/generated_resources.h"
37 #include "content/public/browser/notification_service.h"
38 #include "content/public/browser/web_contents.h"
39 #include "content/public/browser/web_ui.h"
40 #include "google_apis/gaia/gaia_auth_fetcher.h"
41 #include "google_apis/gaia/gaia_constants.h"
42 #include "third_party/skia/include/core/SkBitmap.h"
43 #include "ui/base/l10n/l10n_util.h"
44 #include "ui/base/resource/resource_bundle.h"
45 #include "ui/base/webui/web_ui_util.h"
46 #include "ui/gfx/image/image.h"
47 #include "ui/gfx/image/image_skia.h"
48 #include "ui/gfx/image/image_util.h"
50 #if defined(USE_ASH)
51 #include "ash/shell.h"
52 #endif
54 namespace {
55 // User dictionary keys.
56 const char kKeyUsername[] = "username";
57 const char kKeyDisplayName[]= "displayName";
58 const char kKeyEmailAddress[] = "emailAddress";
59 const char kKeyProfilePath[] = "profilePath";
60 const char kKeyPublicAccount[] = "publicAccount";
61 const char kKeyLegacySupervisedUser[] = "legacySupervisedUser";
62 const char kKeyChildUser[] = "childUser";
63 const char kKeyCanRemove[] = "canRemove";
64 const char kKeyIsOwner[] = "isOwner";
65 const char kKeyIsDesktop[] = "isDesktopUser";
66 const char kKeyAvatarUrl[] = "userImage";
67 const char kKeyNeedsSignin[] = "needsSignin";
69 // JS API callback names.
70 const char kJsApiUserManagerInitialize[] = "userManagerInitialize";
71 const char kJsApiUserManagerAddUser[] = "addUser";
72 const char kJsApiUserManagerAuthLaunchUser[] = "authenticatedLaunchUser";
73 const char kJsApiUserManagerLaunchGuest[] = "launchGuest";
74 const char kJsApiUserManagerLaunchUser[] = "launchUser";
75 const char kJsApiUserManagerRemoveUser[] = "removeUser";
76 const char kJsApiUserManagerAttemptUnlock[] = "attemptUnlock";
78 const size_t kAvatarIconSize = 180;
80 void HandleAndDoNothing(const base::ListValue* args) {
83 // This callback is run if the only profile has been deleted, and a new
84 // profile has been created to replace it.
85 void OpenNewWindowForProfile(
86 chrome::HostDesktopType desktop_type,
87 Profile* profile,
88 Profile::CreateStatus status) {
89 if (status != Profile::CREATE_STATUS_INITIALIZED)
90 return;
91 profiles::FindOrCreateNewWindowForProfile(
92 profile,
93 chrome::startup::IS_PROCESS_STARTUP,
94 chrome::startup::IS_FIRST_RUN,
95 desktop_type,
96 false);
99 std::string GetAvatarImageAtIndex(
100 size_t index, const ProfileInfoCache& info_cache) {
101 bool is_gaia_picture =
102 info_cache.IsUsingGAIAPictureOfProfileAtIndex(index) &&
103 info_cache.GetGAIAPictureOfProfileAtIndex(index);
105 // If the avatar is too small (i.e. the old-style low resolution avatar),
106 // it will be pixelated when displayed in the User Manager, so we should
107 // return the placeholder avatar instead.
108 gfx::Image avatar_image = info_cache.GetAvatarIconOfProfileAtIndex(index);
109 if (avatar_image.Width() <= profiles::kAvatarIconWidth ||
110 avatar_image.Height() <= profiles::kAvatarIconHeight ) {
111 avatar_image = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
112 profiles::GetPlaceholderAvatarIconResourceID());
114 gfx::Image resized_image = profiles::GetSizedAvatarIcon(
115 avatar_image, is_gaia_picture, kAvatarIconSize, kAvatarIconSize);
116 return webui::GetBitmapDataUrl(resized_image.AsBitmap());
119 size_t GetIndexOfProfileWithEmail(const ProfileInfoCache& info_cache,
120 const std::string& email) {
121 const base::string16& profile_email = base::UTF8ToUTF16(email);
122 for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) {
123 if (info_cache.GetUserNameOfProfileAtIndex(i) == profile_email)
124 return i;
126 return std::string::npos;
129 extensions::ScreenlockPrivateEventRouter* GetScreenlockRouter(
130 const std::string& email) {
131 const ProfileInfoCache& info_cache =
132 g_browser_process->profile_manager()->GetProfileInfoCache();
133 const size_t profile_index = GetIndexOfProfileWithEmail(info_cache, email);
134 Profile* profile = g_browser_process->profile_manager()
135 ->GetProfileByPath(info_cache.GetPathOfProfileAtIndex(profile_index));
136 return extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()->Get(
137 profile);
140 bool IsGuestModeEnabled() {
141 PrefService* service = g_browser_process->local_state();
142 DCHECK(service);
143 return service->GetBoolean(prefs::kBrowserGuestModeEnabled);
146 bool IsAddPersonEnabled() {
147 PrefService* service = g_browser_process->local_state();
148 DCHECK(service);
149 return service->GetBoolean(prefs::kBrowserAddPersonEnabled);
152 // Executes the action specified by the URL's Hash parameter, if any. Deletes
153 // itself after the action would be performed.
154 class UrlHashHelper : public chrome::BrowserListObserver {
155 public:
156 UrlHashHelper(Browser* browser, const std::string& hash);
157 ~UrlHashHelper() override;
159 void ExecuteUrlHash();
161 // chrome::BrowserListObserver overrides:
162 void OnBrowserRemoved(Browser* browser) override;
164 private:
165 Browser* browser_;
166 Profile* profile_;
167 chrome::HostDesktopType desktop_type_;
168 std::string hash_;
170 DISALLOW_COPY_AND_ASSIGN(UrlHashHelper);
173 UrlHashHelper::UrlHashHelper(Browser* browser, const std::string& hash)
174 : browser_(browser),
175 profile_(browser->profile()),
176 desktop_type_(browser->host_desktop_type()),
177 hash_(hash) {
178 BrowserList::AddObserver(this);
181 UrlHashHelper::~UrlHashHelper() {
182 BrowserList::RemoveObserver(this);
185 void UrlHashHelper::OnBrowserRemoved(Browser* browser) {
186 if (browser == browser_)
187 browser_ = nullptr;
190 void UrlHashHelper::ExecuteUrlHash() {
191 if (hash_ == profiles::kUserManagerSelectProfileAppLauncher) {
192 AppListService* app_list_service = AppListService::Get(desktop_type_);
193 app_list_service->ShowForProfile(profile_);
194 return;
197 Browser* target_browser = browser_;
198 if (!target_browser) {
199 target_browser = chrome::FindLastActiveWithProfile(profile_, desktop_type_);
200 if (!target_browser)
201 return;
204 if (hash_ == profiles::kUserManagerSelectProfileTaskManager)
205 chrome::OpenTaskManager(target_browser);
206 else if (hash_ == profiles::kUserManagerSelectProfileAboutChrome)
207 chrome::ShowAboutChrome(target_browser);
208 else if (hash_ == profiles::kUserManagerSelectProfileChromeSettings)
209 chrome::ShowSettings(target_browser);
210 else if (hash_ == profiles::kUserManagerSelectProfileChromeMemory)
211 chrome::ShowMemory(target_browser);
214 } // namespace
216 // ProfileUpdateObserver ------------------------------------------------------
218 class UserManagerScreenHandler::ProfileUpdateObserver
219 : public ProfileInfoCacheObserver {
220 public:
221 ProfileUpdateObserver(
222 ProfileManager* profile_manager, UserManagerScreenHandler* handler)
223 : profile_manager_(profile_manager),
224 user_manager_handler_(handler) {
225 DCHECK(profile_manager_);
226 DCHECK(user_manager_handler_);
227 profile_manager_->GetProfileInfoCache().AddObserver(this);
230 ~ProfileUpdateObserver() override {
231 DCHECK(profile_manager_);
232 profile_manager_->GetProfileInfoCache().RemoveObserver(this);
235 private:
236 // ProfileInfoCacheObserver implementation:
237 // If any change has been made to a profile, propagate it to all the
238 // visible user manager screens.
239 void OnProfileAdded(const base::FilePath& profile_path) override {
240 user_manager_handler_->SendUserList();
243 void OnProfileWasRemoved(const base::FilePath& profile_path,
244 const base::string16& profile_name) override {
245 // TODO(noms): Change 'SendUserList' to 'removeUser' JS-call when
246 // UserManager is able to find pod belonging to removed user.
247 user_manager_handler_->SendUserList();
250 void OnProfileNameChanged(const base::FilePath& profile_path,
251 const base::string16& old_profile_name) override {
252 user_manager_handler_->SendUserList();
255 void OnProfileAvatarChanged(const base::FilePath& profile_path) override {
256 user_manager_handler_->SendUserList();
259 void OnProfileHighResAvatarLoaded(
260 const base::FilePath& profile_path) override {
261 user_manager_handler_->SendUserList();
264 void OnProfileSigninRequiredChanged(
265 const base::FilePath& profile_path) override {
266 user_manager_handler_->SendUserList();
269 ProfileManager* profile_manager_;
271 UserManagerScreenHandler* user_manager_handler_; // Weak; owns us.
273 DISALLOW_COPY_AND_ASSIGN(ProfileUpdateObserver);
276 // UserManagerScreenHandler ---------------------------------------------------
278 UserManagerScreenHandler::UserManagerScreenHandler()
279 : desktop_type_(chrome::GetActiveDesktop()),
280 weak_ptr_factory_(this) {
281 profileInfoCacheObserver_.reset(
282 new UserManagerScreenHandler::ProfileUpdateObserver(
283 g_browser_process->profile_manager(), this));
286 UserManagerScreenHandler::~UserManagerScreenHandler() {
287 ScreenlockBridge::Get()->SetLockHandler(NULL);
290 void UserManagerScreenHandler::ShowBannerMessage(
291 const base::string16& message) {
292 web_ui()->CallJavascriptFunction(
293 "login.AccountPickerScreen.showBannerMessage",
294 base::StringValue(message));
297 void UserManagerScreenHandler::ShowUserPodCustomIcon(
298 const std::string& user_email,
299 const ScreenlockBridge::UserPodCustomIconOptions& icon_options) {
300 scoped_ptr<base::DictionaryValue> icon = icon_options.ToDictionaryValue();
301 if (!icon || icon->empty())
302 return;
303 web_ui()->CallJavascriptFunction(
304 "login.AccountPickerScreen.showUserPodCustomIcon",
305 base::StringValue(user_email),
306 *icon);
309 void UserManagerScreenHandler::HideUserPodCustomIcon(
310 const std::string& user_email) {
311 web_ui()->CallJavascriptFunction(
312 "login.AccountPickerScreen.hideUserPodCustomIcon",
313 base::StringValue(user_email));
316 void UserManagerScreenHandler::EnableInput() {
317 // Nothing here because UI is not disabled when starting to authenticate.
320 void UserManagerScreenHandler::SetAuthType(
321 const std::string& user_email,
322 ScreenlockBridge::LockHandler::AuthType auth_type,
323 const base::string16& auth_value) {
324 if (GetAuthType(user_email) ==
325 ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD)
326 return;
328 user_auth_type_map_[user_email] = auth_type;
329 web_ui()->CallJavascriptFunction(
330 "login.AccountPickerScreen.setAuthType",
331 base::StringValue(user_email),
332 base::FundamentalValue(auth_type),
333 base::StringValue(auth_value));
336 ScreenlockBridge::LockHandler::AuthType UserManagerScreenHandler::GetAuthType(
337 const std::string& user_email) const {
338 UserAuthTypeMap::const_iterator it = user_auth_type_map_.find(user_email);
339 if (it == user_auth_type_map_.end())
340 return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
341 return it->second;
344 ScreenlockBridge::LockHandler::ScreenType
345 UserManagerScreenHandler::GetScreenType() const {
346 return ScreenlockBridge::LockHandler::LOCK_SCREEN;
349 void UserManagerScreenHandler::Unlock(const std::string& user_email) {
350 const ProfileInfoCache& info_cache =
351 g_browser_process->profile_manager()->GetProfileInfoCache();
352 const size_t profile_index =
353 GetIndexOfProfileWithEmail(info_cache, user_email);
354 DCHECK_LT(profile_index, info_cache.GetNumberOfProfiles());
356 authenticating_profile_index_ = profile_index;
357 ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL);
360 void UserManagerScreenHandler::AttemptEasySignin(
361 const std::string& user_email,
362 const std::string& secret,
363 const std::string& key_label) {
364 NOTREACHED();
367 void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) {
368 // If the URL has a hash parameter, store it for later.
369 args->GetString(0, &url_hash_);
371 SendUserList();
372 web_ui()->CallJavascriptFunction("cr.ui.Oobe.showUserManagerScreen",
373 base::FundamentalValue(IsGuestModeEnabled()),
374 base::FundamentalValue(IsAddPersonEnabled()));
375 desktop_type_ = chrome::GetHostDesktopTypeForNativeView(
376 web_ui()->GetWebContents()->GetNativeView());
378 ScreenlockBridge::Get()->SetLockHandler(this);
381 void UserManagerScreenHandler::HandleAddUser(const base::ListValue* args) {
382 if (!IsAddPersonEnabled()) {
383 // The 'Add User' UI should not be showing.
384 NOTREACHED();
385 return;
387 profiles::CreateAndSwitchToNewProfile(
388 desktop_type_,
389 base::Bind(&UserManagerScreenHandler::OnSwitchToProfileComplete,
390 weak_ptr_factory_.GetWeakPtr()),
391 ProfileMetrics::ADD_NEW_USER_MANAGER);
394 void UserManagerScreenHandler::HandleAuthenticatedLaunchUser(
395 const base::ListValue* args) {
396 const base::Value* profile_path_value;
397 if (!args->Get(0, &profile_path_value))
398 return;
400 base::FilePath profile_path;
401 if (!base::GetValueAsFilePath(*profile_path_value, &profile_path))
402 return;
404 base::string16 email_address;
405 if (!args->GetString(1, &email_address))
406 return;
408 std::string password;
409 if (!args->GetString(2, &password))
410 return;
412 const ProfileInfoCache& info_cache =
413 g_browser_process->profile_manager()->GetProfileInfoCache();
414 size_t profile_index = info_cache.GetIndexOfProfileWithPath(profile_path);
416 if (profile_index == std::string::npos) {
417 NOTREACHED();
418 return;
421 authenticating_profile_index_ = profile_index;
422 if (!LocalAuth::ValidateLocalAuthCredentials(profile_index, password)) {
423 // Make a second attempt via an on-line authentication call. This handles
424 // profiles that are missing sign-in credentials and also cases where the
425 // password has been changed externally.
426 client_login_.reset(new GaiaAuthFetcher(
427 this,
428 GaiaConstants::kChromeSource,
429 web_ui()->GetWebContents()->GetBrowserContext()->GetRequestContext()));
431 client_login_->StartClientLogin(
432 base::UTF16ToUTF8(email_address),
433 password,
434 GaiaConstants::kSyncService,
435 std::string(),
436 std::string(),
437 GaiaAuthFetcher::HostedAccountsAllowed);
438 password_attempt_ = password;
439 return;
442 ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL);
445 void UserManagerScreenHandler::HandleRemoveUser(const base::ListValue* args) {
446 DCHECK(args);
447 const base::Value* profile_path_value;
448 if (!args->Get(0, &profile_path_value))
449 return;
451 base::FilePath profile_path;
452 if (!base::GetValueAsFilePath(*profile_path_value, &profile_path))
453 return;
455 if (!profiles::IsMultipleProfilesEnabled())
456 return;
458 g_browser_process->profile_manager()->ScheduleProfileForDeletion(
459 profile_path,
460 base::Bind(&OpenNewWindowForProfile, desktop_type_));
461 ProfileMetrics::LogProfileDeleteUser(
462 ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
465 void UserManagerScreenHandler::HandleLaunchGuest(const base::ListValue* args) {
466 if (IsGuestModeEnabled()) {
467 profiles::SwitchToGuestProfile(
468 desktop_type_,
469 base::Bind(&UserManagerScreenHandler::OnSwitchToProfileComplete,
470 weak_ptr_factory_.GetWeakPtr()));
471 } else {
472 // The UI should have prevented the user from allowing the selection of
473 // guest mode.
474 NOTREACHED();
478 void UserManagerScreenHandler::HandleLaunchUser(const base::ListValue* args) {
479 const base::Value* profile_path_value = NULL;
480 if (!args->Get(0, &profile_path_value))
481 return;
483 base::FilePath profile_path;
484 if (!base::GetValueAsFilePath(*profile_path_value, &profile_path))
485 return;
487 const ProfileInfoCache& info_cache =
488 g_browser_process->profile_manager()->GetProfileInfoCache();
489 size_t profile_index = info_cache.GetIndexOfProfileWithPath(profile_path);
491 if (profile_index == std::string::npos) {
492 NOTREACHED();
493 return;
496 // It's possible that a user breaks into the user-manager page using the
497 // JavaScript Inspector and causes a "locked" profile to call this
498 // unauthenticated version of "launch" instead of the proper one. Thus,
499 // we have to validate in (secure) C++ code that it really is a profile
500 // not needing authentication. If it is, just ignore the "launch" request.
501 if (info_cache.ProfileIsSigninRequiredAtIndex(profile_index))
502 return;
503 ProfileMetrics::LogProfileAuthResult(ProfileMetrics::AUTH_UNNECESSARY);
505 profiles::SwitchToProfile(
506 profile_path,
507 desktop_type_,
508 false, /* reuse any existing windows */
509 base::Bind(&UserManagerScreenHandler::OnSwitchToProfileComplete,
510 weak_ptr_factory_.GetWeakPtr()),
511 ProfileMetrics::SWITCH_PROFILE_MANAGER);
514 void UserManagerScreenHandler::HandleAttemptUnlock(
515 const base::ListValue* args) {
516 std::string email;
517 CHECK(args->GetString(0, &email));
518 GetScreenlockRouter(email)->OnAuthAttempted(GetAuthType(email), "");
521 void UserManagerScreenHandler::HandleHardlockUserPod(
522 const base::ListValue* args) {
523 std::string email;
524 CHECK(args->GetString(0, &email));
525 SetAuthType(email,
526 ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD,
527 base::string16());
528 HideUserPodCustomIcon(email);
531 void UserManagerScreenHandler::OnClientLoginSuccess(
532 const ClientLoginResult& result) {
533 LocalAuth::SetLocalAuthCredentials(authenticating_profile_index_,
534 password_attempt_);
535 ReportAuthenticationResult(true, ProfileMetrics::AUTH_ONLINE);
538 void UserManagerScreenHandler::OnClientLoginFailure(
539 const GoogleServiceAuthError& error) {
540 const GoogleServiceAuthError::State state = error.state();
541 // Some "error" results mean the password was correct but some other action
542 // should be taken. For our purposes, we only care that the password was
543 // correct so count those as a success.
544 bool success = (state == GoogleServiceAuthError::NONE ||
545 state == GoogleServiceAuthError::CAPTCHA_REQUIRED ||
546 state == GoogleServiceAuthError::TWO_FACTOR ||
547 state == GoogleServiceAuthError::ACCOUNT_DELETED ||
548 state == GoogleServiceAuthError::ACCOUNT_DISABLED ||
549 state == GoogleServiceAuthError::WEB_LOGIN_REQUIRED);
551 // If the password was correct, the user must have changed it since the
552 // profile was locked. Save the password to streamline future unlocks.
553 if (success) {
554 DCHECK(!password_attempt_.empty());
555 LocalAuth::SetLocalAuthCredentials(authenticating_profile_index_,
556 password_attempt_);
559 bool offline = (state == GoogleServiceAuthError::CONNECTION_FAILED ||
560 state == GoogleServiceAuthError::SERVICE_UNAVAILABLE ||
561 state == GoogleServiceAuthError::REQUEST_CANCELED);
562 ProfileMetrics::ProfileAuth failure_metric =
563 offline ? ProfileMetrics::AUTH_FAILED_OFFLINE :
564 ProfileMetrics::AUTH_FAILED;
565 ReportAuthenticationResult(
566 success, success ? ProfileMetrics::AUTH_ONLINE : failure_metric);
569 void UserManagerScreenHandler::RegisterMessages() {
570 web_ui()->RegisterMessageCallback(kJsApiUserManagerInitialize,
571 base::Bind(&UserManagerScreenHandler::HandleInitialize,
572 base::Unretained(this)));
573 web_ui()->RegisterMessageCallback(kJsApiUserManagerAddUser,
574 base::Bind(&UserManagerScreenHandler::HandleAddUser,
575 base::Unretained(this)));
576 web_ui()->RegisterMessageCallback(kJsApiUserManagerAuthLaunchUser,
577 base::Bind(&UserManagerScreenHandler::HandleAuthenticatedLaunchUser,
578 base::Unretained(this)));
579 web_ui()->RegisterMessageCallback(kJsApiUserManagerLaunchGuest,
580 base::Bind(&UserManagerScreenHandler::HandleLaunchGuest,
581 base::Unretained(this)));
582 web_ui()->RegisterMessageCallback(kJsApiUserManagerLaunchUser,
583 base::Bind(&UserManagerScreenHandler::HandleLaunchUser,
584 base::Unretained(this)));
585 web_ui()->RegisterMessageCallback(kJsApiUserManagerRemoveUser,
586 base::Bind(&UserManagerScreenHandler::HandleRemoveUser,
587 base::Unretained(this)));
588 web_ui()->RegisterMessageCallback(kJsApiUserManagerAttemptUnlock,
589 base::Bind(&UserManagerScreenHandler::HandleAttemptUnlock,
590 base::Unretained(this)));
592 const content::WebUI::MessageCallback& kDoNothingCallback =
593 base::Bind(&HandleAndDoNothing);
595 // Unused callbacks from screen_account_picker.js
596 web_ui()->RegisterMessageCallback("accountPickerReady", kDoNothingCallback);
597 web_ui()->RegisterMessageCallback("loginUIStateChanged", kDoNothingCallback);
598 web_ui()->RegisterMessageCallback("hideCaptivePortal", kDoNothingCallback);
599 web_ui()->RegisterMessageCallback("getTouchViewState", kDoNothingCallback);
600 // Unused callbacks from display_manager.js
601 web_ui()->RegisterMessageCallback("showAddUser", kDoNothingCallback);
602 web_ui()->RegisterMessageCallback("loadWallpaper", kDoNothingCallback);
603 web_ui()->RegisterMessageCallback("updateCurrentScreen", kDoNothingCallback);
604 web_ui()->RegisterMessageCallback("loginVisible", kDoNothingCallback);
605 // Unused callbacks from user_pod_row.js
606 web_ui()->RegisterMessageCallback("focusPod", kDoNothingCallback);
609 void UserManagerScreenHandler::GetLocalizedValues(
610 base::DictionaryValue* localized_strings) {
611 // For Control Bar.
612 localized_strings->SetString("signedIn",
613 l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_ACTIVE_USER));
614 localized_strings->SetString("signinButton",
615 l10n_util::GetStringUTF16(IDS_LOGIN_BUTTON));
616 localized_strings->SetString("addUser",
617 l10n_util::GetStringUTF16(IDS_ADD_USER_BUTTON));
618 localized_strings->SetString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL));
619 localized_strings->SetString("browseAsGuest",
620 l10n_util::GetStringUTF16(IDS_GO_INCOGNITO_BUTTON));
621 localized_strings->SetString("signOutUser",
622 l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_SIGN_OUT));
624 // For AccountPickerScreen.
625 localized_strings->SetString("screenType", "login-add-user");
626 localized_strings->SetString("highlightStrength", "normal");
627 localized_strings->SetString("title",
628 l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
629 localized_strings->SetString("passwordHint",
630 l10n_util::GetStringUTF16(IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT));
631 localized_strings->SetString("signingIn",
632 l10n_util::GetStringUTF16(IDS_LOGIN_POD_SIGNING_IN));
633 localized_strings->SetString("podMenuButtonAccessibleName",
634 l10n_util::GetStringUTF16(IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME));
635 localized_strings->SetString("podMenuRemoveItemAccessibleName",
636 l10n_util::GetStringUTF16(
637 IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME));
638 localized_strings->SetString("removeUser",
639 l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON));
640 localized_strings->SetString("passwordFieldAccessibleName",
641 l10n_util::GetStringUTF16(IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME));
642 localized_strings->SetString("bootIntoWallpaper", "off");
644 // For AccountPickerScreen, the remove user warning overlay.
645 localized_strings->SetString("removeUserWarningButtonTitle",
646 l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON));
647 localized_strings->SetString("removeUserWarningText",
648 l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING));
649 localized_strings->SetString("removeLegacySupervisedUserWarningText",
650 l10n_util::GetStringFUTF16(
651 IDS_LOGIN_POD_LEGACY_SUPERVISED_USER_REMOVE_WARNING,
652 base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL)));
654 // Strings needed for the User Manager tutorial slides.
655 localized_strings->SetString("tutorialNext",
656 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_NEXT));
657 localized_strings->SetString("tutorialDone",
658 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_DONE));
659 localized_strings->SetString("slideWelcomeTitle",
660 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_INTRO_TITLE));
661 localized_strings->SetString("slideWelcomeText",
662 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_INTRO_TEXT));
663 localized_strings->SetString("slideYourChromeTitle",
664 l10n_util::GetStringUTF16(
665 IDS_USER_MANAGER_TUTORIAL_SLIDE_YOUR_CHROME_TITLE));
666 localized_strings->SetString("slideYourChromeText", l10n_util::GetStringUTF16(
667 IDS_USER_MANAGER_TUTORIAL_SLIDE_YOUR_CHROME_TEXT));
668 localized_strings->SetString("slideGuestsTitle",
669 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_GUEST_TITLE));
670 localized_strings->SetString("slideGuestsText",
671 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_GUEST_TEXT));
672 localized_strings->SetString("slideFriendsTitle",
673 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_FRIENDS_TITLE));
674 localized_strings->SetString("slideFriendsText",
675 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_FRIENDS_TEXT));
676 localized_strings->SetString("slideCompleteTitle",
677 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_TITLE));
678 localized_strings->SetString("slideCompleteText",
679 l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_TEXT));
680 localized_strings->SetString("slideCompleteUserNotFound",
681 l10n_util::GetStringUTF16(
682 IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_USER_NOT_FOUND));
683 localized_strings->SetString("slideCompleteAddUser",
684 l10n_util::GetStringUTF16(
685 IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_ADD_USER));
687 // Strings needed for the user_pod_template public account div, but not ever
688 // actually displayed for desktop users.
689 localized_strings->SetString("publicAccountReminder", base::string16());
690 localized_strings->SetString("publicSessionLanguageAndInput",
691 base::string16());
692 localized_strings->SetString("publicAccountEnter", base::string16());
693 localized_strings->SetString("publicAccountEnterAccessibleName",
694 base::string16());
695 localized_strings->SetString("publicSessionSelectLanguage", base::string16());
696 localized_strings->SetString("publicSessionSelectKeyboard", base::string16());
697 localized_strings->SetString("signinBannerText", base::string16());
698 localized_strings->SetString("launchAppButton", base::string16());
699 localized_strings->SetString("multiProfilesRestrictedPolicyTitle",
700 base::string16());
701 localized_strings->SetString("multiProfilesNotAllowedPolicyMsg",
702 base::string16());
703 localized_strings->SetString("multiProfilesPrimaryOnlyPolicyMsg",
704 base::string16());
705 localized_strings->SetString("multiProfilesOwnerPrimaryOnlyMsg",
706 base::string16());
709 void UserManagerScreenHandler::SendUserList() {
710 base::ListValue users_list;
711 const ProfileInfoCache& info_cache =
712 g_browser_process->profile_manager()->GetProfileInfoCache();
713 user_auth_type_map_.clear();
715 // Profile deletion is not allowed in Metro mode.
716 bool can_remove = true;
717 #if defined(USE_ASH)
718 can_remove = !ash::Shell::HasInstance();
719 #endif
721 for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) {
722 base::DictionaryValue* profile_value = new base::DictionaryValue();
723 base::FilePath profile_path = info_cache.GetPathOfProfileAtIndex(i);
725 profile_value->SetString(
726 kKeyUsername, info_cache.GetUserNameOfProfileAtIndex(i));
727 profile_value->SetString(
728 kKeyEmailAddress, info_cache.GetUserNameOfProfileAtIndex(i));
729 profile_value->SetString(
730 kKeyDisplayName,
731 profiles::GetAvatarNameForProfile(profile_path));
732 profile_value->Set(
733 kKeyProfilePath, base::CreateFilePathValue(profile_path));
734 profile_value->SetBoolean(kKeyPublicAccount, false);
735 profile_value->SetBoolean(kKeyLegacySupervisedUser,
736 info_cache.ProfileIsLegacySupervisedAtIndex(i));
737 profile_value->SetBoolean(
738 kKeyChildUser, info_cache.ProfileIsChildAtIndex(i));
739 profile_value->SetBoolean(
740 kKeyNeedsSignin, info_cache.ProfileIsSigninRequiredAtIndex(i));
741 profile_value->SetBoolean(kKeyIsOwner, false);
742 profile_value->SetBoolean(kKeyCanRemove, can_remove);
743 profile_value->SetBoolean(kKeyIsDesktop, true);
744 profile_value->SetString(
745 kKeyAvatarUrl, GetAvatarImageAtIndex(i, info_cache));
747 users_list.Append(profile_value);
750 web_ui()->CallJavascriptFunction("login.AccountPickerScreen.loadUsers",
751 users_list, base::FundamentalValue(IsGuestModeEnabled()));
754 void UserManagerScreenHandler::ReportAuthenticationResult(
755 bool success,
756 ProfileMetrics::ProfileAuth auth) {
757 ProfileMetrics::LogProfileAuthResult(auth);
758 password_attempt_.clear();
760 if (success) {
761 const ProfileInfoCache& info_cache =
762 g_browser_process->profile_manager()->GetProfileInfoCache();
763 base::FilePath path = info_cache.GetPathOfProfileAtIndex(
764 authenticating_profile_index_);
765 profiles::SwitchToProfile(
766 path,
767 desktop_type_,
768 true,
769 base::Bind(&UserManagerScreenHandler::OnSwitchToProfileComplete,
770 weak_ptr_factory_.GetWeakPtr()),
771 ProfileMetrics::SWITCH_PROFILE_UNLOCK);
772 } else {
773 web_ui()->CallJavascriptFunction(
774 "cr.ui.Oobe.showSignInError",
775 base::FundamentalValue(0),
776 base::StringValue(l10n_util::GetStringUTF8(
777 auth == ProfileMetrics::AUTH_FAILED_OFFLINE ?
778 IDS_LOGIN_ERROR_AUTHENTICATING_OFFLINE :
779 IDS_LOGIN_ERROR_AUTHENTICATING)),
780 base::StringValue(""),
781 base::FundamentalValue(0));
785 void UserManagerScreenHandler::OnBrowserWindowReady(Browser* browser) {
786 DCHECK(browser);
787 DCHECK(browser->window());
789 // Unlock the profile after browser opens so startup can read the lock bit.
790 // Any necessary authentication must have been successful to reach this point.
791 if (!browser->profile()->IsGuestSession()) {
792 ProfileInfoCache& info_cache =
793 g_browser_process->profile_manager()->GetProfileInfoCache();
794 size_t index = info_cache.GetIndexOfProfileWithPath(
795 browser->profile()->GetPath());
796 info_cache.SetProfileSigninRequiredAtIndex(index, false);
799 if (!url_hash_.empty()) {
800 base::MessageLoop::current()->PostTask(
801 FROM_HERE,
802 base::Bind(&UrlHashHelper::ExecuteUrlHash,
803 base::Owned(new UrlHashHelper(browser, url_hash_))));
806 // This call is last as it deletes this object.
807 UserManager::Hide();
810 void UserManagerScreenHandler::Observe(
811 int type,
812 const content::NotificationSource& source,
813 const content::NotificationDetails& details) {
814 switch (type) {
815 case chrome::NOTIFICATION_BROWSER_WINDOW_READY:
816 // Only respond to one Browser Window Ready event.
817 registrar_.Remove(this,
818 chrome::NOTIFICATION_BROWSER_WINDOW_READY,
819 content::NotificationService::AllSources());
820 OnBrowserWindowReady(content::Source<Browser>(source).ptr());
821 break;
822 default:
823 NOTREACHED();
827 // This callback is run after switching to a new profile has finished. This
828 // means either a new browser has been created (but not the window), or an
829 // existing one has been found. The HideUserManager task needs to be posted
830 // since closing the User Manager before the window is created can flakily
831 // cause Chrome to close.
832 void UserManagerScreenHandler::OnSwitchToProfileComplete(
833 Profile* profile, Profile::CreateStatus profile_create_status) {
834 Browser* browser = chrome::FindAnyBrowser(profile, false, desktop_type_);
835 if (browser && browser->window()) {
836 OnBrowserWindowReady(browser);
837 } else {
838 registrar_.Add(this,
839 chrome::NOTIFICATION_BROWSER_WINDOW_READY,
840 content::NotificationService::AllSources());