This source file includes following definitions.
- RefreshPoliciesOnUIThread
- TransferContextAuthenticationsOnIOThread
- network_state_helper_
- Init
- UpdateLoginDisplay
- DoAutoEnrollment
- ResumeLogin
- Observe
- CancelPasswordChangedFlow
- CreateAccount
- CompleteLogin
- CompleteLoginInternal
- GetConnectedNetworkName
- IsSigninInProgress
- Login
- PerformLogin
- LoginAsRetailModeUser
- LoginAsGuest
- MigrateUserData
- LoginAsPublicAccount
- LoginAsKioskApp
- OnSigninScreenReady
- OnUserSelected
- OnStartEnterpriseEnrollment
- OnStartKioskEnableScreen
- OnStartDeviceReset
- OnStartKioskAutolaunchScreen
- ResyncUserData
- SetDisplayEmail
- ShowWrongHWIDScreen
- Signout
- OnConsumerKioskAutoLaunchCheckCompleted
- OnEnrollmentOwnershipCheckCompleted
- ShowEnrollmentScreen
- ShowResetScreen
- ShowKioskEnableScreen
- ShowKioskAutolaunchScreen
- ShowTPMError
- OnLoginFailure
- OnLoginSuccess
- OnProfilePrepared
- OnOffTheRecordLoginSuccess
- OnPasswordChangeDetected
- WhiteListCheckFailed
- PolicyLoadFailed
- OnOnlineChecked
- DeviceSettingsChanged
- ActivateWizard
- ConfigurePublicSessionAutoLogin
- ResetPublicSessionAutoLoginTimer
- OnPublicSessionAutoLoginTimerFire
- StopPublicSessionAutoLoginTimer
- StartPublicSessionAutoLoginTimer
- GetNativeWindow
- InitializeStartUrls
- ShowError
- ShowGaiaPasswordChanged
- SendAccessibilityAlert
#include "chrome/browser/chromeos/login/existing_user_controller.h"
#include <vector>
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "base/version.h"
#include "chrome/browser/accessibility/accessibility_events.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/chromeos/boot_times_loader.h"
#include "chrome/browser/chromeos/customization_document.h"
#include "chrome/browser/chromeos/first_run/first_run.h"
#include "chrome/browser/chromeos/kiosk_mode/kiosk_mode_settings.h"
#include "chrome/browser/chromeos/login/helper.h"
#include "chrome/browser/chromeos/login/login_display_host.h"
#include "chrome/browser/chromeos/login/login_utils.h"
#include "chrome/browser/chromeos/login/startup_utils.h"
#include "chrome/browser/chromeos/login/user_manager.h"
#include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/policy/device_local_account.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/google/google_util.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/power_manager_client.h"
#include "chromeos/dbus/session_manager_client.h"
#include "chromeos/settings/cros_settings_names.h"
#include "components/policy/core/common/policy_service.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "content/public/browser/notification_types.h"
#include "content/public/browser/user_metrics.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "grit/generated_resources.h"
#include "net/http/http_auth_cache.h"
#include "net/http/http_network_session.h"
#include "net/http/http_transaction_factory.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"
#include "ui/accessibility/ax_enums.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/widget/widget.h"
namespace chromeos {
namespace {
const char kCreateAccountURL[] =
"https://accounts.google.com/NewAccount?service=mail";
const char kChromeVoxTutorialURLPattern[] =
"http://www.chromevox.com/tutorial/index.html?lang=%s";
const long int kAuthCacheTransferDelayMs = 2000;
const long int kSafeModeRestartUiDelayMs = 30000;
void RefreshPoliciesOnUIThread() {
if (g_browser_process->policy_service())
g_browser_process->policy_service()->RefreshPolicies(base::Closure());
}
void TransferContextAuthenticationsOnIOThread(
net::URLRequestContextGetter* default_profile_context_getter,
net::URLRequestContextGetter* browser_process_context_getter) {
net::HttpAuthCache* new_cache =
browser_process_context_getter->GetURLRequestContext()->
http_transaction_factory()->GetSession()->http_auth_cache();
net::HttpAuthCache* old_cache =
default_profile_context_getter->GetURLRequestContext()->
http_transaction_factory()->GetSession()->http_auth_cache();
new_cache->UpdateAllFrom(*old_cache);
VLOG(1) << "Main request context populated with authentication data.";
content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
base::Bind(&RefreshPoliciesOnUIThread));
}
}
ExistingUserController* ExistingUserController::current_controller_ = NULL;
ExistingUserController::ExistingUserController(LoginDisplayHost* host)
: login_status_consumer_(NULL),
host_(host),
login_display_(host_->CreateLoginDisplay(this)),
num_login_attempts_(0),
cros_settings_(CrosSettings::Get()),
weak_factory_(this),
offline_failed_(false),
is_login_in_progress_(false),
password_changed_(false),
do_auto_enrollment_(false),
signin_screen_ready_(false),
network_state_helper_(new login::NetworkStateHelper) {
DCHECK(current_controller_ == NULL);
current_controller_ = this;
registrar_.Add(this,
chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED,
content::NotificationService::AllSources());
registrar_.Add(this,
chrome::NOTIFICATION_USER_LIST_CHANGED,
content::NotificationService::AllSources());
registrar_.Add(this,
chrome::NOTIFICATION_AUTH_SUPPLIED,
content::NotificationService::AllSources());
registrar_.Add(this,
chrome::NOTIFICATION_SESSION_STARTED,
content::NotificationService::AllSources());
show_user_names_subscription_ = cros_settings_->AddSettingsObserver(
kAccountsPrefShowUserNamesOnSignIn,
base::Bind(&ExistingUserController::DeviceSettingsChanged,
base::Unretained(this)));
allow_new_user_subscription_ = cros_settings_->AddSettingsObserver(
kAccountsPrefAllowNewUser,
base::Bind(&ExistingUserController::DeviceSettingsChanged,
base::Unretained(this)));
allow_guest_subscription_ = cros_settings_->AddSettingsObserver(
kAccountsPrefAllowGuest,
base::Bind(&ExistingUserController::DeviceSettingsChanged,
base::Unretained(this)));
users_subscription_ = cros_settings_->AddSettingsObserver(
kAccountsPrefUsers,
base::Bind(&ExistingUserController::DeviceSettingsChanged,
base::Unretained(this)));
local_account_auto_login_id_subscription_ =
cros_settings_->AddSettingsObserver(
kAccountsPrefDeviceLocalAccountAutoLoginId,
base::Bind(&ExistingUserController::ConfigurePublicSessionAutoLogin,
base::Unretained(this)));
local_account_auto_login_delay_subscription_ =
cros_settings_->AddSettingsObserver(
kAccountsPrefDeviceLocalAccountAutoLoginDelay,
base::Bind(&ExistingUserController::ConfigurePublicSessionAutoLogin,
base::Unretained(this)));
}
void ExistingUserController::Init(const UserList& users) {
time_init_ = base::Time::Now();
UpdateLoginDisplay(users);
ConfigurePublicSessionAutoLogin();
}
void ExistingUserController::UpdateLoginDisplay(const UserList& users) {
bool show_users_on_signin;
UserList filtered_users;
cros_settings_->GetBoolean(kAccountsPrefShowUserNamesOnSignIn,
&show_users_on_signin);
if (show_users_on_signin) {
for (UserList::const_iterator it = users.begin(); it != users.end(); ++it) {
bool meets_locally_managed_requirements =
(*it)->GetType() != User::USER_TYPE_LOCALLY_MANAGED ||
UserManager::Get()->AreLocallyManagedUsersAllowed();
bool meets_whitelist_requirements =
LoginUtils::IsWhitelisted((*it)->email(), NULL) ||
(*it)->GetType() != User::USER_TYPE_REGULAR;
if (meets_locally_managed_requirements && meets_whitelist_requirements) {
filtered_users.push_back(*it);
}
}
}
bool show_guest;
cros_settings_->GetBoolean(kAccountsPrefAllowGuest, &show_guest);
bool show_users;
cros_settings_->GetBoolean(kAccountsPrefShowUserNamesOnSignIn, &show_users);
show_guest &= !filtered_users.empty();
bool show_new_user = true;
login_display_->set_parent_window(GetNativeWindow());
login_display_->Init(filtered_users, show_guest, show_users, show_new_user);
host_->OnPreferencesChanged();
}
void ExistingUserController::DoAutoEnrollment() {
do_auto_enrollment_ = true;
}
void ExistingUserController::ResumeLogin() {
resume_login_callback_.Run();
resume_login_callback_.Reset();
}
void ExistingUserController::Observe(
int type,
const content::NotificationSource& source,
const content::NotificationDetails& details) {
if (type == chrome::NOTIFICATION_SESSION_STARTED) {
registrar_.RemoveAll();
return;
}
if (type == chrome::NOTIFICATION_USER_LIST_CHANGED) {
DeviceSettingsChanged();
return;
}
if (type == chrome::NOTIFICATION_AUTH_SUPPLIED) {
VLOG(1) << "Authentication was entered manually, possibly for proxyauth.";
scoped_refptr<net::URLRequestContextGetter> browser_process_context_getter =
g_browser_process->system_request_context();
Profile* signin_profile = ProfileHelper::GetSigninProfile();
scoped_refptr<net::URLRequestContextGetter> signin_profile_context_getter =
signin_profile->GetRequestContext();
DCHECK(browser_process_context_getter.get());
DCHECK(signin_profile_context_getter.get());
content::BrowserThread::PostDelayedTask(
content::BrowserThread::IO, FROM_HERE,
base::Bind(&TransferContextAuthenticationsOnIOThread,
signin_profile_context_getter,
browser_process_context_getter),
base::TimeDelta::FromMilliseconds(kAuthCacheTransferDelayMs));
}
if (type != chrome::NOTIFICATION_LOGIN_USER_IMAGE_CHANGED)
return;
login_display_->OnUserImageChanged(*content::Details<User>(details).ptr());
}
ExistingUserController::~ExistingUserController() {
LoginUtils::Get()->DelegateDeleted(this);
if (current_controller_ == this) {
current_controller_ = NULL;
} else {
NOTREACHED() << "More than one controller are alive.";
}
DCHECK(login_display_.get());
}
void ExistingUserController::CancelPasswordChangedFlow() {
login_performer_.reset(NULL);
login_display_->SetUIEnabled(true);
StartPublicSessionAutoLoginTimer();
}
void ExistingUserController::CreateAccount() {
content::RecordAction(base::UserMetricsAction("Login.CreateAccount"));
guest_mode_url_ =
google_util::AppendGoogleLocaleParam(GURL(kCreateAccountURL));
LoginAsGuest();
}
void ExistingUserController::CompleteLogin(const UserContext& user_context) {
login_display_->set_signin_completed(true);
if (!host_) {
return;
}
StopPublicSessionAutoLoginTimer();
login_display_->SetUIEnabled(false);
if (!time_init_.is_null()) {
base::TimeDelta delta = base::Time::Now() - time_init_;
UMA_HISTOGRAM_MEDIUM_TIMES("Login.PromptToCompleteLoginTime", delta);
time_init_ = base::Time();
}
host_->OnCompleteLogin();
DeviceSettingsService::Get()->GetOwnershipStatusAsync(
base::Bind(&ExistingUserController::CompleteLoginInternal,
weak_factory_.GetWeakPtr(),
user_context));
}
void ExistingUserController::CompleteLoginInternal(
const UserContext& user_context,
DeviceSettingsService::OwnershipStatus ownership_status) {
if (do_auto_enrollment_ &&
ownership_status == DeviceSettingsService::OWNERSHIP_NONE) {
VLOG(1) << "Forcing auto-enrollment before completing login";
do_auto_enrollment_ = false;
auto_enrollment_username_ = user_context.username;
resume_login_callback_ = base::Bind(
&ExistingUserController::PerformLogin,
weak_factory_.GetWeakPtr(),
user_context, LoginPerformer::AUTH_MODE_EXTENSION);
ShowEnrollmentScreen(true, user_context.username);
login_display_->SetUIEnabled(true);
} else {
PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
}
}
base::string16 ExistingUserController::GetConnectedNetworkName() {
return network_state_helper_->GetCurrentNetworkName();
}
bool ExistingUserController::IsSigninInProgress() const {
return is_login_in_progress_;
}
void ExistingUserController::Login(const UserContext& user_context) {
if ((user_context.username.empty() || user_context.password.empty()) &&
user_context.auth_code.empty())
return;
StopPublicSessionAutoLoginTimer();
login_display_->SetUIEnabled(false);
BootTimesLoader::Get()->RecordLoginAttempted();
if (last_login_attempt_username_ != user_context.username) {
last_login_attempt_username_ = user_context.username;
num_login_attempts_ = 0;
offline_failed_ = false;
online_succeeded_for_.clear();
}
num_login_attempts_++;
PerformLogin(user_context, LoginPerformer::AUTH_MODE_INTERNAL);
}
void ExistingUserController::PerformLogin(
const UserContext& user_context,
LoginPerformer::AuthorizationMode auth_mode) {
UserManager::Get()->GetUserFlow(last_login_attempt_username_)->
set_host(host_);
login_display_->SetUIEnabled(false);
if (!login_performer_.get() || num_login_attempts_ <= 1) {
LoginPerformer::Delegate* delegate = this;
if (login_performer_delegate_.get())
delegate = login_performer_delegate_.get();
login_performer_.reset(NULL);
login_performer_.reset(new LoginPerformer(delegate));
}
is_login_in_progress_ = true;
if (gaia::ExtractDomainName(user_context.username) ==
UserManager::kLocallyManagedUserDomain) {
login_performer_->LoginAsLocallyManagedUser(
UserContext(user_context.username,
user_context.password,
std::string()));
} else {
login_performer_->PerformLogin(user_context, auth_mode);
}
SendAccessibilityAlert(
l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNING_IN));
}
void ExistingUserController::LoginAsRetailModeUser() {
StopPublicSessionAutoLoginTimer();
login_display_->SetUIEnabled(false);
login_performer_.reset(NULL);
login_performer_.reset(new LoginPerformer(this));
is_login_in_progress_ = true;
login_performer_->LoginRetailMode();
SendAccessibilityAlert(
l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_DEMOUSER));
}
void ExistingUserController::LoginAsGuest() {
if (is_login_in_progress_ || UserManager::Get()->IsUserLoggedIn())
return;
StopPublicSessionAutoLoginTimer();
login_display_->SetUIEnabled(false);
CrosSettingsProvider::TrustedStatus status =
cros_settings_->PrepareTrustedValues(
base::Bind(&ExistingUserController::LoginAsGuest,
weak_factory_.GetWeakPtr()));
if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1,
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
login_display_->SetUIEnabled(true);
StartPublicSessionAutoLoginTimer();
display_email_.clear();
return;
} else if (status != CrosSettingsProvider::TRUSTED) {
return;
}
bool allow_guest;
cros_settings_->GetBoolean(kAccountsPrefAllowGuest, &allow_guest);
if (!allow_guest) {
login_display_->ShowError(IDS_LOGIN_ERROR_WHITELIST, 1,
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
login_display_->SetUIEnabled(true);
StartPublicSessionAutoLoginTimer();
display_email_.clear();
return;
}
login_performer_.reset(NULL);
login_performer_.reset(new LoginPerformer(this));
is_login_in_progress_ = true;
login_performer_->LoginOffTheRecord();
SendAccessibilityAlert(
l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_OFFRECORD));
}
void ExistingUserController::MigrateUserData(const std::string& old_password) {
if (login_performer_.get())
login_performer_->RecoverEncryptedData(old_password);
}
void ExistingUserController::LoginAsPublicAccount(
const std::string& username) {
if (is_login_in_progress_ || UserManager::Get()->IsUserLoggedIn())
return;
StopPublicSessionAutoLoginTimer();
login_display_->SetUIEnabled(false);
CrosSettingsProvider::TrustedStatus status =
cros_settings_->PrepareTrustedValues(
base::Bind(&ExistingUserController::LoginAsPublicAccount,
weak_factory_.GetWeakPtr(),
username));
if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1,
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
login_display_->SetUIEnabled(true);
return;
}
if (status != CrosSettingsProvider::TRUSTED)
return;
const User* user = UserManager::Get()->FindUser(username);
if (!user || user->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT) {
login_display_->SetUIEnabled(true);
StartPublicSessionAutoLoginTimer();
return;
}
login_performer_.reset(NULL);
login_performer_.reset(new LoginPerformer(this));
is_login_in_progress_ = true;
login_performer_->LoginAsPublicAccount(username);
SendAccessibilityAlert(
l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_PUBLIC_ACCOUNT));
}
void ExistingUserController::LoginAsKioskApp(const std::string& app_id,
bool diagnostic_mode) {
host_->StartAppLaunch(app_id, diagnostic_mode);
}
void ExistingUserController::OnSigninScreenReady() {
signin_screen_ready_ = true;
StartPublicSessionAutoLoginTimer();
}
void ExistingUserController::OnUserSelected(const std::string& username) {
login_performer_.reset(NULL);
num_login_attempts_ = 0;
}
void ExistingUserController::OnStartEnterpriseEnrollment() {
if (KioskAppManager::Get()->IsConsumerKioskDeviceWithAutoLaunch()) {
LOG(WARNING) << "Enterprise enrollment is not available after kiosk auto "
"launch is set.";
return;
}
DeviceSettingsService::Get()->GetOwnershipStatusAsync(
base::Bind(&ExistingUserController::OnEnrollmentOwnershipCheckCompleted,
weak_factory_.GetWeakPtr()));
}
void ExistingUserController::OnStartKioskEnableScreen() {
KioskAppManager::Get()->GetConsumerKioskAutoLaunchStatus(
base::Bind(
&ExistingUserController::OnConsumerKioskAutoLaunchCheckCompleted,
weak_factory_.GetWeakPtr()));
}
void ExistingUserController::OnStartDeviceReset() {
ShowResetScreen();
}
void ExistingUserController::OnStartKioskAutolaunchScreen() {
ShowKioskAutolaunchScreen();
}
void ExistingUserController::ResyncUserData() {
if (login_performer_.get())
login_performer_->ResyncEncryptedData();
}
void ExistingUserController::SetDisplayEmail(const std::string& email) {
display_email_ = email;
}
void ExistingUserController::ShowWrongHWIDScreen() {
scoped_ptr<base::DictionaryValue> params;
host_->StartWizard(WizardController::kWrongHWIDScreenName, params.Pass());
login_display_->OnFadeOut();
}
void ExistingUserController::Signout() {
NOTREACHED();
}
void ExistingUserController::OnConsumerKioskAutoLaunchCheckCompleted(
KioskAppManager::ConsumerKioskAutoLaunchStatus status) {
if (status == KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE)
ShowKioskEnableScreen();
}
void ExistingUserController::OnEnrollmentOwnershipCheckCompleted(
DeviceSettingsService::OwnershipStatus status) {
if (status == DeviceSettingsService::OWNERSHIP_NONE) {
ShowEnrollmentScreen(false, std::string());
} else if (status == DeviceSettingsService::OWNERSHIP_TAKEN) {
CrosSettingsProvider::TrustedStatus trusted_status =
CrosSettings::Get()->PrepareTrustedValues(
base::Bind(
&ExistingUserController::OnEnrollmentOwnershipCheckCompleted,
weak_factory_.GetWeakPtr(), status));
if (trusted_status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
ShowEnrollmentScreen(false, std::string());
}
} else {
NOTREACHED();
}
}
void ExistingUserController::ShowEnrollmentScreen(bool is_auto_enrollment,
const std::string& user) {
scoped_ptr<base::DictionaryValue> params;
if (is_auto_enrollment) {
params.reset(new base::DictionaryValue());
params->SetBoolean("is_auto_enrollment", true);
params->SetString("user", user);
}
host_->StartWizard(WizardController::kEnrollmentScreenName,
params.Pass());
login_display_->OnFadeOut();
}
void ExistingUserController::ShowResetScreen() {
scoped_ptr<base::DictionaryValue> params;
host_->StartWizard(WizardController::kResetScreenName, params.Pass());
login_display_->OnFadeOut();
}
void ExistingUserController::ShowKioskEnableScreen() {
scoped_ptr<base::DictionaryValue> params;
host_->StartWizard(WizardController::kKioskEnableScreenName, params.Pass());
login_display_->OnFadeOut();
}
void ExistingUserController::ShowKioskAutolaunchScreen() {
scoped_ptr<base::DictionaryValue> params;
host_->StartWizard(WizardController::kKioskAutolaunchScreenName,
params.Pass());
login_display_->OnFadeOut();
}
void ExistingUserController::ShowTPMError() {
login_display_->SetUIEnabled(false);
login_display_->ShowErrorScreen(LoginDisplay::TPM_ERROR);
}
void ExistingUserController::OnLoginFailure(const LoginFailure& failure) {
is_login_in_progress_ = false;
offline_failed_ = true;
guest_mode_url_ = GURL::EmptyGURL();
std::string error = failure.GetErrorString();
if (UserManager::Get()->GetUserFlow(last_login_attempt_username_)->
HandleLoginFailure(failure)) {
login_display_->SetUIEnabled(true);
return;
}
if (failure.reason() == LoginFailure::OWNER_REQUIRED) {
ShowError(IDS_LOGIN_ERROR_OWNER_REQUIRED, error);
content::BrowserThread::PostDelayedTask(
content::BrowserThread::UI, FROM_HERE,
base::Bind(&SessionManagerClient::StopSession,
base::Unretained(DBusThreadManager::Get()->
GetSessionManagerClient())),
base::TimeDelta::FromMilliseconds(kSafeModeRestartUiDelayMs));
} else if (failure.reason() == LoginFailure::TPM_ERROR) {
ShowTPMError();
} else if (!online_succeeded_for_.empty()) {
ShowGaiaPasswordChanged(online_succeeded_for_);
} else {
bool is_known_user =
UserManager::Get()->IsKnownUser(last_login_attempt_username_);
if (!network_state_helper_->IsConnected()) {
if (is_known_user)
ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
else
ShowError(IDS_LOGIN_ERROR_OFFLINE_FAILED_NETWORK_NOT_CONNECTED, error);
} else {
if (failure.reason() == LoginFailure::NETWORK_AUTH_FAILED &&
failure.error().state() ==
GoogleServiceAuthError::HOSTED_NOT_ALLOWED) {
ShowError(IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED, error);
} else {
if (!is_known_user)
ShowError(IDS_LOGIN_ERROR_AUTHENTICATING_NEW, error);
else
ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
}
}
login_display_->SetUIEnabled(true);
login_display_->ClearAndEnablePassword();
StartPublicSessionAutoLoginTimer();
}
UserManager::Get()->ResetUserFlow(last_login_attempt_username_);
if (login_status_consumer_)
login_status_consumer_->OnLoginFailure(failure);
display_email_.clear();
}
void ExistingUserController::OnLoginSuccess(const UserContext& user_context) {
is_login_in_progress_ = false;
offline_failed_ = false;
login_display_->set_signin_completed(true);
UserManager::Get()->GetUserFlow(user_context.username)->HandleLoginSuccess(
user_context);
StopPublicSessionAutoLoginTimer();
bool has_cookies =
login_performer_->auth_mode() == LoginPerformer::AUTH_MODE_EXTENSION &&
user_context.auth_code.empty();
password_changed_ = login_performer_->password_changed();
login_performer_->set_delegate(NULL);
ignore_result(login_performer_.release());
LoginUtils::Get()->PrepareProfile(user_context,
display_email_,
has_cookies,
false,
this);
display_email_.clear();
login_display_->OnLoginSuccess(user_context.username);
}
void ExistingUserController::OnProfilePrepared(Profile* profile) {
login_display_->SetUIEnabled(true);
UserManager* user_manager = UserManager::Get();
if (user_manager->IsCurrentUserNew() &&
user_manager->IsLoggedInAsLocallyManagedUser()) {
CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
}
if (user_manager->IsCurrentUserNew() &&
!user_manager->GetCurrentUserFlow()->ShouldSkipPostLoginScreens() &&
!WizardController::default_controller()->skip_post_login_screens()) {
if (!SessionStartupPref::TypeIsManaged(profile->GetPrefs()))
InitializeStartUrls();
if (!StartupUtils::IsDeviceRegistered())
StartupUtils::MarkDeviceRegistered();
if (CommandLine::ForCurrentProcess()->HasSwitch(
chromeos::switches::kOobeSkipPostLogin)) {
LoginUtils::Get()->DoBrowserLaunch(profile, host_);
host_ = NULL;
} else {
ActivateWizard(WizardController::kTermsOfServiceScreenName);
}
} else {
LoginUtils::Get()->DoBrowserLaunch(profile, host_);
host_ = NULL;
}
if (login_status_consumer_)
login_status_consumer_->OnLoginSuccess(UserContext());
login_display_->OnFadeOut();
}
void ExistingUserController::OnOffTheRecordLoginSuccess() {
is_login_in_progress_ = false;
offline_failed_ = false;
if (!StartupUtils::IsDeviceRegistered())
StartupUtils::MarkDeviceRegistered();
LoginUtils::Get()->CompleteOffTheRecordLogin(guest_mode_url_);
if (login_status_consumer_)
login_status_consumer_->OnOffTheRecordLoginSuccess();
}
void ExistingUserController::OnPasswordChangeDetected() {
is_login_in_progress_ = false;
offline_failed_ = false;
if (CrosSettingsProvider::TRUSTED != cros_settings_->PrepareTrustedValues(
base::Bind(&ExistingUserController::OnPasswordChangeDetected,
weak_factory_.GetWeakPtr()))) {
return;
}
if (UserManager::Get()->GetUserFlow(last_login_attempt_username_)->
HandlePasswordChangeDetected()) {
return;
}
bool show_invalid_old_password_error =
login_performer_->password_changed_callback_count() > 1;
login_display_->ShowPasswordChangedDialog(show_invalid_old_password_error);
if (login_status_consumer_)
login_status_consumer_->OnPasswordChangeDetected();
display_email_.clear();
}
void ExistingUserController::WhiteListCheckFailed(const std::string& email) {
is_login_in_progress_ = false;
offline_failed_ = false;
ShowError(IDS_LOGIN_ERROR_WHITELIST, email);
login_display_->SetUIEnabled(true);
login_display_->ShowSigninUI(email);
if (login_status_consumer_) {
login_status_consumer_->OnLoginFailure(LoginFailure(
LoginFailure::WHITELIST_CHECK_FAILED));
}
display_email_.clear();
StartPublicSessionAutoLoginTimer();
}
void ExistingUserController::PolicyLoadFailed() {
ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, "");
is_login_in_progress_ = false;
offline_failed_ = false;
login_display_->SetUIEnabled(true);
display_email_.clear();
StartPublicSessionAutoLoginTimer();
}
void ExistingUserController::OnOnlineChecked(const std::string& username,
bool success) {
if (success && last_login_attempt_username_ == username) {
online_succeeded_for_ = username;
if (offline_failed_ && !is_login_in_progress_)
ShowGaiaPasswordChanged(username);
}
}
void ExistingUserController::DeviceSettingsChanged() {
if (host_ != NULL) {
UpdateLoginDisplay(chromeos::UserManager::Get()->GetUsers());
ConfigurePublicSessionAutoLogin();
return;
}
}
void ExistingUserController::ActivateWizard(const std::string& screen_name) {
scoped_ptr<base::DictionaryValue> params;
host_->StartWizard(screen_name, params.Pass());
}
void ExistingUserController::ConfigurePublicSessionAutoLogin() {
std::string auto_login_account_id;
cros_settings_->GetString(kAccountsPrefDeviceLocalAccountAutoLoginId,
&auto_login_account_id);
const std::vector<policy::DeviceLocalAccount> device_local_accounts =
policy::GetDeviceLocalAccounts(cros_settings_);
public_session_auto_login_username_.clear();
for (std::vector<policy::DeviceLocalAccount>::const_iterator
it = device_local_accounts.begin();
it != device_local_accounts.end(); ++it) {
if (it->account_id == auto_login_account_id) {
public_session_auto_login_username_ = it->user_id;
break;
}
}
const User* user =
UserManager::Get()->FindUser(public_session_auto_login_username_);
if (!user || user->GetType() != User::USER_TYPE_PUBLIC_ACCOUNT)
public_session_auto_login_username_.clear();
if (!cros_settings_->GetInteger(
kAccountsPrefDeviceLocalAccountAutoLoginDelay,
&public_session_auto_login_delay_)) {
public_session_auto_login_delay_ = 0;
}
if (!public_session_auto_login_username_.empty())
StartPublicSessionAutoLoginTimer();
else
StopPublicSessionAutoLoginTimer();
}
void ExistingUserController::ResetPublicSessionAutoLoginTimer() {
if (auto_login_timer_ && auto_login_timer_->IsRunning()) {
StopPublicSessionAutoLoginTimer();
StartPublicSessionAutoLoginTimer();
}
}
void ExistingUserController::OnPublicSessionAutoLoginTimerFire() {
CHECK(signin_screen_ready_ &&
!is_login_in_progress_ &&
!public_session_auto_login_username_.empty());
LoginAsPublicAccount(public_session_auto_login_username_);
}
void ExistingUserController::StopPublicSessionAutoLoginTimer() {
if (auto_login_timer_)
auto_login_timer_->Stop();
}
void ExistingUserController::StartPublicSessionAutoLoginTimer() {
if (!signin_screen_ready_ ||
is_login_in_progress_ ||
public_session_auto_login_username_.empty()) {
return;
}
if (!auto_login_timer_)
auto_login_timer_.reset(new base::OneShotTimer<ExistingUserController>);
auto_login_timer_->Start(
FROM_HERE,
base::TimeDelta::FromMilliseconds(
public_session_auto_login_delay_),
base::Bind(
&ExistingUserController::OnPublicSessionAutoLoginTimerFire,
weak_factory_.GetWeakPtr()));
}
gfx::NativeWindow ExistingUserController::GetNativeWindow() const {
return host_->GetNativeWindow();
}
void ExistingUserController::InitializeStartUrls() const {
std::vector<std::string> start_urls;
const base::ListValue *urls;
UserManager* user_manager = UserManager::Get();
bool can_show_getstarted_guide =
user_manager->GetActiveUser()->GetType() == User::USER_TYPE_REGULAR &&
!user_manager->IsCurrentUserNonCryptohomeDataEphemeral();
if (user_manager->IsLoggedInAsDemoUser()) {
if (CrosSettings::Get()->GetList(kStartUpUrls, &urls)) {
for (base::ListValue::const_iterator it = urls->begin();
it != urls->end(); ++it) {
std::string url;
if ((*it)->GetAsString(&url))
start_urls.push_back(url);
}
}
can_show_getstarted_guide = false;
} else if (!user_manager->IsLoggedInAsPublicAccount()) {
if (AccessibilityManager::Get()->IsSpokenFeedbackEnabled()) {
const char* url = kChromeVoxTutorialURLPattern;
PrefService* prefs = g_browser_process->local_state();
const std::string current_locale =
StringToLowerASCII(prefs->GetString(prefs::kApplicationLocale));
std::string vox_url = base::StringPrintf(url, current_locale.c_str());
start_urls.push_back(vox_url);
can_show_getstarted_guide = false;
}
}
const bool should_show_getstarted_guide = user_manager->IsCurrentUserNew();
if (can_show_getstarted_guide && should_show_getstarted_guide) {
CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
first_run::MaybeLaunchDialogAfterSessionStart();
} else {
for (size_t i = 0; i < start_urls.size(); ++i) {
CommandLine::ForCurrentProcess()->AppendArg(start_urls[i]);
}
}
}
void ExistingUserController::ShowError(int error_id,
const std::string& details) {
VLOG(1) << details;
HelpAppLauncher::HelpTopic help_topic_id;
bool is_offline = !network_state_helper_->IsConnected();
switch (login_performer_->error().state()) {
case GoogleServiceAuthError::CONNECTION_FAILED:
help_topic_id = HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT_OFFLINE;
break;
case GoogleServiceAuthError::ACCOUNT_DISABLED:
help_topic_id = HelpAppLauncher::HELP_ACCOUNT_DISABLED;
break;
case GoogleServiceAuthError::HOSTED_NOT_ALLOWED:
help_topic_id = HelpAppLauncher::HELP_HOSTED_ACCOUNT;
break;
default:
help_topic_id = is_offline ?
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT_OFFLINE :
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT;
break;
}
login_display_->ShowError(error_id, num_login_attempts_, help_topic_id);
}
void ExistingUserController::ShowGaiaPasswordChanged(
const std::string& username) {
UserManager::Get()->SaveUserOAuthStatus(
username,
User::OAUTH2_TOKEN_STATUS_INVALID);
login_display_->SetUIEnabled(true);
login_display_->ShowGaiaPasswordChanged(username);
}
void ExistingUserController::SendAccessibilityAlert(
const std::string& alert_text) {
AccessibilityAlertInfo event(ProfileHelper::GetSigninProfile(), alert_text);
SendControlAccessibilityNotification(
ui::AX_EVENT_VALUE_CHANGED, &event);
}
}