summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/signin/signin_manager.cc16
-rw-r--r--chrome/browser/signin/signin_manager.h3
-rw-r--r--chrome/browser/sync/profile_sync_service.cc91
-rw-r--r--chrome/browser/sync/profile_sync_service.h27
-rw-r--r--chrome/browser/sync/profile_sync_service_mock.cc4
-rw-r--r--chrome/browser/sync/sync_setup_flow.cc160
-rw-r--r--chrome/browser/sync/sync_setup_flow.h20
-rw-r--r--chrome/browser/sync/sync_setup_flow_handler.h7
-rw-r--r--chrome/browser/sync/sync_setup_wizard.cc61
-rw-r--r--chrome/browser/sync/sync_setup_wizard.h24
-rw-r--r--chrome/browser/sync/sync_setup_wizard_unittest.cc335
-rw-r--r--chrome/browser/ui/webui/options/options_sync_setup_handler.cc18
-rw-r--r--chrome/browser/ui/webui/options/options_sync_setup_handler.h4
-rw-r--r--chrome/browser/ui/webui/signin/login_ui_service.cc60
-rw-r--r--chrome/browser/ui/webui/signin/login_ui_service.h59
-rw-r--r--chrome/browser/ui/webui/signin/login_ui_service_factory.cc36
-rw-r--r--chrome/browser/ui/webui/signin/login_ui_service_factory.h41
-rw-r--r--chrome/browser/ui/webui/signin/signin_tracker.cc98
-rw-r--r--chrome/browser/ui/webui/signin/signin_tracker.h110
-rw-r--r--chrome/browser/ui/webui/sync_promo/sync_promo_handler.cc20
-rw-r--r--chrome/browser/ui/webui/sync_promo/sync_promo_handler.h6
-rw-r--r--chrome/browser/ui/webui/sync_promo/sync_promo_handler2.cc7
-rw-r--r--chrome/browser/ui/webui/sync_promo/sync_promo_handler2.h2
-rw-r--r--chrome/browser/ui/webui/sync_setup_handler.cc256
-rw-r--r--chrome/browser/ui/webui/sync_setup_handler.h79
-rw-r--r--chrome/chrome_browser.gypi6
26 files changed, 745 insertions, 805 deletions
diff --git a/chrome/browser/signin/signin_manager.cc b/chrome/browser/signin/signin_manager.cc
index 47c0c85..a45318f 100644
--- a/chrome/browser/signin/signin_manager.cc
+++ b/chrome/browser/signin/signin_manager.cc
@@ -68,12 +68,8 @@ const std::string& SigninManager::GetAuthenticatedUsername() {
}
void SigninManager::SetAuthenticatedUsername(const std::string& username) {
- if (!authenticated_username_.empty()) {
- DLOG_IF(ERROR, username != authenticated_username_) <<
- "Tried to change the authenticated username to something different: " <<
- "Current: " << authenticated_username_ << ", New: " << username;
- return;
- }
+ DCHECK(authenticated_username_.empty() ||
+ username == authenticated_username_);
authenticated_username_ = username;
// TODO(tim): We could go further in ensuring kGoogleServicesUsername and
// authenticated_username_ are consistent once established (e.g. remove
@@ -196,10 +192,6 @@ const GoogleServiceAuthError& SigninManager::GetLoginAuthError() const {
return last_login_auth_error_;
}
-bool SigninManager::AuthInProgress() const {
- return !possibly_invalid_username_.empty();
-}
-
void SigninManager::OnClientLoginSuccess(const ClientLoginResult& result) {
DCHECK(!browser_sync::IsUsingOAuth());
last_result_ = result;
@@ -212,8 +204,10 @@ void SigninManager::OnGetUserInfoSuccess(const std::string& key,
const std::string& value) {
DCHECK(!browser_sync::IsUsingOAuth());
DCHECK(key == kGetInfoEmailKey);
+ DCHECK(authenticated_username_.empty() || authenticated_username_ == value);
+
last_login_auth_error_ = GoogleServiceAuthError::None();
- SetAuthenticatedUsername(value);
+ authenticated_username_ = value;
possibly_invalid_username_.clear();
profile_->GetPrefs()->SetString(prefs::kGoogleServicesUsername,
authenticated_username_);
diff --git a/chrome/browser/signin/signin_manager.h b/chrome/browser/signin/signin_manager.h
index 5f4e806..1f0fd67 100644
--- a/chrome/browser/signin/signin_manager.h
+++ b/chrome/browser/signin/signin_manager.h
@@ -97,9 +97,6 @@ class SigninManager : public GaiaAuthConsumer,
// there have been no login failures.
virtual const GoogleServiceAuthError& GetLoginAuthError() const;
- // Returns true if there's a signin in progress.
- bool AuthInProgress() const;
-
// GaiaAuthConsumer
virtual void OnClientLoginSuccess(const ClientLoginResult& result) OVERRIDE;
virtual void OnClientLoginFailure(
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index a62cb1d..f414098 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -48,8 +48,6 @@
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/global_error_service.h"
#include "chrome/browser/ui/global_error_service_factory.h"
-#include "chrome/browser/ui/webui/signin/login_ui_service.h"
-#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
#include "chrome/common/chrome_notification_types.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/chrome_version_info.h"
@@ -159,13 +157,6 @@ bool ProfileSyncService::AreCredentialsAvailable(
return false;
}
- // If we have start suppressed, then basically just act like we have no
- // credentials (login is required to fix this, since we need the user's
- // passphrase to encrypt/decrypt anyway).
- // TODO(sync): Revisit this when we move to a server-based keystore.
- if (sync_prefs_.IsStartSuppressed())
- return false;
-
// CrOS user is always logged in. Chrome uses signin_ to check logged in.
if (signin_->GetAuthenticatedUsername().empty())
return false;
@@ -722,8 +713,22 @@ void ProfileSyncService::OnDataTypesChanged(
void ProfileSyncService::UpdateAuthErrorState(
const GoogleServiceAuthError& error) {
- is_auth_in_progress_ = false;
last_auth_error_ = error;
+ // Protect against the in-your-face dialogs that pop out of nowhere.
+ // Require the user to click somewhere to run the setup wizard in the case
+ // of a steady-state auth failure.
+ if (WizardIsVisible()) {
+ wizard_.Step(last_auth_error_.state() == AuthError::NONE ?
+ SyncSetupWizard::GAIA_SUCCESS : SyncSetupWizard::GetLoginState());
+ } else {
+ auth_error_time_ = base::TimeTicks::Now();
+ }
+
+ if (!auth_start_time_.is_null()) {
+ UMA_HISTOGRAM_TIMES("Sync.AuthorizationTimeInNetwork",
+ base::TimeTicks::Now() - auth_start_time_);
+ auth_start_time_ = base::TimeTicks();
+ }
// Fan the notification out to interested UI-thread components.
NotifyObservers();
@@ -734,12 +739,8 @@ void ProfileSyncService::OnAuthError() {
}
void ProfileSyncService::OnStopSyncingPermanently() {
- UpdateAuthErrorState(
- GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
-
- // If the wizard is visible, close it.
- if (WizardIsVisible()) {
- wizard_.Step(SyncSetupWizard::ABORT);
+ if (SetupInProgress()) {
+ wizard_.Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR);
expect_sync_configuration_aborted_ = true;
}
sync_prefs_.SetStartSuppressed(true);
@@ -939,9 +940,23 @@ void ProfileSyncService::OnActionableError(const SyncProtocolError& error) {
}
void ProfileSyncService::ShowLoginDialog() {
- // TODO(atwilson): Remove this API and have the callers directly call
- // LoginUIService.
- LoginUIServiceFactory::GetForProfile(profile_)->ShowLoginUI();
+ if (WizardIsVisible()) {
+ wizard_.Focus();
+ // Force the wizard to step to the login screen (which will only actually
+ // happen if the transition is valid).
+ wizard_.Step(SyncSetupWizard::GetLoginState());
+ return;
+ }
+
+ if (!auth_error_time_.is_null()) {
+ UMA_HISTOGRAM_LONG_TIMES("Sync.ReauthorizationTime",
+ base::TimeTicks::Now() - auth_error_time_);
+ auth_error_time_ = base::TimeTicks(); // Reset auth_error_time_ to null.
+ }
+
+ ShowSyncSetupWithWizard(SyncSetupWizard::GetLoginState());
+
+ NotifyObservers();
}
void ProfileSyncService::ShowErrorUI() {
@@ -950,21 +965,12 @@ void ProfileSyncService::ShowErrorUI() {
return;
}
- // Figure out what kind of error we've encountered. There are only 3 kinds:
- // 1) auth error.
- // 2) server-initiated error
- // 3) passphrase error
- // Any other errors (such as unrecoverable error) should be handled by the UI
- // itself and should not result in a call to ShowErrorUI.
- if (last_auth_error_.state() != AuthError::NONE) {
+ if (last_auth_error_.state() != AuthError::NONE)
ShowLoginDialog();
- } else if (ShouldShowActionOnUI(last_actionable_error_)) {
+ else if (ShouldShowActionOnUI(last_actionable_error_))
ShowSyncSetup(chrome::kPersonalOptionsSubPage);
- } else {
- // We should only get here for passphrase error.
- DCHECK(IsPassphraseRequired());
- ShowSyncSetupWithWizard(SyncSetupWizard::ENTER_PASSPHRASE);
- }
+ else
+ ShowSyncSetupWithWizard(SyncSetupWizard::NONFATAL_ERROR);
}
void ProfileSyncService::ShowConfigure(bool sync_everything) {
@@ -1050,7 +1056,18 @@ bool ProfileSyncService::unrecoverable_error_detected() const {
}
bool ProfileSyncService::UIShouldDepictAuthInProgress() const {
- return signin()->AuthInProgress();
+ return is_auth_in_progress_;
+}
+
+void ProfileSyncService::SetUIShouldDepictAuthInProgress(
+ bool auth_in_progress) {
+ is_auth_in_progress_ = auth_in_progress;
+ // TODO(atwilson): Figure out if we still need to track this or if we should
+ // move this up to the UI (or break it out into two stats that track GAIA
+ // auth and sync auth separately).
+ if (is_auth_in_progress_)
+ auth_start_time_ = base::TimeTicks::Now();
+ NotifyObservers();
}
bool ProfileSyncService::IsPassphraseRequired() const {
@@ -1427,8 +1444,6 @@ void ProfileSyncService::Observe(int type,
details).ptr();
// The user has submitted credentials, which indicates they don't
// want to suppress start up anymore.
- // TODO(sync): Remove this when sync is no longer tied to browser signin.
- // http://crbug/com/95269.
sync_prefs_.SetStartSuppressed(false);
// Because we specify IMPLICIT to SetPassphrase, we know it won't override
@@ -1437,12 +1452,6 @@ void ProfileSyncService::Observe(int type,
// an explicit passphrase set so this becomes a no-op.
if (!successful->password.empty())
SetPassphrase(successful->password, IMPLICIT, INTERNAL);
-
- if (!sync_initialized() ||
- GetAuthError().state() != GoogleServiceAuthError::NONE) {
- // Track the fact that we're still waiting for auth to complete.
- is_auth_in_progress_ = true;
- }
break;
}
case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: {
diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h
index e9f4e16..c05d70b 100644
--- a/chrome/browser/sync/profile_sync_service.h
+++ b/chrome/browser/sync/profile_sync_service.h
@@ -319,13 +319,14 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
return unrecoverable_error_location_;
}
- // Reports whether the user is currently authenticating or not. This is used
+ // Tracks whether the user is currently authenticating or not. This is used
// by the sync_ui_util helper routines to allow the UI to properly display
// an "authenticating..." status message instead of an auth error when we are
// in the process of trying to update credentials.
- // TODO(atwilson): This state now resides in SigninManager - this method
- // will be removed once we've cleaned up the callers. http://crbug.com/95269.
+ // TODO(atwilson): This state should reside up in the UI or in a profile-
+ // specific SyncUIUtil object rather than in ProfileSyncService.
virtual bool UIShouldDepictAuthInProgress() const;
+ virtual void SetUIShouldDepictAuthInProgress(bool auth_in_progress);
// Returns true if OnPassphraseRequired has been called for any reason.
virtual bool IsPassphraseRequired() const;
@@ -514,13 +515,6 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
return configure_status_;
}
- // If true, the ProfileSyncService has detected that a new GAIA signin has
- // succeeded, and is waiting for initialization to complete. This is used by
- // the UI to differentiate between a new auth error (encountered as part of
- // the initialization process) and a pre-existing auth error that just hasn't
- // been cleared yet.
- bool waiting_for_auth() const { return is_auth_in_progress_; }
-
// ProfileKeyedService implementation.
virtual void Shutdown() OVERRIDE;
@@ -620,6 +614,13 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
// want to startup once more.
virtual void ReconfigureDatatypeManager();
+
+ // Time at which we begin an attempt a GAIA authorization.
+ base::TimeTicks auth_start_time_;
+
+ // Time at which error UI is presented for the new tab page.
+ base::TimeTicks auth_error_time_;
+
// Factory used to create various dependent objects.
scoped_ptr<ProfileSyncComponentsFactory> factory_;
@@ -644,8 +645,10 @@ class ProfileSyncService : public browser_sync::SyncFrontend,
// Whether the SyncBackendHost has been initialized.
bool backend_initialized_;
- // Set to true if a signin has completed but we're still waiting for the
- // backend to refresh its credentials.
+ // Various pieces of UI query this value to determine if they should show
+ // an "Authenticating.." type of message. We are the only central place
+ // all auth attempts funnel through, so it makes sense to provide this.
+ // As its name suggests, this should NOT be used for anything other than UI.
bool is_auth_in_progress_;
SyncSetupWizard wizard_;
diff --git a/chrome/browser/sync/profile_sync_service_mock.cc b/chrome/browser/sync/profile_sync_service_mock.cc
index c52e9d1..b5755bb 100644
--- a/chrome/browser/sync/profile_sync_service_mock.cc
+++ b/chrome/browser/sync/profile_sync_service_mock.cc
@@ -4,6 +4,7 @@
#include "chrome/browser/prefs/pref_service_mock_builder.h"
#include "chrome/browser/prefs/testing_pref_store.h"
+#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/sync/profile_sync_service_mock.h"
#include "chrome/browser/ui/webui/chrome_url_data_manager.h"
@@ -14,7 +15,7 @@
ProfileSyncServiceMock::ProfileSyncServiceMock()
: ProfileSyncService(NULL,
NULL,
- NULL,
+ new SigninManager(),
ProfileSyncService::MANUAL_START) {
}
@@ -26,6 +27,7 @@ ProfileSyncServiceMock::ProfileSyncServiceMock(
}
ProfileSyncServiceMock::~ProfileSyncServiceMock() {
+ delete signin();
}
// static
diff --git a/chrome/browser/sync/sync_setup_flow.cc b/chrome/browser/sync/sync_setup_flow.cc
index fb9e188..67e0a5a 100644
--- a/chrome/browser/sync/sync_setup_flow.cc
+++ b/chrome/browser/sync/sync_setup_flow.cc
@@ -12,6 +12,7 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "base/values.h"
+#include "chrome/browser/net/gaia/gaia_oauth_fetcher.h"
#include "chrome/browser/prefs/pref_service.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/signin_manager.h"
@@ -38,6 +39,37 @@ void DisablePasswordSync(ProfileSyncService* service) {
service->OnUserChoseDatatypes(false, types);
}
+// Returns the next step for the non-fatal error case.
+SyncSetupWizard::State GetStepForNonFatalError(ProfileSyncService* service) {
+ // TODO(sync): Update this error handling to allow different platforms to
+ // display the error appropriately (http://crbug.com/92722) instead of
+ // navigating to a LOGIN state that is not supported on every platform.
+ if (service->IsPassphraseRequired()) {
+#if defined(OS_CHROMEOS)
+ // On ChromeOS, we never want to request login information; this state
+ // always represents an invalid secondary passphrase.
+ // TODO(sync): correctly handle auth errors on ChromeOS: crosbug.com/24647.
+ return SyncSetupWizard::ENTER_PASSPHRASE;
+#else
+ if (service->IsUsingSecondaryPassphrase())
+ return SyncSetupWizard::ENTER_PASSPHRASE;
+ return SyncSetupWizard::GetLoginState();
+#endif
+ }
+
+ const GoogleServiceAuthError& error = service->GetAuthError();
+ if (error.state() == GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS ||
+ error.state() == GoogleServiceAuthError::CAPTCHA_REQUIRED ||
+ error.state() == GoogleServiceAuthError::ACCOUNT_DELETED ||
+ error.state() == GoogleServiceAuthError::ACCOUNT_DISABLED ||
+ error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE) {
+ return SyncSetupWizard::GetLoginState();
+ }
+
+ NOTREACHED();
+ return SyncSetupWizard::FATAL_ERROR;
+}
+
bool HasConfigurationChanged(const SyncConfiguration& configuration,
Profile* profile) {
CHECK(profile);
@@ -194,6 +226,8 @@ SyncSetupFlow* SyncSetupFlow::Run(ProfileSyncService* service,
SyncSetupFlowContainer* container,
SyncSetupWizard::State start,
SyncSetupWizard::State end) {
+ if (start == SyncSetupWizard::NONFATAL_ERROR)
+ start = GetStepForNonFatalError(service);
if ((start == SyncSetupWizard::CONFIGURE ||
start == SyncSetupWizard::SYNC_EVERYTHING ||
start == SyncSetupWizard::ENTER_PASSPHRASE) &&
@@ -207,6 +241,24 @@ SyncSetupFlow* SyncSetupFlow::Run(ProfileSyncService* service,
return new SyncSetupFlow(start, end, container, service);
}
+void SyncSetupFlow::GetArgsForGaiaLogin(DictionaryValue* args) {
+ const GoogleServiceAuthError& error = service_->GetAuthError();
+ if (!last_attempted_user_email_.empty()) {
+ args->SetString("user", last_attempted_user_email_);
+ args->SetInteger("error", error.state());
+ args->SetBoolean("editable_user", true);
+ } else {
+ string16 user;
+ user = UTF8ToUTF16(service_->profile()->GetPrefs()->GetString(
+ prefs::kGoogleServicesUsername));
+ args->SetString("user", user);
+ args->SetInteger("error", 0);
+ args->SetBoolean("editable_user", user.empty());
+ }
+
+ args->SetString("captchaUrl", error.captcha().image_url.spec());
+}
+
void SyncSetupFlow::GetArgsForConfigure(DictionaryValue* args) {
// The SYNC_EVERYTHING case will set this to true.
args->SetBoolean("showSyncEverythingPage", false);
@@ -312,6 +364,7 @@ void SyncSetupFlow::Focus() {
}
// A callback to notify the delegate that the dialog closed.
+// TODO(rickcam): Bug 90713: Handle OAUTH_LOGIN case here
void SyncSetupFlow::OnDialogClosed(const std::string& json_retval) {
DCHECK(json_retval.empty());
container_->set_flow(NULL); // Sever ties from the wizard.
@@ -322,6 +375,14 @@ void SyncSetupFlow::OnDialogClosed(const std::string& json_retval) {
// Record the state at which the user cancelled the signon dialog.
switch (current_state_) {
+ case SyncSetupWizard::GAIA_LOGIN:
+ ProfileSyncService::SyncEvent(
+ ProfileSyncService::CANCEL_FROM_SIGNON_WITHOUT_AUTH);
+ break;
+ case SyncSetupWizard::GAIA_SUCCESS:
+ ProfileSyncService::SyncEvent(
+ ProfileSyncService::CANCEL_DURING_SIGNON);
+ break;
case SyncSetupWizard::CONFIGURE:
case SyncSetupWizard::ENTER_PASSPHRASE:
case SyncSetupWizard::SETTING_UP:
@@ -330,14 +391,53 @@ void SyncSetupFlow::OnDialogClosed(const std::string& json_retval) {
ProfileSyncService::SyncEvent(
ProfileSyncService::CANCEL_DURING_CONFIGURE);
break;
+ case SyncSetupWizard::DONE:
+ // TODO(sync): rename this histogram; it's tracking authorization AND
+ // initial sync download time.
+ UMA_HISTOGRAM_MEDIUM_TIMES("Sync.UserPerceivedAuthorizationTime",
+ base::TimeTicks::Now() - login_start_time_);
+ break;
default:
break;
}
+ service_->SetUIShouldDepictAuthInProgress(false);
service_->OnUserCancelledDialog();
delete this;
}
+void SyncSetupFlow::OnUserSubmittedAuth(const std::string& username,
+ const std::string& password,
+ const std::string& captcha,
+ const std::string& access_code) {
+ last_attempted_user_email_ = username;
+ service_->SetUIShouldDepictAuthInProgress(true);
+
+ // If we're just being called to provide an ASP, then pass it to the
+ // SigninManager and wait for the next step.
+ if (!access_code.empty()) {
+ service_->signin()->ProvideSecondFactorAccessCode(access_code);
+ return;
+ }
+
+ // Kick off a sign-in through the signin manager.
+ SigninManager* signin = service_->signin();
+ signin->StartSignIn(username,
+ password,
+ signin->GetLoginAuthError().captcha().token,
+ captcha);
+}
+
+void SyncSetupFlow::OnUserSubmittedOAuth(
+ const std::string& oauth1_request_token) {
+ GaiaOAuthFetcher* fetcher = new GaiaOAuthFetcher(
+ service_->signin(),
+ service_->profile()->GetRequestContext(),
+ service_->profile(),
+ GaiaConstants::kSyncServiceOAuth);
+ service_->signin()->StartOAuthSignIn(oauth1_request_token, fetcher);
+}
+
void SyncSetupFlow::OnUserConfigured(const SyncConfiguration& configuration) {
// Update sync histograms. This is a no-op if |configuration| has not changed.
UpdateHistogram(configuration, service_);
@@ -423,6 +523,7 @@ SyncSetupFlow::SyncSetupFlow(SyncSetupWizard::State start_state,
: container_(container),
current_state_(start_state),
end_state_(end_state),
+ login_start_time_(base::TimeTicks::Now()),
flow_handler_(NULL),
service_(service),
user_tried_creating_explicit_passphrase_(false),
@@ -432,17 +533,33 @@ SyncSetupFlow::SyncSetupFlow(SyncSetupWizard::State start_state,
// Returns true if the flow should advance to |state| based on |current_state_|.
bool SyncSetupFlow::ShouldAdvance(SyncSetupWizard::State state) {
switch (state) {
+ case SyncSetupWizard::OAUTH_LOGIN:
+ return current_state_ == SyncSetupWizard::FATAL_ERROR ||
+ current_state_ == SyncSetupWizard::OAUTH_LOGIN ||
+ current_state_ == SyncSetupWizard::SETTING_UP;
+ case SyncSetupWizard::GAIA_LOGIN:
+ return current_state_ == SyncSetupWizard::FATAL_ERROR ||
+ current_state_ == SyncSetupWizard::GAIA_LOGIN ||
+ current_state_ == SyncSetupWizard::SETTING_UP;
+ case SyncSetupWizard::GAIA_SUCCESS:
+ return current_state_ == SyncSetupWizard::GAIA_LOGIN ||
+ current_state_ == SyncSetupWizard::OAUTH_LOGIN;
case SyncSetupWizard::SYNC_EVERYTHING: // Intentionally fall through.
case SyncSetupWizard::CONFIGURE:
- return current_state_ != SyncSetupWizard::SETTING_UP;
+ return current_state_ == SyncSetupWizard::GAIA_SUCCESS;
case SyncSetupWizard::ENTER_PASSPHRASE:
- return current_state_ == SyncSetupWizard::SYNC_EVERYTHING ||
+ return (service_->auto_start_enabled() &&
+ current_state_ == SyncSetupWizard::GAIA_LOGIN) ||
+ current_state_ == SyncSetupWizard::SYNC_EVERYTHING ||
current_state_ == SyncSetupWizard::CONFIGURE ||
current_state_ == SyncSetupWizard::SETTING_UP;
+ case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR:
+ return current_state_ != SyncSetupWizard::ABORT;
case SyncSetupWizard::SETTING_UP:
return current_state_ == SyncSetupWizard::SYNC_EVERYTHING ||
current_state_ == SyncSetupWizard::CONFIGURE ||
current_state_ == SyncSetupWizard::ENTER_PASSPHRASE;
+ case SyncSetupWizard::NONFATAL_ERROR: // Intentionally fall through.
case SyncSetupWizard::FATAL_ERROR:
return current_state_ != SyncSetupWizard::ABORT;
case SyncSetupWizard::ABORT:
@@ -459,9 +576,31 @@ bool SyncSetupFlow::ShouldAdvance(SyncSetupWizard::State state) {
void SyncSetupFlow::ActivateState(SyncSetupWizard::State state) {
DCHECK(flow_handler_);
+ if (state == SyncSetupWizard::NONFATAL_ERROR)
+ state = GetStepForNonFatalError(service_);
+
current_state_ = state;
switch (state) {
+ case SyncSetupWizard::OAUTH_LOGIN: {
+ flow_handler_->ShowOAuthLogin();
+ break;
+ }
+ case SyncSetupWizard::GAIA_LOGIN: {
+ DictionaryValue args;
+ GetArgsForGaiaLogin(&args);
+ flow_handler_->ShowGaiaLogin(args);
+ break;
+ }
+ case SyncSetupWizard::GAIA_SUCCESS:
+ // Authentication is complete now.
+ service_->SetUIShouldDepictAuthInProgress(false);
+ if (end_state_ == SyncSetupWizard::GAIA_SUCCESS) {
+ flow_handler_->ShowGaiaSuccessAndClose();
+ break;
+ }
+ flow_handler_->ShowGaiaSuccessAndSettingUp();
+ break;
case SyncSetupWizard::SYNC_EVERYTHING: {
DictionaryValue args;
GetArgsForConfigure(&args);
@@ -483,6 +622,17 @@ void SyncSetupFlow::ActivateState(SyncSetupWizard::State state) {
flow_handler_->ShowPassphraseEntry(args);
break;
}
+ case SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR: {
+ // TODO(sync): We should expose a real "display an error" API on
+ // SyncSetupFlowHandler (crbug.com/92722) but for now just transition
+ // to the login state with a special error code.
+ DictionaryValue args;
+ GetArgsForGaiaLogin(&args);
+ args.SetInteger("error", GoogleServiceAuthError::SERVICE_UNAVAILABLE);
+ current_state_ = SyncSetupWizard::GAIA_LOGIN;
+ flow_handler_->ShowGaiaLogin(args);
+ break;
+ }
case SyncSetupWizard::SETTING_UP: {
flow_handler_->ShowSettingUp();
break;
@@ -491,7 +641,11 @@ void SyncSetupFlow::ActivateState(SyncSetupWizard::State state) {
// This shows the user the "Could not connect to server" error.
// TODO(sync): Update this error handling to allow different platforms to
// display the error appropriately (http://crbug.com/92722).
- flow_handler_->ShowFatalError();
+ DictionaryValue args;
+ GetArgsForGaiaLogin(&args);
+ args.SetBoolean("fatalError", true);
+ current_state_ = SyncSetupWizard::GAIA_LOGIN;
+ flow_handler_->ShowGaiaLogin(args);
break;
}
case SyncSetupWizard::DONE:
diff --git a/chrome/browser/sync/sync_setup_flow.h b/chrome/browser/sync/sync_setup_flow.h
index c38db7e..2338d6f 100644
--- a/chrome/browser/sync/sync_setup_flow.h
+++ b/chrome/browser/sync/sync_setup_flow.h
@@ -62,6 +62,9 @@ class SyncSetupFlow {
SyncSetupWizard::State start,
SyncSetupWizard::State end);
+ // Fills |args| with "user" and "error" arguments per our current state.
+ void GetArgsForGaiaLogin(DictionaryValue* args);
+
// Fills |args| for the configure screen (Choose Data Types/Encryption)
void GetArgsForConfigure(DictionaryValue* args);
@@ -79,6 +82,13 @@ class SyncSetupFlow {
// obscured by a browser window.
void Focus();
+ void OnUserSubmittedAuth(const std::string& username,
+ const std::string& password,
+ const std::string& captcha,
+ const std::string& access_code);
+
+ void OnUserSubmittedOAuth(const std::string& oauth1_request_token);
+
void OnUserConfigured(const SyncConfiguration& configuration);
// The 'passphrase' screen is used when the user is prompted to enter
@@ -103,8 +113,7 @@ class SyncSetupFlow {
FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest,
DiscreteRunChooseDataTypesAbortedByPendingClear);
FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, EnterPassphraseRequired);
- FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, EnterPassphrase);
- FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, FatalErrorDuringConfigure);
+ FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, NonFatalError);
FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, CrosAuthSetup);
FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, ShowErrorUIForPasswordTest);
FRIEND_TEST_ALL_PREFIXES(SyncSetupWizardTest, ShowErrorUIForPassphraseTest);
@@ -128,6 +137,9 @@ class SyncSetupFlow {
SyncSetupWizard::State current_state_;
SyncSetupWizard::State end_state_; // The goal.
+ // Time that the GAIA_LOGIN step was received.
+ base::TimeTicks login_start_time_;
+
// The handler needed for the entire flow. Weak reference.
SyncSetupFlowHandler* flow_handler_;
@@ -142,6 +154,10 @@ class SyncSetupFlow {
// reflect this in the UI.
bool user_tried_setting_passphrase_;
+ // Cache of the last name the client attempted to authenticate.
+ // TODO(atwilson): Move this out of here entirely and up into the UI layer.
+ std::string last_attempted_user_email_;
+
DISALLOW_COPY_AND_ASSIGN(SyncSetupFlow);
};
diff --git a/chrome/browser/sync/sync_setup_flow_handler.h b/chrome/browser/sync/sync_setup_flow_handler.h
index 6a8ef2c..4bf788f 100644
--- a/chrome/browser/sync/sync_setup_flow_handler.h
+++ b/chrome/browser/sync/sync_setup_flow_handler.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -17,7 +17,10 @@ class DictionaryValue;
class SyncSetupFlowHandler {
public:
// These functions control which part of the HTML is visible.
- virtual void ShowFatalError() = 0;
+ virtual void ShowOAuthLogin() = 0;
+ virtual void ShowGaiaLogin(const base::DictionaryValue& args) = 0;
+ virtual void ShowGaiaSuccessAndClose() = 0;
+ virtual void ShowGaiaSuccessAndSettingUp() = 0;
virtual void ShowConfigure(const base::DictionaryValue& args) = 0;
virtual void ShowPassphraseEntry(const base::DictionaryValue& args) = 0;
virtual void ShowSettingUp() = 0;
diff --git a/chrome/browser/sync/sync_setup_wizard.cc b/chrome/browser/sync/sync_setup_wizard.cc
index 97b501a..80d892f 100644
--- a/chrome/browser/sync/sync_setup_wizard.cc
+++ b/chrome/browser/sync/sync_setup_wizard.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -18,10 +18,33 @@
namespace {
+// If we just need to pop open an individual dialog, say to collect
+// gaia credentials in the event of a steady-state auth failure, this is
+// a "discrete" run (as in not a continuous wizard flow). This returns
+// the end state to pass to Run for a given |start_state|.
+SyncSetupWizard::State GetEndStateForDiscreteRun(
+ SyncSetupWizard::State start_state) {
+ SyncSetupWizard::State result = SyncSetupWizard::FATAL_ERROR;
+ if (start_state == SyncSetupWizard::GAIA_LOGIN ||
+ start_state == SyncSetupWizard::OAUTH_LOGIN) {
+ result = SyncSetupWizard::GAIA_SUCCESS;
+ } else if (start_state == SyncSetupWizard::ENTER_PASSPHRASE ||
+ start_state == SyncSetupWizard::NONFATAL_ERROR ||
+ start_state == SyncSetupWizard::SYNC_EVERYTHING ||
+ start_state == SyncSetupWizard::CONFIGURE) {
+ result = SyncSetupWizard::DONE;
+ }
+ DCHECK_NE(SyncSetupWizard::FATAL_ERROR, result) <<
+ "Invalid start state for discrete run: " << start_state;
+ return result;
+}
+
// Helper to return whether |state| warrants starting a new flow.
bool IsTerminalState(SyncSetupWizard::State state) {
- return state == SyncSetupWizard::DONE ||
- state == SyncSetupWizard::FATAL_ERROR;
+ return state == SyncSetupWizard::GAIA_SUCCESS ||
+ state == SyncSetupWizard::DONE ||
+ state == SyncSetupWizard::FATAL_ERROR ||
+ state == SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR;
}
} // namespace
@@ -40,15 +63,28 @@ void SyncSetupWizard::Step(State advance_state) {
if (flow) {
// A setup flow is in progress and dialog is currently showing.
flow->Advance(advance_state);
- } else {
+ } else if (!service_->HasSyncSetupCompleted()) {
if (IsTerminalState(advance_state))
return;
- // Starting a new flow - make sure we're at a valid starting state.
- DCHECK(advance_state == ENTER_PASSPHRASE ||
- advance_state == SYNC_EVERYTHING ||
- advance_state == CONFIGURE);
+ // No flow is in progress, and we have never escorted the user all the
+ // way through the wizard flow.
+ // TODO(atwilson): Make sure this works on all autostart_enabled platforms.
+ State end_state = DONE;
+ if (service_->auto_start_enabled() &&
+ !service_->profile()->GetPrefs()->GetBoolean(
+ prefs::kSyncSuppressStart)) {
+ end_state = GAIA_SUCCESS;
+ }
flow_container_->set_flow(
- SyncSetupFlow::Run(service_, flow_container_, advance_state, DONE));
+ SyncSetupFlow::Run(service_, flow_container_, advance_state,
+ end_state));
+ } else {
+ // No flow in progress, but we've finished the wizard flow once before.
+ // This is just a discrete run.
+ if (IsTerminalState(advance_state))
+ return;
+ flow_container_->set_flow(SyncSetupFlow::Run(service_, flow_container_,
+ advance_state, GetEndStateForDiscreteRun(advance_state)));
}
}
@@ -57,6 +93,13 @@ bool SyncSetupWizard::IsVisible() const {
flow_container_->get_flow()->IsAttached();
}
+// static
+SyncSetupWizard::State SyncSetupWizard::GetLoginState() {
+ return browser_sync::IsUsingOAuth() ?
+ SyncSetupWizard::OAUTH_LOGIN :
+ SyncSetupWizard::GAIA_LOGIN;
+}
+
void SyncSetupWizard::Focus() {
SyncSetupFlow* flow = flow_container_->get_flow();
if (flow)
diff --git a/chrome/browser/sync/sync_setup_wizard.h b/chrome/browser/sync/sync_setup_wizard.h
index fd2b153..efaeff7 100644
--- a/chrome/browser/sync/sync_setup_wizard.h
+++ b/chrome/browser/sync/sync_setup_wizard.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -17,6 +17,15 @@ class ProfileSyncService;
class SyncSetupWizard {
public:
enum State {
+ // Show the Google Account login UI.
+ GAIA_LOGIN = 0,
+ // Show the Gaia OAuth login UI.
+ // TODO(rickcam): After Sync with OAuth works, revisit removing this state.
+ OAUTH_LOGIN,
+ // A login attempt succeeded. This will wait for an explicit transition
+ // (via Step) to the next state.
+ GAIA_SUCCESS,
+ // Show the screen that confirms everything will be synced.
SYNC_EVERYTHING,
// Show the screen that lets you configure sync.
// There are two tabs:
@@ -28,15 +37,20 @@ class SyncSetupWizard {
CONFIGURE,
// Show the screen that prompts for your passphrase
ENTER_PASSPHRASE,
+ // An error has occurred in the backend. The next appropriate step is picked
+ // based on which error has occurred.
+ NONFATAL_ERROR,
// The panic switch. Something went terribly wrong during setup and we can't
// recover.
FATAL_ERROR,
+ // The client can't set up sync at the moment due to a concurrent operation
+ // to clear cloud data being in progress on the server.
+ SETUP_ABORTED_BY_PENDING_CLEAR,
// Loading screen with throbber.
SETTING_UP,
// A catch-all done case for any setup process.
DONE,
- // Exit the wizard (for example, if the user clears the data on the
- // dashboard while the wizard is open).
+ // Exit the wizard.
ABORT,
};
@@ -54,6 +68,10 @@ class SyncSetupWizard {
// if various buttons in the UI should be enabled or disabled.
bool IsVisible() const;
+ // Returns either GAIA_LOGIN or OAUTH_LOGIN depending on which
+ // authentication scheme is in force.
+ static State GetLoginState();
+
// Focus the dialog if it is already open. Does nothing if the dialog is
// not visible.
void Focus();
diff --git a/chrome/browser/sync/sync_setup_wizard_unittest.cc b/chrome/browser/sync/sync_setup_wizard_unittest.cc
index d1ed84e..2c2b859 100644
--- a/chrome/browser/sync/sync_setup_wizard_unittest.cc
+++ b/chrome/browser/sync/sync_setup_wizard_unittest.cc
@@ -18,7 +18,6 @@
#include "chrome/browser/sync/sync_setup_flow.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/webui/signin/login_ui_service.h"
#include "chrome/browser/ui/webui/options/options_sync_setup_handler.h"
#include "chrome/common/net/gaia/google_service_auth_error.h"
#include "chrome/common/pref_names.h"
@@ -36,36 +35,26 @@ typedef GoogleServiceAuthError AuthError;
class MockSyncSetupHandler : public OptionsSyncSetupHandler {
public:
- MockSyncSetupHandler()
- : OptionsSyncSetupHandler(NULL),
- login_ui_(new LoginUIService(NULL)) {}
+ MockSyncSetupHandler() : OptionsSyncSetupHandler(NULL) {}
// SyncSetupFlowHandler implementation.
- virtual void ShowFatalError() OVERRIDE {
- ShowSetupDone(string16());
+ virtual void ShowGaiaLogin(const DictionaryValue& args) OVERRIDE {}
+ virtual void ShowGaiaSuccessAndClose() OVERRIDE {
+ flow()->OnDialogClosed("");
}
+ virtual void ShowGaiaSuccessAndSettingUp() OVERRIDE {}
virtual void ShowConfigure(const DictionaryValue& args) OVERRIDE {}
virtual void ShowPassphraseEntry(const DictionaryValue& args) OVERRIDE {}
virtual void ShowSettingUp() OVERRIDE {}
virtual void ShowSetupDone(const string16& user) OVERRIDE {
- if (flow())
- flow()->OnDialogClosed("");
- }
-
- SyncSetupFlow* GetFlow() {
- return flow();
+ flow()->OnDialogClosed("");
}
void CloseSetupUI() {
ShowSetupDone(string16());
}
- virtual LoginUIService* GetLoginUIService() const OVERRIDE {
- return login_ui_.get();
- }
-
private:
- scoped_ptr<LoginUIService> login_ui_;
DISALLOW_COPY_AND_ASSIGN(MockSyncSetupHandler);
};
@@ -210,7 +199,8 @@ class SyncSetupWizardTest : public BrowserWithTestWindowTest {
public:
SyncSetupWizardTest()
: wizard_(NULL),
- service_(NULL) {}
+ service_(NULL),
+ flow_(NULL) {}
virtual ~SyncSetupWizardTest() {}
virtual TestingProfile* BuildProfile() {
TestingProfile* profile = new TestingProfile();
@@ -237,16 +227,20 @@ class SyncSetupWizardTest : public BrowserWithTestWindowTest {
virtual void TearDown() {
wizard_ = NULL;
service_ = NULL;
+ flow_ = NULL;
}
protected:
void AttachSyncSetupHandler() {
- wizard_->AttachSyncSetupHandler(&handler_);
+ flow_ = wizard_->AttachSyncSetupHandler(&handler_);
}
void CompleteSetup() {
- wizard_->Step(SyncSetupWizard::SYNC_EVERYTHING);
+ // For a discrete run, we need to have ran through setup once.
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
AttachSyncSetupHandler();
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ wizard_->Step(SyncSetupWizard::SYNC_EVERYTHING);
wizard_->Step(SyncSetupWizard::SETTING_UP);
wizard_->Step(SyncSetupWizard::DONE);
}
@@ -258,12 +252,92 @@ class SyncSetupWizardTest : public BrowserWithTestWindowTest {
// This pointer is owned by the |Service_|.
SyncSetupWizard* wizard_;
ProfileSyncServiceForWizardTest* service_;
+ SyncSetupFlow* flow_;
MockSyncSetupHandler handler_;
};
+TEST_F(SyncSetupWizardTest, InitialStepLogin) {
+ ListValue credentials;
+ std::string auth = "{\"user\":\"";
+ auth += std::string(kTestUser) + "\",\"pass\":\"";
+ auth += std::string(kTestPassword) + "\",\"captcha\":\"";
+ auth += std::string(kTestCaptcha) + "\",\"access_code\":\"";
+ auth += std::string() + "\"}";
+ credentials.Append(new StringValue(auth));
+
+ EXPECT_FALSE(wizard_->IsVisible());
+ EXPECT_EQ(static_cast<SyncSetupFlow*>(NULL), flow_);
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ AttachSyncSetupHandler();
+
+ EXPECT_TRUE(wizard_->IsVisible());
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
+
+ // Simulate the user submitting credentials.
+ handler_.HandleSubmitAuth(&credentials);
+ EXPECT_TRUE(wizard_->IsVisible());
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ EXPECT_EQ(kTestUser, service_->mock_signin_.username_);
+ EXPECT_EQ(kTestPassword, service_->mock_signin_.password_);
+ EXPECT_EQ(kTestCaptcha, service_->mock_signin_.captcha_);
+ EXPECT_FALSE(service_->user_cancelled_dialog_);
+ service_->ResetTestStats();
+
+ // Simulate failed credentials.
+ AuthError invalid_gaia(AuthError::INVALID_GAIA_CREDENTIALS);
+ flow_->last_attempted_user_email_ = kTestUser;
+ service_->set_last_auth_error(invalid_gaia);
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ EXPECT_TRUE(wizard_->IsVisible());
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ DictionaryValue dialog_args;
+ flow_->GetArgsForGaiaLogin(&dialog_args);
+ EXPECT_EQ(4U, dialog_args.size());
+ std::string actual_user;
+ dialog_args.GetString("user", &actual_user);
+ EXPECT_EQ(kTestUser, actual_user);
+ int error = -1;
+ dialog_args.GetInteger("error", &error);
+ EXPECT_EQ(static_cast<int>(AuthError::INVALID_GAIA_CREDENTIALS), error);
+ flow_->last_attempted_user_email_ = kTestUser;
+ service_->set_last_auth_error(AuthError::None());
+
+ // Simulate captcha.
+ AuthError captcha_error(AuthError::FromCaptchaChallenge(
+ std::string(), GURL(kTestCaptchaUrl), GURL()));
+ flow_->last_attempted_user_email_ = kTestUser;
+ service_->set_last_auth_error(captcha_error);
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ flow_->GetArgsForGaiaLogin(&dialog_args);
+ EXPECT_EQ(4U, dialog_args.size());
+ std::string captcha_url;
+ dialog_args.GetString("captchaUrl", &captcha_url);
+ EXPECT_EQ(kTestCaptchaUrl, GURL(captcha_url).spec());
+ error = -1;
+ dialog_args.GetInteger("error", &error);
+ EXPECT_EQ(static_cast<int>(AuthError::CAPTCHA_REQUIRED), error);
+ flow_->last_attempted_user_email_ = kTestUser;
+ service_->set_last_auth_error(AuthError::None());
+
+ // Simulate success.
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ EXPECT_TRUE(wizard_->IsVisible());
+ wizard_->Step(SyncSetupWizard::SYNC_EVERYTHING);
+ EXPECT_EQ(SyncSetupWizard::SYNC_EVERYTHING, flow_->current_state_);
+
+ // That's all we're testing here, just move on to DONE. We'll test the
+ // "choose data types" scenarios elsewhere.
+ wizard_->Step(SyncSetupWizard::SETTING_UP); // No merge and sync.
+ wizard_->Step(SyncSetupWizard::DONE); // No merge and sync.
+ EXPECT_FALSE(wizard_->IsVisible());
+}
+
TEST_F(SyncSetupWizardTest, ChooseDataTypesSetsPrefs) {
- wizard_->Step(SyncSetupWizard::CONFIGURE);
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
AttachSyncSetupHandler();
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ wizard_->Step(SyncSetupWizard::CONFIGURE);
ListValue data_type_choices_value;
std::string data_type_choices =
@@ -293,6 +367,25 @@ TEST_F(SyncSetupWizardTest, ChooseDataTypesSetsPrefs) {
syncable::APP_NOTIFICATIONS));
}
+TEST_F(SyncSetupWizardTest, ShowErrorUIForPasswordTest) {
+ service_->ClearObservers();
+ CompleteSetup();
+
+ // Simulate an auth error and make sure the start and end state are set
+ // right.
+ service_->set_last_auth_error(
+ AuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+ service_->ShowErrorUI();
+ AttachSyncSetupHandler();
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ EXPECT_EQ(SyncSetupWizard::GAIA_SUCCESS, flow_->end_state_);
+ ASSERT_TRUE(wizard_->IsVisible());
+
+ // Make sure the wizard is dismissed.
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ ASSERT_FALSE(wizard_->IsVisible());
+}
+
TEST_F(SyncSetupWizardTest, ShowErrorUIForPassphraseTest) {
service_->ClearObservers();
CompleteSetup();
@@ -303,9 +396,8 @@ TEST_F(SyncSetupWizardTest, ShowErrorUIForPassphraseTest) {
service_->set_is_using_secondary_passphrase(true);
service_->ShowErrorUI();
AttachSyncSetupHandler();
- EXPECT_EQ(SyncSetupWizard::ENTER_PASSPHRASE,
- handler_.GetFlow()->current_state_);
- EXPECT_EQ(SyncSetupWizard::DONE, handler_.GetFlow()->end_state_);
+ EXPECT_EQ(SyncSetupWizard::ENTER_PASSPHRASE, flow_->current_state_);
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
ASSERT_TRUE(wizard_->IsVisible());
// Make sure the wizard is dismissed.
@@ -314,13 +406,14 @@ TEST_F(SyncSetupWizardTest, ShowErrorUIForPassphraseTest) {
}
TEST_F(SyncSetupWizardTest, EnterPassphraseRequired) {
- wizard_->Step(SyncSetupWizard::CONFIGURE);
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
AttachSyncSetupHandler();
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ wizard_->Step(SyncSetupWizard::CONFIGURE);
wizard_->Step(SyncSetupWizard::SETTING_UP);
service_->set_passphrase_required_reason(sync_api::REASON_ENCRYPTION);
wizard_->Step(SyncSetupWizard::ENTER_PASSPHRASE);
- EXPECT_EQ(SyncSetupWizard::ENTER_PASSPHRASE,
- handler_.GetFlow()->current_state_);
+ EXPECT_EQ(SyncSetupWizard::ENTER_PASSPHRASE, flow_->current_state_);
ListValue value;
value.Append(new StringValue("{\"passphrase\":\"myPassphrase\","
@@ -330,21 +423,49 @@ TEST_F(SyncSetupWizardTest, EnterPassphraseRequired) {
CloseSetupUI();
}
+TEST_F(SyncSetupWizardTest, DialogCancelled) {
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ AttachSyncSetupHandler();
+ // Simulate the user closing the dialog.
+ CloseSetupUI();
+ EXPECT_FALSE(wizard_->IsVisible());
+ EXPECT_TRUE(service_->user_cancelled_dialog_);
+ EXPECT_EQ(std::string(), service_->mock_signin_.username_);
+ EXPECT_EQ(std::string(), service_->mock_signin_.password_);
+
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ AttachSyncSetupHandler();
+ EXPECT_TRUE(wizard_->IsVisible());
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+
+ CloseSetupUI();
+ EXPECT_FALSE(wizard_->IsVisible());
+ EXPECT_TRUE(service_->user_cancelled_dialog_);
+ EXPECT_EQ(std::string(), service_->mock_signin_.username_);
+ EXPECT_EQ(std::string(), service_->mock_signin_.password_);
+}
+
TEST_F(SyncSetupWizardTest, InvalidTransitions) {
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ EXPECT_FALSE(wizard_->IsVisible());
+
wizard_->Step(SyncSetupWizard::DONE);
EXPECT_FALSE(wizard_->IsVisible());
- wizard_->Step(SyncSetupWizard::SYNC_EVERYTHING);
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
AttachSyncSetupHandler();
- EXPECT_EQ(SyncSetupWizard::SYNC_EVERYTHING,
- handler_.GetFlow()->current_state_);
- EXPECT_TRUE(wizard_->IsVisible());
+
+ wizard_->Step(SyncSetupWizard::DONE);
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ wizard_->Step(SyncSetupWizard::SYNC_EVERYTHING);
+ EXPECT_EQ(SyncSetupWizard::SYNC_EVERYTHING, flow_->current_state_);
wizard_->Step(SyncSetupWizard::FATAL_ERROR);
- // Stepping to FATAL_ERROR leaves us in a FATAL_ERROR state and blows away
- // the SyncSetupFlow.
- EXPECT_FALSE(wizard_->IsVisible());
- EXPECT_TRUE(handler_.GetFlow() == NULL);
+ // Stepping to FATAL_ERROR sends us back to GAIA_LOGIN.
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ CloseSetupUI();
}
TEST_F(SyncSetupWizardTest, FullSuccessfulRunSetsPref) {
@@ -355,12 +476,15 @@ TEST_F(SyncSetupWizardTest, FullSuccessfulRunSetsPref) {
}
TEST_F(SyncSetupWizardTest, AbortedByPendingClear) {
- wizard_->Step(SyncSetupWizard::SYNC_EVERYTHING);
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
AttachSyncSetupHandler();
- EXPECT_TRUE(wizard_->IsVisible());
- wizard_->Step(SyncSetupWizard::ABORT);
- // Stepping to ABORT should leave us in ABORT state, and should close the
- // wizard.
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ wizard_->Step(SyncSetupWizard::SYNC_EVERYTHING);
+ wizard_->Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR);
+ // Stepping to SETUP_ABORTED should redirect us to GAIA_LOGIN state, since
+ // that's where we display the error.
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ CloseSetupUI();
EXPECT_FALSE(wizard_->IsVisible());
}
@@ -369,7 +493,7 @@ TEST_F(SyncSetupWizardTest, DiscreteRunChooseDataTypes) {
wizard_->Step(SyncSetupWizard::CONFIGURE);
AttachSyncSetupHandler();
- EXPECT_EQ(SyncSetupWizard::DONE, handler_.GetFlow()->end_state_);
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
wizard_->Step(SyncSetupWizard::SETTING_UP);
wizard_->Step(SyncSetupWizard::DONE);
@@ -381,36 +505,107 @@ TEST_F(SyncSetupWizardTest, DiscreteRunChooseDataTypesAbortedByPendingClear) {
wizard_->Step(SyncSetupWizard::CONFIGURE);
AttachSyncSetupHandler();
- EXPECT_TRUE(wizard_->IsVisible());
- EXPECT_EQ(SyncSetupWizard::DONE, handler_.GetFlow()->end_state_);
- wizard_->Step(SyncSetupWizard::ABORT);
- // Stepping to ABORT should leave us in the ABORT state and close the dialog.
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
+ wizard_->Step(SyncSetupWizard::SETUP_ABORTED_BY_PENDING_CLEAR);
+ // Stepping to SETUP_ABORTED should redirect us to GAIA_LOGIN state, since
+ // that's where we display the error.
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+
+ CloseSetupUI();
EXPECT_FALSE(wizard_->IsVisible());
}
-TEST_F(SyncSetupWizardTest, EnterPassphrase) {
+TEST_F(SyncSetupWizardTest, DiscreteRunGaiaLogin) {
+ CompleteSetup();
+
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ AttachSyncSetupHandler();
+ EXPECT_EQ(SyncSetupWizard::GAIA_SUCCESS, flow_->end_state_);
+
+ AuthError invalid_gaia(AuthError::INVALID_GAIA_CREDENTIALS);
+ flow_->last_attempted_user_email_ = kTestUser;
+ service_->set_last_auth_error(invalid_gaia);
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+ EXPECT_TRUE(wizard_->IsVisible());
+
+ DictionaryValue dialog_args;
+ flow_->GetArgsForGaiaLogin(&dialog_args);
+ EXPECT_EQ(4U, dialog_args.size());
+ std::string actual_user;
+ dialog_args.GetString("user", &actual_user);
+ EXPECT_EQ(kTestUser, actual_user);
+ int error = -1;
+ dialog_args.GetInteger("error", &error);
+ EXPECT_EQ(static_cast<int>(AuthError::INVALID_GAIA_CREDENTIALS), error);
+ flow_->last_attempted_user_email_ = kTestUser;
+ service_->set_last_auth_error(AuthError::None());
+
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+}
+
+TEST_F(SyncSetupWizardTest, NonFatalError) {
CompleteSetup();
// Set up the ENTER_PASSPHRASE case.
service_->set_passphrase_required_reason(sync_api::REASON_ENCRYPTION);
service_->set_is_using_secondary_passphrase(true);
- wizard_->Step(SyncSetupWizard::ENTER_PASSPHRASE);
+ wizard_->Step(SyncSetupWizard::NONFATAL_ERROR);
AttachSyncSetupHandler();
- EXPECT_EQ(SyncSetupWizard::ENTER_PASSPHRASE,
- handler_.GetFlow()->current_state_);
- EXPECT_EQ(SyncSetupWizard::DONE, handler_.GetFlow()->end_state_);
+ EXPECT_EQ(SyncSetupWizard::ENTER_PASSPHRASE, flow_->current_state_);
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
CloseSetupUI();
EXPECT_FALSE(wizard_->IsVisible());
-}
-TEST_F(SyncSetupWizardTest, FatalErrorDuringConfigure) {
- CompleteSetup();
+ // Reset.
+ service_->set_passphrase_required_reason(
+ sync_api::REASON_PASSPHRASE_NOT_REQUIRED);
+ service_->set_is_using_secondary_passphrase(false);
- wizard_->Step(SyncSetupWizard::CONFIGURE);
+ // Test the various auth error states that lead to GAIA_LOGIN.
+
+ service_->set_last_auth_error(
+ AuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+ wizard_->Step(SyncSetupWizard::NONFATAL_ERROR);
AttachSyncSetupHandler();
- EXPECT_EQ(SyncSetupWizard::DONE, handler_.GetFlow()->end_state_);
- wizard_->Step(SyncSetupWizard::FATAL_ERROR);
- EXPECT_TRUE(handler_.GetFlow() == NULL);
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
+ CloseSetupUI();
+ EXPECT_FALSE(wizard_->IsVisible());
+
+ service_->set_last_auth_error(
+ AuthError(GoogleServiceAuthError::CAPTCHA_REQUIRED));
+ wizard_->Step(SyncSetupWizard::NONFATAL_ERROR);
+ AttachSyncSetupHandler();
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
+ CloseSetupUI();
+ EXPECT_FALSE(wizard_->IsVisible());
+
+ service_->set_last_auth_error(
+ AuthError(GoogleServiceAuthError::ACCOUNT_DELETED));
+ wizard_->Step(SyncSetupWizard::NONFATAL_ERROR);
+ AttachSyncSetupHandler();
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
+ CloseSetupUI();
+ EXPECT_FALSE(wizard_->IsVisible());
+
+ service_->set_last_auth_error(
+ AuthError(GoogleServiceAuthError::ACCOUNT_DISABLED));
+ wizard_->Step(SyncSetupWizard::NONFATAL_ERROR);
+ AttachSyncSetupHandler();
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
+ CloseSetupUI();
+ EXPECT_FALSE(wizard_->IsVisible());
+
+ service_->set_last_auth_error(
+ AuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
+ wizard_->Step(SyncSetupWizard::NONFATAL_ERROR);
+ AttachSyncSetupHandler();
+ EXPECT_EQ(SyncSetupWizard::GAIA_LOGIN, flow_->current_state_);
+ EXPECT_EQ(SyncSetupWizard::DONE, flow_->end_state_);
+ CloseSetupUI();
EXPECT_FALSE(wizard_->IsVisible());
}
@@ -424,3 +619,29 @@ class SyncSetupWizardCrosTest : public SyncSetupWizardTest {
return profile;
}
};
+
+// Tests a scenario where sync is disabled on chrome os on startup due to
+// an auth error (application specific password is needed).
+TEST_F(SyncSetupWizardCrosTest, CrosAuthSetup) {
+ wizard_->Step(SyncSetupWizard::GAIA_LOGIN);
+
+ AttachSyncSetupHandler();
+ EXPECT_EQ(SyncSetupWizard::GAIA_SUCCESS, flow_->end_state_);
+
+ DictionaryValue dialog_args;
+ flow_->GetArgsForGaiaLogin(&dialog_args);
+ EXPECT_EQ(4U, dialog_args.size());
+ std::string actual_user;
+ dialog_args.GetString("user", &actual_user);
+ EXPECT_EQ(kTestUser, actual_user);
+ int error = -1;
+ dialog_args.GetInteger("error", &error);
+ EXPECT_EQ(0, error);
+ bool editable = true;
+ dialog_args.GetBoolean("editable_user", &editable);
+ EXPECT_FALSE(editable);
+ wizard_->Step(SyncSetupWizard::GAIA_SUCCESS);
+ EXPECT_TRUE(service_->user_cancelled_dialog_);
+ EXPECT_TRUE(service_->profile()->GetPrefs()->GetBoolean(
+ prefs::kSyncHasSetupCompleted));
+}
diff --git a/chrome/browser/ui/webui/options/options_sync_setup_handler.cc b/chrome/browser/ui/webui/options/options_sync_setup_handler.cc
index 85ad94d..af88e2c 100644
--- a/chrome/browser/ui/webui/options/options_sync_setup_handler.cc
+++ b/chrome/browser/ui/webui/options/options_sync_setup_handler.cc
@@ -16,6 +16,24 @@ OptionsSyncSetupHandler::OptionsSyncSetupHandler(
OptionsSyncSetupHandler::~OptionsSyncSetupHandler() {
}
+void OptionsSyncSetupHandler::StepWizardForShowSetupUI() {
+ ProfileSyncService* service(ProfileSyncServiceFactory::
+ GetInstance()->GetForProfile(Profile::FromWebUI(web_ui())));
+ DCHECK(service);
+
+ // We should bring up either a login or a configure flow based on the state of
+ // sync.
+ if (service->HasSyncSetupCompleted()) {
+ if (service->IsPassphraseRequiredForDecryption()) {
+ service->get_wizard().Step(SyncSetupWizard::ENTER_PASSPHRASE);
+ } else {
+ service->get_wizard().Step(SyncSetupWizard::CONFIGURE);
+ }
+ } else {
+ service->get_wizard().Step(SyncSetupWizard::GetLoginState());
+ }
+}
+
void OptionsSyncSetupHandler::ShowSetupUI() {
// Show the Sync Setup page.
scoped_ptr<Value> page(Value::CreateStringValue("syncSetup"));
diff --git a/chrome/browser/ui/webui/options/options_sync_setup_handler.h b/chrome/browser/ui/webui/options/options_sync_setup_handler.h
index 679fbbd..3f761ac 100644
--- a/chrome/browser/ui/webui/options/options_sync_setup_handler.h
+++ b/chrome/browser/ui/webui/options/options_sync_setup_handler.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -15,6 +15,8 @@ class OptionsSyncSetupHandler : public SyncSetupHandler {
virtual ~OptionsSyncSetupHandler();
protected:
+ virtual void StepWizardForShowSetupUI() OVERRIDE;
+
virtual void ShowSetupUI() OVERRIDE;
};
diff --git a/chrome/browser/ui/webui/signin/login_ui_service.cc b/chrome/browser/ui/webui/signin/login_ui_service.cc
deleted file mode 100644
index fe957d0..0000000
--- a/chrome/browser/ui/webui/signin/login_ui_service.cc
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/webui/signin/login_ui_service.h"
-
-#include "chrome/browser/profiles/profile.h"
-#include "chrome/browser/ui/browser.h"
-#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/browser_window.h"
-#include "chrome/common/url_constants.h"
-#include "content/browser/renderer_host/render_view_host.h"
-#include "content/public/browser/render_view_host_delegate.h"
-#include "content/public/browser/web_contents.h"
-#include "content/public/browser/web_ui.h"
-
-LoginUIService::LoginUIService(Profile* profile)
- : ui_(NULL),
- profile_(profile) {
-}
-
-LoginUIService::~LoginUIService() {}
-
-void LoginUIService::SetLoginUI(content::WebUI* ui) {
- DCHECK(!current_login_ui() || current_login_ui() == ui);
- ui_ = ui;
-}
-
-void LoginUIService::LoginUIClosed(content::WebUI* ui) {
- if (current_login_ui() == ui)
- ui_ = NULL;
-}
-
-void LoginUIService::FocusLoginUI() {
- if (!ui_) {
- NOTREACHED() << "FocusLoginUI() called with no active login UI";
- return;
- }
- ui_->GetWebContents()->GetRenderViewHost()->delegate()->Activate();
-}
-
-void LoginUIService::ShowLoginUI() {
- if (ui_) {
- // We already have active login UI - make it visible.
- FocusLoginUI();
- return;
- }
-
- // Need to navigate to the settings page and display the UI.
- if (profile_) {
- Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
- if (!browser) {
- browser = Browser::Create(profile_);
- browser->ShowOptionsTab(chrome::kSyncSetupSubPage);
- browser->window()->Show();
- } else {
- browser->ShowOptionsTab(chrome::kSyncSetupSubPage);
- }
- }
-}
diff --git a/chrome/browser/ui/webui/signin/login_ui_service.h b/chrome/browser/ui/webui/signin/login_ui_service.h
deleted file mode 100644
index ae8817f6..0000000
--- a/chrome/browser/ui/webui/signin/login_ui_service.h
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_SIGNIN_LOGIN_UI_SERVICE_H_
-#define CHROME_BROWSER_UI_WEBUI_SIGNIN_LOGIN_UI_SERVICE_H_
-#pragma once
-
-#include "base/basictypes.h"
-#include "chrome/browser/profiles/profile_keyed_service.h"
-
-class Profile;
-
-namespace content {
-class WebUI;
-};
-
-// The LoginUIService helps track per-profile information for the login UI -
-// for example, whether there is login UI currently on-screen.
-class LoginUIService : public ProfileKeyedService {
- public:
- // Creates a LoginUIService associated with the passed |profile|. |profile|
- // is used to create a new browser in the case that ShowLoginUI() is invoked
- // when no browser windows are open (e.g. via the Mac menu bar).
- explicit LoginUIService(Profile* profile);
- virtual ~LoginUIService();
-
- // Gets the currently active login UI, or null if no login UI is active.
- content::WebUI* current_login_ui() const {
- return ui_;
- }
-
- // Sets the currently active login UI. It is illegal to call this if there is
- // already login UI visible.
- void SetLoginUI(content::WebUI* ui);
-
- // Called when login UI is closed. If the passed UI is the current login UI,
- // sets current_login_ui() to null.
- void LoginUIClosed(content::WebUI* ui);
-
- // Brings the current login UI for this profile to the foreground (it is an
- // error to call this if there is no visible login UI.
- void FocusLoginUI();
-
- // Displays the login dialog to the user.
- void ShowLoginUI();
-
- private:
- // Weak pointer to the currently active login UI, or null if none.
- content::WebUI* ui_;
-
- // Weak pointer to the profile this service is associated with.
- Profile* profile_;
-
- DISALLOW_COPY_AND_ASSIGN(LoginUIService);
-};
-
-
-#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_LOGIN_UI_SERVICE_H_
diff --git a/chrome/browser/ui/webui/signin/login_ui_service_factory.cc b/chrome/browser/ui/webui/signin/login_ui_service_factory.cc
deleted file mode 100644
index 5b0dac8..0000000
--- a/chrome/browser/ui/webui/signin/login_ui_service_factory.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
-
-#include "chrome/browser/prefs/pref_service.h"
-#include "chrome/browser/profiles/profile_dependency_manager.h"
-#include "chrome/browser/signin/signin_manager.h"
-#include "chrome/browser/ui/webui/signin/login_ui_service.h"
-#include "chrome/common/pref_names.h"
-
-LoginUIServiceFactory::LoginUIServiceFactory()
- : ProfileKeyedServiceFactory("LoginUIServiceFactory",
- ProfileDependencyManager::GetInstance()) {
-}
-
-LoginUIServiceFactory::~LoginUIServiceFactory() {}
-
-// static
-LoginUIService* LoginUIServiceFactory::GetForProfile(Profile* profile) {
- return static_cast<LoginUIService*>(
- GetInstance()->GetServiceForProfile(profile, true));
-}
-
-// static
-LoginUIServiceFactory* LoginUIServiceFactory::GetInstance() {
- return Singleton<LoginUIServiceFactory>::get();
-}
-
-ProfileKeyedService* LoginUIServiceFactory::BuildServiceInstanceFor(
- Profile* profile) const {
- LoginUIService* service = new LoginUIService(profile);
- return service;
-}
-
diff --git a/chrome/browser/ui/webui/signin/login_ui_service_factory.h b/chrome/browser/ui/webui/signin/login_ui_service_factory.h
deleted file mode 100644
index c9a60e0..0000000
--- a/chrome/browser/ui/webui/signin/login_ui_service_factory.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_SIGNIN_LOGIN_UI_SERVICE_FACTORY_H_
-#define CHROME_BROWSER_UI_WEBUI_SIGNIN_LOGIN_UI_SERVICE_FACTORY_H_
-#pragma once
-
-#include "base/memory/singleton.h"
-#include "chrome/browser/profiles/profile_keyed_service_factory.h"
-
-class LoginUIService;
-class Profile;
-
-// Singleton that owns all LoginUIServices and associates them with
-// Profiles. Listens for the Profile's destruction notification and cleans up
-// the associated LoginUIService.
-class LoginUIServiceFactory : public ProfileKeyedServiceFactory {
- public:
- // Returns the instance of LoginUIService associated with this profile
- // (creating one if none exists). Returns NULL if this profile cannot have a
- // LoginUIService (for example, if |profile| is incognito).
- static LoginUIService* GetForProfile(Profile* profile);
-
- // Returns an instance of the LoginUIServiceFactory singleton.
- static LoginUIServiceFactory* GetInstance();
-
- private:
- friend struct DefaultSingletonTraits<LoginUIServiceFactory>;
-
- LoginUIServiceFactory();
- virtual ~LoginUIServiceFactory();
-
- // ProfileKeyedServiceFactory:
- virtual ProfileKeyedService* BuildServiceInstanceFor(
- Profile* profile) const OVERRIDE;
-
- DISALLOW_COPY_AND_ASSIGN(LoginUIServiceFactory);
-};
-
-#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_LOGIN_UI_SERVICE_FACTORY_H_
diff --git a/chrome/browser/ui/webui/signin/signin_tracker.cc b/chrome/browser/ui/webui/signin/signin_tracker.cc
deleted file mode 100644
index b58ff45..0000000
--- a/chrome/browser/ui/webui/signin/signin_tracker.cc
+++ /dev/null
@@ -1,98 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/ui/webui/signin/signin_tracker.h"
-
-#include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/browser/sync/profile_sync_service_factory.h"
-#include "chrome/common/chrome_notification_types.h"
-#include "content/public/browser/notification_details.h"
-#include "content/public/browser/notification_source.h"
-
-SigninTracker::SigninTracker(Profile* profile, Observer* observer)
- : state_(WAITING_FOR_GAIA_VALIDATION),
- profile_(profile),
- observer_(observer),
- credentials_valid_(false) {
- DCHECK(observer_);
- // Register for notifications from the SigninManager.
- registrar_.Add(this,
- chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL,
- content::Source<Profile>(profile_));
- registrar_.Add(this,
- chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED,
- content::Source<Profile>(profile_));
-
- // Also listen for notifications from the various signed in services (only
- // sync for now).
- ProfileSyncService* service =
- ProfileSyncServiceFactory::GetForProfile(profile_);
- service->AddObserver(this);
-}
-
-SigninTracker::~SigninTracker() {
- ProfileSyncService* service =
- ProfileSyncServiceFactory::GetForProfile(profile_);
- service->RemoveObserver(this);
-}
-
-void SigninTracker::Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) {
- // We should not get more than one of these notifications.
- DCHECK_EQ(state_, WAITING_FOR_GAIA_VALIDATION);
- switch (type) {
- case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL:
- state_ = SERVICES_INITIALIZING;
- observer_->GaiaCredentialsValid();
- break;
- case chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED:
- state_ = WAITING_FOR_GAIA_VALIDATION;
- observer_->SigninFailed();
- break;
- default:
- NOTREACHED();
- }
-}
-
-// Called when the ProfileSyncService state changes.
-void SigninTracker::OnStateChanged() {
- if (state_ != SERVICES_INITIALIZING) {
- // Ignore service updates until after our GAIA credentials are validated.
- return;
- }
- // Wait until all of our services are logged in. For now this just means sync.
- // Long term, we should separate out service auth failures from the signin
- // process, but for the current UI flow we'll validate service signin status
- // also.
- // TODO(atwilson): Move the code to wait for app notification oauth tokens out
- // of ProfileSyncService and over to here (http://crbug.com/114209).
- ProfileSyncService* service =
- ProfileSyncServiceFactory::GetForProfile(profile_);
- if (service->waiting_for_auth()) {
- // Still waiting for an auth token to come in so stay in the INITIALIZING
- // state (we do this to avoid triggering an early signin error in the case
- // where there's a previous auth error in the sync service that hasn't
- // been cleared yet).
- return;
- }
-
- if (!AreServicesSignedIn(profile_)) {
- state_ = WAITING_FOR_GAIA_VALIDATION;
- observer_->SigninFailed();
- } else if (service->sync_initialized()) {
- state_ = SIGNIN_COMPLETE;
- observer_->SigninSuccess();
- }
-}
-
-// static
-bool SigninTracker::AreServicesSignedIn(Profile* profile) {
- ProfileSyncService* service =
- ProfileSyncServiceFactory::GetForProfile(profile);
- return (service->AreCredentialsAvailable() &&
- service->GetAuthError().state() == GoogleServiceAuthError::NONE &&
- !service->unrecoverable_error_detected());
-}
-
diff --git a/chrome/browser/ui/webui/signin/signin_tracker.h b/chrome/browser/ui/webui/signin/signin_tracker.h
deleted file mode 100644
index 1365bef..0000000
--- a/chrome/browser/ui/webui/signin/signin_tracker.h
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_TRACKER_H_
-#define CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_TRACKER_H_
-
-#include "chrome/browser/sync/profile_sync_service_observer.h"
-#include "content/public/browser/notification_observer.h"
-#include "content/public/browser/notification_registrar.h"
-#include "content/public/browser/notification_types.h"
-
-class Profile;
-
-// The signin flow logic is spread across several classes with varying
-// responsibilities:
-//
-// SigninTracker (this class) - This class listens to notifications from various
-// services (SigninManager, ProfileSyncService, etc) and coalesces them into
-// notifications for the UI layer. This is the class that encapsulates the logic
-// that determines whether a user is fully logged in or not, and exposes
-// callbacks to SyncSetupHandler (login failed, login succeeded, services
-// started up) to help drive the login wizard.
-//
-// SyncSetupHandler - This class is primarily responsible for interacting with
-// the web UI for performing system login and sync configuration. Receives
-// callbacks from the UI when the user wishes to initiate a login, and
-// translates system state (login errors, etc) into the appropriate calls into
-// the UI to reflect this status to the user. Various subclasses
-// (OptionsSyncSetupHandler and SyncPromoHandler provide different UIs to the
-// user, but the core logic lies in the base SyncSetupHandler class).
-//
-// LoginUIService - Our desktop UI flows rely on having only a single login flow
-// visible to the user at once. This is achieved via LoginUIService (a
-// ProfileKeyedService that keeps track of the currently visible login UI).
-//
-// SigninManager - Records the currently-logged-in user and handles all
-// interaction with the GAIA backend during the signin process. Unlike
-// SigninTracker, SigninManager only knows about the GAIA login state and is
-// not aware of the state of any signed in services.
-//
-// TokenService - Uses credentials provided by SigninManager to generate tokens
-// for all signed-in services in Chrome.
-//
-// ProfileSyncService - Provides the external API for interacting with the
-// sync framework. Listens for notifications from the TokenService to know
-// when to startup sync, and provides an Observer interface to notify the UI
-// layer of changes in sync state so they can be reflected in the UI.
-class SigninTracker : public ProfileSyncServiceObserver,
- public content::NotificationObserver {
- public:
- class Observer {
- public:
- // The GAIA credentials entered by the user have been validated.
- virtual void GaiaCredentialsValid() = 0;
-
- // The signin attempt failed. If this is called after GaiaCredentialsValid()
- // then it means there was an error launching one of the dependent services.
- virtual void SigninFailed() = 0;
-
- // The signin attempt succeeded.
- virtual void SigninSuccess() = 0;
- };
-
- // Creates a SigninTracker that tracks the signin status on the passed
- // |profile|, and notifies the |observer| on status changes. |observer| must
- // be non-null and must outlive the SigninTracker.
- SigninTracker(Profile* profile, Observer* observer);
- virtual ~SigninTracker();
-
- // content::NotificationObserver implementation.
- virtual void Observe(int type,
- const content::NotificationSource& source,
- const content::NotificationDetails& details) OVERRIDE;
-
- // ProfileSyncServiceObserver implementation.
- virtual void OnStateChanged() OVERRIDE;
-
- // Returns true if the various authenticated services are properly signed in
- // (no auth errors, etc).
- static bool AreServicesSignedIn(Profile* profile);
-
- private:
- // The various states the login process can be in.
- enum LoginState {
- WAITING_FOR_GAIA_VALIDATION,
- SERVICES_INITIALIZING,
- SIGNIN_COMPLETE
- };
-
- // The current state of the login process.
- LoginState state_;
-
- // The profile whose signin status we are tracking.
- Profile* profile_;
-
- // Weak pointer to the observer we call when the signin state changes.
- Observer* observer_;
-
- // Set to true when SigninManager has validated our credentials.
- bool credentials_valid_;
-
- // Used to listen to notifications from the SigninManager.
- content::NotificationRegistrar registrar_;
-
- DISALLOW_COPY_AND_ASSIGN(SigninTracker);
-};
-
-#endif // CHROME_BROWSER_UI_WEBUI_SIGNIN_SIGNIN_TRACKER_H_
-
diff --git a/chrome/browser/ui/webui/sync_promo/sync_promo_handler.cc b/chrome/browser/ui/webui/sync_promo/sync_promo_handler.cc
index 8710fad..90029ea 100644
--- a/chrome/browser/ui/webui/sync_promo/sync_promo_handler.cc
+++ b/chrome/browser/ui/webui/sync_promo/sync_promo_handler.cc
@@ -127,8 +127,14 @@ void SyncPromoHandler::RegisterMessages() {
SyncSetupHandler::RegisterMessages();
}
-void SyncPromoHandler::RecordSignin() {
+void SyncPromoHandler::ShowGaiaSuccessAndClose() {
sync_promo_trial::RecordUserSignedIn(web_ui());
+ SyncSetupHandler::ShowGaiaSuccessAndClose();
+}
+
+void SyncPromoHandler::ShowGaiaSuccessAndSettingUp() {
+ sync_promo_trial::RecordUserSignedIn(web_ui());
+ SyncSetupHandler::ShowGaiaSuccessAndSettingUp();
}
void SyncPromoHandler::ShowConfigure(const base::DictionaryValue& args) {
@@ -175,7 +181,19 @@ void SyncPromoHandler::Observe(int type,
}
}
+void SyncPromoHandler::StepWizardForShowSetupUI() {
+}
+
void SyncPromoHandler::ShowSetupUI() {
+ // SyncSetupWizard::Step should be called in StepWizardForShowSetupUI above,
+ // but it causes the sync promo page to not set focus properly to the login
+ // email address. This happens because focus is lost between the call to
+ // StepWizardForShowSetupUI and ShowSetupUI.
+ // TODO(binji): Move this function back and fix the focus the right way.
+ ProfileSyncService* service =
+ ProfileSyncServiceFactory::GetInstance()->GetForProfile(
+ Profile::FromWebUI(web_ui()));
+ service->get_wizard().Step(SyncSetupWizard::GetLoginState());
}
void SyncPromoHandler::HandleCloseSyncPromo(const base::ListValue* args) {
diff --git a/chrome/browser/ui/webui/sync_promo/sync_promo_handler.h b/chrome/browser/ui/webui/sync_promo/sync_promo_handler.h
index f83d8de..9bbd721 100644
--- a/chrome/browser/ui/webui/sync_promo/sync_promo_handler.h
+++ b/chrome/browser/ui/webui/sync_promo/sync_promo_handler.h
@@ -25,6 +25,8 @@ class SyncPromoHandler : public SyncSetupHandler {
virtual void RegisterMessages() OVERRIDE;
// SyncSetupFlowHandler implementation.
+ virtual void ShowGaiaSuccessAndClose() OVERRIDE;
+ virtual void ShowGaiaSuccessAndSettingUp() OVERRIDE;
virtual void ShowConfigure(const base::DictionaryValue& args) OVERRIDE;
// content::NotificationObserver implementation.
@@ -33,9 +35,9 @@ class SyncPromoHandler : public SyncSetupHandler {
const content::NotificationDetails& details) OVERRIDE;
protected:
- virtual void ShowSetupUI() OVERRIDE;
+ virtual void StepWizardForShowSetupUI() OVERRIDE;
- virtual void RecordSignin() OVERRIDE;
+ virtual void ShowSetupUI() OVERRIDE;
private:
// JavaScript callback handler to close the sync promo.
diff --git a/chrome/browser/ui/webui/sync_promo/sync_promo_handler2.cc b/chrome/browser/ui/webui/sync_promo/sync_promo_handler2.cc
index 1c6e522..b638cdc 100644
--- a/chrome/browser/ui/webui/sync_promo/sync_promo_handler2.cc
+++ b/chrome/browser/ui/webui/sync_promo/sync_promo_handler2.cc
@@ -181,6 +181,13 @@ void SyncPromoHandler2::Observe(int type,
}
}
+void SyncPromoHandler2::StepWizardForShowSetupUI() {
+ ProfileSyncService* service =
+ ProfileSyncServiceFactory::GetInstance()->GetForProfile(
+ Profile::FromWebUI(web_ui_));
+ service->get_wizard().Step(SyncSetupWizard::GetLoginState());
+}
+
void SyncPromoHandler2::ShowSetupUI() {
// We don't need to do anything here; The UI for the sync promo is already
// displayed.
diff --git a/chrome/browser/ui/webui/sync_promo/sync_promo_handler2.h b/chrome/browser/ui/webui/sync_promo/sync_promo_handler2.h
index 7d86cd2..23572be 100644
--- a/chrome/browser/ui/webui/sync_promo/sync_promo_handler2.h
+++ b/chrome/browser/ui/webui/sync_promo/sync_promo_handler2.h
@@ -38,6 +38,8 @@ class SyncPromoHandler2 : public SyncSetupHandler2 {
const content::NotificationDetails& details) OVERRIDE;
protected:
+ virtual void StepWizardForShowSetupUI() OVERRIDE;
+
virtual void ShowSetupUI() OVERRIDE;
private:
diff --git a/chrome/browser/ui/webui/sync_setup_handler.cc b/chrome/browser/ui/webui/sync_setup_handler.cc
index 7482a80..1dab8c8 100644
--- a/chrome/browser/ui/webui/sync_setup_handler.cc
+++ b/chrome/browser/ui/webui/sync_setup_handler.cc
@@ -16,15 +16,12 @@
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/profiles/profile_metrics.h"
#include "chrome/browser/signin/signin_manager.h"
-#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_service_factory.h"
#include "chrome/browser/sync/protocol/service_constants.h"
#include "chrome/browser/sync/sync_setup_flow.h"
#include "chrome/browser/sync/util/oauth.h"
#include "chrome/browser/ui/browser_list.h"
-#include "chrome/browser/ui/webui/signin/login_ui_service.h"
-#include "chrome/browser/ui/webui/signin/login_ui_service_factory.h"
#include "chrome/browser/ui/webui/sync_promo/sync_promo_ui.h"
#include "chrome/common/net/gaia/gaia_constants.h"
#include "chrome/common/url_constants.h"
@@ -185,12 +182,9 @@ SyncSetupHandler::SyncSetupHandler(ProfileManager* profile_manager)
}
SyncSetupHandler::~SyncSetupHandler() {
- // Just exit if running unit tests (no actual WebUI is attached).
- if (!web_ui())
- return;
-
// This case is hit when the user performs a back navigation.
- CloseSyncSetup();
+ if (flow_)
+ flow_->OnDialogClosed("");
}
void SyncSetupHandler::GetLocalizedValues(DictionaryValue* localized_strings) {
@@ -355,41 +349,16 @@ void SyncSetupHandler::GetStaticLocalizedValues(
RegisterTitle(localized_strings, "syncSetupOverlay", IDS_SYNC_SETUP_TITLE);
}
-void SyncSetupHandler::StartConfigureSync() {
- DCHECK(!flow_);
- // We only get here if we're signed in, so no longer need our SigninTracker.
- signin_tracker_.reset();
- ProfileSyncService* service = GetSyncService();
- service->get_wizard().Step(
- service->HasSyncSetupCompleted() ?
- SyncSetupWizard::CONFIGURE : SyncSetupWizard::SYNC_EVERYTHING);
-
- // Attach this as the sync setup handler.
- if (!service->get_wizard().AttachSyncSetupHandler(this)) {
- LOG(ERROR) << "SyncSetupHandler attach failed!";
- CloseOverlay();
- }
-}
-
-bool SyncSetupHandler::IsActiveLogin() const {
- LoginUIService* service = GetLoginUIService();
- return service->current_login_ui() == web_ui();
+void SyncSetupHandler::Initialize() {
}
void SyncSetupHandler::OnGetOAuthTokenSuccess(const std::string& oauth_token) {
- Profile* profile = Profile::FromWebUI(web_ui());
- SigninManager* signin = GetSignin();
- GaiaOAuthFetcher* fetcher = new GaiaOAuthFetcher(
- signin,
- profile->GetRequestContext(),
- profile,
- GaiaConstants::kSyncServiceOAuth);
- signin->StartOAuthSignIn(oauth_token, fetcher);
+ flow_->OnUserSubmittedOAuth(oauth_token);
}
void SyncSetupHandler::OnGetOAuthTokenFailure(
const GoogleServiceAuthError& error) {
- CloseOverlay();
+ CloseSyncSetup();
}
void SyncSetupHandler::RegisterMessages() {
@@ -419,80 +388,37 @@ void SyncSetupHandler::RegisterMessages() {
base::Unretained(this)));
}
-SigninManager* SyncSetupHandler::GetSignin() const {
- Profile* profile = Profile::FromWebUI(web_ui());
- return SigninManagerFactory::GetForProfile(profile);
-}
+// Ideal(?) solution here would be to mimic the ClientLogin overlay. Since
+// this UI must render an external URL, that overlay cannot be used directly.
+// The current implementation is functional, but fails asthetically.
+// TODO(rickcam): Bug 90711: Update UI for OAuth sign-in flow
+void SyncSetupHandler::ShowOAuthLogin() {
+ DCHECK(browser_sync::IsUsingOAuth());
-void SyncSetupHandler::DisplayGaiaLogin(bool fatal_error) {
- DisplayGaiaLoginWithErrorMessage(string16(), fatal_error);
+ Profile* profile = Profile::FromWebUI(web_ui());
+ oauth_login_.reset(new GaiaOAuthFetcher(this,
+ profile->GetRequestContext(),
+ profile,
+ GaiaConstants::kSyncServiceOAuth));
+ oauth_login_->SetAutoFetchLimit(GaiaOAuthFetcher::OAUTH1_REQUEST_TOKEN);
+ oauth_login_->StartGetOAuthToken();
}
-void SyncSetupHandler::DisplayGaiaLoginWithErrorMessage(
- const string16& error_message, bool fatal_error) {
+void SyncSetupHandler::ShowGaiaLogin(const DictionaryValue& args) {
DCHECK(!browser_sync::IsUsingOAuth());
- // If we're exiting from sync config (due to some kind of error), notify
- // SyncSetupFlow.
- if (flow_) {
- flow_->OnDialogClosed(std::string());
- flow_ = NULL;
- }
-
- // Setup args for the GAIA login screen:
- // error_message: custom error message to display
- // error: GoogleServiceAuthError from previous login attempt (0 if none)
- // user: The email the user most recently entered.
- // editable_user: Whether the username field should be editable.
- SigninManager* signin = GetSignin();
- std::string user;
- int error;
- bool editable_user;
- if (!last_attempted_user_email_.empty()) {
- // This is a repeat of a login attempt.
- user = last_attempted_user_email_;
- error = signin->GetLoginAuthError().state();
- editable_user = true;
- } else {
- // Fresh login attempt - lock in the authenticated username if there is
- // one (don't let the user change it).
- user = signin->GetAuthenticatedUsername();
- error = 0;
- editable_user = user.empty();
- }
- DictionaryValue args;
- args.SetString("user", user);
- args.SetInteger("error", error);
- args.SetBoolean("editable_user", editable_user);
- if (!error_message.empty())
- args.SetString("error_message", error_message);
- if (fatal_error)
- args.SetBoolean("fatalError", true);
StringValue page("login");
web_ui()->CallJavascriptFunction(
"SyncSetupOverlay.showSyncSetupPage", page, args);
}
-void SyncSetupHandler::RecordSignin() {
- // By default, do nothing - subclasses can override.
-}
-
-void SyncSetupHandler::DisplayGaiaSuccessAndClose() {
- // TODO(atwilson): Can we remove this now that we've changed the signin flow?
- RecordSignin();
+void SyncSetupHandler::ShowGaiaSuccessAndClose() {
web_ui()->CallJavascriptFunction("SyncSetupOverlay.showSuccessAndClose");
}
-void SyncSetupHandler::DisplayGaiaSuccessAndSettingUp() {
- RecordSignin();
+void SyncSetupHandler::ShowGaiaSuccessAndSettingUp() {
web_ui()->CallJavascriptFunction("SyncSetupOverlay.showSuccessAndSettingUp");
}
-void SyncSetupHandler::ShowFatalError() {
- // For now, just send the user back to the login page. Ultimately we may want
- // to give different feedback (especially for chromeos).
- DisplayGaiaLogin(true);
-}
-
void SyncSetupHandler::ShowConfigure(const DictionaryValue& args) {
StringValue page("configure");
web_ui()->CallJavascriptFunction(
@@ -521,7 +447,9 @@ void SyncSetupHandler::ShowSetupDone(const string16& user) {
SyncPromoUI::SetUserSkippedSyncPromo(Profile::FromWebUI(web_ui()));
Profile* profile = Profile::FromWebUI(web_ui());
- ProfileSyncService* service = GetSyncService();
+ ProfileSyncService* service =
+ ProfileSyncServiceFactory::GetInstance()->GetForProfile(
+ profile);
if (!service->HasSyncSetupCompleted()) {
FilePath profile_file_path = profile->GetPath();
ProfileMetrics::LogProfileSyncSignIn(profile_file_path);
@@ -560,58 +488,12 @@ void SyncSetupHandler::HandleSubmitAuth(const ListValue* args) {
string16 error_message;
if (!IsLoginAuthDataValid(username, &error_message)) {
- DisplayGaiaLoginWithErrorMessage(error_message, false);
- return;
- }
-
- TryLogin(username, password, captcha, access_code);
-}
-
-void SyncSetupHandler::TryLogin(const std::string& username,
- const std::string& password,
- const std::string& captcha,
- const std::string& access_code) {
- DCHECK(IsActiveLogin());
- // Make sure we are listening for signin traffic.
- if (!signin_tracker_.get())
- signin_tracker_.reset(new SigninTracker(Profile::FromWebUI(web_ui()),
- this));
-
- last_attempted_user_email_ = username;
- // If we're just being called to provide an ASP, then pass it to the
- // SigninManager and wait for the next step.
- SigninManager* signin = GetSignin();
- if (!access_code.empty()) {
- signin->ProvideSecondFactorAccessCode(access_code);
+ ShowLoginErrorMessage(error_message);
return;
}
- // Kick off a sign-in through the signin manager.
- signin->StartSignIn(username,
- password,
- signin->GetLoginAuthError().captcha().token,
- captcha);
-}
-
-void SyncSetupHandler::GaiaCredentialsValid() {
- DCHECK(IsActiveLogin());
- // Gaia credentials are valid - update the UI.
- DisplayGaiaSuccessAndSettingUp();
-}
-
-void SyncSetupHandler::SigninFailed() {
- // Got a failed signin - this is either just a typical auth error, or a
- // sync error (treat sync errors as "fatal errors" - i.e. non-auth errors).
- DisplayGaiaLogin(GetSyncService()->unrecoverable_error_detected());
-}
-
-ProfileSyncService* SyncSetupHandler::GetSyncService() const {
- return ProfileSyncServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()));
-}
-
-void SyncSetupHandler::SigninSuccess() {
- DCHECK(GetSyncService()->sync_initialized());
- StartConfigureSync();
+ if (flow_)
+ flow_->OnUserSubmittedAuth(username, password, captcha, access_code);
}
void SyncSetupHandler::HandleConfigure(const ListValue* args) {
@@ -681,7 +563,9 @@ void SyncSetupHandler::HandleAttachHandler(const ListValue* args) {
void SyncSetupHandler::HandleShowErrorUI(const ListValue* args) {
DCHECK(!flow_);
- ProfileSyncService* service = GetSyncService();
+ Profile* profile = Profile::FromWebUI(web_ui());
+ ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
+ GetForProfile(profile);
DCHECK(service);
service->ShowErrorUI();
@@ -689,56 +573,52 @@ void SyncSetupHandler::HandleShowErrorUI(const ListValue* args) {
void SyncSetupHandler::HandleShowSetupUI(const ListValue* args) {
DCHECK(!flow_);
- OpenSyncSetup();
+ if (FocusExistingWizard()) {
+ CloseOverlay();
+ return;
+ }
+
+ StepWizardForShowSetupUI();
+ ShowSetupUI();
}
void SyncSetupHandler::CloseSyncSetup() {
- // TODO(atwilson): Move UMA tracking of signin events out of sync module.
- if (IsActiveLogin()) {
- if (signin_tracker_.get()) {
- ProfileSyncService::SyncEvent(
- ProfileSyncService::CANCEL_DURING_SIGNON);
- } else if (!flow_) {
- ProfileSyncService::SyncEvent(
- ProfileSyncService::CANCEL_FROM_SIGNON_WITHOUT_AUTH);
- }
- }
-
if (flow_) {
flow_->OnDialogClosed(std::string());
flow_ = NULL;
}
- signin_tracker_.reset();
- GetLoginUIService()->LoginUIClosed(web_ui());
}
void SyncSetupHandler::OpenSyncSetup() {
- ProfileSyncService* service = GetSyncService();
+ DCHECK(!flow_);
+
+ Profile* profile = Profile::FromWebUI(web_ui());
+ ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
+ GetForProfile(profile);
if (!service) {
// If there's no sync service, the user tried to manually invoke a syncSetup
// URL, but sync features are disabled. We need to close the overlay for
// this (rare) case.
- DLOG(WARNING) << "Closing sync UI because sync is disabled";
CloseOverlay();
return;
}
- // If the wizard is already visible, just focus that one.
- if (FocusExistingWizardIfPresent()) {
- if (!IsActiveLogin())
- CloseOverlay();
+ // If the wizard is already visible, it must be attached to another flow
+ // handler.
+ if (FocusExistingWizard()) {
+ CloseOverlay();
return;
}
- GetLoginUIService()->SetLoginUI(web_ui());
+ // The wizard must be stepped before attaching. Allow subclasses to step the
+ // wizard to appropriate state.
+ StepWizardForShowSetupUI();
- if (!SigninTracker::AreServicesSignedIn(Profile::FromWebUI(web_ui()))) {
- // User is not logged in - need to display login UI.
- DisplayGaiaLogin(false);
- } else {
- // User is already logged in. They must have brought up the config wizard
- // via the "Advanced..." button or the wrench menu.
- StartConfigureSync();
+ // Attach this as the sync setup handler, before calling ShowSetupUI().
+ if (!service->get_wizard().AttachSyncSetupHandler(this)) {
+ LOG(ERROR) << "SyncSetupHandler attach failed!";
+ CloseOverlay();
+ return;
}
ShowSetupUI();
@@ -746,20 +626,22 @@ void SyncSetupHandler::OpenSyncSetup() {
// Private member functions.
-bool SyncSetupHandler::FocusExistingWizardIfPresent() {
- LoginUIService* service = GetLoginUIService();
- if (!service->current_login_ui())
+bool SyncSetupHandler::FocusExistingWizard() {
+ Profile* profile = Profile::FromWebUI(web_ui());
+ ProfileSyncService* service = ProfileSyncServiceFactory::GetInstance()->
+ GetForProfile(profile);
+ if (!service)
return false;
- service->FocusLoginUI();
- return true;
-}
-LoginUIService* SyncSetupHandler::GetLoginUIService() const {
- return LoginUIServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()));
+ // If the wizard is already visible, focus it.
+ if (service->get_wizard().IsVisible()) {
+ service->get_wizard().Focus();
+ return true;
+ }
+ return false;
}
void SyncSetupHandler::CloseOverlay() {
- CloseSyncSetup();
web_ui()->CallJavascriptFunction("OptionsPage.closeOverlay");
}
@@ -789,3 +671,11 @@ bool SyncSetupHandler::IsLoginAuthDataValid(const std::string& username,
return true;
}
+
+void SyncSetupHandler::ShowLoginErrorMessage(const string16& error_message) {
+ DCHECK(flow_);
+ DictionaryValue args;
+ flow_->GetArgsForGaiaLogin(&args);
+ args.SetString("error_message", error_message);
+ ShowGaiaLogin(args);
+}
diff --git a/chrome/browser/ui/webui/sync_setup_handler.h b/chrome/browser/ui/webui/sync_setup_handler.h
index 0e67313..90e1127 100644
--- a/chrome/browser/ui/webui/sync_setup_handler.h
+++ b/chrome/browser/ui/webui/sync_setup_handler.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -10,17 +10,13 @@
#include "chrome/browser/net/gaia/gaia_oauth_fetcher.h"
#include "chrome/browser/sync/sync_setup_flow_handler.h"
#include "chrome/browser/ui/webui/options/options_ui.h"
-#include "chrome/browser/ui/webui/signin/signin_tracker.h"
-class LoginUIService;
-class SigninManager;
class SyncSetupFlow;
class ProfileManager;
class SyncSetupHandler : public GaiaOAuthConsumer,
public OptionsPageUIHandler,
- public SyncSetupFlowHandler,
- public SigninTracker::Observer {
+ public SyncSetupFlowHandler {
public:
// Constructs a new SyncSetupHandler. |profile_manager| may be NULL.
explicit SyncSetupHandler(ProfileManager* profile_manager);
@@ -29,11 +25,15 @@ class SyncSetupHandler : public GaiaOAuthConsumer,
// OptionsPageUIHandler implementation.
virtual void GetLocalizedValues(base::DictionaryValue* localized_strings)
OVERRIDE;
+ virtual void Initialize() OVERRIDE;
virtual void RegisterMessages() OVERRIDE;
// SyncSetupFlowHandler implementation.
+ virtual void ShowOAuthLogin() OVERRIDE;
+ virtual void ShowGaiaLogin(const base::DictionaryValue& args) OVERRIDE;
+ virtual void ShowGaiaSuccessAndClose() OVERRIDE;
+ virtual void ShowGaiaSuccessAndSettingUp() OVERRIDE;
virtual void ShowConfigure(const base::DictionaryValue& args) OVERRIDE;
- virtual void ShowFatalError() OVERRIDE;
virtual void ShowPassphraseEntry(const base::DictionaryValue& args) OVERRIDE;
virtual void ShowSettingUp() OVERRIDE;
virtual void ShowSetupDone(const string16& user) OVERRIDE;
@@ -45,11 +45,6 @@ class SyncSetupHandler : public GaiaOAuthConsumer,
virtual void OnGetOAuthTokenFailure(
const GoogleServiceAuthError& error) OVERRIDE;
- // SigninTracker::Observer implementation
- virtual void GaiaCredentialsValid() OVERRIDE;
- virtual void SigninFailed() OVERRIDE;
- virtual void SigninSuccess() OVERRIDE;
-
static void GetStaticLocalizedValues(
base::DictionaryValue* localized_strings,
content::WebUI* web_ui);
@@ -86,50 +81,17 @@ class SyncSetupHandler : public GaiaOAuthConsumer,
SyncSetupFlow* flow() { return flow_; }
+ // Subclasses must implement to step the SyncSetupWizard to the correct state
+ // before showing the Setup UI.
+ virtual void StepWizardForShowSetupUI() = 0;
+
// Subclasses must implement this to show the setup UI that's appropriate
// for the page this is contained in.
virtual void ShowSetupUI() = 0;
- // Overridden by subclasses (like SyncPromoHandler) to log stats about the
- // user's signin activity.
- virtual void RecordSignin();
-
private:
- // Helper routine that gets the ProfileSyncService associated with the parent
- // profile.
- class ProfileSyncService* GetSyncService() const;
-
- // Start up the sync setup configuration wizard.
- void StartConfigureSync();
-
- // Shows the GAIA login success page then exits.
- void DisplayGaiaSuccessAndClose();
-
- // Displays the GAIA login success page then transitions to sync setup.
- void DisplayGaiaSuccessAndSettingUp();
-
- // Displays the GAIA login form. If |fatal_error| is true, displays the fatal
- // error UI.
- void DisplayGaiaLogin(bool fatal_error);
-
- // Displays the GAIA login form with a custom error message (used for errors
- // like "email address already in use by another profile"). No message
- // displayed if |error_message| is empty. Displays fatal error UI if
- // |fatal_error| = true.
- void DisplayGaiaLoginWithErrorMessage(const string16& error_message,
- bool fatal_error);
-
- // Returns true if we're the active login object.
- bool IsActiveLogin() const;
-
- // Initiates a login via the signin manager.
- void TryLogin(const std::string& username,
- const std::string& password,
- const std::string& captcha,
- const std::string& access_code);
-
// If a wizard already exists, focus it and return true.
- bool FocusExistingWizardIfPresent();
+ bool FocusExistingWizard();
// Invokes the javascript call to close the setup overlay.
void CloseOverlay();
@@ -140,26 +102,15 @@ class SyncSetupHandler : public GaiaOAuthConsumer,
bool IsLoginAuthDataValid(const std::string& username,
string16* error_message);
- // Returns the SigninManager for the parent profile. Overridden by tests.
- virtual SigninManager* GetSignin() const;
-
- // Returns the LoginUIService for the parent profile. Overridden by tests.
- virtual LoginUIService* GetLoginUIService() const;
-
- // The SigninTracker object used to determine when the user has fully signed
- // in (this requires waiting for various services to initialize and tracking
- // errors from multiple sources). Should only be non-null while the login UI
- // is visible.
- scoped_ptr<SigninTracker> signin_tracker_;
+ // Displays the given error message in the login UI.
+ void ShowLoginErrorMessage(const string16& error_message);
// Weak reference.
SyncSetupFlow* flow_;
+ scoped_ptr<GaiaOAuthFetcher> oauth_login_;
// Weak reference to the profile manager.
ProfileManager* const profile_manager_;
- // Cache of the last name the client attempted to authenticate.
- std::string last_attempted_user_email_;
-
DISALLOW_COPY_AND_ASSIGN(SyncSetupHandler);
};
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index d0cf916..cf7efd7 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -4177,12 +4177,6 @@
'browser/ui/webui/sessions_ui.h',
'browser/ui/webui/shared_resources_data_source.cc',
'browser/ui/webui/shared_resources_data_source.h',
- 'browser/ui/webui/signin/login_ui_service.cc',
- 'browser/ui/webui/signin/login_ui_service.h',
- 'browser/ui/webui/signin/login_ui_service_factory.cc',
- 'browser/ui/webui/signin/login_ui_service_factory.h',
- 'browser/ui/webui/signin/signin_tracker.cc',
- 'browser/ui/webui/signin/signin_tracker.h',
'browser/ui/webui/ssl_client_certificate_selector_webui.cc',
'browser/ui/webui/ssl_client_certificate_selector_webui.h',
'browser/ui/webui/sync_internals_ui.cc',