diff options
author | rbyers@chromium.org <rbyers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-15 14:15:38 +0000 |
---|---|---|
committer | rbyers@chromium.org <rbyers@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-02-15 14:15:38 +0000 |
commit | 977268f00da9e10a906c0cf37984b6c9a5b768c0 (patch) | |
tree | 05ffe66cd230b2958f3e94e375a57819ec905704 | |
parent | 604a61037af0a3ebada8c7165144d991b4cb2282 (diff) | |
download | chromium_src-977268f00da9e10a906c0cf37984b6c9a5b768c0.zip chromium_src-977268f00da9e10a906c0cf37984b6c9a5b768c0.tar.gz chromium_src-977268f00da9e10a906c0cf37984b6c9a5b768c0.tar.bz2 |
Revert 122030 - Start moving signin code out of browser/sync.
Reverting due to crashes in SyncSetupHandler::CloseSyncSetup during
BrowserGuestSessionNavigatorTest.Disposition_Settings_UseIncognitoWindow on
ChromeOS bots.
---
This starts to break the dependency between sync and the signin UI.
BUG=111859
TEST=run ALL the login test cases!
Review URL: http://codereview.chromium.org/9295044
TBR=atwilson@chromium.org
Review URL: https://chromiumcodereview.appspot.com/9405004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@122080 0039d316-1c4b-4281-b951-d872f2087c98
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', |