Commit d148a566 authored by rogerta@chromium.org's avatar rogerta@chromium.org

Delay loading the NTP after sign in until MergeSession has been performed in

the content area.

Also fixes a bug where the account reconcilor would run concurrent
MergeSessions on startup if there are multiple accounts connected to the
profile.  This led to a race condition that could mess up the gaia cookie.

Added more tests to  GoogleAutoLoginHelper.

BUG=315269

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244044 0039d316-1c4b-4281-b951-d872f2087c98
parent d948c115
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include "chrome/browser/browsing_data/browsing_data_remover.h" #include "chrome/browser/browsing_data/browsing_data_remover.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/android_profile_oauth2_token_service.h" #include "chrome/browser/signin/android_profile_oauth2_token_service.h"
#include "chrome/browser/signin/google_auto_login_helper.h"
#include "chrome/browser/signin/profile_oauth2_token_service.h" #include "chrome/browser/signin/profile_oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager.h" #include "chrome/browser/signin/signin_manager.h"
...@@ -206,6 +205,12 @@ void SigninManagerAndroid::OnBrowsingDataRemoverDone() { ...@@ -206,6 +205,12 @@ void SigninManagerAndroid::OnBrowsingDataRemoverDone() {
java_signin_manager_.obj()); java_signin_manager_.obj());
} }
void SigninManagerAndroid::MergeSessionCompleted(
const std::string& account_id,
const GoogleServiceAuthError& error) {
merge_session_helper_.reset();
}
void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env, jobject obj) { void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env, jobject obj) {
if (switches::IsNewProfileManagement()) { if (switches::IsNewProfileManagement()) {
// New Mirror code path that just fires the events and let the // New Mirror code path that just fires the events and let the
...@@ -223,9 +228,8 @@ void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env, jobject obj) { ...@@ -223,9 +228,8 @@ void SigninManagerAndroid::LogInSignedInUser(JNIEnv* env, jobject obj) {
// Old code path that doesn't depend on the new Account Reconcilor. // Old code path that doesn't depend on the new Account Reconcilor.
// We manually login. // We manually login.
// AutoLogin deletes itself. merge_session_helper_.reset(new GoogleAutoLoginHelper(profile_, this));
GoogleAutoLoginHelper* autoLogin = new GoogleAutoLoginHelper(profile_); merge_session_helper_->LogIn();
autoLogin->LogIn();
} }
} }
......
...@@ -13,7 +13,9 @@ ...@@ -13,7 +13,9 @@
#include "base/basictypes.h" #include "base/basictypes.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chrome/browser/signin/google_auto_login_helper.h"
class GoogleServiceAuthError;
class Profile; class Profile;
namespace policy { namespace policy {
...@@ -28,7 +30,7 @@ class CloudPolicyClient; ...@@ -28,7 +30,7 @@ class CloudPolicyClient;
// //
// This class implements parts of the sign-in flow, to make sure that policy // This class implements parts of the sign-in flow, to make sure that policy
// is available before sign-in completes. // is available before sign-in completes.
class SigninManagerAndroid { class SigninManagerAndroid : public GoogleAutoLoginHelper::Observer {
public: public:
SigninManagerAndroid(JNIEnv* env, jobject obj); SigninManagerAndroid(JNIEnv* env, jobject obj);
...@@ -61,6 +63,11 @@ class SigninManagerAndroid { ...@@ -61,6 +63,11 @@ class SigninManagerAndroid {
void OnBrowsingDataRemoverDone(); void OnBrowsingDataRemoverDone();
// GoogleAutoLoginHelper::Observer implementation.
virtual void MergeSessionCompleted(
const std::string& account_id,
const GoogleServiceAuthError& error) OVERRIDE;
Profile* profile_; Profile* profile_;
// Java-side SigninManager object. // Java-side SigninManager object.
...@@ -77,6 +84,9 @@ class SigninManagerAndroid { ...@@ -77,6 +84,9 @@ class SigninManagerAndroid {
std::string username_; std::string username_;
#endif #endif
// Helper to merge the signed into account into the cookie jar session.
scoped_ptr<GoogleAutoLoginHelper> merge_session_helper_;
base::WeakPtrFactory<SigninManagerAndroid> weak_factory_; base::WeakPtrFactory<SigninManagerAndroid> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(SigninManagerAndroid); DISALLOW_COPY_AND_ASSIGN(SigninManagerAndroid);
......
...@@ -451,6 +451,13 @@ void WebstorePrivateBeginInstallWithManifest3Function::SigninSuccess() { ...@@ -451,6 +451,13 @@ void WebstorePrivateBeginInstallWithManifest3Function::SigninSuccess() {
SigninCompletedOrNotNeeded(); SigninCompletedOrNotNeeded();
} }
void WebstorePrivateBeginInstallWithManifest3Function::MergeSessionComplete(
const GoogleServiceAuthError& error) {
// TODO(rogerta): once the embeded inline flow is enabled, the code in
// WebstorePrivateBeginInstallWithManifest3Function::SigninSuccess()
// should move to here.
}
void WebstorePrivateBeginInstallWithManifest3Function:: void WebstorePrivateBeginInstallWithManifest3Function::
SigninCompletedOrNotNeeded() { SigninCompletedOrNotNeeded() {
content::WebContents* web_contents = GetAssociatedWebContents(); content::WebContents* web_contents = GetAssociatedWebContents();
......
...@@ -144,6 +144,8 @@ class WebstorePrivateBeginInstallWithManifest3Function ...@@ -144,6 +144,8 @@ class WebstorePrivateBeginInstallWithManifest3Function
// SigninTracker::Observer override. // SigninTracker::Observer override.
virtual void SigninFailed(const GoogleServiceAuthError& error) OVERRIDE; virtual void SigninFailed(const GoogleServiceAuthError& error) OVERRIDE;
virtual void SigninSuccess() OVERRIDE; virtual void SigninSuccess() OVERRIDE;
virtual void MergeSessionComplete(
const GoogleServiceAuthError& error) OVERRIDE;
// Called when signin is complete or not needed. // Called when signin is complete or not needed.
void SigninCompletedOrNotNeeded(); void SigninCompletedOrNotNeeded();
......
...@@ -10,7 +10,6 @@ ...@@ -10,7 +10,6 @@
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/net/chrome_cookie_notification_details.h" #include "chrome/browser/net/chrome_cookie_notification_details.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/google_auto_login_helper.h"
#include "chrome/browser/signin/profile_oauth2_token_service.h" #include "chrome/browser/signin/profile_oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager.h" #include "chrome/browser/signin/signin_manager.h"
...@@ -79,9 +78,9 @@ void AccountReconcilor::UserIdFetcher::OnNetworkError(int response_code) { ...@@ -79,9 +78,9 @@ void AccountReconcilor::UserIdFetcher::OnNetworkError(int response_code) {
AccountReconcilor::AccountReconcilor(Profile* profile) AccountReconcilor::AccountReconcilor(Profile* profile)
: OAuth2TokenService::Consumer("account_reconcilor"), : OAuth2TokenService::Consumer("account_reconcilor"),
profile_(profile), profile_(profile),
merge_session_helper_(profile, NULL),
registered_with_token_service_(false), registered_with_token_service_(false),
are_gaia_accounts_set_(false), are_gaia_accounts_set_(false),requests_(NULL) {
requests_(NULL) {
DVLOG(1) << "AccountReconcilor::AccountReconcilor"; DVLOG(1) << "AccountReconcilor::AccountReconcilor";
RegisterWithSigninManager(); RegisterWithSigninManager();
RegisterWithCookieMonster(); RegisterWithCookieMonster();
...@@ -105,6 +104,7 @@ AccountReconcilor::~AccountReconcilor() { ...@@ -105,6 +104,7 @@ AccountReconcilor::~AccountReconcilor() {
void AccountReconcilor::Shutdown() { void AccountReconcilor::Shutdown() {
DVLOG(1) << "AccountReconcilor::Shutdown"; DVLOG(1) << "AccountReconcilor::Shutdown";
merge_session_helper_.CancelAll();
DeleteAccessTokenRequestsAndUserIdFetchers(); DeleteAccessTokenRequestsAndUserIdFetchers();
UnregisterWithSigninManager(); UnregisterWithSigninManager();
UnregisterWithTokenService(); UnregisterWithTokenService();
...@@ -112,6 +112,16 @@ void AccountReconcilor::Shutdown() { ...@@ -112,6 +112,16 @@ void AccountReconcilor::Shutdown() {
StopPeriodicReconciliation(); StopPeriodicReconciliation();
} }
void AccountReconcilor::AddMergeSessionObserver(
GoogleAutoLoginHelper::Observer* observer) {
merge_session_helper_.AddObserver(observer);
}
void AccountReconcilor::RemoveMergeSessionObserver(
GoogleAutoLoginHelper::Observer* observer) {
merge_session_helper_.RemoveObserver(observer);
}
void AccountReconcilor::DeleteAccessTokenRequestsAndUserIdFetchers() { void AccountReconcilor::DeleteAccessTokenRequestsAndUserIdFetchers() {
delete[] requests_; delete[] requests_;
requests_ = NULL; requests_ = NULL;
...@@ -237,9 +247,7 @@ void AccountReconcilor::OnRefreshTokenRevoked(const std::string& account_id) { ...@@ -237,9 +247,7 @@ void AccountReconcilor::OnRefreshTokenRevoked(const std::string& account_id) {
void AccountReconcilor::OnRefreshTokensLoaded() {} void AccountReconcilor::OnRefreshTokensLoaded() {}
void AccountReconcilor::PerformMergeAction(const std::string& account_id) { void AccountReconcilor::PerformMergeAction(const std::string& account_id) {
// GoogleAutoLoginHelper deletes itself upon success / failure. merge_session_helper_.LogIn(account_id);
GoogleAutoLoginHelper* helper = new GoogleAutoLoginHelper(profile_);
helper->LogIn(account_id);
} }
void AccountReconcilor::PerformRemoveAction(const std::string& account_id) { void AccountReconcilor::PerformRemoveAction(const std::string& account_id) {
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "base/compiler_specific.h" #include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h" #include "base/memory/scoped_vector.h"
#include "chrome/browser/signin/google_auto_login_helper.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h" #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
...@@ -19,10 +20,10 @@ class Profile; ...@@ -19,10 +20,10 @@ class Profile;
struct ChromeCookieDetails; struct ChromeCookieDetails;
class AccountReconcilor : public BrowserContextKeyedService, class AccountReconcilor : public BrowserContextKeyedService,
content::NotificationObserver, public content::NotificationObserver,
GaiaAuthConsumer, public GaiaAuthConsumer,
OAuth2TokenService::Consumer, public OAuth2TokenService::Consumer,
OAuth2TokenService::Observer { public OAuth2TokenService::Observer {
public: public:
explicit AccountReconcilor(Profile* profile); explicit AccountReconcilor(Profile* profile);
virtual ~AccountReconcilor(); virtual ~AccountReconcilor();
...@@ -30,6 +31,10 @@ class AccountReconcilor : public BrowserContextKeyedService, ...@@ -30,6 +31,10 @@ class AccountReconcilor : public BrowserContextKeyedService,
// BrowserContextKeyedService implementation. // BrowserContextKeyedService implementation.
virtual void Shutdown() OVERRIDE; virtual void Shutdown() OVERRIDE;
// Add or remove observers for the merge session notification.
void AddMergeSessionObserver(GoogleAutoLoginHelper::Observer* observer);
void RemoveMergeSessionObserver(GoogleAutoLoginHelper::Observer* observer);
Profile* profile() { return profile_; } Profile* profile() { return profile_; }
bool IsPeriodicReconciliationRunning() const { bool IsPeriodicReconciliationRunning() const {
...@@ -126,6 +131,7 @@ class AccountReconcilor : public BrowserContextKeyedService, ...@@ -126,6 +131,7 @@ class AccountReconcilor : public BrowserContextKeyedService,
Profile* profile_; Profile* profile_;
content::NotificationRegistrar registrar_; content::NotificationRegistrar registrar_;
base::RepeatingTimer<AccountReconcilor> reconciliation_timer_; base::RepeatingTimer<AccountReconcilor> reconciliation_timer_;
GoogleAutoLoginHelper merge_session_helper_;
bool registered_with_token_service_; bool registered_with_token_service_;
// Used during reconcile action. // Used during reconcile action.
......
...@@ -274,4 +274,3 @@ TEST_F(AccountReconcilorTest, StartReconcileAction) { ...@@ -274,4 +274,3 @@ TEST_F(AccountReconcilorTest, StartReconcileAction) {
base::RunLoop().RunUntilIdle(); base::RunLoop().RunUntilIdle();
ASSERT_TRUE(reconcilor->AreAllRefreshTokensChecked()); ASSERT_TRUE(reconcilor->AreAllRefreshTokensChecked());
} }
...@@ -5,86 +5,108 @@ ...@@ -5,86 +5,108 @@
#include "chrome/browser/signin/google_auto_login_helper.h" #include "chrome/browser/signin/google_auto_login_helper.h"
#include "chrome/browser/browser_process.h" #include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile_manager.h" #include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/signin/profile_oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "content/public/browser/notification_service.h"
#include "google_apis/gaia/gaia_auth_fetcher.h" #include "google_apis/gaia/gaia_auth_fetcher.h"
#include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_constants.h"
GoogleAutoLoginHelper::GoogleAutoLoginHelper(Profile* profile) GoogleAutoLoginHelper::GoogleAutoLoginHelper(Profile* profile,
: profile_(profile) {} Observer* observer)
: profile_(profile) {
if (observer)
AddObserver(observer);
}
GoogleAutoLoginHelper::~GoogleAutoLoginHelper() { GoogleAutoLoginHelper::~GoogleAutoLoginHelper() {
DCHECK(accounts_.empty()); DCHECK(accounts_.empty());
} }
void GoogleAutoLoginHelper::LogIn() { void GoogleAutoLoginHelper::LogIn() {
// This is the code path for non-mirror world. ProfileOAuth2TokenService* token_service =
uber_token_fetcher_.reset(CreateNewUbertokenFetcher()); ProfileOAuth2TokenServiceFactory::GetForProfile(profile_);
uber_token_fetcher_->StartFetchingToken(); LogIn(token_service->GetPrimaryAccountId());
DCHECK(accounts_.empty());
} }
void GoogleAutoLoginHelper::LogIn(const std::string& account_id) { void GoogleAutoLoginHelper::LogIn(const std::string& account_id) {
if (uber_token_fetcher_.get()) { accounts_.push_back(account_id);
accounts_.push_back(account_id); if (accounts_.size() == 1)
} else { StartFetching();
uber_token_fetcher_.reset(CreateNewUbertokenFetcher()); }
uber_token_fetcher_->StartFetchingToken(account_id);
} void GoogleAutoLoginHelper::AddObserver(Observer* observer) {
observer_list_.AddObserver(observer);
}
void GoogleAutoLoginHelper::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
void GoogleAutoLoginHelper::CancelAll() {
gaia_auth_fetcher_.reset();
uber_token_fetcher_.reset();
accounts_.clear();
} }
void GoogleAutoLoginHelper::OnUbertokenSuccess(const std::string& uber_token) { void GoogleAutoLoginHelper::OnUbertokenSuccess(const std::string& uber_token) {
VLOG(1) << "GoogleAutoLoginHelper::OnUbertokenSuccess"; VLOG(1) << "GoogleAutoLoginHelper::OnUbertokenSuccess"
gaia_auth_fetcher_.reset(CreateNewGaiaAuthFetcher()); << " account=" << accounts_.front();
gaia_auth_fetcher_.reset(
new GaiaAuthFetcher(this, GaiaConstants::kChromeSource,
profile_->GetRequestContext()));
gaia_auth_fetcher_->StartMergeSession(uber_token); gaia_auth_fetcher_->StartMergeSession(uber_token);
} }
void GoogleAutoLoginHelper::OnUbertokenFailure( void GoogleAutoLoginHelper::OnUbertokenFailure(
const GoogleServiceAuthError& error) { const GoogleServiceAuthError& error) {
VLOG(1) << "Failed to retrieve ubertoken, error: " << error.ToString(); VLOG(1) << "Failed to retrieve ubertoken"
if (base::MessageLoop::current()) { << " account=" << accounts_.front()
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); << " error=" << error.ToString();
} else { const std::string account_id = accounts_.front();
delete this; MergeNextAccount();
} SignalComplete(account_id, error);
} }
void GoogleAutoLoginHelper::OnMergeSessionSuccess(const std::string& data) { void GoogleAutoLoginHelper::OnMergeSessionSuccess(const std::string& data) {
DVLOG(1) << "MergeSession successful." << data; DVLOG(1) << "MergeSession successful account=" << accounts_.front();
if (accounts_.empty()) { const std::string account_id = accounts_.front();
if (base::MessageLoop::current()) { MergeNextAccount();
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); SignalComplete(account_id, GoogleServiceAuthError::AuthErrorNone());
} else {
delete this;
}
} else {
uber_token_fetcher_.reset(CreateNewUbertokenFetcher());
uber_token_fetcher_->StartFetchingToken(accounts_.front());
accounts_.pop_front();
}
} }
void GoogleAutoLoginHelper::OnMergeSessionFailure( void GoogleAutoLoginHelper::OnMergeSessionFailure(
const GoogleServiceAuthError& error) { const GoogleServiceAuthError& error) {
VLOG(1) << "Failed MergeSession request, error: " << error.ToString(); VLOG(1) << "Failed MergeSession"
// TODO(acleung): Depending on the return error we should probably << " account=" << accounts_.front()
// take different actions instead of just throw our hands up. << " error=" << error.ToString();
const std::string account_id = accounts_.front();
// Clearning pending accounts for now. MergeNextAccount();
accounts_.clear(); SignalComplete(account_id, error);
if (base::MessageLoop::current()) {
base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
} else {
delete this;
}
} }
UbertokenFetcher* GoogleAutoLoginHelper::CreateNewUbertokenFetcher() { void GoogleAutoLoginHelper::StartFetching() {
return new UbertokenFetcher(profile_, this); uber_token_fetcher_.reset(new UbertokenFetcher(profile_, this));
uber_token_fetcher_->StartFetchingToken(accounts_.front());
} }
GaiaAuthFetcher* GoogleAutoLoginHelper::CreateNewGaiaAuthFetcher() { void GoogleAutoLoginHelper::SignalComplete(
return new GaiaAuthFetcher( const std::string& account_id,
this, GaiaConstants::kChromeSource, profile_->GetRequestContext()); const GoogleServiceAuthError& error) {
// Its possible for the observer to delete |this| object. Don't access
// access any members after this calling the observer. This method should
// be the last call in any other method.
FOR_EACH_OBSERVER(Observer, observer_list_,
MergeSessionCompleted(account_id, error));
} }
void GoogleAutoLoginHelper::MergeNextAccount() {
gaia_auth_fetcher_.reset();
accounts_.pop_front();
if (accounts_.empty()) {
uber_token_fetcher_.reset();
} else {
StartFetching();
}
}
...@@ -2,48 +2,84 @@ ...@@ -2,48 +2,84 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef CHROME_BROWSER_ANDROID_SIGNIN_GOOGLE_AUTO_LOGIN_HELPER_H_ #ifndef CHROME_BROWSER_SIGNIN_GOOGLE_AUTO_LOGIN_HELPER_H_
#define CHROME_BROWSER_ANDROID_SIGNIN_GOOGLE_AUTO_LOGIN_HELPER_H_ #define CHROME_BROWSER_SIGNIN_GOOGLE_AUTO_LOGIN_HELPER_H_
#include <deque> #include <deque>
#include "base/observer_list.h"
#include "chrome/browser/signin/ubertoken_fetcher.h" #include "chrome/browser/signin/ubertoken_fetcher.h"
#include "google_apis/gaia/gaia_auth_consumer.h" #include "google_apis/gaia/gaia_auth_consumer.h"
class GaiaAuthFetcher; class GaiaAuthFetcher;
class GoogleServiceAuthError;
class Profile; class Profile;
// Logs in the current signed in user into Google services. Populates the cookie // Merges a Google account known to Chrome into the cookie jar. Once the
// jar with Google credentials of the signed in user. // account is merged, successfully or not, a NOTIFICATION_MERGE_SESSION_COMPLETE
// notification is sent out. When merging multiple accounts, one instance of
// the helper is better than multiple instances if there is the possibility
// that they run concurrently, since changes to the cookie must be serialized.
//
// By default instances of GoogleAutoLoginHelper delete themselves when done.
class GoogleAutoLoginHelper : public GaiaAuthConsumer, class GoogleAutoLoginHelper : public GaiaAuthConsumer,
public UbertokenConsumer { public UbertokenConsumer {
public: public:
explicit GoogleAutoLoginHelper(Profile* profile); class Observer {
public:
// Called whenever a merge session is completed. The account that was
// merged is given by |account_id|. If |error| is equal to
// GoogleServiceAuthError::AuthErrorNone() then the merge succeeeded.
virtual void MergeSessionCompleted(const std::string& account_id,
const GoogleServiceAuthError& error) = 0;
protected:
virtual ~Observer() {}
};
GoogleAutoLoginHelper(Profile* profile, Observer* observer);
virtual ~GoogleAutoLoginHelper(); virtual ~GoogleAutoLoginHelper();
void LogIn(); void LogIn();
void LogIn(const std::string& account_id); void LogIn(const std::string& account_id);
// Add or remove observers of this helper.
void AddObserver(Observer* observer);
void RemoveObserver(Observer* observer);
// Cancel all login requests.
void CancelAll();
private:
// Overridden from UbertokenConsumer.
virtual void OnUbertokenSuccess(const std::string& token) OVERRIDE;
virtual void OnUbertokenFailure(const GoogleServiceAuthError& error) OVERRIDE;
// Overridden from GaiaAuthConsumer. // Overridden from GaiaAuthConsumer.
virtual void OnMergeSessionSuccess(const std::string& data) OVERRIDE; virtual void OnMergeSessionSuccess(const std::string& data) OVERRIDE;
virtual void OnMergeSessionFailure(const GoogleServiceAuthError& error) virtual void OnMergeSessionFailure(const GoogleServiceAuthError& error)
OVERRIDE; OVERRIDE;
// Overridden from UbertokenConsumer. // Starts the proess of fetching the uber token and performing a merge session
virtual void OnUbertokenSuccess(const std::string& token) OVERRIDE; // for the next account. Virtual so that it can be overriden in tests.
virtual void OnUbertokenFailure(const GoogleServiceAuthError& error) OVERRIDE; virtual void StartFetching();
// For testing. // Call observer when merge session completes.
virtual UbertokenFetcher* CreateNewUbertokenFetcher(); void SignalComplete(const std::string& account_id,
virtual GaiaAuthFetcher* CreateNewGaiaAuthFetcher(); const GoogleServiceAuthError& error);
// Start the next merge session, if needed.
void MergeNextAccount();
private:
Profile* profile_; Profile* profile_;
scoped_ptr<GaiaAuthFetcher> gaia_auth_fetcher_; scoped_ptr<GaiaAuthFetcher> gaia_auth_fetcher_;
scoped_ptr<UbertokenFetcher> uber_token_fetcher_; scoped_ptr<UbertokenFetcher> uber_token_fetcher_;
std::deque<std::string> accounts_; std::deque<std::string> accounts_;
// List of observers to notify when merge session completes.
// Makes sure list is empty on destruction.
ObserverList<Observer, true> observer_list_;
DISALLOW_COPY_AND_ASSIGN(GoogleAutoLoginHelper); DISALLOW_COPY_AND_ASSIGN(GoogleAutoLoginHelper);
}; };
#endif // CHROME_BROWSER_ANDROID_SIGNIN_GOOGLE_AUTO_LOGIN_HELPER_H_ #endif // CHROME_BROWSER_SIGNIN_GOOGLE_AUTO_LOGIN_HELPER_H_
...@@ -7,27 +7,32 @@ ...@@ -7,27 +7,32 @@
#include <vector> #include <vector>
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/strings/stringprintf.h"
#include "chrome/browser/signin/google_auto_login_helper.h" #include "chrome/browser/signin/google_auto_login_helper.h"
#include "chrome/test/base/testing_profile.h" #include "chrome/test/base/testing_profile.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace { namespace {
class MockUbertokenFetcher : public UbertokenFetcher { class MockObserver : public GoogleAutoLoginHelper::Observer {
public: public:
MockUbertokenFetcher(Profile* profile, UbertokenConsumer* consumer) : explicit MockObserver(GoogleAutoLoginHelper* helper) : helper_(helper) {
UbertokenFetcher(profile, consumer), account_id("") {} helper_->AddObserver(this);
void completePendingRequest() {
OnUberAuthTokenSuccess("mock token: " + account_id);
} }
virtual void StartFetchingToken(const std::string& id) OVERRIDE { ~MockObserver() {
account_id = id; helper_->RemoveObserver(this);
} }
std::string account_id; MOCK_METHOD2(MergeSessionCompleted,
void(const std::string&,
const GoogleServiceAuthError& ));
private:
GoogleAutoLoginHelper* helper_;
DISALLOW_COPY_AND_ASSIGN(MockObserver);
}; };
// Counts number of InstrumentedGoogleAutoLoginHelper created. // Counts number of InstrumentedGoogleAutoLoginHelper created.
...@@ -38,12 +43,8 @@ int total = 0; ...@@ -38,12 +43,8 @@ int total = 0;
class InstrumentedGoogleAutoLoginHelper : public GoogleAutoLoginHelper { class InstrumentedGoogleAutoLoginHelper : public GoogleAutoLoginHelper {
public: public:
std::vector<MockUbertokenFetcher*>* mock_uber_fetchers_; explicit InstrumentedGoogleAutoLoginHelper(Profile* profile) :
TestingProfile profile_; GoogleAutoLoginHelper(profile, NULL) {
InstrumentedGoogleAutoLoginHelper(
std::vector<MockUbertokenFetcher*>* fetchers) :
GoogleAutoLoginHelper(0), mock_uber_fetchers_(fetchers) {
total++; total++;
} }
...@@ -51,66 +52,142 @@ class InstrumentedGoogleAutoLoginHelper : public GoogleAutoLoginHelper { ...@@ -51,66 +52,142 @@ class InstrumentedGoogleAutoLoginHelper : public GoogleAutoLoginHelper {
total--; total--;
} }
virtual void OnUbertokenSuccess(const std::string& token) OVERRIDE { MOCK_METHOD0(StartFetching, void());
OnMergeSessionSuccess(token);
}
virtual UbertokenFetcher* CreateNewUbertokenFetcher() OVERRIDE { private:
MockUbertokenFetcher* m = new MockUbertokenFetcher(&profile_, this); DISALLOW_COPY_AND_ASSIGN(InstrumentedGoogleAutoLoginHelper);
mock_uber_fetchers_->push_back(m); };
return m;
} class GoogleAutoLoginHelperTest : public testing::Test {
public:
GoogleAutoLoginHelperTest()
: no_error_(GoogleServiceAuthError::NONE),
error_(GoogleServiceAuthError::SERVICE_ERROR) {}
TestingProfile* profile() { return &profile_; }
void completePendingFetchers() { void SimulateUbertokenFailure(UbertokenConsumer* consumer,
while (!mock_uber_fetchers_->empty()) { const GoogleServiceAuthError& error) {
MockUbertokenFetcher* fetcher = mock_uber_fetchers_->back(); consumer->OnUbertokenFailure(error);
mock_uber_fetchers_->pop_back();
fetcher->completePendingRequest();
}
} }
MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& uber_token)); void SimulateMergeSessionSuccess(GaiaAuthConsumer* consumer,
const std::string& data) {
consumer->OnMergeSessionSuccess(data);
}
void OnMergeSessionSuccessConcrete(const std::string& uber_token) { void SimulateMergeSessionFailure(GaiaAuthConsumer* consumer,
GoogleAutoLoginHelper::OnMergeSessionSuccess(uber_token); const GoogleServiceAuthError& error) {
consumer->OnMergeSessionFailure(error);
} }
};
class GoogleAutoLoginHelperTest : public testing::Test { const GoogleServiceAuthError& no_error() { return no_error_; }
public: const GoogleServiceAuthError& error() { return error_; }
std::vector<MockUbertokenFetcher*> mock_uber_fetchers_;
base::MessageLoop message_loop_; private:
content::TestBrowserThreadBundle thread_bundle_;
TestingProfile profile_;
GoogleServiceAuthError no_error_;
GoogleServiceAuthError error_;
}; };
} // namespace } // namespace
using ::testing::Invoke;
using ::testing::_; using ::testing::_;
TEST_F(GoogleAutoLoginHelperTest, AllRequestsInOneGo) { TEST_F(GoogleAutoLoginHelperTest, Success) {
total = 0; InstrumentedGoogleAutoLoginHelper helper(profile());
MockObserver observer(&helper);
InstrumentedGoogleAutoLoginHelper* helper =
new InstrumentedGoogleAutoLoginHelper(&mock_uber_fetchers_); EXPECT_CALL(helper, StartFetching());
EXPECT_CALL(*helper, OnMergeSessionSuccess("mock token: acc1@gmail.com")); EXPECT_CALL(observer, MergeSessionCompleted("acc1@gmail.com", no_error()));
EXPECT_CALL(*helper, OnMergeSessionSuccess("mock token: acc2@gmail.com"));
EXPECT_CALL(*helper, OnMergeSessionSuccess("mock token: acc3@gmail.com")); helper.LogIn("acc1@gmail.com");
EXPECT_CALL(*helper, OnMergeSessionSuccess("mock token: acc4@gmail.com")); SimulateMergeSessionSuccess(&helper, "token");
EXPECT_CALL(*helper, OnMergeSessionSuccess("mock token: acc5@gmail.com")); }
// Don't completely mock out OnMergeSessionSuccess, let GoogleAutoLoginHelper TEST_F(GoogleAutoLoginHelperTest, FailedMergeSession) {
// actually call OnMergeSessionSuccess to clean up it's work queue because InstrumentedGoogleAutoLoginHelper helper(profile());
// it'll delete itself once the work queue becomes empty. MockObserver observer(&helper);
ON_CALL(*helper, OnMergeSessionSuccess(_)).WillByDefault(Invoke(helper,
&InstrumentedGoogleAutoLoginHelper::OnMergeSessionSuccessConcrete)); EXPECT_CALL(helper, StartFetching());
helper->LogIn("acc1@gmail.com"); EXPECT_CALL(observer, MergeSessionCompleted("acc1@gmail.com", error()));
helper->LogIn("acc2@gmail.com");
helper->LogIn("acc3@gmail.com"); helper.LogIn("acc1@gmail.com");
helper->LogIn("acc4@gmail.com"); SimulateMergeSessionFailure(&helper, error());
helper->LogIn("acc5@gmail.com"); }
helper->completePendingFetchers();
TEST_F(GoogleAutoLoginHelperTest, FailedUbertoken) {
// Make sure GoogleAutoLoginHelper cleans itself up after everything is done. InstrumentedGoogleAutoLoginHelper helper(profile());
message_loop_.RunUntilIdle(); MockObserver observer(&helper);
EXPECT_EQ(0, total);
EXPECT_CALL(helper, StartFetching());
EXPECT_CALL(observer, MergeSessionCompleted("acc1@gmail.com", error()));
helper.LogIn("acc1@gmail.com");
SimulateUbertokenFailure(&helper, error());
}
TEST_F(GoogleAutoLoginHelperTest, ContinueAfterSuccess) {
InstrumentedGoogleAutoLoginHelper helper(profile());
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetching()).Times(2);
EXPECT_CALL(observer, MergeSessionCompleted("acc1@gmail.com", no_error()));
EXPECT_CALL(observer, MergeSessionCompleted("acc2@gmail.com", no_error()));
helper.LogIn("acc1@gmail.com");
helper.LogIn("acc2@gmail.com");
SimulateMergeSessionSuccess(&helper, "token1");
SimulateMergeSessionSuccess(&helper, "token2");
}
TEST_F(GoogleAutoLoginHelperTest, ContinueAfterFailure1) {
InstrumentedGoogleAutoLoginHelper helper(profile());
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetching()).Times(2);
EXPECT_CALL(observer, MergeSessionCompleted("acc1@gmail.com", error()));
EXPECT_CALL(observer, MergeSessionCompleted("acc2@gmail.com", no_error()));
helper.LogIn("acc1@gmail.com");
helper.LogIn("acc2@gmail.com");
SimulateMergeSessionFailure(&helper, error());
SimulateMergeSessionSuccess(&helper, "token2");
}
TEST_F(GoogleAutoLoginHelperTest, ContinueAfterFailure2) {
InstrumentedGoogleAutoLoginHelper helper(profile());
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetching()).Times(2);
EXPECT_CALL(observer, MergeSessionCompleted("acc1@gmail.com", error()));
EXPECT_CALL(observer, MergeSessionCompleted("acc2@gmail.com", no_error()));
helper.LogIn("acc1@gmail.com");
helper.LogIn("acc2@gmail.com");
SimulateUbertokenFailure(&helper, error());
SimulateMergeSessionSuccess(&helper, "token2");
}
TEST_F(GoogleAutoLoginHelperTest, AllRequestsInMultipleGoes) {
InstrumentedGoogleAutoLoginHelper helper(profile());
MockObserver observer(&helper);
EXPECT_CALL(helper, StartFetching()).Times(4);
EXPECT_CALL(observer, MergeSessionCompleted(_, no_error())).Times(4);
helper.LogIn("acc1@gmail.com");
helper.LogIn("acc2@gmail.com");
SimulateMergeSessionSuccess(&helper, "token1");
helper.LogIn("acc3@gmail.com");
SimulateMergeSessionSuccess(&helper, "token2");
SimulateMergeSessionSuccess(&helper, "token3");
helper.LogIn("acc4@gmail.com");
SimulateMergeSessionSuccess(&helper, "token4");
} }
...@@ -117,6 +117,18 @@ bool SigninManager::HasSigninProcess() const { ...@@ -117,6 +117,18 @@ bool SigninManager::HasSigninProcess() const {
return signin_host_id_ != ChildProcessHost::kInvalidUniqueID; return signin_host_id_ != ChildProcessHost::kInvalidUniqueID;
} }
void SigninManager::AddMergeSessionObserver(
GoogleAutoLoginHelper::Observer* observer) {
if (merge_session_helper_)
merge_session_helper_->AddObserver(observer);
}
void SigninManager::RemoveMergeSessionObserver(
GoogleAutoLoginHelper::Observer* observer) {
if (merge_session_helper_)
merge_session_helper_->RemoveObserver(observer);
}
SigninManager::~SigninManager() { SigninManager::~SigninManager() {
} }
...@@ -369,6 +381,9 @@ void SigninManager::Initialize(Profile* profile, PrefService* local_state) { ...@@ -369,6 +381,9 @@ void SigninManager::Initialize(Profile* profile, PrefService* local_state) {
} }
void SigninManager::Shutdown() { void SigninManager::Shutdown() {
if (merge_session_helper_)
merge_session_helper_->CancelAll();
local_state_pref_registrar_.RemoveAll(); local_state_pref_registrar_.RemoveAll();
account_id_helper_.reset(); account_id_helper_.reset();
SigninManagerBase::Shutdown(); SigninManagerBase::Shutdown();
...@@ -557,6 +572,15 @@ void SigninManager::CompletePendingSignin() { ...@@ -557,6 +572,15 @@ void SigninManager::CompletePendingSignin() {
DCHECK(!possibly_invalid_username_.empty()); DCHECK(!possibly_invalid_username_.empty());
OnSignedIn(possibly_invalid_username_); OnSignedIn(possibly_invalid_username_);
// If inline sign in is enabled, but new profile management is not, perform a
// merge session now to push the user's credentials into the cookie jar.
bool do_merge_session_in_signin_manager =
!switches::IsEnableWebBasedSignin() &&
!switches::IsNewProfileManagement();
if (do_merge_session_in_signin_manager)
merge_session_helper_.reset(new GoogleAutoLoginHelper(profile_, NULL));
DCHECK(!temp_oauth_login_tokens_.refresh_token.empty()); DCHECK(!temp_oauth_login_tokens_.refresh_token.empty());
DCHECK(!GetAuthenticatedUsername().empty()); DCHECK(!GetAuthenticatedUsername().empty());
ProfileOAuth2TokenService* token_service = ProfileOAuth2TokenService* token_service =
...@@ -564,6 +588,9 @@ void SigninManager::CompletePendingSignin() { ...@@ -564,6 +588,9 @@ void SigninManager::CompletePendingSignin() {
token_service->UpdateCredentials(GetAuthenticatedUsername(), token_service->UpdateCredentials(GetAuthenticatedUsername(),
temp_oauth_login_tokens_.refresh_token); temp_oauth_login_tokens_.refresh_token);
temp_oauth_login_tokens_ = ClientOAuthResult(); temp_oauth_login_tokens_ = ClientOAuthResult();
if (do_merge_session_in_signin_manager)
merge_session_helper_->LogIn();
} }
void SigninManager::OnExternalSigninCompleted(const std::string& username) { void SigninManager::OnExternalSigninCompleted(const std::string& username) {
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "base/prefs/pref_change_registrar.h" #include "base/prefs/pref_change_registrar.h"
#include "base/prefs/pref_member.h" #include "base/prefs/pref_member.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/google_auto_login_helper.h"
#include "chrome/browser/signin/signin_internals_util.h" #include "chrome/browser/signin/signin_internals_util.h"
#include "chrome/browser/signin/signin_manager_base.h" #include "chrome/browser/signin/signin_manager_base.h"
#include "components/browser_context_keyed_service/browser_context_keyed_service.h" #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
...@@ -185,6 +186,10 @@ class SigninManager : public SigninManagerBase, ...@@ -185,6 +186,10 @@ class SigninManager : public SigninManagerBase,
bool IsSigninProcess(int host_id) const; bool IsSigninProcess(int host_id) const;
bool HasSigninProcess() const; bool HasSigninProcess() const;
// Add or remove observers for the merge session notification.
void AddMergeSessionObserver(GoogleAutoLoginHelper::Observer* observer);
void RemoveMergeSessionObserver(GoogleAutoLoginHelper::Observer* observer);
protected: protected:
// Flag saying whether signing out is allowed. // Flag saying whether signing out is allowed.
bool prohibit_signout_; bool prohibit_signout_;
...@@ -291,6 +296,9 @@ class SigninManager : public SigninManagerBase, ...@@ -291,6 +296,9 @@ class SigninManager : public SigninManagerBase,
// Helper object to listen for changes to the signin allowed preference. // Helper object to listen for changes to the signin allowed preference.
BooleanPrefMember signin_allowed_; BooleanPrefMember signin_allowed_;
// Helper to merge signed in account into the content area.
scoped_ptr<GoogleAutoLoginHelper> merge_session_helper_;
DISALLOW_COPY_AND_ASSIGN(SigninManager); DISALLOW_COPY_AND_ASSIGN(SigninManager);
}; };
......
...@@ -6,14 +6,19 @@ ...@@ -6,14 +6,19 @@
#include "chrome/browser/chrome_notification_types.h" #include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/profiles/profile.h" #include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/account_reconcilor_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service.h" #include "chrome/browser/signin/profile_oauth2_token_service.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager.h" #include "chrome/common/profile_management_switches.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "content/public/browser/notification_details.h" #include "content/public/browser/notification_details.h"
#include "content/public/browser/notification_source.h" #include "content/public/browser/notification_source.h"
#include "google_apis/gaia/gaia_constants.h" #include "google_apis/gaia/gaia_constants.h"
#if !defined(OS_CHROMEOS)
#include "chrome/browser/signin/signin_manager.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#endif
SigninTracker::SigninTracker(Profile* profile, Observer* observer) SigninTracker::SigninTracker(Profile* profile, Observer* observer)
: profile_(profile), observer_(observer) { : profile_(profile), observer_(observer) {
DCHECK(profile_); DCHECK(profile_);
...@@ -23,6 +28,18 @@ SigninTracker::SigninTracker(Profile* profile, Observer* observer) ...@@ -23,6 +28,18 @@ SigninTracker::SigninTracker(Profile* profile, Observer* observer)
SigninTracker::~SigninTracker() { SigninTracker::~SigninTracker() {
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)-> ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->
RemoveObserver(this); RemoveObserver(this);
if (!switches::IsEnableWebBasedSignin()) {
if (switches::IsNewProfileManagement()) {
AccountReconcilorFactory::GetForProfile(profile_)->
RemoveMergeSessionObserver(this);
#if !defined(OS_CHROMEOS)
} else {
SigninManagerFactory::GetForProfile(profile_)->
RemoveMergeSessionObserver(this);
#endif
}
}
} }
void SigninTracker::Initialize() { void SigninTracker::Initialize() {
...@@ -52,9 +69,27 @@ void SigninTracker::Observe(int type, ...@@ -52,9 +69,27 @@ void SigninTracker::Observe(int type,
void SigninTracker::OnRefreshTokenAvailable(const std::string& account_id) { void SigninTracker::OnRefreshTokenAvailable(const std::string& account_id) {
// TODO: when OAuth2TokenService handles multi-login, this should check // TODO: when OAuth2TokenService handles multi-login, this should check
// that |account_id| is the primary account before signalling success. // that |account_id| is the primary account before signalling success.
if (!switches::IsEnableWebBasedSignin()) {
if (switches::IsNewProfileManagement()) {
AccountReconcilorFactory::GetForProfile(profile_)->
AddMergeSessionObserver(this);
#if !defined(OS_CHROMEOS)
} else {
SigninManagerFactory::GetForProfile(profile_)->
AddMergeSessionObserver(this);
#endif
}
}
observer_->SigninSuccess(); observer_->SigninSuccess();
} }
void SigninTracker::OnRefreshTokenRevoked(const std::string& account_id) { void SigninTracker::OnRefreshTokenRevoked(const std::string& account_id) {
NOTREACHED(); NOTREACHED();
} }
void SigninTracker::MergeSessionCompleted(
const std::string& account_id,
const GoogleServiceAuthError& error) {
observer_->MergeSessionComplete(error);
}
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef CHROME_BROWSER_SIGNIN_SIGNIN_TRACKER_H_ #ifndef CHROME_BROWSER_SIGNIN_SIGNIN_TRACKER_H_
#define CHROME_BROWSER_SIGNIN_SIGNIN_TRACKER_H_ #define CHROME_BROWSER_SIGNIN_SIGNIN_TRACKER_H_
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/signin/google_auto_login_helper.h"
#include "content/public/browser/notification_observer.h" #include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h" #include "content/public/browser/notification_registrar.h"
#include "content/public/browser/notification_types.h" #include "content/public/browser/notification_types.h"
...@@ -47,7 +49,8 @@ class Profile; ...@@ -47,7 +49,8 @@ class Profile;
// sync, and provides an Observer interface to notify the UI layer of changes // sync, and provides an Observer interface to notify the UI layer of changes
// in sync state so they can be reflected in the UI. // in sync state so they can be reflected in the UI.
class SigninTracker : public content::NotificationObserver, class SigninTracker : public content::NotificationObserver,
public OAuth2TokenService::Observer { public OAuth2TokenService::Observer,
public GoogleAutoLoginHelper::Observer {
public: public:
class Observer { class Observer {
public: public:
...@@ -56,6 +59,10 @@ class SigninTracker : public content::NotificationObserver, ...@@ -56,6 +59,10 @@ class SigninTracker : public content::NotificationObserver,
// The signin attempt succeeded. // The signin attempt succeeded.
virtual void SigninSuccess() = 0; virtual void SigninSuccess() = 0;
// The signed in account has been merged into the content area cookie jar.
// This will be called only after a call to SigninSuccess().
virtual void MergeSessionComplete(const GoogleServiceAuthError& error) = 0;
}; };
// Creates a SigninTracker that tracks the signin status on the passed // Creates a SigninTracker that tracks the signin status on the passed
...@@ -77,6 +84,11 @@ class SigninTracker : public content::NotificationObserver, ...@@ -77,6 +84,11 @@ class SigninTracker : public content::NotificationObserver,
// Initializes this by adding notifications and observers. // Initializes this by adding notifications and observers.
void Initialize(); void Initialize();
// GoogleAutoLoginHelper::Observer implementation.
virtual void MergeSessionCompleted(
const std::string& account_id,
const GoogleServiceAuthError& error) OVERRIDE;
// The profile whose signin status we are tracking. // The profile whose signin status we are tracking.
Profile* profile_; Profile* profile_;
......
...@@ -42,12 +42,19 @@ class MockObserver : public SigninTracker::Observer { ...@@ -42,12 +42,19 @@ class MockObserver : public SigninTracker::Observer {
MOCK_METHOD1(SigninFailed, void(const GoogleServiceAuthError&)); MOCK_METHOD1(SigninFailed, void(const GoogleServiceAuthError&));
MOCK_METHOD0(SigninSuccess, void(void)); MOCK_METHOD0(SigninSuccess, void(void));
MOCK_METHOD1(MergeSessionComplete, void(const GoogleServiceAuthError&));
}; };
} // namespace } // namespace
class SigninTrackerTest : public testing::Test { class SigninTrackerTest : public testing::Test {
public: public:
#if defined(OS_CHROMEOS)
typedef FakeSigninManagerBase FakeSigninManagerForTesting;
#else
typedef FakeSigninManager FakeSigninManagerForTesting;
#endif
SigninTrackerTest() {} SigninTrackerTest() {}
virtual void SetUp() OVERRIDE { virtual void SetUp() OVERRIDE {
TestingProfile::Builder builder; TestingProfile::Builder builder;
...@@ -60,9 +67,9 @@ class SigninTrackerTest : public testing::Test { ...@@ -60,9 +67,9 @@ class SigninTrackerTest : public testing::Test {
static_cast<FakeProfileOAuth2TokenService*>( static_cast<FakeProfileOAuth2TokenService*>(
ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get())); ProfileOAuth2TokenServiceFactory::GetForProfile(profile_.get()));
mock_signin_manager_ = static_cast<FakeSigninManagerBase*>( mock_signin_manager_ = static_cast<FakeSigninManagerForTesting*>(
SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse( SigninManagerFactory::GetInstance()->SetTestingFactoryAndUse(
profile_.get(), FakeSigninManagerBase::Build)); profile_.get(), FakeSigninManagerForTesting::Build));
mock_signin_manager_->Initialize(profile_.get(), NULL); mock_signin_manager_->Initialize(profile_.get(), NULL);
tracker_.reset(new SigninTracker(profile_.get(), &observer_)); tracker_.reset(new SigninTracker(profile_.get(), &observer_));
...@@ -75,7 +82,7 @@ class SigninTrackerTest : public testing::Test { ...@@ -75,7 +82,7 @@ class SigninTrackerTest : public testing::Test {
content::TestBrowserThreadBundle thread_bundle_; content::TestBrowserThreadBundle thread_bundle_;
scoped_ptr<SigninTracker> tracker_; scoped_ptr<SigninTracker> tracker_;
scoped_ptr<TestingProfile> profile_; scoped_ptr<TestingProfile> profile_;
FakeSigninManagerBase* mock_signin_manager_; FakeSigninManagerForTesting* mock_signin_manager_;
FakeProfileOAuth2TokenService* fake_oauth2_token_service_; FakeProfileOAuth2TokenService* fake_oauth2_token_service_;
MockObserver observer_; MockObserver observer_;
}; };
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "chrome/browser/ui/webui/signin/login_ui_service.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/signin/login_ui_service_factory.h"
#include "chrome/browser/ui/webui/signin/profile_signin_confirmation_dialog.h" #include "chrome/browser/ui/webui/signin/profile_signin_confirmation_dialog.h"
#include "chrome/common/profile_management_switches.h"
#include "chrome/common/url_constants.h" #include "chrome/common/url_constants.h"
#include "grit/chromium_strings.h" #include "grit/chromium_strings.h"
#include "grit/generated_resources.h" #include "grit/generated_resources.h"
...@@ -366,6 +367,15 @@ void OneClickSigninSyncStarter::SigninFailed( ...@@ -366,6 +367,15 @@ void OneClickSigninSyncStarter::SigninFailed(
} }
void OneClickSigninSyncStarter::SigninSuccess() { void OneClickSigninSyncStarter::SigninSuccess() {
if (switches::IsEnableWebBasedSignin())
MergeSessionComplete(GoogleServiceAuthError(GoogleServiceAuthError::NONE));
}
void OneClickSigninSyncStarter::MergeSessionComplete(
const GoogleServiceAuthError& error) {
// Regardless of whether the merge session completed sucessfully or not,
// continue with sync starting.
if (!sync_setup_completed_callback_.is_null()) if (!sync_setup_completed_callback_.is_null())
sync_setup_completed_callback_.Run(SYNC_SETUP_SUCCESS); sync_setup_completed_callback_.Run(SYNC_SETUP_SUCCESS);
......
...@@ -112,6 +112,8 @@ class OneClickSigninSyncStarter : public SigninTracker::Observer, ...@@ -112,6 +112,8 @@ class OneClickSigninSyncStarter : public SigninTracker::Observer,
// SigninTracker::Observer override. // SigninTracker::Observer override.
virtual void SigninFailed(const GoogleServiceAuthError& error) OVERRIDE; virtual void SigninFailed(const GoogleServiceAuthError& error) OVERRIDE;
virtual void SigninSuccess() OVERRIDE; virtual void SigninSuccess() OVERRIDE;
virtual void MergeSessionComplete(
const GoogleServiceAuthError& error) OVERRIDE;
#if defined(ENABLE_CONFIGURATION_POLICY) #if defined(ENABLE_CONFIGURATION_POLICY)
// User input handler for the signin confirmation dialog. // User input handler for the signin confirmation dialog.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment