Commit 609c2d1d authored by nkostylev's avatar nkostylev Committed by Commit bot

[session_manager] Move user session initialization code out of ExistingUserController

Added UserSessionManager::InitializeUserSession()
(1) Launches browser for most common case
(2) Continues new user sign in with TOS (public sessions)/image screen (new users)
(3) For kiosk flow delegates launching app to the existing kiosk initialization flow

(1) Currently results in LoginUtils::Get()->DoBrowserLaunch() which may postpone launching browser for these reasons:
(a) There's custom user login flow defined like SupervisedUserCreationFlow. In that case login UI continues to live and custom flow UI is launched in that context.
(b) User has different app locale which requires reloading resource_bundle prior to launching browser
(c) User has custom flags set (or user flags are different from login screen flags defined by the owner), this requires restarting Chrome which will be launched in the active user session.

Small refactoring in ExistingUserController, added

* PerformPreLoginActions() - performs sets of actions right prior to login has been started.
* PerformLoginFinishedActions() - performs set of actions when login has been completed or has been cancelled.

BUG=370175

Review URL: https://codereview.chromium.org/656283002

Cr-Commit-Position: refs/heads/master@{#300708}
parent 8aecd2dd
...@@ -183,7 +183,8 @@ void KioskProfileLoader::OnOnlineChecked( ...@@ -183,7 +183,8 @@ void KioskProfileLoader::OnOnlineChecked(
NOTREACHED(); NOTREACHED();
} }
void KioskProfileLoader::OnProfilePrepared(Profile* profile) { void KioskProfileLoader::OnProfilePrepared(Profile* profile,
bool browser_launched) {
// This object could be deleted any time after successfully reporting // This object could be deleted any time after successfully reporting
// a profile load, so invalidate the LoginUtils delegate now. // a profile load, so invalidate the LoginUtils delegate now.
LoginUtils::Get()->DelegateDeleted(this); LoginUtils::Get()->DelegateDeleted(this);
......
...@@ -57,7 +57,8 @@ class KioskProfileLoader : public LoginPerformer::Delegate, ...@@ -57,7 +57,8 @@ class KioskProfileLoader : public LoginPerformer::Delegate,
const std::string& email, bool success) override; const std::string& email, bool success) override;
// LoginUtils::Delegate implementation: // LoginUtils::Delegate implementation:
virtual void OnProfilePrepared(Profile* profile) override; virtual void OnProfilePrepared(Profile* profile,
bool browser_launched) override;
std::string user_id_; std::string user_id_;
bool use_guest_mount_; bool use_guest_mount_;
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "base/metrics/histogram.h" #include "base/metrics/histogram.h"
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "base/strings/string_util.h" #include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "base/values.h" #include "base/values.h"
#include "base/version.h" #include "base/version.h"
...@@ -24,10 +23,8 @@ ...@@ -24,10 +23,8 @@
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part.h" #include "chrome/browser/browser_process_platform_part.h"
#include "chrome/browser/chrome_notification_types.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/boot_times_loader.h"
#include "chrome/browser/chromeos/customization_document.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/kiosk_mode/kiosk_mode_settings.h"
#include "chrome/browser/chromeos/login/auth/chrome_login_performer.h" #include "chrome/browser/chromeos/login/auth/chrome_login_performer.h"
#include "chrome/browser/chromeos/login/helper.h" #include "chrome/browser/chromeos/login/helper.h"
...@@ -43,7 +40,6 @@ ...@@ -43,7 +40,6 @@
#include "chrome/browser/chromeos/policy/device_local_account_policy_service.h" #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/cros_settings.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
#include "chrome/common/chrome_switches.h" #include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h" #include "chrome/common/chrome_version_info.h"
...@@ -89,11 +85,6 @@ namespace { ...@@ -89,11 +85,6 @@ namespace {
const char kCreateAccountURL[] = const char kCreateAccountURL[] =
"https://accounts.google.com/NewAccount?service=mail"; "https://accounts.google.com/NewAccount?service=mail";
// ChromeVox tutorial URL (used in place of "getting started" url when
// accessibility is enabled).
const char kChromeVoxTutorialURLPattern[] =
"http://www.chromevox.com/tutorial/index.html?lang=%s";
// Delay for transferring the auth cache to the system profile. // Delay for transferring the auth cache to the system profile.
const long int kAuthCacheTransferDelayMs = 2000; const long int kAuthCacheTransferDelayMs = 2000;
...@@ -326,8 +317,7 @@ ExistingUserController::~ExistingUserController() { ...@@ -326,8 +317,7 @@ ExistingUserController::~ExistingUserController() {
void ExistingUserController::CancelPasswordChangedFlow() { void ExistingUserController::CancelPasswordChangedFlow() {
login_performer_.reset(NULL); login_performer_.reset(NULL);
login_display_->SetUIEnabled(true); PerformLoginFinishedActions(true /* start public session timer */);
StartPublicSessionAutoLoginTimer();
} }
void ExistingUserController::CreateAccount() { void ExistingUserController::CreateAccount() {
...@@ -344,11 +334,7 @@ void ExistingUserController::CompleteLogin(const UserContext& user_context) { ...@@ -344,11 +334,7 @@ void ExistingUserController::CompleteLogin(const UserContext& user_context) {
return; return;
} }
// Stop the auto-login timer when attempting login. PerformPreLoginActions(user_context);
StopPublicSessionAutoLoginTimer();
// Disable UI while loading user profile.
login_display_->SetUIEnabled(false);
if (!time_init_.is_null()) { if (!time_init_.is_null()) {
base::TimeDelta delta = base::Time::Now() - time_init_; base::TimeDelta delta = base::Time::Now() - time_init_;
...@@ -387,7 +373,7 @@ void ExistingUserController::CompleteLoginInternal( ...@@ -387,7 +373,7 @@ void ExistingUserController::CompleteLoginInternal(
// Enable UI for the enrollment screen. SetUIEnabled(true) will post a // Enable UI for the enrollment screen. SetUIEnabled(true) will post a
// request to show the sign-in screen again when invoked at the sign-in // request to show the sign-in screen again when invoked at the sign-in
// screen; invoke SetUIEnabled() after navigating to the enrollment screen. // screen; invoke SetUIEnabled() after navigating to the enrollment screen.
login_display_->SetUIEnabled(true); PerformLoginFinishedActions(false /* don't start public session timer */);
} else { } else {
PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION); PerformLogin(user_context, LoginPerformer::AUTH_MODE_EXTENSION);
} }
...@@ -428,34 +414,18 @@ void ExistingUserController::Login(const UserContext& user_context, ...@@ -428,34 +414,18 @@ void ExistingUserController::Login(const UserContext& user_context,
if (!user_context.HasCredentials()) if (!user_context.HasCredentials())
return; return;
// Stop the auto-login timer when attempting login. PerformPreLoginActions(user_context);
StopPublicSessionAutoLoginTimer();
// Disable clicking on other windows.
login_display_->SetUIEnabled(false);
if (last_login_attempt_username_ != user_context.GetUserID()) {
last_login_attempt_username_ = user_context.GetUserID();
num_login_attempts_ = 0;
// Also reset state variables, which are used to determine password change.
offline_failed_ = false;
online_succeeded_for_.clear();
}
num_login_attempts_++;
PerformLogin(user_context, LoginPerformer::AUTH_MODE_INTERNAL); PerformLogin(user_context, LoginPerformer::AUTH_MODE_INTERNAL);
} }
void ExistingUserController::PerformLogin( void ExistingUserController::PerformLogin(
const UserContext& user_context, const UserContext& user_context,
LoginPerformer::AuthorizationMode auth_mode) { LoginPerformer::AuthorizationMode auth_mode) {
ChromeUserManager::Get()->GetUserFlow(last_login_attempt_username_)->set_host( ChromeUserManager::Get()->GetUserFlow(user_context.GetUserID())->set_host(
host_); host_);
BootTimesLoader::Get()->RecordLoginAttempted(); BootTimesLoader::Get()->RecordLoginAttempted();
// Disable UI while loading user profile.
login_display_->SetUIEnabled(false);
// Use the same LoginPerformer for subsequent login as it has state // Use the same LoginPerformer for subsequent login as it has state
// such as Authenticator instance. // such as Authenticator instance.
if (!login_performer_.get() || num_login_attempts_ <= 1) { if (!login_performer_.get() || num_login_attempts_ <= 1) {
...@@ -464,7 +434,6 @@ void ExistingUserController::PerformLogin( ...@@ -464,7 +434,6 @@ void ExistingUserController::PerformLogin(
login_performer_.reset(new ChromeLoginPerformer(this)); login_performer_.reset(new ChromeLoginPerformer(this));
} }
is_login_in_progress_ = true;
if (gaia::ExtractDomainName(user_context.GetUserID()) == if (gaia::ExtractDomainName(user_context.GetUserID()) ==
chromeos::login::kSupervisedUserDomain) { chromeos::login::kSupervisedUserDomain) {
login_performer_->LoginAsSupervisedUser(user_context); login_performer_->LoginAsSupervisedUser(user_context);
...@@ -476,18 +445,15 @@ void ExistingUserController::PerformLogin( ...@@ -476,18 +445,15 @@ void ExistingUserController::PerformLogin(
} }
void ExistingUserController::LoginAsRetailModeUser() { void ExistingUserController::LoginAsRetailModeUser() {
// Stop the auto-login timer when attempting login. PerformPreLoginActions(UserContext(user_manager::USER_TYPE_RETAIL_MODE,
StopPublicSessionAutoLoginTimer(); chromeos::login::kRetailModeUserName));
// Disable clicking on other windows.
login_display_->SetUIEnabled(false);
// TODO(rkc): Add a CHECK to make sure retail mode logins are allowed once // TODO(rkc): Add a CHECK to make sure retail mode logins are allowed once
// the enterprise policy wiring is done for retail mode. // the enterprise policy wiring is done for retail mode.
// Only one instance of LoginPerformer should exist at a time. // Only one instance of LoginPerformer should exist at a time.
login_performer_.reset(NULL); login_performer_.reset(NULL);
login_performer_.reset(new ChromeLoginPerformer(this)); login_performer_.reset(new ChromeLoginPerformer(this));
is_login_in_progress_ = true;
login_performer_->LoginRetailMode(); login_performer_->LoginRetailMode();
SendAccessibilityAlert( SendAccessibilityAlert(
l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_DEMOUSER)); l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_DEMOUSER));
...@@ -499,11 +465,8 @@ void ExistingUserController::LoginAsGuest() { ...@@ -499,11 +465,8 @@ void ExistingUserController::LoginAsGuest() {
return; return;
} }
// Stop the auto-login timer when attempting login. PerformPreLoginActions(UserContext(user_manager::USER_TYPE_GUEST,
StopPublicSessionAutoLoginTimer(); chromeos::login::kGuestUserName));
// Disable clicking on other windows.
login_display_->SetUIEnabled(false);
CrosSettingsProvider::TrustedStatus status = CrosSettingsProvider::TrustedStatus status =
cros_settings_->PrepareTrustedValues( cros_settings_->PrepareTrustedValues(
...@@ -513,9 +476,7 @@ void ExistingUserController::LoginAsGuest() { ...@@ -513,9 +476,7 @@ void ExistingUserController::LoginAsGuest() {
if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) { if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1, login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1,
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT); HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
// Reenable clicking on other windows and status area. PerformLoginFinishedActions(false /* don't start public session timer */);
login_display_->SetUIEnabled(true);
StartPublicSessionAutoLoginTimer();
display_email_.clear(); display_email_.clear();
return; return;
} else if (status != CrosSettingsProvider::TRUSTED) { } else if (status != CrosSettingsProvider::TRUSTED) {
...@@ -532,9 +493,7 @@ void ExistingUserController::LoginAsGuest() { ...@@ -532,9 +493,7 @@ void ExistingUserController::LoginAsGuest() {
// this nicely. // this nicely.
login_display_->ShowError(IDS_LOGIN_ERROR_WHITELIST, 1, login_display_->ShowError(IDS_LOGIN_ERROR_WHITELIST, 1,
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT); HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
// Reenable clicking on other windows and status area. PerformLoginFinishedActions(true /* start public session timer */);
login_display_->SetUIEnabled(true);
StartPublicSessionAutoLoginTimer();
display_email_.clear(); display_email_.clear();
return; return;
} }
...@@ -542,7 +501,6 @@ void ExistingUserController::LoginAsGuest() { ...@@ -542,7 +501,6 @@ void ExistingUserController::LoginAsGuest() {
// Only one instance of LoginPerformer should exist at a time. // Only one instance of LoginPerformer should exist at a time.
login_performer_.reset(NULL); login_performer_.reset(NULL);
login_performer_.reset(new ChromeLoginPerformer(this)); login_performer_.reset(new ChromeLoginPerformer(this));
is_login_in_progress_ = true;
login_performer_->LoginOffTheRecord(); login_performer_->LoginOffTheRecord();
SendAccessibilityAlert( SendAccessibilityAlert(
l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_OFFRECORD)); l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_OFFRECORD));
...@@ -561,11 +519,7 @@ void ExistingUserController::LoginAsPublicSession( ...@@ -561,11 +519,7 @@ void ExistingUserController::LoginAsPublicSession(
return; return;
} }
// Stop the auto-login timer when attempting login. PerformPreLoginActions(user_context);
StopPublicSessionAutoLoginTimer();
// Disable clicking on other windows.
login_display_->SetUIEnabled(false);
CrosSettingsProvider::TrustedStatus status = CrosSettingsProvider::TrustedStatus status =
cros_settings_->PrepareTrustedValues( cros_settings_->PrepareTrustedValues(
...@@ -577,8 +531,7 @@ void ExistingUserController::LoginAsPublicSession( ...@@ -577,8 +531,7 @@ void ExistingUserController::LoginAsPublicSession(
if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) { if (status == CrosSettingsProvider::PERMANENTLY_UNTRUSTED) {
login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1, login_display_->ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, 1,
HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT); HelpAppLauncher::HELP_CANT_ACCESS_ACCOUNT);
// Re-enable clicking on other windows. PerformLoginFinishedActions(false /* don't start public session timer */);
login_display_->SetUIEnabled(true);
return; return;
} }
...@@ -592,9 +545,7 @@ void ExistingUserController::LoginAsPublicSession( ...@@ -592,9 +545,7 @@ void ExistingUserController::LoginAsPublicSession(
const user_manager::User* user = const user_manager::User* user =
user_manager::UserManager::Get()->FindUser(user_context.GetUserID()); user_manager::UserManager::Get()->FindUser(user_context.GetUserID());
if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) { if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) {
// Re-enable clicking on other windows. PerformLoginFinishedActions(true /* start public session timer */);
login_display_->SetUIEnabled(true);
StartPublicSessionAutoLoginTimer();
return; return;
} }
...@@ -769,16 +720,15 @@ void ExistingUserController::ShowTPMError() { ...@@ -769,16 +720,15 @@ void ExistingUserController::ShowTPMError() {
// //
void ExistingUserController::OnAuthFailure(const AuthFailure& failure) { void ExistingUserController::OnAuthFailure(const AuthFailure& failure) {
is_login_in_progress_ = false;
offline_failed_ = true; offline_failed_ = true;
guest_mode_url_ = GURL::EmptyGURL(); guest_mode_url_ = GURL::EmptyGURL();
std::string error = failure.GetErrorString(); std::string error = failure.GetErrorString();
PerformLoginFinishedActions(false /* don't start public session timer */);
if (ChromeUserManager::Get() if (ChromeUserManager::Get()
->GetUserFlow(last_login_attempt_username_) ->GetUserFlow(last_login_attempt_username_)
->HandleLoginFailure(failure)) { ->HandleLoginFailure(failure)) {
login_display_->SetUIEnabled(true);
return; return;
} }
...@@ -817,8 +767,6 @@ void ExistingUserController::OnAuthFailure(const AuthFailure& failure) { ...@@ -817,8 +767,6 @@ void ExistingUserController::OnAuthFailure(const AuthFailure& failure) {
ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error); ShowError(IDS_LOGIN_ERROR_AUTHENTICATING, error);
} }
} }
// Reenable clicking on other windows and status area.
login_display_->SetUIEnabled(true);
login_display_->ClearAndEnablePassword(); login_display_->ClearAndEnablePassword();
StartPublicSessionAutoLoginTimer(); StartPublicSessionAutoLoginTimer();
} }
...@@ -876,46 +824,20 @@ void ExistingUserController::OnAuthSuccess(const UserContext& user_context) { ...@@ -876,46 +824,20 @@ void ExistingUserController::OnAuthSuccess(const UserContext& user_context) {
} }
} }
void ExistingUserController::OnProfilePrepared(Profile* profile) { void ExistingUserController::OnProfilePrepared(Profile* profile,
bool browser_launched) {
// Reenable clicking on other windows and status area. // Reenable clicking on other windows and status area.
login_display_->SetUIEnabled(true); login_display_->SetUIEnabled(true);
user_manager::UserManager* user_manager = user_manager::UserManager::Get(); if (browser_launched)
if (user_manager->IsCurrentUserNew() &&
user_manager->IsLoggedInAsSupervisedUser()) {
// Supervised users should launch into empty desktop on first run.
CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
}
if (user_manager->IsCurrentUserNew() &&
!ChromeUserManager::Get()
->GetCurrentUserFlow()
->ShouldSkipPostLoginScreens() &&
!WizardController::default_controller()->skip_post_login_screens()) {
// Don't specify start URLs if the administrator has configured the start
// URLs via policy.
if (!SessionStartupPref::TypeIsManaged(profile->GetPrefs()))
InitializeStartUrls();
// Mark the device as registered., i.e. the second part of OOBE as
// completed.
if (!StartupUtils::IsDeviceRegistered())
StartupUtils::MarkDeviceRegistered(base::Closure());
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; host_ = NULL;
}
// Inform |auth_status_consumer_| about successful login. // Inform |auth_status_consumer_| about successful login.
if (auth_status_consumer_) // TODO(nkostylev): Pass UserContext back crbug.com/424550
auth_status_consumer_->OnAuthSuccess(UserContext()); if (auth_status_consumer_) {
auth_status_consumer_->
OnAuthSuccess(UserContext(last_login_attempt_username_));
}
} }
void ExistingUserController::OnOffTheRecordAuthSuccess() { void ExistingUserController::OnOffTheRecordAuthSuccess() {
...@@ -969,13 +891,11 @@ void ExistingUserController::OnPasswordChangeDetected() { ...@@ -969,13 +891,11 @@ void ExistingUserController::OnPasswordChangeDetected() {
} }
void ExistingUserController::WhiteListCheckFailed(const std::string& email) { void ExistingUserController::WhiteListCheckFailed(const std::string& email) {
is_login_in_progress_ = false; PerformLoginFinishedActions(true /* start public session timer */);
offline_failed_ = false; offline_failed_ = false;
ShowError(IDS_LOGIN_ERROR_WHITELIST, email); ShowError(IDS_LOGIN_ERROR_WHITELIST, email);
// Reenable clicking on other windows and status area.
login_display_->SetUIEnabled(true);
login_display_->ShowSigninUI(email); login_display_->ShowSigninUI(email);
if (auth_status_consumer_) { if (auth_status_consumer_) {
...@@ -984,22 +904,14 @@ void ExistingUserController::WhiteListCheckFailed(const std::string& email) { ...@@ -984,22 +904,14 @@ void ExistingUserController::WhiteListCheckFailed(const std::string& email) {
} }
display_email_.clear(); display_email_.clear();
StartPublicSessionAutoLoginTimer();
} }
void ExistingUserController::PolicyLoadFailed() { void ExistingUserController::PolicyLoadFailed() {
ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, ""); ShowError(IDS_LOGIN_ERROR_OWNER_KEY_LOST, "");
// Reenable clicking on other windows and status area. PerformLoginFinishedActions(false /* don't start public session timer */);
is_login_in_progress_ = false;
offline_failed_ = false; offline_failed_ = false;
login_display_->SetUIEnabled(true);
display_email_.clear(); display_email_.clear();
// Policy load failure stops login attempts -- restart the timer.
StartPublicSessionAutoLoginTimer();
} }
void ExistingUserController::OnOnlineChecked(const std::string& username, void ExistingUserController::OnOnlineChecked(const std::string& username,
...@@ -1024,11 +936,6 @@ void ExistingUserController::DeviceSettingsChanged() { ...@@ -1024,11 +936,6 @@ void ExistingUserController::DeviceSettingsChanged() {
} }
} }
void ExistingUserController::ActivateWizard(const std::string& screen_name) {
scoped_ptr<base::DictionaryValue> params;
host_->StartWizard(screen_name, params.Pass());
}
LoginPerformer::AuthorizationMode ExistingUserController::auth_mode() const { LoginPerformer::AuthorizationMode ExistingUserController::auth_mode() const {
if (login_performer_) if (login_performer_)
return login_performer_->auth_mode(); return login_performer_->auth_mode();
...@@ -1123,56 +1030,6 @@ gfx::NativeWindow ExistingUserController::GetNativeWindow() const { ...@@ -1123,56 +1030,6 @@ gfx::NativeWindow ExistingUserController::GetNativeWindow() const {
return host_->GetNativeWindow(); return host_->GetNativeWindow();
} }
void ExistingUserController::InitializeStartUrls() const {
std::vector<std::string> start_urls;
const base::ListValue *urls;
user_manager::UserManager* user_manager = user_manager::UserManager::Get();
bool can_show_getstarted_guide =
user_manager->GetActiveUser()->GetType() ==
user_manager::USER_TYPE_REGULAR &&
!user_manager->IsCurrentUserNonCryptohomeDataEphemeral();
if (user_manager->IsLoggedInAsDemoUser()) {
if (CrosSettings::Get()->GetList(kStartUpUrls, &urls)) {
// The retail mode user will get start URLs from a special policy if it is
// set.
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;
// Skip the default first-run behavior for public accounts.
} 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 =
base::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;
}
}
// Only show getting started guide for a new user.
const bool should_show_getstarted_guide = user_manager->IsCurrentUserNew();
if (can_show_getstarted_guide && should_show_getstarted_guide) {
// Don't open default Chrome window if we're going to launch the first-run
// app. Because we dont' want the first-run app to be hidden in the
// background.
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, void ExistingUserController::ShowError(int error_id,
const std::string& details) { const std::string& details) {
// TODO(dpolukhin): show detailed error info. |details| string contains // TODO(dpolukhin): show detailed error info. |details| string contains
...@@ -1256,10 +1113,46 @@ void ExistingUserController::LoginAsPublicSessionInternal( ...@@ -1256,10 +1113,46 @@ void ExistingUserController::LoginAsPublicSessionInternal(
// Only one instance of LoginPerformer should exist at a time. // Only one instance of LoginPerformer should exist at a time.
login_performer_.reset(NULL); login_performer_.reset(NULL);
login_performer_.reset(new ChromeLoginPerformer(this)); login_performer_.reset(new ChromeLoginPerformer(this));
is_login_in_progress_ = true;
login_performer_->LoginAsPublicSession(user_context); login_performer_->LoginAsPublicSession(user_context);
SendAccessibilityAlert( SendAccessibilityAlert(
l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_PUBLIC_ACCOUNT)); l10n_util::GetStringUTF8(IDS_CHROMEOS_ACC_LOGIN_SIGNIN_PUBLIC_ACCOUNT));
} }
void ExistingUserController::PerformPreLoginActions(
const UserContext& user_context) {
// Disable clicking on other windows and status tray.
login_display_->SetUIEnabled(false);
if (last_login_attempt_username_ != user_context.GetUserID()) {
last_login_attempt_username_ = user_context.GetUserID();
num_login_attempts_ = 0;
// Also reset state variables, which are used to determine password change.
offline_failed_ = false;
online_succeeded_for_.clear();
}
// Guard in cases when we're called twice but login process is still active.
// This might happen when login process is paused till signed settings status
// is verified which results in Login* method called again as a callback.
if (!is_login_in_progress_)
num_login_attempts_++;
is_login_in_progress_ = true;
// Stop the auto-login timer when attempting login.
StopPublicSessionAutoLoginTimer();
}
void ExistingUserController::PerformLoginFinishedActions(
bool start_public_session_timer) {
is_login_in_progress_ = false;
// Reenable clicking on other windows and status area.
login_display_->SetUIEnabled(true);
if (start_public_session_timer)
StartPublicSessionAutoLoginTimer();
}
} // namespace chromeos } // namespace chromeos
...@@ -156,20 +156,15 @@ class ExistingUserController : public LoginDisplay::Delegate, ...@@ -156,20 +156,15 @@ class ExistingUserController : public LoginDisplay::Delegate,
const std::string& username, bool success) override; const std::string& username, bool success) override;
// LoginUtils::Delegate implementation: // LoginUtils::Delegate implementation:
virtual void OnProfilePrepared(Profile* profile) override; virtual void OnProfilePrepared(Profile* profile,
bool browser_launched) override;
// Called when device settings change. // Called when device settings change.
void DeviceSettingsChanged(); void DeviceSettingsChanged();
// Starts WizardController with the specified screen.
void ActivateWizard(const std::string& screen_name);
// Returns corresponding native window. // Returns corresponding native window.
gfx::NativeWindow GetNativeWindow() const; gfx::NativeWindow GetNativeWindow() const;
// Adds first-time login URLs.
void InitializeStartUrls() const;
// Show error message. |error_id| error message ID in resources. // Show error message. |error_id| error message ID in resources.
// If |details| string is not empty, it specify additional error text // If |details| string is not empty, it specify additional error text
// provided by authenticator, it is not localized. // provided by authenticator, it is not localized.
...@@ -235,6 +230,14 @@ class ExistingUserController : public LoginDisplay::Delegate, ...@@ -235,6 +230,14 @@ class ExistingUserController : public LoginDisplay::Delegate,
// preconditions have been verified. // preconditions have been verified.
void LoginAsPublicSessionInternal(const UserContext& user_context); void LoginAsPublicSessionInternal(const UserContext& user_context);
// Performs sets of actions right prior to login has been started.
void PerformPreLoginActions(const UserContext& user_context);
// Performs set of actions when login has been completed or has been
// cancelled. If |start_public_session_timer| is true than public session
// auto-login timer is started.
void PerformLoginFinishedActions(bool start_public_session_timer);
// Public session auto-login timer. // Public session auto-login timer.
scoped_ptr<base::OneShotTimer<ExistingUserController> > auto_login_timer_; scoped_ptr<base::OneShotTimer<ExistingUserController> > auto_login_timer_;
......
...@@ -163,6 +163,9 @@ class ExistingUserControllerTest : public policy::DevicePolicyCrosBrowserTest { ...@@ -163,6 +163,9 @@ class ExistingUserControllerTest : public policy::DevicePolicyCrosBrowserTest {
.WillRepeatedly(Return(false)); .WillRepeatedly(Return(false));
EXPECT_CALL(*mock_user_manager_, Shutdown()) EXPECT_CALL(*mock_user_manager_, Shutdown())
.Times(1); .Times(1);
EXPECT_CALL(*mock_user_manager_, FindUser(_))
.Times(AnyNumber())
.WillRepeatedly(ReturnNull());
} }
virtual void SetUpOnMainThread() override { virtual void SetUpOnMainThread() override {
...@@ -175,7 +178,8 @@ class ExistingUserControllerTest : public policy::DevicePolicyCrosBrowserTest { ...@@ -175,7 +178,8 @@ class ExistingUserControllerTest : public policy::DevicePolicyCrosBrowserTest {
profile_prepared_cb_ = profile_prepared_cb_ =
base::Bind(&ExistingUserController::OnProfilePrepared, base::Bind(&ExistingUserController::OnProfilePrepared,
base::Unretained(existing_user_controller()), base::Unretained(existing_user_controller()),
testing_profile_.get()); testing_profile_.get(),
false);
} }
virtual void TearDownOnMainThread() override { virtual void TearDownOnMainThread() override {
...@@ -232,10 +236,8 @@ class ExistingUserControllerTest : public policy::DevicePolicyCrosBrowserTest { ...@@ -232,10 +236,8 @@ class ExistingUserControllerTest : public policy::DevicePolicyCrosBrowserTest {
}; };
IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ExistingUserLogin) { IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ExistingUserLogin) {
// This is disabled twice: once right after signin but before checking for
// auto-enrollment, and again after doing an ownership status check.
EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)) EXPECT_CALL(*mock_login_display_, SetUIEnabled(false))
.Times(2); .Times(1);
UserContext user_context(kUsername); UserContext user_context(kUsername);
user_context.SetKey(Key(kPassword)); user_context.SetKey(Key(kPassword));
user_context.SetUserIDHash(kUsername); user_context.SetUserIDHash(kUsername);
...@@ -246,10 +248,6 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ExistingUserLogin) { ...@@ -246,10 +248,6 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ExistingUserLogin) {
.Times(1) .Times(1)
.WillOnce(InvokeWithoutArgs(&profile_prepared_cb_, .WillOnce(InvokeWithoutArgs(&profile_prepared_cb_,
&base::Callback<void(void)>::Run)); &base::Callback<void(void)>::Run));
EXPECT_CALL(*mock_login_utils_,
DoBrowserLaunch(testing_profile_.get(),
mock_login_display_host_.get()))
.Times(1);
EXPECT_CALL(*mock_login_display_, SetUIEnabled(true)) EXPECT_CALL(*mock_login_display_, SetUIEnabled(true))
.Times(1); .Times(1);
EXPECT_CALL(*mock_login_display_host_, EXPECT_CALL(*mock_login_display_host_,
...@@ -294,10 +292,6 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ...@@ -294,10 +292,6 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest,
StartWizardPtr(WizardController::kEnrollmentScreenName, StartWizardPtr(WizardController::kEnrollmentScreenName,
_)) _))
.Times(0); .Times(0);
EXPECT_CALL(*mock_login_display_host_,
StartWizardPtr(WizardController::kTermsOfServiceScreenName,
NULL))
.Times(1);
UserContext user_context(kNewUsername); UserContext user_context(kNewUsername);
user_context.SetKey(Key(kPassword)); user_context.SetKey(Key(kPassword));
user_context.SetUserIDHash(kNewUsername); user_context.SetUserIDHash(kNewUsername);
...@@ -327,7 +321,7 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest, ...@@ -327,7 +321,7 @@ IN_PROC_BROWSER_TEST_F(ExistingUserControllerTest,
// This is disabled twice: once right after signin but before checking for // This is disabled twice: once right after signin but before checking for
// auto-enrollment, and again after doing an ownership status check. // auto-enrollment, and again after doing an ownership status check.
EXPECT_CALL(*mock_login_display_, SetUIEnabled(false)) EXPECT_CALL(*mock_login_display_, SetUIEnabled(false))
.Times(2) .Times(1)
.InSequence(uiEnabledSequence); .InSequence(uiEnabledSequence);
EXPECT_CALL(*mock_login_display_, SetUIEnabled(true)) EXPECT_CALL(*mock_login_display_, SetUIEnabled(true))
.Times(1) .Times(1)
...@@ -437,10 +431,6 @@ class ExistingUserControllerPublicSessionTest ...@@ -437,10 +431,6 @@ class ExistingUserControllerPublicSessionTest
.Times(1) .Times(1)
.WillOnce(InvokeWithoutArgs(&profile_prepared_cb_, .WillOnce(InvokeWithoutArgs(&profile_prepared_cb_,
&base::Callback<void(void)>::Run)); &base::Callback<void(void)>::Run));
EXPECT_CALL(*mock_login_utils_,
DoBrowserLaunch(testing_profile_.get(),
mock_login_display_host_.get()))
.Times(1);
EXPECT_CALL(*mock_login_display_, SetUIEnabled(true)) EXPECT_CALL(*mock_login_display_, SetUIEnabled(true))
.Times(1); .Times(1);
EXPECT_CALL(*mock_login_display_host_, EXPECT_CALL(*mock_login_display_host_,
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h"
#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
#include "chrome/browser/chromeos/login/user_flow.h" #include "chrome/browser/chromeos/login/user_flow.h"
#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
...@@ -60,11 +61,11 @@ void FakeLoginUtils::PrepareProfile(const UserContext& user_context, ...@@ -60,11 +61,11 @@ void FakeLoginUtils::PrepareProfile(const UserContext& user_context,
bool has_cookies, bool has_cookies,
bool has_active_session, bool has_active_session,
LoginUtils::Delegate* delegate) { LoginUtils::Delegate* delegate) {
user_manager::UserManager::Get()->UserLoggedIn( user_manager::UserManager* user_manager = user_manager::UserManager::Get();
user_manager->UserLoggedIn(
user_context.GetUserID(), user_context.GetUserIDHash(), false); user_context.GetUserID(), user_context.GetUserIDHash(), false);
user_manager::User* user = user_manager::User* user =
user_manager::UserManager::Get()->FindUserAndModify( user_manager->FindUserAndModify(user_context.GetUserID());
user_context.GetUserID());
DCHECK(user); DCHECK(user);
// Make sure that we get the real Profile instead of the login Profile. // Make sure that we get the real Profile instead of the login Profile.
...@@ -73,9 +74,8 @@ void FakeLoginUtils::PrepareProfile(const UserContext& user_context, ...@@ -73,9 +74,8 @@ void FakeLoginUtils::PrepareProfile(const UserContext& user_context,
profile->GetPrefs()->SetString(prefs::kGoogleServicesUsername, profile->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
user_context.GetUserID()); user_context.GetUserID());
if (user_manager::UserManager::Get()->IsLoggedInAsSupervisedUser()) { if (user_manager->IsLoggedInAsSupervisedUser()) {
user_manager::User* active_user = user_manager::User* active_user = user_manager->GetActiveUser();
user_manager::UserManager::Get()->GetActiveUser();
std::string supervised_user_sync_id = std::string supervised_user_sync_id =
ChromeUserManager::Get()->GetSupervisedUserManager()->GetUserSyncId( ChromeUserManager::Get()->GetSupervisedUserManager()->GetUserSyncId(
active_user->email()); active_user->email());
...@@ -89,8 +89,22 @@ void FakeLoginUtils::PrepareProfile(const UserContext& user_context, ...@@ -89,8 +89,22 @@ void FakeLoginUtils::PrepareProfile(const UserContext& user_context,
chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED, chrome::NOTIFICATION_LOGIN_USER_PROFILE_PREPARED,
content::NotificationService::AllSources(), content::NotificationService::AllSources(),
content::Details<Profile>(profile)); content::Details<Profile>(profile));
// Emulate UserSessionManager::InitializeUserSession() for now till
// FakeLoginUtils are deprecated.
bool browser_launched = false;
if (!user_manager->IsLoggedInAsKioskApp()) {
if (user_manager->IsCurrentUserNew()) {
NOTREACHED() << "Method not implemented.";
} else {
browser_launched = true;
LoginUtils::Get()->DoBrowserLaunch(profile,
LoginDisplayHostImpl::default_host());
}
}
if (delegate) if (delegate)
delegate->OnProfilePrepared(profile); delegate->OnProfilePrepared(profile, browser_launched);
} }
void FakeLoginUtils::DelegateDeleted(LoginUtils::Delegate* delegate) { void FakeLoginUtils::DelegateDeleted(LoginUtils::Delegate* delegate) {
......
...@@ -126,6 +126,6 @@ void LoginManagerTest::InitializeWebContents() { ...@@ -126,6 +126,6 @@ void LoginManagerTest::InitializeWebContents() {
EXPECT_TRUE(web_contents != NULL); EXPECT_TRUE(web_contents != NULL);
set_web_contents(web_contents); set_web_contents(web_contents);
js_checker_.set_web_contents(web_contents); js_checker_.set_web_contents(web_contents);
} }
} // namespace chromeos } // namespace chromeos
...@@ -48,6 +48,7 @@ ...@@ -48,6 +48,7 @@
#include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h" #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
#include "chrome/browser/chromeos/login/ui/input_events_blocker.h" #include "chrome/browser/chromeos/login/ui/input_events_blocker.h"
#include "chrome/browser/chromeos/login/ui/login_display_host.h" #include "chrome/browser/chromeos/login/ui/login_display_host.h"
#include "chrome/browser/chromeos/login/ui/user_adding_screen.h"
#include "chrome/browser/chromeos/login/user_flow.h" #include "chrome/browser/chromeos/login/user_flow.h"
#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
...@@ -200,7 +201,8 @@ class LoginUtilsImpl : public LoginUtils, ...@@ -200,7 +201,8 @@ class LoginUtilsImpl : public LoginUtils,
bool early_restart) override; bool early_restart) override;
// UserSessionManager::Delegate implementation: // UserSessionManager::Delegate implementation:
virtual void OnProfilePrepared(Profile* profile) override; virtual void OnProfilePrepared(Profile* profile,
bool browser_launched) override;
#if defined(ENABLE_RLZ) #if defined(ENABLE_RLZ)
virtual void OnRlzInitialized() override; virtual void OnRlzInitialized() override;
#endif #endif
...@@ -371,12 +373,21 @@ void LoginUtilsImpl::PrepareProfile( ...@@ -371,12 +373,21 @@ void LoginUtilsImpl::PrepareProfile(
// as it coexist with SessionManager. // as it coexist with SessionManager.
delegate_ = delegate; delegate_ = delegate;
UserSessionManager::StartSessionType start_session_type =
UserAddingScreen::Get()->IsRunning() ?
UserSessionManager::SECONDARY_USER_SESSION :
UserSessionManager::PRIMARY_USER_SESSION;
// For the transition part LoginUtils will just delegate profile // For the transition part LoginUtils will just delegate profile
// creation and initialization to SessionManager. Later LoginUtils will be // creation and initialization to SessionManager. Later LoginUtils will be
// removed and all LoginUtils clients will just work with SessionManager // removed and all LoginUtils clients will just work with SessionManager
// directly. // directly.
UserSessionManager::GetInstance()->StartSession( UserSessionManager::GetInstance()->StartSession(user_context,
user_context, authenticator_, has_auth_cookies, has_active_session, this); start_session_type,
authenticator_,
has_auth_cookies,
has_active_session,
this);
} }
void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) { void LoginUtilsImpl::DelegateDeleted(LoginUtils::Delegate* delegate) {
...@@ -429,9 +440,10 @@ scoped_refptr<Authenticator> LoginUtilsImpl::CreateAuthenticator( ...@@ -429,9 +440,10 @@ scoped_refptr<Authenticator> LoginUtilsImpl::CreateAuthenticator(
return authenticator_; return authenticator_;
} }
void LoginUtilsImpl::OnProfilePrepared(Profile* profile) { void LoginUtilsImpl::OnProfilePrepared(Profile* profile,
bool browser_launched) {
if (delegate_) if (delegate_)
delegate_->OnProfilePrepared(profile); delegate_->OnProfilePrepared(profile, browser_launched);
} }
#if defined(ENABLE_RLZ) #if defined(ENABLE_RLZ)
......
...@@ -29,7 +29,10 @@ class LoginUtils { ...@@ -29,7 +29,10 @@ class LoginUtils {
class Delegate { class Delegate {
public: public:
// Called after profile is loaded and prepared for the session. // Called after profile is loaded and prepared for the session.
virtual void OnProfilePrepared(Profile* profile) = 0; // |browser_launched| will be true is browser has been launched, otherwise
// it will return false and client is responsible on launching browser.
virtual void OnProfilePrepared(Profile* profile,
bool browser_launched) = 0;
#if defined(ENABLE_RLZ) #if defined(ENABLE_RLZ)
// Called after post-profile RLZ initialization. // Called after post-profile RLZ initialization.
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/prefs/pref_registry_simple.h" #include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h" #include "base/prefs/pref_service.h"
#include "base/strings/string16.h" #include "base/strings/string16.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h" #include "base/sys_info.h"
#include "base/task_runner_util.h" #include "base/task_runner_util.h"
#include "base/threading/worker_pool.h" #include "base/threading/worker_pool.h"
...@@ -23,8 +24,10 @@ ...@@ -23,8 +24,10 @@
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/browser_process_platform_part_chromeos.h" #include "chrome/browser/browser_process_platform_part_chromeos.h"
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/accessibility/accessibility_manager.h"
#include "chrome/browser/chromeos/base/locale_util.h" #include "chrome/browser/chromeos/base/locale_util.h"
#include "chrome/browser/chromeos/boot_times_loader.h" #include "chrome/browser/chromeos/boot_times_loader.h"
#include "chrome/browser/chromeos/first_run/first_run.h"
#include "chrome/browser/chromeos/input_method/input_method_util.h" #include "chrome/browser/chromeos/input_method/input_method_util.h"
#include "chrome/browser/chromeos/login/chrome_restart_request.h" #include "chrome/browser/chromeos/login/chrome_restart_request.h"
#include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h" #include "chrome/browser/chromeos/login/demo_mode/demo_app_launcher.h"
...@@ -35,8 +38,12 @@ ...@@ -35,8 +38,12 @@
#include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h" #include "chrome/browser/chromeos/login/signin/oauth2_login_manager.h"
#include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h" #include "chrome/browser/chromeos/login/signin/oauth2_login_manager_factory.h"
#include "chrome/browser/chromeos/login/startup_utils.h" #include "chrome/browser/chromeos/login/startup_utils.h"
#include "chrome/browser/chromeos/login/ui/login_display_host.h"
#include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
#include "chrome/browser/chromeos/login/user_flow.h"
#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" #include "chrome/browser/chromeos/login/users/supervised_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/browser_policy_connector_chromeos.h"
#include "chrome/browser/chromeos/profiles/profile_helper.h" #include "chrome/browser/chromeos/profiles/profile_helper.h"
#include "chrome/browser/chromeos/settings/cros_settings.h" #include "chrome/browser/chromeos/settings/cros_settings.h"
...@@ -45,6 +52,7 @@ ...@@ -45,6 +52,7 @@
#include "chrome/browser/lifetime/application_lifetime.h" #include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/net/crl_set_fetcher.h" #include "chrome/browser/net/crl_set_fetcher.h"
#include "chrome/browser/net/nss_context.h" #include "chrome/browser/net/nss_context.h"
#include "chrome/browser/prefs/session_startup_pref.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/rlz/rlz.h" #include "chrome/browser/rlz/rlz.h"
...@@ -79,6 +87,11 @@ namespace chromeos { ...@@ -79,6 +87,11 @@ namespace chromeos {
namespace { namespace {
// ChromeVox tutorial URL (used in place of "getting started" url when
// accessibility is enabled).
const char kChromeVoxTutorialURLPattern[] =
"http://www.chromevox.com/tutorial/index.html?lang=%s";
void InitLocaleAndInputMethodsForNewUser( void InitLocaleAndInputMethodsForNewUser(
UserSessionManager* session_manager, UserSessionManager* session_manager,
Profile* profile, Profile* profile,
...@@ -278,12 +291,14 @@ void UserSessionManager::CompleteGuestSessionLogin(const GURL& start_url) { ...@@ -278,12 +291,14 @@ void UserSessionManager::CompleteGuestSessionLogin(const GURL& start_url) {
void UserSessionManager::StartSession( void UserSessionManager::StartSession(
const UserContext& user_context, const UserContext& user_context,
StartSessionType start_session_type,
scoped_refptr<Authenticator> authenticator, scoped_refptr<Authenticator> authenticator,
bool has_auth_cookies, bool has_auth_cookies,
bool has_active_session, bool has_active_session,
UserSessionManagerDelegate* delegate) { UserSessionManagerDelegate* delegate) {
authenticator_ = authenticator; authenticator_ = authenticator;
delegate_ = delegate; delegate_ = delegate;
start_session_type_ = start_session_type;
VLOG(1) << "Starting session for " << user_context.GetUserID(); VLOG(1) << "Starting session for " << user_context.GetUserID();
...@@ -615,9 +630,8 @@ void UserSessionManager::OnConnectionTypeChanged( ...@@ -615,9 +630,8 @@ void UserSessionManager::OnConnectionTypeChanged(
} }
} }
void UserSessionManager::OnProfilePrepared(Profile* profile) { void UserSessionManager::OnProfilePrepared(Profile* profile,
LoginUtils::Get()->DoBrowserLaunch(profile, NULL); // host_, not needed here bool browser_launched) {
if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) { if (!CommandLine::ForCurrentProcess()->HasSwitch(::switches::kTestName)) {
// Did not log in (we crashed or are debugging), need to restore Sync. // Did not log in (we crashed or are debugging), need to restore Sync.
// TODO(nkostylev): Make sure that OAuth state is restored correctly for all // TODO(nkostylev): Make sure that OAuth state is restored correctly for all
...@@ -743,8 +757,10 @@ void UserSessionManager::InitProfilePreferences( ...@@ -743,8 +757,10 @@ void UserSessionManager::InitProfilePreferences(
void UserSessionManager::UserProfileInitialized(Profile* profile, void UserSessionManager::UserProfileInitialized(Profile* profile,
bool is_incognito_profile, bool is_incognito_profile,
const std::string& user_id) { const std::string& user_id) {
// Demo user signed in.
if (is_incognito_profile) { if (is_incognito_profile) {
profile->OnLogin(); profile->OnLogin();
// Send the notification before creating the browser so additional objects // Send the notification before creating the browser so additional objects
// that need the profile (e.g. the launcher) can be created first. // that need the profile (e.g. the launcher) can be created first.
content::NotificationService::current()->Notify( content::NotificationService::current()->Notify(
...@@ -753,7 +769,7 @@ void UserSessionManager::UserProfileInitialized(Profile* profile, ...@@ -753,7 +769,7 @@ void UserSessionManager::UserProfileInitialized(Profile* profile,
content::Details<Profile>(profile)); content::Details<Profile>(profile));
if (delegate_) if (delegate_)
delegate_->OnProfilePrepared(profile); delegate_->OnProfilePrepared(profile, false);
return; return;
} }
...@@ -852,6 +868,10 @@ void UserSessionManager::FinalizePrepareProfile(Profile* profile) { ...@@ -852,6 +868,10 @@ void UserSessionManager::FinalizePrepareProfile(Profile* profile) {
UpdateEasyUnlockKeys(user_context_); UpdateEasyUnlockKeys(user_context_);
user_context_.ClearSecrets(); user_context_.ClearSecrets();
// Now that profile is ready, proceed to either alternative login flows or
// launch browser.
bool browser_launched = InitializeUserSession(profile);
// TODO(nkostylev): This pointer should probably never be NULL, but it looks // TODO(nkostylev): This pointer should probably never be NULL, but it looks
// like LoginUtilsImpl::OnProfileCreated() may be getting called before // like LoginUtilsImpl::OnProfileCreated() may be getting called before
// UserSessionManager::PrepareProfile() has set |delegate_| when Chrome is // UserSessionManager::PrepareProfile() has set |delegate_| when Chrome is
...@@ -859,7 +879,103 @@ void UserSessionManager::FinalizePrepareProfile(Profile* profile) { ...@@ -859,7 +879,103 @@ void UserSessionManager::FinalizePrepareProfile(Profile* profile) {
// this 'if' statement with a CHECK(delegate_) once the underlying issue is // this 'if' statement with a CHECK(delegate_) once the underlying issue is
// resolved. // resolved.
if (delegate_) if (delegate_)
delegate_->OnProfilePrepared(profile); delegate_->OnProfilePrepared(profile, browser_launched);
}
void UserSessionManager::ActivateWizard(const std::string& screen_name) {
LoginDisplayHost* host = LoginDisplayHostImpl::default_host();
DCHECK(host);
if (host) {
scoped_ptr<base::DictionaryValue> params;
host->StartWizard(screen_name, params.Pass());
}
}
void UserSessionManager::InitializeStartUrls() const {
std::vector<std::string> start_urls;
const base::ListValue *urls;
user_manager::UserManager* user_manager = user_manager::UserManager::Get();
bool can_show_getstarted_guide =
user_manager->GetActiveUser()->GetType() ==
user_manager::USER_TYPE_REGULAR &&
!user_manager->IsCurrentUserNonCryptohomeDataEphemeral();
if (user_manager->IsLoggedInAsDemoUser()) {
if (CrosSettings::Get()->GetList(kStartUpUrls, &urls)) {
// The retail mode user will get start URLs from a special policy if it is
// set.
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;
// Skip the default first-run behavior for public accounts.
} 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 =
base::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;
}
}
// Only show getting started guide for a new user.
const bool should_show_getstarted_guide = user_manager->IsCurrentUserNew();
if (can_show_getstarted_guide && should_show_getstarted_guide) {
// Don't open default Chrome window if we're going to launch the first-run
// app. Because we dont' want the first-run app to be hidden in the
// background.
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]);
}
}
}
bool UserSessionManager::InitializeUserSession(Profile* profile) {
user_manager::UserManager* user_manager = user_manager::UserManager::Get();
// Kiosk apps has their own session initialization pipeline.
if (user_manager->IsLoggedInAsKioskApp())
return false;
if (start_session_type_ == PRIMARY_USER_SESSION) {
UserFlow* user_flow = ChromeUserManager::Get()->GetCurrentUserFlow();
WizardController* oobe_controller = WizardController::default_controller();
base::CommandLine* cmdline = CommandLine::ForCurrentProcess();
bool skip_post_login_screens =
user_flow->ShouldSkipPostLoginScreens() ||
(oobe_controller && oobe_controller->skip_post_login_screens()) ||
cmdline->HasSwitch(chromeos::switches::kOobeSkipPostLogin);
if (user_manager->IsCurrentUserNew() && !skip_post_login_screens) {
// Don't specify start URLs if the administrator has configured the start
// URLs via policy.
if (!SessionStartupPref::TypeIsManaged(profile->GetPrefs()))
InitializeStartUrls();
// Mark the device as registered., i.e. the second part of OOBE as
// completed.
if (!StartupUtils::IsDeviceRegistered())
StartupUtils::MarkDeviceRegistered(base::Closure());
ActivateWizard(WizardController::kTermsOfServiceScreenName);
return false;
}
}
LoginUtils::Get()->DoBrowserLaunch(profile,
LoginDisplayHostImpl::default_host());
return true;
} }
void UserSessionManager::InitSessionRestoreStrategy() { void UserSessionManager::InitSessionRestoreStrategy() {
...@@ -944,7 +1060,7 @@ void UserSessionManager::InitRlzImpl(Profile* profile, bool disabled) { ...@@ -944,7 +1060,7 @@ void UserSessionManager::InitRlzImpl(Profile* profile, bool disabled) {
} }
// Init the RLZ library. // Init the RLZ library.
int ping_delay = profile->GetPrefs()->GetInteger( int ping_delay = profile->GetPrefs()->GetInteger(
first_run::GetPingDelayPrefName().c_str()); ::first_run::GetPingDelayPrefName().c_str());
// Negative ping delay means to send ping immediately after a first search is // Negative ping delay means to send ping immediately after a first search is
// recorded. // recorded.
RLZTracker::InitRlzFromProfileDelayed( RLZTracker::InitRlzFromProfileDelayed(
...@@ -1043,10 +1159,13 @@ void UserSessionManager::RestorePendingUserSessions() { ...@@ -1043,10 +1159,13 @@ void UserSessionManager::RestorePendingUserSessions() {
user_context.SetIsUsingOAuth(false); user_context.SetIsUsingOAuth(false);
// Will call OnProfilePrepared() once profile has been loaded. // Will call OnProfilePrepared() once profile has been loaded.
// Only handling secondary users here since primary user profile
// (and session) has been loaded on Chrome startup.
StartSession(user_context, StartSession(user_context,
SECONDARY_USER_SESSION_AFTER_CRASH,
NULL, // authenticator NULL, // authenticator
false, // has_auth_cookies false, // has_auth_cookies
true, // has_active_session true, // has_active_session, this is restart after crash
this); this);
} else { } else {
RestorePendingUserSessions(); RestorePendingUserSessions();
......
...@@ -41,7 +41,10 @@ class EasyUnlockKeyManager; ...@@ -41,7 +41,10 @@ class EasyUnlockKeyManager;
class UserSessionManagerDelegate { class UserSessionManagerDelegate {
public: public:
// Called after profile is loaded and prepared for the session. // Called after profile is loaded and prepared for the session.
virtual void OnProfilePrepared(Profile* profile) = 0; // |browser_launched| will be true is browser has been launched, otherwise
// it will return false and client is responsible on launching browser.
virtual void OnProfilePrepared(Profile* profile,
bool browser_launched) = 0;
#if defined(ENABLE_RLZ) #if defined(ENABLE_RLZ)
// Called after post-profile RLZ initialization. // Called after post-profile RLZ initialization.
...@@ -61,10 +64,10 @@ class UserSessionStateObserver { ...@@ -61,10 +64,10 @@ class UserSessionStateObserver {
}; };
// UserSessionManager is responsible for starting user session which includes: // UserSessionManager is responsible for starting user session which includes:
// load and initialize Profile (including custom Profile preferences), // * load and initialize Profile (including custom Profile preferences),
// mark user as logged in and notify observers, // * mark user as logged in and notify observers,
// initialize OAuth2 authentication session, // * initialize OAuth2 authentication session,
// initialize and launch user session based on the user type. // * initialize and launch user session based on the user type.
// Also supports restoring active user sessions after browser crash: // Also supports restoring active user sessions after browser crash:
// load profile, restore OAuth authentication session etc. // load profile, restore OAuth authentication session etc.
class UserSessionManager class UserSessionManager
...@@ -74,6 +77,21 @@ class UserSessionManager ...@@ -74,6 +77,21 @@ class UserSessionManager
public UserSessionManagerDelegate, public UserSessionManagerDelegate,
public user_manager::UserManager::UserSessionStateObserver { public user_manager::UserManager::UserSessionStateObserver {
public: public:
// Context of StartSession calls.
typedef enum {
// Starting primary user session, through login UI.
PRIMARY_USER_SESSION,
// Starting secondary user session, through multi-profiles login UI.
SECONDARY_USER_SESSION,
// Starting primary user session after browser crash.
PRIMARY_USER_SESSION_AFTER_CRASH,
// Starting secondary user session after browser crash.
SECONDARY_USER_SESSION_AFTER_CRASH,
} StartSessionType;
// Returns UserSessionManager instance. // Returns UserSessionManager instance.
static UserSessionManager* GetInstance(); static UserSessionManager* GetInstance();
...@@ -91,6 +109,7 @@ class UserSessionManager ...@@ -91,6 +109,7 @@ class UserSessionManager
// Start user session given |user_context| and |authenticator| which holds // Start user session given |user_context| and |authenticator| which holds
// authentication context (profile). // authentication context (profile).
void StartSession(const UserContext& user_context, void StartSession(const UserContext& user_context,
StartSessionType start_session_type,
scoped_refptr<Authenticator> authenticator, scoped_refptr<Authenticator> authenticator,
bool has_auth_cookies, bool has_auth_cookies,
bool has_active_session, bool has_active_session,
...@@ -198,7 +217,8 @@ class UserSessionManager ...@@ -198,7 +217,8 @@ class UserSessionManager
// UserSessionManagerDelegate overrides: // UserSessionManagerDelegate overrides:
// Used when restoring user sessions after crash. // Used when restoring user sessions after crash.
virtual void OnProfilePrepared(Profile* profile) override; virtual void OnProfilePrepared(Profile* profile,
bool browser_launched) override;
void CreateUserSession(const UserContext& user_context, void CreateUserSession(const UserContext& user_context,
bool has_auth_cookies); bool has_auth_cookies);
...@@ -233,6 +253,18 @@ class UserSessionManager ...@@ -233,6 +253,18 @@ class UserSessionManager
// Finalized profile preparation. // Finalized profile preparation.
void FinalizePrepareProfile(Profile* profile); void FinalizePrepareProfile(Profile* profile);
// Starts out-of-box flow with the specified screen.
void ActivateWizard(const std::string& screen_name);
// Adds first-time login URLs.
void InitializeStartUrls() const;
// Perform session initialization and either move to additional login flows
// such as TOS (public sessions), priority pref sync UI (new users) or
// launch browser.
// Returns true if browser has been launched or false otherwise.
bool InitializeUserSession(Profile* profile);
// Initializes member variables needed for session restore process via // Initializes member variables needed for session restore process via
// OAuthLoginManager. // OAuthLoginManager.
void InitSessionRestoreStrategy(); void InitSessionRestoreStrategy();
...@@ -270,6 +302,7 @@ class UserSessionManager ...@@ -270,6 +302,7 @@ class UserSessionManager
// Authentication/user context. // Authentication/user context.
UserContext user_context_; UserContext user_context_;
scoped_refptr<Authenticator> authenticator_; scoped_refptr<Authenticator> authenticator_;
StartSessionType start_session_type_;
// True if the authentication context's cookie jar contains authentication // True if the authentication context's cookie jar contains authentication
// cookies from the authentication extension login flow. // cookies from the authentication extension login flow.
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h" #include "chrome/browser/chromeos/login/supervised/supervised_user_login_flow.h"
#include "base/base64.h" #include "base/base64.h"
#include "base/command_line.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/metrics/histogram.h" #include "base/metrics/histogram.h"
#include "base/prefs/pref_registry_simple.h" #include "base/prefs/pref_registry_simple.h"
...@@ -18,6 +19,7 @@ ...@@ -18,6 +19,7 @@
#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
#include "chrome/browser/chromeos/login/wizard_controller.h" #include "chrome/browser/chromeos/login/wizard_controller.h"
#include "chrome/common/chrome_switches.h"
#include "chromeos/login/auth/key.h" #include "chromeos/login/auth/key.h"
#include "components/user_manager/user_manager.h" #include "components/user_manager/user_manager.h"
#include "content/public/browser/browser_thread.h" #include "content/public/browser/browser_thread.h"
...@@ -35,6 +37,14 @@ SupervisedUserLoginFlow::SupervisedUserLoginFlow( ...@@ -35,6 +37,14 @@ SupervisedUserLoginFlow::SupervisedUserLoginFlow(
SupervisedUserLoginFlow::~SupervisedUserLoginFlow() {} SupervisedUserLoginFlow::~SupervisedUserLoginFlow() {}
void SupervisedUserLoginFlow::AppendAdditionalCommandLineSwitches() {
user_manager::UserManager* user_manager = user_manager::UserManager::Get();
if (user_manager->IsCurrentUserNew()) {
// Supervised users should launch into empty desktop on first run.
CommandLine::ForCurrentProcess()->AppendSwitch(::switches::kSilentLaunch);
}
}
bool SupervisedUserLoginFlow::CanLockScreen() { bool SupervisedUserLoginFlow::CanLockScreen() {
return true; return true;
} }
...@@ -59,10 +69,6 @@ bool SupervisedUserLoginFlow::HandlePasswordChangeDetected() { ...@@ -59,10 +69,6 @@ bool SupervisedUserLoginFlow::HandlePasswordChangeDetected() {
return false; return false;
} }
void SupervisedUserLoginFlow::HandleOAuthTokenStatusChange(
user_manager::User::OAuthTokenStatus status) {
}
void SupervisedUserLoginFlow::OnSyncSetupDataLoaded( void SupervisedUserLoginFlow::OnSyncSetupDataLoaded(
const std::string& token) { const std::string& token) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
......
...@@ -24,6 +24,7 @@ class SupervisedUserLoginFlow ...@@ -24,6 +24,7 @@ class SupervisedUserLoginFlow
virtual ~SupervisedUserLoginFlow(); virtual ~SupervisedUserLoginFlow();
// ExtendedUserFlow overrides. // ExtendedUserFlow overrides.
virtual void AppendAdditionalCommandLineSwitches() override;
virtual bool CanLockScreen() override; virtual bool CanLockScreen() override;
virtual bool ShouldLaunchBrowser() override; virtual bool ShouldLaunchBrowser() override;
virtual bool ShouldSkipPostLoginScreens() override; virtual bool ShouldSkipPostLoginScreens() override;
...@@ -31,8 +32,6 @@ class SupervisedUserLoginFlow ...@@ -31,8 +32,6 @@ class SupervisedUserLoginFlow
virtual bool HandleLoginFailure(const AuthFailure& failure) override; virtual bool HandleLoginFailure(const AuthFailure& failure) override;
virtual void HandleLoginSuccess(const UserContext& context) override; virtual void HandleLoginSuccess(const UserContext& context) override;
virtual bool HandlePasswordChangeDetected() override; virtual bool HandlePasswordChangeDetected() override;
virtual void HandleOAuthTokenStatusChange(
user_manager::User::OAuthTokenStatus status) override;
virtual void LaunchExtraSteps(Profile* profile) override; virtual void LaunchExtraSteps(Profile* profile) override;
// ExtendedAuthenticator::NewAuthStatusConsumer overrides. // ExtendedAuthenticator::NewAuthStatusConsumer overrides.
......
...@@ -24,8 +24,9 @@ void TestLoginUtils::PrepareProfile( ...@@ -24,8 +24,9 @@ void TestLoginUtils::PrepareProfile(
Delegate* delegate) { Delegate* delegate) {
if (user_context != expected_user_context_) if (user_context != expected_user_context_)
NOTREACHED(); NOTREACHED();
// Profile hasn't been loaded. // Profile hasn't been loaded.
delegate->OnProfilePrepared(NULL); delegate->OnProfilePrepared(NULL, false);
} }
void TestLoginUtils::DelegateDeleted(Delegate* delegate) { void TestLoginUtils::DelegateDeleted(Delegate* delegate) {
......
...@@ -24,6 +24,9 @@ UserFlow::~UserFlow() {} ...@@ -24,6 +24,9 @@ UserFlow::~UserFlow() {}
DefaultUserFlow::~DefaultUserFlow() {} DefaultUserFlow::~DefaultUserFlow() {}
void DefaultUserFlow::AppendAdditionalCommandLineSwitches() {
}
bool DefaultUserFlow::CanLockScreen() { bool DefaultUserFlow::CanLockScreen() {
return true; return true;
} }
...@@ -68,10 +71,17 @@ ExtendedUserFlow::ExtendedUserFlow(const std::string& user_id) ...@@ -68,10 +71,17 @@ ExtendedUserFlow::ExtendedUserFlow(const std::string& user_id)
ExtendedUserFlow::~ExtendedUserFlow() { ExtendedUserFlow::~ExtendedUserFlow() {
} }
void ExtendedUserFlow::AppendAdditionalCommandLineSwitches() {
}
bool ExtendedUserFlow::ShouldShowSettings() { bool ExtendedUserFlow::ShouldShowSettings() {
return true; return true;
} }
void ExtendedUserFlow::HandleOAuthTokenStatusChange(
user_manager::User::OAuthTokenStatus status) {
}
void ExtendedUserFlow::UnregisterFlowSoon() { void ExtendedUserFlow::UnregisterFlowSoon() {
std::string id_copy(user_id()); std::string id_copy(user_id());
base::MessageLoop::current()->PostTask(FROM_HERE, base::MessageLoop::current()->PostTask(FROM_HERE,
......
...@@ -21,6 +21,10 @@ class UserFlow { ...@@ -21,6 +21,10 @@ class UserFlow {
public: public:
UserFlow(); UserFlow();
virtual ~UserFlow() = 0; virtual ~UserFlow() = 0;
// Provides ability to alter command line before session has started.
virtual void AppendAdditionalCommandLineSwitches() = 0;
// Indicates if screen locking should be enabled or disabled for a flow. // Indicates if screen locking should be enabled or disabled for a flow.
virtual bool CanLockScreen() = 0; virtual bool CanLockScreen() = 0;
virtual bool ShouldShowSettings() = 0; virtual bool ShouldShowSettings() = 0;
...@@ -51,6 +55,7 @@ class DefaultUserFlow : public UserFlow { ...@@ -51,6 +55,7 @@ class DefaultUserFlow : public UserFlow {
public: public:
virtual ~DefaultUserFlow(); virtual ~DefaultUserFlow();
virtual void AppendAdditionalCommandLineSwitches() override;
virtual bool CanLockScreen() override; virtual bool CanLockScreen() override;
virtual bool ShouldShowSettings() override; virtual bool ShouldShowSettings() override;
virtual bool ShouldLaunchBrowser() override; virtual bool ShouldLaunchBrowser() override;
...@@ -70,7 +75,10 @@ class ExtendedUserFlow : public UserFlow { ...@@ -70,7 +75,10 @@ class ExtendedUserFlow : public UserFlow {
explicit ExtendedUserFlow(const std::string& user_id); explicit ExtendedUserFlow(const std::string& user_id);
virtual ~ExtendedUserFlow(); virtual ~ExtendedUserFlow();
virtual void AppendAdditionalCommandLineSwitches() override;
virtual bool ShouldShowSettings() override; virtual bool ShouldShowSettings() override;
virtual void HandleOAuthTokenStatusChange(
user_manager::User::OAuthTokenStatus status) override;
protected: protected:
// Subclasses can call this method to unregister flow in the next event. // Subclasses can call this method to unregister flow in the next event.
......
...@@ -25,8 +25,9 @@ std::string CanonicalizeEmailImpl(const std::string& email_address, ...@@ -25,8 +25,9 @@ std::string CanonicalizeEmailImpl(const std::string& email_address,
char at = '@'; char at = '@';
base::SplitString(email_address, at, &parts); base::SplitString(email_address, at, &parts);
if (parts.size() != 2U) { if (parts.size() != 2U) {
NOTREACHED() << "expecting exactly one @, but got " << parts.size()-1 << NOTREACHED() << "expecting exactly one @, but got "
" : " << email_address; << (parts.empty() ? 0 : parts.size() - 1)
<< " : " << email_address;
} else { } else {
if (change_googlemail_to_gmail && parts[1] == kGooglemailDomain) if (change_googlemail_to_gmail && parts[1] == kGooglemailDomain)
parts[1] = kGmailDomain; parts[1] = kGmailDomain;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment