blob: 4314bc081215d0eb59a5d4ab0b85e06693fc83a7 [file] [log] [blame]
// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/ui/webui/signin/user_manager_screen_handler.h"
#include "base/bind.h"
#include "base/prefs/pref_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/value_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/api/screenlock_private/screenlock_private_api.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_avatar_icon_util.h"
#include "chrome/browser/profiles/profile_info_cache.h"
#include "chrome/browser/profiles/profile_info_cache_observer.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/profiles/profile_window.h"
#include "chrome/browser/profiles/profiles_state.h"
#include "chrome/browser/signin/local_auth.h"
#include "chrome/browser/ui/browser_dialogs.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/singleton_tabs.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_ui.h"
#include "google_apis/gaia/gaia_auth_fetcher.h"
#include "google_apis/gaia/gaia_constants.h"
#include "grit/browser_resources.h"
#include "grit/chromium_strings.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_util.h"
namespace {
// User dictionary keys.
const char kKeyUsername[] = "username";
const char kKeyDisplayName[]= "displayName";
const char kKeyEmailAddress[] = "emailAddress";
const char kKeyProfilePath[] = "profilePath";
const char kKeyPublicAccount[] = "publicAccount";
const char kKeySupervisedUser[] = "supervisedUser";
const char kKeySignedIn[] = "signedIn";
const char kKeyCanRemove[] = "canRemove";
const char kKeyIsOwner[] = "isOwner";
const char kKeyIsDesktop[] = "isDesktopUser";
const char kKeyAvatarUrl[] = "userImage";
const char kKeyNeedsSignin[] = "needsSignin";
// JS API callback names.
const char kJsApiUserManagerInitialize[] = "userManagerInitialize";
const char kJsApiUserManagerAddUser[] = "addUser";
const char kJsApiUserManagerAuthLaunchUser[] = "authenticatedLaunchUser";
const char kJsApiUserManagerLaunchGuest[] = "launchGuest";
const char kJsApiUserManagerLaunchUser[] = "launchUser";
const char kJsApiUserManagerRemoveUser[] = "removeUser";
const char kJsApiUserManagerAttemptUnlock[] = "attemptUnlock";
const size_t kAvatarIconSize = 180;
void HandleAndDoNothing(const base::ListValue* args) {
}
// This callback is run if the only profile has been deleted, and a new
// profile has been created to replace it.
void OpenNewWindowForProfile(
chrome::HostDesktopType desktop_type,
Profile* profile,
Profile::CreateStatus status) {
if (status != Profile::CREATE_STATUS_INITIALIZED)
return;
profiles::FindOrCreateNewWindowForProfile(
profile,
chrome::startup::IS_PROCESS_STARTUP,
chrome::startup::IS_FIRST_RUN,
desktop_type,
false);
}
// This callback is run after switching to a new profile has finished. This
// means either a new browser window has been opened, or an existing one
// has been found, which means we can safely close the User Manager without
// accidentally terminating the browser process. The task needs to be posted,
// as HideUserManager will end up destroying its WebContents, which will
// destruct the UserManagerScreenHandler as well.
void OnSwitchToProfileComplete() {
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&chrome::HideUserManager));
}
std::string GetAvatarImageAtIndex(
size_t index, const ProfileInfoCache& info_cache) {
bool is_gaia_picture =
info_cache.IsUsingGAIAPictureOfProfileAtIndex(index) &&
info_cache.GetGAIAPictureOfProfileAtIndex(index);
// If the avatar is too small (i.e. the old-style low resolution avatar),
// it will be pixelated when displayed in the User Manager, so we should
// return the placeholder avatar instead.
gfx::Image avatar_image = info_cache.GetAvatarIconOfProfileAtIndex(index);
if (avatar_image.Width() <= profiles::kAvatarIconWidth ||
avatar_image.Height() <= profiles::kAvatarIconHeight ) {
avatar_image = ui::ResourceBundle::GetSharedInstance().GetImageNamed(
profiles::GetPlaceholderAvatarIconResourceID());
}
gfx::Image resized_image = profiles::GetSizedAvatarIcon(
avatar_image, is_gaia_picture, kAvatarIconSize, kAvatarIconSize);
return webui::GetBitmapDataUrl(resized_image.AsBitmap());
}
size_t GetIndexOfProfileWithEmailAndName(const ProfileInfoCache& info_cache,
const base::string16& email,
const base::string16& name) {
for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) {
if (info_cache.GetUserNameOfProfileAtIndex(i) == email &&
(name.empty() ||
profiles::GetAvatarNameForProfile(
info_cache.GetPathOfProfileAtIndex(i)) == name)) {
return i;
}
}
return std::string::npos;
}
extensions::ScreenlockPrivateEventRouter* GetScreenlockRouter(
const std::string& email) {
ProfileInfoCache& info_cache =
g_browser_process->profile_manager()->GetProfileInfoCache();
const size_t profile_index = GetIndexOfProfileWithEmailAndName(
info_cache, base::UTF8ToUTF16(email), base::string16());
Profile* profile = g_browser_process->profile_manager()
->GetProfileByPath(info_cache.GetPathOfProfileAtIndex(profile_index));
return extensions::ScreenlockPrivateEventRouter::GetFactoryInstance()->Get(
profile);
}
bool IsGuestModeEnabled() {
PrefService* service = g_browser_process->local_state();
DCHECK(service);
return service->GetBoolean(prefs::kBrowserGuestModeEnabled);
}
} // namespace
// ProfileUpdateObserver ------------------------------------------------------
class UserManagerScreenHandler::ProfileUpdateObserver
: public ProfileInfoCacheObserver {
public:
ProfileUpdateObserver(
ProfileManager* profile_manager, UserManagerScreenHandler* handler)
: profile_manager_(profile_manager),
user_manager_handler_(handler) {
DCHECK(profile_manager_);
DCHECK(user_manager_handler_);
profile_manager_->GetProfileInfoCache().AddObserver(this);
}
virtual ~ProfileUpdateObserver() {
DCHECK(profile_manager_);
profile_manager_->GetProfileInfoCache().RemoveObserver(this);
}
private:
// ProfileInfoCacheObserver implementation:
// If any change has been made to a profile, propagate it to all the
// visible user manager screens.
virtual void OnProfileAdded(const base::FilePath& profile_path) OVERRIDE {
user_manager_handler_->SendUserList();
}
virtual void OnProfileWasRemoved(
const base::FilePath& profile_path,
const base::string16& profile_name) OVERRIDE {
// TODO(noms): Change 'SendUserList' to 'removeUser' JS-call when
// UserManager is able to find pod belonging to removed user.
user_manager_handler_->SendUserList();
}
virtual void OnProfileNameChanged(
const base::FilePath& profile_path,
const base::string16& old_profile_name) OVERRIDE {
user_manager_handler_->SendUserList();
}
virtual void OnProfileAvatarChanged(
const base::FilePath& profile_path) OVERRIDE {
user_manager_handler_->SendUserList();
}
virtual void OnProfileSigninRequiredChanged(
const base::FilePath& profile_path) OVERRIDE {
user_manager_handler_->SendUserList();
}
ProfileManager* profile_manager_;
UserManagerScreenHandler* user_manager_handler_; // Weak; owns us.
DISALLOW_COPY_AND_ASSIGN(ProfileUpdateObserver);
};
// UserManagerScreenHandler ---------------------------------------------------
UserManagerScreenHandler::UserManagerScreenHandler()
: desktop_type_(chrome::GetActiveDesktop()) {
profileInfoCacheObserver_.reset(
new UserManagerScreenHandler::ProfileUpdateObserver(
g_browser_process->profile_manager(), this));
}
UserManagerScreenHandler::~UserManagerScreenHandler() {
ScreenlockBridge::Get()->SetLockHandler(NULL);
}
void UserManagerScreenHandler::ShowBannerMessage(
const base::string16& message) {
web_ui()->CallJavascriptFunction(
"login.AccountPickerScreen.showBannerMessage",
base::StringValue(message));
}
void UserManagerScreenHandler::ShowUserPodCustomIcon(
const std::string& user_email,
const ScreenlockBridge::UserPodCustomIconOptions& icon_options) {
scoped_ptr<base::DictionaryValue> icon = icon_options.ToDictionaryValue();
if (!icon || icon->empty())
return;
web_ui()->CallJavascriptFunction(
"login.AccountPickerScreen.showUserPodCustomIcon",
base::StringValue(user_email),
*icon);
}
void UserManagerScreenHandler::HideUserPodCustomIcon(
const std::string& user_email) {
web_ui()->CallJavascriptFunction(
"login.AccountPickerScreen.hideUserPodCustomIcon",
base::StringValue(user_email));
}
void UserManagerScreenHandler::EnableInput() {
// Nothing here because UI is not disabled when starting to authenticate.
}
void UserManagerScreenHandler::SetAuthType(
const std::string& user_email,
ScreenlockBridge::LockHandler::AuthType auth_type,
const base::string16& auth_value) {
if (GetAuthType(user_email) ==
ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD)
return;
user_auth_type_map_[user_email] = auth_type;
web_ui()->CallJavascriptFunction(
"login.AccountPickerScreen.setAuthType",
base::StringValue(user_email),
base::FundamentalValue(auth_type),
base::StringValue(auth_value));
}
ScreenlockBridge::LockHandler::AuthType UserManagerScreenHandler::GetAuthType(
const std::string& user_email) const {
UserAuthTypeMap::const_iterator it = user_auth_type_map_.find(user_email);
if (it == user_auth_type_map_.end())
return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
return it->second;
}
void UserManagerScreenHandler::Unlock(const std::string& user_email) {
ProfileInfoCache& info_cache =
g_browser_process->profile_manager()->GetProfileInfoCache();
const size_t profile_index = GetIndexOfProfileWithEmailAndName(
info_cache, base::UTF8ToUTF16(user_email), base::string16());
DCHECK_LT(profile_index, info_cache.GetNumberOfProfiles());
authenticating_profile_index_ = profile_index;
ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL);
}
void UserManagerScreenHandler::HandleInitialize(const base::ListValue* args) {
SendUserList();
web_ui()->CallJavascriptFunction("cr.ui.Oobe.showUserManagerScreen",
base::FundamentalValue(IsGuestModeEnabled()));
desktop_type_ = chrome::GetHostDesktopTypeForNativeView(
web_ui()->GetWebContents()->GetNativeView());
ScreenlockBridge::Get()->SetLockHandler(this);
}
void UserManagerScreenHandler::HandleAddUser(const base::ListValue* args) {
profiles::CreateAndSwitchToNewProfile(desktop_type_,
base::Bind(&OnSwitchToProfileComplete),
ProfileMetrics::ADD_NEW_USER_MANAGER);
}
void UserManagerScreenHandler::HandleAuthenticatedLaunchUser(
const base::ListValue* args) {
base::string16 email_address;
if (!args->GetString(0, &email_address))
return;
base::string16 display_name;
if (!args->GetString(1, &display_name))
return;
std::string password;
if (!args->GetString(2, &password))
return;
ProfileInfoCache& info_cache =
g_browser_process->profile_manager()->GetProfileInfoCache();
size_t profile_index = GetIndexOfProfileWithEmailAndName(
info_cache, email_address, display_name);
if (profile_index >= info_cache.GetNumberOfProfiles()) {
NOTREACHED();
return;
}
authenticating_profile_index_ = profile_index;
if (!chrome::ValidateLocalAuthCredentials(profile_index, password)) {
// Make a second attempt via an on-line authentication call. This handles
// profiles that are missing sign-in credentials and also cases where the
// password has been changed externally.
client_login_.reset(new GaiaAuthFetcher(
this,
GaiaConstants::kChromeSource,
web_ui()->GetWebContents()->GetBrowserContext()->GetRequestContext()));
std::string email_string;
args->GetString(0, &email_string);
client_login_->StartClientLogin(
email_string,
password,
GaiaConstants::kSyncService,
std::string(),
std::string(),
GaiaAuthFetcher::HostedAccountsAllowed);
password_attempt_ = password;
return;
}
ReportAuthenticationResult(true, ProfileMetrics::AUTH_LOCAL);
}
void UserManagerScreenHandler::HandleRemoveUser(const base::ListValue* args) {
DCHECK(args);
const base::Value* profile_path_value;
if (!args->Get(0, &profile_path_value))
return;
base::FilePath profile_path;
if (!base::GetValueAsFilePath(*profile_path_value, &profile_path))
return;
// This handler could have been called for a supervised user, for example
// because the user fiddled with the web inspector. Silently return in this
// case.
if (Profile::FromWebUI(web_ui())->IsSupervised())
return;
if (!profiles::IsMultipleProfilesEnabled())
return;
g_browser_process->profile_manager()->ScheduleProfileForDeletion(
profile_path,
base::Bind(&OpenNewWindowForProfile, desktop_type_));
ProfileMetrics::LogProfileDeleteUser(
ProfileMetrics::DELETE_PROFILE_USER_MANAGER);
}
void UserManagerScreenHandler::HandleLaunchGuest(const base::ListValue* args) {
if (IsGuestModeEnabled()) {
profiles::SwitchToGuestProfile(desktop_type_,
base::Bind(&OnSwitchToProfileComplete));
ProfileMetrics::LogProfileSwitchUser(ProfileMetrics::SWITCH_PROFILE_GUEST);
} else {
// The UI should have prevented the user from allowing the selection of
// guest mode.
NOTREACHED();
}
}
void UserManagerScreenHandler::HandleLaunchUser(const base::ListValue* args) {
base::string16 email_address;
base::string16 display_name;
if (!args->GetString(0, &email_address) ||
!args->GetString(1, &display_name)) {
NOTREACHED();
return;
}
ProfileInfoCache& info_cache =
g_browser_process->profile_manager()->GetProfileInfoCache();
size_t profile_index = GetIndexOfProfileWithEmailAndName(
info_cache, email_address, display_name);
if (profile_index >= info_cache.GetNumberOfProfiles()) {
NOTREACHED();
return;
}
// It's possible that a user breaks into the user-manager page using the
// JavaScript Inspector and causes a "locked" profile to call this
// unauthenticated version of "launch" instead of the proper one. Thus,
// we have to validate in (secure) C++ code that it really is a profile
// not needing authentication. If it is, just ignore the "launch" request.
if (info_cache.ProfileIsSigninRequiredAtIndex(profile_index))
return;
ProfileMetrics::LogProfileAuthResult(ProfileMetrics::AUTH_UNNECESSARY);
base::FilePath path = info_cache.GetPathOfProfileAtIndex(profile_index);
profiles::SwitchToProfile(path,
desktop_type_,
false, /* reuse any existing windows */
base::Bind(&OnSwitchToProfileComplete),
ProfileMetrics::SWITCH_PROFILE_MANAGER);
}
void UserManagerScreenHandler::HandleAttemptUnlock(
const base::ListValue* args) {
std::string email;
CHECK(args->GetString(0, &email));
GetScreenlockRouter(email)->OnAuthAttempted(GetAuthType(email), "");
}
void UserManagerScreenHandler::HandleHardlockUserPod(
const base::ListValue* args) {
std::string email;
CHECK(args->GetString(0, &email));
SetAuthType(email,
ScreenlockBridge::LockHandler::FORCE_OFFLINE_PASSWORD,
base::string16());
HideUserPodCustomIcon(email);
}
void UserManagerScreenHandler::OnClientLoginSuccess(
const ClientLoginResult& result) {
chrome::SetLocalAuthCredentials(authenticating_profile_index_,
password_attempt_);
ReportAuthenticationResult(true, ProfileMetrics::AUTH_ONLINE);
}
void UserManagerScreenHandler::OnClientLoginFailure(
const GoogleServiceAuthError& error) {
const GoogleServiceAuthError::State state = error.state();
// Some "error" results mean the password was correct but some other action
// should be taken. For our purposes, we only care that the password was
// correct so count those as a success.
bool success = (state == GoogleServiceAuthError::NONE ||
state == GoogleServiceAuthError::CAPTCHA_REQUIRED ||
state == GoogleServiceAuthError::TWO_FACTOR ||
state == GoogleServiceAuthError::ACCOUNT_DELETED ||
state == GoogleServiceAuthError::ACCOUNT_DISABLED);
ReportAuthenticationResult(success,
success ? ProfileMetrics::AUTH_ONLINE
: ProfileMetrics::AUTH_FAILED);
}
void UserManagerScreenHandler::RegisterMessages() {
web_ui()->RegisterMessageCallback(kJsApiUserManagerInitialize,
base::Bind(&UserManagerScreenHandler::HandleInitialize,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(kJsApiUserManagerAddUser,
base::Bind(&UserManagerScreenHandler::HandleAddUser,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(kJsApiUserManagerAuthLaunchUser,
base::Bind(&UserManagerScreenHandler::HandleAuthenticatedLaunchUser,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(kJsApiUserManagerLaunchGuest,
base::Bind(&UserManagerScreenHandler::HandleLaunchGuest,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(kJsApiUserManagerLaunchUser,
base::Bind(&UserManagerScreenHandler::HandleLaunchUser,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(kJsApiUserManagerRemoveUser,
base::Bind(&UserManagerScreenHandler::HandleRemoveUser,
base::Unretained(this)));
web_ui()->RegisterMessageCallback(kJsApiUserManagerAttemptUnlock,
base::Bind(&UserManagerScreenHandler::HandleAttemptUnlock,
base::Unretained(this)));
const content::WebUI::MessageCallback& kDoNothingCallback =
base::Bind(&HandleAndDoNothing);
// Unused callbacks from screen_account_picker.js
web_ui()->RegisterMessageCallback("accountPickerReady", kDoNothingCallback);
web_ui()->RegisterMessageCallback("loginUIStateChanged", kDoNothingCallback);
web_ui()->RegisterMessageCallback("hideCaptivePortal", kDoNothingCallback);
// Unused callbacks from display_manager.js
web_ui()->RegisterMessageCallback("showAddUser", kDoNothingCallback);
web_ui()->RegisterMessageCallback("loadWallpaper", kDoNothingCallback);
web_ui()->RegisterMessageCallback("updateCurrentScreen", kDoNothingCallback);
web_ui()->RegisterMessageCallback("loginVisible", kDoNothingCallback);
// Unused callbacks from user_pod_row.js
web_ui()->RegisterMessageCallback("focusPod", kDoNothingCallback);
}
void UserManagerScreenHandler::GetLocalizedValues(
base::DictionaryValue* localized_strings) {
// For Control Bar.
localized_strings->SetString("signedIn",
l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_ACTIVE_USER));
localized_strings->SetString("signinButton",
l10n_util::GetStringUTF16(IDS_LOGIN_BUTTON));
localized_strings->SetString("addUser",
l10n_util::GetStringUTF16(IDS_ADD_USER_BUTTON));
localized_strings->SetString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL));
localized_strings->SetString("browseAsGuest",
l10n_util::GetStringUTF16(IDS_GO_INCOGNITO_BUTTON));
localized_strings->SetString("signOutUser",
l10n_util::GetStringUTF16(IDS_SCREEN_LOCK_SIGN_OUT));
// For AccountPickerScreen.
localized_strings->SetString("screenType", "login-add-user");
localized_strings->SetString("highlightStrength", "normal");
localized_strings->SetString("title",
l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
localized_strings->SetString("passwordHint",
l10n_util::GetStringUTF16(IDS_LOGIN_POD_EMPTY_PASSWORD_TEXT));
localized_strings->SetString("podMenuButtonAccessibleName",
l10n_util::GetStringUTF16(IDS_LOGIN_POD_MENU_BUTTON_ACCESSIBLE_NAME));
localized_strings->SetString("podMenuRemoveItemAccessibleName",
l10n_util::GetStringUTF16(
IDS_LOGIN_POD_MENU_REMOVE_ITEM_ACCESSIBLE_NAME));
localized_strings->SetString("removeUser",
l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON));
localized_strings->SetString("passwordFieldAccessibleName",
l10n_util::GetStringUTF16(IDS_LOGIN_POD_PASSWORD_FIELD_ACCESSIBLE_NAME));
localized_strings->SetString("bootIntoWallpaper", "off");
// For AccountPickerScreen, the remove user warning overlay.
localized_strings->SetString("removeUserWarningButtonTitle",
l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING_BUTTON));
localized_strings->SetString("removeUserWarningText",
l10n_util::GetStringUTF16(IDS_LOGIN_POD_USER_REMOVE_WARNING));
localized_strings->SetString("removeSupervisedUserWarningText",
l10n_util::GetStringFUTF16(
IDS_LOGIN_POD_SUPERVISED_USER_REMOVE_WARNING,
base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL)));
// Strings needed for the User Manager tutorial slides.
localized_strings->SetString("tutorialNext",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_NEXT));
localized_strings->SetString("tutorialDone",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_DONE));
localized_strings->SetString("slideWelcomeTitle",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_INTRO_TITLE));
localized_strings->SetString("slideWelcomeText",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_INTRO_TEXT));
localized_strings->SetString("slideYourChromeTitle",
l10n_util::GetStringUTF16(
IDS_USER_MANAGER_TUTORIAL_SLIDE_YOUR_CHROME_TITLE));
localized_strings->SetString("slideYourChromeText", l10n_util::GetStringUTF16(
IDS_USER_MANAGER_TUTORIAL_SLIDE_YOUR_CHROME_TEXT));
localized_strings->SetString("slideGuestsTitle",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_GUEST_TITLE));
localized_strings->SetString("slideGuestsText",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_GUEST_TEXT));
localized_strings->SetString("slideFriendsTitle",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_FRIENDS_TITLE));
localized_strings->SetString("slideFriendsText",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_FRIENDS_TEXT));
localized_strings->SetString("slideCompleteTitle",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_TITLE));
localized_strings->SetString("slideCompleteText",
l10n_util::GetStringUTF16(IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_TEXT));
localized_strings->SetString("slideCompleteUserNotFound",
l10n_util::GetStringUTF16(
IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_USER_NOT_FOUND));
localized_strings->SetString("slideCompleteAddUser",
l10n_util::GetStringUTF16(
IDS_USER_MANAGER_TUTORIAL_SLIDE_OUTRO_ADD_USER));
// Strings needed for the user_pod_template public account div, but not ever
// actually displayed for desktop users.
localized_strings->SetString("publicAccountReminder", base::string16());
localized_strings->SetString("publicSessionLanguageAndInput",
base::string16());
localized_strings->SetString("publicAccountEnter", base::string16());
localized_strings->SetString("publicAccountEnterAccessibleName",
base::string16());
localized_strings->SetString("publicSessionSelectLanguage", base::string16());
localized_strings->SetString("publicSessionSelectKeyboard", base::string16());
localized_strings->SetString("signinBannerText", base::string16());
localized_strings->SetString("launchAppButton", base::string16());
localized_strings->SetString("multiProfilesRestrictedPolicyTitle",
base::string16());
localized_strings->SetString("multiProfilesNotAllowedPolicyMsg",
base::string16());
localized_strings->SetString("multiProfilesPrimaryOnlyPolicyMsg",
base::string16());
localized_strings->SetString("multiProfilesOwnerPrimaryOnlyMsg",
base::string16());
}
void UserManagerScreenHandler::SendUserList() {
base::ListValue users_list;
base::FilePath active_profile_path =
web_ui()->GetWebContents()->GetBrowserContext()->GetPath();
const ProfileInfoCache& info_cache =
g_browser_process->profile_manager()->GetProfileInfoCache();
user_auth_type_map_.clear();
// If the active user is a supervised user, then they may not perform
// certain actions (i.e. delete another user).
bool active_user_is_supervised = Profile::FromWebUI(web_ui())->IsSupervised();
for (size_t i = 0; i < info_cache.GetNumberOfProfiles(); ++i) {
base::DictionaryValue* profile_value = new base::DictionaryValue();
base::FilePath profile_path = info_cache.GetPathOfProfileAtIndex(i);
bool is_active_user = (profile_path == active_profile_path);
profile_value->SetString(
kKeyUsername, info_cache.GetUserNameOfProfileAtIndex(i));
profile_value->SetString(
kKeyEmailAddress, info_cache.GetUserNameOfProfileAtIndex(i));
// The profiles displayed in the User Manager are never guest profiles.
profile_value->SetString(
kKeyDisplayName,
profiles::GetAvatarNameForProfile(profile_path));
profile_value->SetString(kKeyProfilePath, profile_path.MaybeAsASCII());
profile_value->SetBoolean(kKeyPublicAccount, false);
profile_value->SetBoolean(
kKeySupervisedUser, info_cache.ProfileIsSupervisedAtIndex(i));
profile_value->SetBoolean(kKeySignedIn, is_active_user);
profile_value->SetBoolean(
kKeyNeedsSignin, info_cache.ProfileIsSigninRequiredAtIndex(i));
profile_value->SetBoolean(kKeyIsOwner, false);
profile_value->SetBoolean(kKeyCanRemove, !active_user_is_supervised);
profile_value->SetBoolean(kKeyIsDesktop, true);
profile_value->SetString(
kKeyAvatarUrl, GetAvatarImageAtIndex(i, info_cache));
// The row of user pods should display the active user first.
if (is_active_user)
users_list.Insert(0, profile_value);
else
users_list.Append(profile_value);
}
web_ui()->CallJavascriptFunction("login.AccountPickerScreen.loadUsers",
users_list, base::FundamentalValue(IsGuestModeEnabled()));
}
void UserManagerScreenHandler::ReportAuthenticationResult(
bool success,
ProfileMetrics::ProfileAuth auth) {
ProfileMetrics::LogProfileAuthResult(auth);
password_attempt_.clear();
if (success) {
ProfileInfoCache& info_cache =
g_browser_process->profile_manager()->GetProfileInfoCache();
info_cache.SetProfileSigninRequiredAtIndex(
authenticating_profile_index_, false);
base::FilePath path = info_cache.GetPathOfProfileAtIndex(
authenticating_profile_index_);
profiles::SwitchToProfile(path, desktop_type_, true,
base::Bind(&OnSwitchToProfileComplete),
ProfileMetrics::SWITCH_PROFILE_UNLOCK);
} else {
web_ui()->CallJavascriptFunction(
"cr.ui.Oobe.showSignInError",
base::FundamentalValue(0),
base::StringValue(
l10n_util::GetStringUTF8(IDS_LOGIN_ERROR_AUTHENTICATING)),
base::StringValue(""),
base::FundamentalValue(0));
}
}