Commit 2c31aa6a authored by Kush Sinha's avatar Kush Sinha Committed by Commit Bot

Bugfix: CrOsOAuth2TsDelegate calling FireRefreshTokensLoaded too early

|ChromeOSOAuth2TokenServiceDelegate| loads tokens at startup and calls
|FireRefreshTokensLoaded| before some token service observers may have
had a chance to register themselves. This causes them to miss the
|OnRefreshTokensLoaded| callback.

For now, the solution is to respect the temporal coupling between
|OAuth2TokenServiceDelegate::LoadCredentials| and
|OAuth2TokenService::AddObserver|, i.e. |LoadCredentials| is called
only when all observers have been added. Ideally, it should be an
observer's responsibility to check whether it has been initialized 'too
late' and may have missed the |OnRefreshTokensLoaded| notification.

Bug: 820046
Change-Id: I3ac67798d165afe230fa29e03ec7af75a9a093a9
Reviewed-on: https://chromium-review.googlesource.com/1069353
Commit-Queue: Kush Sinha <sinhak@chromium.org>
Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Reviewed-by: default avatarLutz Justen <ljusten@chromium.org>
Cr-Commit-Position: refs/heads/master@{#561422}
parent 7aca286a
...@@ -21,12 +21,6 @@ ChromeOSOAuth2TokenServiceDelegate::ChromeOSOAuth2TokenServiceDelegate( ...@@ -21,12 +21,6 @@ ChromeOSOAuth2TokenServiceDelegate::ChromeOSOAuth2TokenServiceDelegate(
: account_tracker_service_(account_tracker_service), : account_tracker_service_(account_tracker_service),
account_manager_(account_manager), account_manager_(account_manager),
weak_factory_(this) { weak_factory_(this) {
DCHECK(account_manager_);
load_credentials_state_ = LOAD_CREDENTIALS_IN_PROGRESS;
account_manager_->AddObserver(this);
account_manager_->GetAccounts(
base::BindOnce(&ChromeOSOAuth2TokenServiceDelegate::GetAccountsCallback,
weak_factory_.GetWeakPtr()));
} }
ChromeOSOAuth2TokenServiceDelegate::~ChromeOSOAuth2TokenServiceDelegate() { ChromeOSOAuth2TokenServiceDelegate::~ChromeOSOAuth2TokenServiceDelegate() {
...@@ -109,10 +103,28 @@ std::vector<std::string> ChromeOSOAuth2TokenServiceDelegate::GetAccounts() { ...@@ -109,10 +103,28 @@ std::vector<std::string> ChromeOSOAuth2TokenServiceDelegate::GetAccounts() {
return accounts; return accounts;
} }
void ChromeOSOAuth2TokenServiceDelegate::LoadCredentials(
const std::string& primary_account_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (load_credentials_state_ != LOAD_CREDENTIALS_NOT_STARTED) {
return;
}
load_credentials_state_ = LOAD_CREDENTIALS_IN_PROGRESS;
DCHECK(account_manager_);
account_manager_->AddObserver(this);
account_manager_->GetAccounts(
base::BindOnce(&ChromeOSOAuth2TokenServiceDelegate::GetAccountsCallback,
weak_factory_.GetWeakPtr()));
}
void ChromeOSOAuth2TokenServiceDelegate::UpdateCredentials( void ChromeOSOAuth2TokenServiceDelegate::UpdateCredentials(
const std::string& account_id, const std::string& account_id,
const std::string& refresh_token) { const std::string& refresh_token) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_EQ(LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS, load_credentials_state_);
DCHECK(!account_id.empty()); DCHECK(!account_id.empty());
DCHECK(!refresh_token.empty()); DCHECK(!refresh_token.empty());
...@@ -146,6 +158,11 @@ void ChromeOSOAuth2TokenServiceDelegate::GetAccountsCallback( ...@@ -146,6 +158,11 @@ void ChromeOSOAuth2TokenServiceDelegate::GetAccountsCallback(
std::vector<AccountManager::AccountKey> account_keys) { std::vector<AccountManager::AccountKey> account_keys) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// This callback should only be triggered during |LoadCredentials|, which
// implies that |load_credentials_state_| should in
// |LOAD_CREDENTIALS_IN_PROGRESS| state.
DCHECK_EQ(LOAD_CREDENTIALS_IN_PROGRESS, load_credentials_state_);
load_credentials_state_ = LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS; load_credentials_state_ = LOAD_CREDENTIALS_FINISHED_WITH_SUCCESS;
// The typical order of |OAuth2TokenService::Observer| callbacks is: // The typical order of |OAuth2TokenService::Observer| callbacks is:
......
...@@ -43,6 +43,7 @@ class ChromeOSOAuth2TokenServiceDelegate : public OAuth2TokenServiceDelegate, ...@@ -43,6 +43,7 @@ class ChromeOSOAuth2TokenServiceDelegate : public OAuth2TokenServiceDelegate,
GoogleServiceAuthError GetAuthError( GoogleServiceAuthError GetAuthError(
const std::string& account_id) const override; const std::string& account_id) const override;
std::vector<std::string> GetAccounts() override; std::vector<std::string> GetAccounts() override;
void LoadCredentials(const std::string& primary_account_id) override;
void UpdateCredentials(const std::string& account_id, void UpdateCredentials(const std::string& account_id,
const std::string& refresh_token) override; const std::string& refresh_token) override;
net::URLRequestContextGetter* GetRequestContext() const override; net::URLRequestContextGetter* GetRequestContext() const override;
......
...@@ -100,6 +100,8 @@ class CrOSOAuthDelegateTest : public testing::Test { ...@@ -100,6 +100,8 @@ class CrOSOAuthDelegateTest : public testing::Test {
delegate_ = std::make_unique<ChromeOSOAuth2TokenServiceDelegate>( delegate_ = std::make_unique<ChromeOSOAuth2TokenServiceDelegate>(
&account_tracker_service_, &account_manager_); &account_tracker_service_, &account_manager_);
delegate_->LoadCredentials(
account_info_.account_id /* primary_account_id */);
} }
AccountInfo CreateAccountInfoTestFixture(const std::string& gaia_id, AccountInfo CreateAccountInfoTestFixture(const std::string& gaia_id,
...@@ -251,6 +253,7 @@ TEST_F(CrOSOAuthDelegateTest, BatchChangeObserversAreNotifiedOncePerBatch) { ...@@ -251,6 +253,7 @@ TEST_F(CrOSOAuthDelegateTest, BatchChangeObserversAreNotifiedOncePerBatch) {
// Register callbacks before AccountManager has been fully initialized. // Register callbacks before AccountManager has been fully initialized.
auto delegate = std::make_unique<ChromeOSOAuth2TokenServiceDelegate>( auto delegate = std::make_unique<ChromeOSOAuth2TokenServiceDelegate>(
&account_tracker_service_, &account_manager); &account_tracker_service_, &account_manager);
delegate->LoadCredentials(account1.account_id /* primary_account_id */);
TokenServiceObserver observer; TokenServiceObserver observer;
delegate->AddObserver(&observer); delegate->AddObserver(&observer);
// Wait until AccountManager is fully initialized. // Wait until AccountManager is fully initialized.
......
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