SigninManagerBase: Change AddObserver to SetObserver.
IdentityManager is intended to be the sole observer of
SigninManagerBase, so we shouldn't allow multiple observers.
Bug: 939372
Change-Id: I81454f4174e19c1dad8fe38df4191878fa9512e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1515573
Commit-Queue: Lowell Manners <lowell@chromium.org>
Reviewed-by: Colin Blundell <blundell@chromium.org>
Reviewed-by: David Roger <droger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#640289}
diff --git a/components/signin/core/browser/signin_manager.cc b/components/signin/core/browser/signin_manager.cc
index 79b00b7..ad3a6f5 100644
--- a/components/signin/core/browser/signin_manager.cc
+++ b/components/signin/core/browser/signin_manager.cc
@@ -39,8 +39,9 @@
SigninManager::~SigninManager() {}
void SigninManager::HandleAuthError(const GoogleServiceAuthError& error) {
- for (auto& observer : observer_list_)
- observer.GoogleSigninFailed(error);
+ if (observer_ != nullptr) {
+ observer_->GoogleSigninFailed(error);
+ }
}
void SigninManager::SignOut(
@@ -253,13 +254,14 @@
void SigninManager::FireGoogleSigninSucceeded() {
const AccountInfo account_info = GetAuthenticatedAccountInfo();
- for (auto& observer : observer_list_)
- observer.GoogleSigninSucceeded(account_info);
+ if (observer_ != nullptr) {
+ observer_->GoogleSigninSucceeded(account_info);
+ }
}
void SigninManager::FireGoogleSignedOut(const AccountInfo& account_info) {
- for (auto& observer : observer_list_) {
- observer.GoogleSignedOut(account_info);
+ if (observer_ != nullptr) {
+ observer_->GoogleSignedOut(account_info);
}
}
diff --git a/components/signin/core/browser/signin_manager_base.cc b/components/signin/core/browser/signin_manager_base.cc
index a6538b3..b3210dea 100644
--- a/components/signin/core/browser/signin_manager_base.cc
+++ b/components/signin/core/browser/signin_manager_base.cc
@@ -37,7 +37,9 @@
DCHECK(account_tracker_service_);
}
-SigninManagerBase::~SigninManagerBase() {}
+SigninManagerBase::~SigninManagerBase() {
+ DCHECK(!observer_);
+}
// static
void SigninManagerBase::RegisterProfilePrefs(PrefRegistrySimple* registry) {
@@ -154,7 +156,9 @@
void SigninManagerBase::FinalizeInitBeforeLoadingRefreshTokens(
PrefService* local_state) {}
-bool SigninManagerBase::IsInitialized() const { return initialized_; }
+bool SigninManagerBase::IsInitialized() const {
+ return initialized_;
+}
bool SigninManagerBase::IsSigninAllowed() const {
return client_->GetPrefs()->GetBoolean(prefs::kSigninAllowed);
@@ -192,8 +196,7 @@
client_->GetPrefs()->GetString(prefs::kGoogleServicesAccountId);
DCHECK(pref_account_id.empty() || pref_account_id == account_id)
- << "account_id=" << account_id
- << " pref_account_id=" << pref_account_id;
+ << "account_id=" << account_id << " pref_account_id=" << pref_account_id;
authenticated_account_id_ = account_id;
client_->GetPrefs()->SetString(prefs::kGoogleServicesAccountId, account_id);
@@ -229,10 +232,12 @@
return !authenticated_account_id_.empty();
}
-void SigninManagerBase::AddObserver(Observer* observer) {
- observer_list_.AddObserver(observer);
+void SigninManagerBase::SetObserver(Observer* observer) {
+ DCHECK(!observer_) << "SetObserver shouldn't be called multiple times.";
+ observer_ = observer;
}
-void SigninManagerBase::RemoveObserver(Observer* observer) {
- observer_list_.RemoveObserver(observer);
+void SigninManagerBase::ClearObserver() {
+ DCHECK(observer_);
+ observer_ = nullptr;
}
diff --git a/components/signin/core/browser/signin_manager_base.h b/components/signin/core/browser/signin_manager_base.h
index b3857e3..fdd331aa 100644
--- a/components/signin/core/browser/signin_manager_base.h
+++ b/components/signin/core/browser/signin_manager_base.h
@@ -125,9 +125,12 @@
// Returns true if there is an authenticated user.
bool IsAuthenticated() const;
- // Methods to register or remove observers of signin.
- void AddObserver(Observer* observer);
- void RemoveObserver(Observer* observer);
+ // Methods to set or clear the observer of signin.
+ // In practice these should only be used by IdentityManager.
+ // NOTE: If SetObserver is called, ClearObserver should be called before
+ // the destruction of SigninManagerBase.
+ void SetObserver(Observer* observer);
+ void ClearObserver();
protected:
SigninClient* signin_client() const { return client_; }
@@ -157,9 +160,9 @@
// call this.
void ClearAuthenticatedAccountId();
- // List of observers to notify on signin events.
- // Makes sure list is empty on destruction.
- base::ObserverList<Observer, true>::Unchecked observer_list_;
+ // Observer to notify on signin events.
+ // There is a DCHECK on destruction that this has been cleared.
+ Observer* observer_ = nullptr;
private:
// Added only to allow SigninManager to call the SigninManagerBase
diff --git a/components/signin/core/browser/signin_manager_unittest.cc b/components/signin/core/browser/signin_manager_unittest.cc
index 255182d..f63322d 100644
--- a/components/signin/core/browser/signin_manager_unittest.cc
+++ b/components/signin/core/browser/signin_manager_unittest.cc
@@ -39,9 +39,7 @@
class TestSigninManagerObserver : public SigninManagerBase::Observer {
public:
TestSigninManagerObserver()
- : num_failed_signins_(0),
- num_successful_signins_(0),
- num_signouts_(0) {}
+ : num_failed_signins_(0), num_successful_signins_(0), num_signouts_(0) {}
~TestSigninManagerObserver() override {}
@@ -87,7 +85,7 @@
~SigninManagerTest() override {
if (manager_) {
- manager_->RemoveObserver(&test_observer_);
+ manager_->ClearObserver();
manager_->Shutdown();
}
token_service_.Shutdown();
@@ -119,13 +117,13 @@
&test_signin_client_, &token_service_, &account_tracker_,
&cookie_manager_service_, account_consistency_);
manager_->Initialize(&local_state_);
- manager_->AddObserver(&test_observer_);
+ manager_->SetObserver(&test_observer_);
}
// Shuts down |manager_|.
void ShutDownManager() {
DCHECK(manager_);
- manager_->RemoveObserver(&test_observer_);
+ manager_->ClearObserver();
manager_->Shutdown();
manager_.reset();
}
diff --git a/services/identity/public/cpp/identity_manager.cc b/services/identity/public/cpp/identity_manager.cc
index 264a32c..a1383631 100644
--- a/services/identity/public/cpp/identity_manager.cc
+++ b/services/identity/public/cpp/identity_manager.cc
@@ -61,7 +61,7 @@
DCHECK(account_fetcher_service_);
DCHECK(accounts_cookie_mutator_);
DCHECK(diagnostics_provider_);
- signin_manager_->AddObserver(this);
+ signin_manager_->SetObserver(this);
token_service_->AddDiagnosticsObserver(this);
token_service_->AddObserver(this);
account_tracker_service_->AddObserver(this);
@@ -69,7 +69,7 @@
}
IdentityManager::~IdentityManager() {
- signin_manager_->RemoveObserver(this);
+ signin_manager_->ClearObserver();
token_service_->RemoveObserver(this);
token_service_->RemoveDiagnosticsObserver(this);
account_tracker_service_->RemoveObserver(this);
diff --git a/services/identity/public/cpp/identity_manager_unittest.cc b/services/identity/public/cpp/identity_manager_unittest.cc
index 01dc48f..b99b658 100644
--- a/services/identity/public/cpp/identity_manager_unittest.cc
+++ b/services/identity/public/cpp/identity_manager_unittest.cc
@@ -110,64 +110,6 @@
base::OnceClosure on_access_token_invalidated_callback_;
};
-class TestSigninManagerObserver : public SigninManagerBase::Observer {
- public:
- explicit TestSigninManagerObserver(SigninManagerBase* signin_manager)
- : signin_manager_(signin_manager) {
- signin_manager_->AddObserver(this);
- }
- ~TestSigninManagerObserver() override {
- signin_manager_->RemoveObserver(this);
- }
-
- void set_identity_manager(IdentityManager* identity_manager) {
- identity_manager_ = identity_manager;
- }
-
- void set_on_google_signin_succeeded_callback(base::OnceClosure callback) {
- on_google_signin_succeeded_callback_ = std::move(callback);
- }
- void set_on_google_signed_out_callback(base::OnceClosure callback) {
- on_google_signed_out_callback_ = std::move(callback);
- }
-
- const CoreAccountInfo& primary_account_from_signin_callback() const {
- return primary_account_from_signin_callback_;
- }
- const CoreAccountInfo& primary_account_from_signout_callback() const {
- return primary_account_from_signout_callback_;
- }
-
- private:
- // SigninManager::Observer:
- void GoogleSigninSucceeded(const AccountInfo&) override {
- // Fetch the primary account from IdentityManager. The goal is to check
- // that the account from IdentityManager has correct values even if other
- // SigninManager::Observer are notified.
- primary_account_from_signin_callback_ =
- identity_manager_->GetPrimaryAccountInfo();
- if (on_google_signin_succeeded_callback_)
- std::move(on_google_signin_succeeded_callback_).Run();
- }
- void GoogleSignedOut(const AccountInfo&) override {
- // Fetch the primary account from IdentityManager. The goal is to check
- // that the account from IdentityManager has correct values even if other
- // SigninManager::Observer are notified.
- primary_account_from_signout_callback_ =
- identity_manager_->GetPrimaryAccountInfo();
- if (on_google_signed_out_callback_)
- std::move(on_google_signed_out_callback_).Run();
- }
-
- SigninManagerBase* signin_manager_;
- IdentityManager* identity_manager_;
- base::OnceClosure on_google_signin_succeeded_callback_;
- base::OnceClosure on_google_signin_failed_callback_;
- base::OnceClosure on_google_signed_out_callback_;
- CoreAccountInfo primary_account_from_signin_callback_;
- CoreAccountInfo primary_account_from_signout_callback_;
-};
-
// Class that observes updates from ProfileOAuth2TokenService and and verifies
// thereby that IdentityManager receives updates before direct observers of
// ProfileOAuth2TokenService.
@@ -1440,62 +1382,6 @@
}
#endif
-#if !defined(OS_CHROMEOS)
-TEST_F(
- IdentityManagerTest,
- IdentityManagerGivesConsistentValuesFromSigninManagerObserverNotificationOfSignIn) {
- ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);
-
- base::RunLoop run_loop;
- TestSigninManagerObserver signin_manager_observer(signin_manager());
- signin_manager_observer.set_on_google_signin_succeeded_callback(
- run_loop.QuitClosure());
-
- // NOTE: For this test to be meaningful, TestSigninManagerObserver
- // needs to be created before the IdentityManager instance that it's
- // interacting with. Otherwise, even an implementation where they're
- // both SigninManager::Observers would work as IdentityManager would
- // get notified first during the observer callbacks.
- RecreateIdentityManager();
- signin_manager_observer.set_identity_manager(identity_manager());
-
- SigninManager::FromSigninManagerBase(signin_manager())
- ->OnExternalSigninCompleted(kTestEmail);
-
- run_loop.Run();
-
- CoreAccountInfo primary_account_from_signin_callback =
- signin_manager_observer.primary_account_from_signin_callback();
- EXPECT_EQ(kTestGaiaId, primary_account_from_signin_callback.gaia);
- EXPECT_EQ(kTestEmail, primary_account_from_signin_callback.email);
-}
-
-TEST_F(
- IdentityManagerTest,
- IdentityManagerGivesConsistentValuesFromSigninManagerObserverNotificationOfSignOut) {
- base::RunLoop run_loop;
- TestSigninManagerObserver signin_manager_observer(signin_manager());
- signin_manager_observer.set_on_google_signed_out_callback(
- run_loop.QuitClosure());
-
- // NOTE: For this test to be meaningful, TestSigninManagerObserver
- // needs to be created before the IdentityManager instance that it's
- // interacting with. Otherwise, even an implementation where they're
- // both SigninManager::Observers would work as IdentityManager would
- // get notified first during the observer callbacks.
- RecreateIdentityManager();
- signin_manager_observer.set_identity_manager(identity_manager());
-
- ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);
- run_loop.Run();
-
- CoreAccountInfo primary_account_from_signout_callback =
- signin_manager_observer.primary_account_from_signout_callback();
- EXPECT_EQ(std::string(), primary_account_from_signout_callback.gaia);
- EXPECT_EQ(std::string(), primary_account_from_signout_callback.email);
-}
-#endif
-
#if defined(OS_CHROMEOS)
// On ChromeOS, AccountTrackerService first receives the normalized email
// address from GAIA and then later has it updated with the user's