summaryrefslogtreecommitdiff
path: root/chromium/components/signin
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-16 11:45:35 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-07-17 08:59:23 +0000
commit552906b0f222c5d5dd11b9fd73829d510980461a (patch)
tree3a11e6ed0538a81dd83b20cf3a4783e297f26d91 /chromium/components/signin
parent1b05827804eaf047779b597718c03e7d38344261 (diff)
downloadqtwebengine-chromium-552906b0f222c5d5dd11b9fd73829d510980461a.tar.gz
BASELINE: Update Chromium to 83.0.4103.122
Change-Id: Ie3a82f5bb0076eec2a7c6a6162326b4301ee291e Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/components/signin')
-rw-r--r--chromium/components/signin/DEPS1
-rw-r--r--chromium/components/signin/core/browser/BUILD.gn17
-rw-r--r--chromium/components/signin/core/browser/about_signin_internals.cc10
-rw-r--r--chromium/components/signin/core/browser/about_signin_internals.h14
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor.cc47
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor.h12
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor_unittest.cc374
-rw-r--r--chromium/components/signin/core/browser/android/BUILD.gn23
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountIdProvider.java84
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java18
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java183
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java85
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java18
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountUtils.java47
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java6
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java2
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ConsistencyCookieManager.java97
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ObservableValue.java3
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SigninActivityMonitor.java68
-rw-r--r--chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java26
-rw-r--r--chromium/components/signin/core/browser/chrome_connected_header_helper.cc13
-rw-r--r--chromium/components/signin/core/browser/consistency_cookie_manager_android.cc50
-rw-r--r--chromium/components/signin/core/browser/consistency_cookie_manager_android.h42
-rw-r--r--chromium/components/signin/core/browser/consistency_cookie_manager_base.cc83
-rw-r--r--chromium/components/signin/core/browser/consistency_cookie_manager_base.h61
-rw-r--r--chromium/components/signin/core/browser/consistency_cookie_manager_unittest.cc132
-rw-r--r--chromium/components/signin/core/browser/cookie_reminter.cc4
-rw-r--r--chromium/components/signin/core/browser/mice_account_reconcilor_delegate.cc76
-rw-r--r--chromium/components/signin/core/browser/mice_account_reconcilor_delegate.h50
-rw-r--r--chromium/components/signin/core/browser/mice_account_reconcilor_delegate_unittest.cc87
-rw-r--r--chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h2
-rw-r--r--chromium/components/signin/core/browser/resources/signin_internals.js12
-rw-r--r--chromium/components/signin/core/browser/signin_error_controller.h6
-rw-r--r--chromium/components/signin/core/browser/signin_error_controller_unittest.cc25
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper.h5
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper_unittest.cc19
-rw-r--r--chromium/components/signin/internal/base/DEPS2
-rw-r--r--chromium/components/signin/internal/base/account_manager_facade_android.cc5
-rw-r--r--chromium/components/signin/internal/identity_manager/BUILD.gn8
-rw-r--r--chromium/components/signin/internal/identity_manager/DEPS3
-rw-r--r--chromium/components/signin/internal/identity_manager/account_fetcher_service.cc69
-rw-r--r--chromium/components/signin/internal/identity_manager/account_fetcher_service.h7
-rw-r--r--chromium/components/signin/internal/identity_manager/account_tracker_service.cc89
-rw-r--r--chromium/components/signin/internal/identity_manager/account_tracker_service.h14
-rw-r--r--chromium/components/signin/internal/identity_manager/account_tracker_service_unittest.cc29
-rw-r--r--chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc51
-rw-r--r--chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h27
-rw-r--r--chromium/components/signin/internal/identity_manager/accounts_mutator_impl.cc6
-rw-r--r--chromium/components/signin/internal/identity_manager/android/BUILD.gn12
-rw-r--r--chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc47
-rw-r--r--chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.h27
-rw-r--r--chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc63
-rw-r--r--chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc6
-rw-r--r--chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.cc22
-rw-r--r--chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.h12
-rw-r--r--chromium/components/signin/internal/identity_manager/oauth_multilogin_helper_unittest.cc34
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_manager.cc24
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_manager.h24
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_manager_unittest.cc15
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.cc13
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.h2
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_policy_manager_impl.cc13
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc10
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc (renamed from chromium/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.cc)175
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h (renamed from chromium/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h)33
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android_unittest.cc (renamed from chromium/components/signin/internal/identity_manager/oauth2_token_service_delegate_android_unittest.cc)7
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm5
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm7
-rw-r--r--chromium/components/signin/ios/OWNERS1
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service.mm12
-rw-r--r--chromium/components/signin/ios/browser/wait_for_network_callback_helper_unittest.cc12
-rw-r--r--chromium/components/signin/public/android/BUILD.gn38
-rw-r--r--chromium/components/signin/public/android/DEPS (renamed from chromium/components/signin/public/identity_manager/android/DEPS)12
-rw-r--r--chromium/components/signin/public/android/java/src/org/chromium/components/signin/base/CoreAccountId.java (renamed from chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java)2
-rw-r--r--chromium/components/signin/public/android/java/src/org/chromium/components/signin/base/CoreAccountInfo.java124
-rw-r--r--chromium/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java (renamed from chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java)57
-rw-r--r--chromium/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java (renamed from chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java)1
-rw-r--r--chromium/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegate.java (renamed from chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/OAuth2TokenService.java)99
-rw-r--r--chromium/components/signin/public/android/javatests/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegateTest.java (renamed from chromium/components/signin/public/identity_manager/android/javatests/src/org/chromium/components/signin/identitymanager/OAuth2TokenServiceTest.java)32
-rw-r--r--chromium/components/signin/public/base/BUILD.gn8
-rw-r--r--chromium/components/signin/public/base/account_consistency_method.cc4
-rw-r--r--chromium/components/signin/public/base/account_consistency_method.h5
-rw-r--r--chromium/components/signin/public/base/persistent_repeating_timer.cc54
-rw-r--r--chromium/components/signin/public/base/persistent_repeating_timer.h54
-rw-r--r--chromium/components/signin/public/base/persistent_repeating_timer_unittest.cc137
-rw-r--r--chromium/components/signin/public/base/signin_pref_names.cc5
-rw-r--r--chromium/components/signin/public/base/signin_pref_names.h1
-rw-r--r--chromium/components/signin/public/base/signin_switches.cc17
-rw-r--r--chromium/components/signin/public/base/signin_switches.h12
-rw-r--r--chromium/components/signin/public/identity_manager/BUILD.gn10
-rw-r--r--chromium/components/signin/public/identity_manager/access_token_fetcher.cc8
-rw-r--r--chromium/components/signin/public/identity_manager/access_token_fetcher.h14
-rw-r--r--chromium/components/signin/public/identity_manager/account_info.cc6
-rw-r--r--chromium/components/signin/public/identity_manager/account_info.h1
-rw-r--r--chromium/components/signin/public/identity_manager/accounts_cookie_mutator.h45
-rw-r--r--chromium/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc107
-rw-r--r--chromium/components/signin/public/identity_manager/android/BUILD.gn45
-rw-r--r--chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java110
-rw-r--r--chromium/components/signin/public/identity_manager/consent_level.h26
-rw-r--r--chromium/components/signin/public/identity_manager/identity_manager.cc90
-rw-r--r--chromium/components/signin/public/identity_manager/identity_manager.h66
-rw-r--r--chromium/components/signin/public/identity_manager/identity_manager_builder.cc1
-rw-r--r--chromium/components/signin/public/identity_manager/identity_manager_unittest.cc183
-rw-r--r--chromium/components/signin/public/identity_manager/identity_mutator.cc2
-rw-r--r--chromium/components/signin/public/identity_manager/identity_test_environment.cc38
-rw-r--r--chromium/components/signin/public/identity_manager/identity_test_environment.h18
-rw-r--r--chromium/components/signin/public/identity_manager/identity_test_utils.cc58
-rw-r--r--chromium/components/signin/public/identity_manager/identity_test_utils.h6
-rw-r--r--chromium/components/signin/public/identity_manager/identity_utils.cc1
-rw-r--r--chromium/components/signin/public/identity_manager/identity_utils.h9
-rw-r--r--chromium/components/signin/public/identity_manager/ios/BUILD.gn4
-rw-r--r--chromium/components/signin/public/identity_manager/objc/BUILD.gn4
-rw-r--r--chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.cc36
-rw-r--r--chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.h23
-rw-r--r--chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher_unittest.cc126
-rw-r--r--chromium/components/signin/public/identity_manager/primary_account_mutator.h13
-rw-r--r--chromium/components/signin/public/identity_manager/primary_account_mutator_unittest.cc34
-rw-r--r--chromium/components/signin/public/identity_manager/scope_set.h17
-rw-r--r--chromium/components/signin/public/webdata/BUILD.gn4
-rw-r--r--chromium/components/signin/public/webdata/token_web_data.cc11
-rw-r--r--chromium/components/signin/public/webdata/token_web_data.h3
121 files changed, 2189 insertions, 2280 deletions
diff --git a/chromium/components/signin/DEPS b/chromium/components/signin/DEPS
index 2bd7b72d440..73fad4f9ba1 100644
--- a/chromium/components/signin/DEPS
+++ b/chromium/components/signin/DEPS
@@ -16,7 +16,6 @@ include_rules = [
"+google_apis/gaia",
"+grit", # For generated headers
"+net",
- "+services/identity/public",
"+services/network/public",
"+services/network/test",
"+sql",
diff --git a/chromium/components/signin/core/browser/BUILD.gn b/chromium/components/signin/core/browser/BUILD.gn
index 0234d4e1bd3..8eb46aefb22 100644
--- a/chromium/components/signin/core/browser/BUILD.gn
+++ b/chromium/components/signin/core/browser/BUILD.gn
@@ -21,8 +21,6 @@ static_library("browser") {
"account_reconcilor_delegate.h",
"chrome_connected_header_helper.cc",
"chrome_connected_header_helper.h",
- "consistency_cookie_manager_base.cc",
- "consistency_cookie_manager_base.h",
"cookie_reminter.cc",
"cookie_reminter.h",
"cookie_settings_util.cc",
@@ -31,8 +29,6 @@ static_library("browser") {
"dice_account_reconcilor_delegate.h",
"dice_header_helper.cc",
"dice_header_helper.h",
- "mice_account_reconcilor_delegate.cc",
- "mice_account_reconcilor_delegate.h",
"mirror_account_reconcilor_delegate.cc",
"mirror_account_reconcilor_delegate.h",
"signin_error_controller.cc",
@@ -93,14 +89,6 @@ static_library("browser") {
]
}
- if (is_android) {
- sources += [
- "consistency_cookie_manager_android.cc",
- "consistency_cookie_manager_android.h",
- ]
- deps += [ "android:jni_headers" ]
- }
-
if (!enable_dice_support) {
sources -= [
"dice_account_reconcilor_delegate.cc",
@@ -117,7 +105,6 @@ source_set("unit_tests") {
"account_investigator_unittest.cc",
"account_reconcilor_unittest.cc",
"dice_account_reconcilor_delegate_unittest.cc",
- "mice_account_reconcilor_delegate_unittest.cc",
"signin_error_controller_unittest.cc",
"signin_header_helper_unittest.cc",
"signin_investigator_unittest.cc",
@@ -154,10 +141,6 @@ source_set("unit_tests") {
]
}
- if (is_android) {
- sources += [ "consistency_cookie_manager_unittest.cc" ]
- }
-
if (!enable_dice_support) {
sources -= [ "dice_account_reconcilor_delegate_unittest.cc" ]
}
diff --git a/chromium/components/signin/core/browser/about_signin_internals.cc b/chromium/components/signin/core/browser/about_signin_internals.cc
index 67e7053c60a..ae036e28bec 100644
--- a/chromium/components/signin/core/browser/about_signin_internals.cc
+++ b/chromium/components/signin/core/browser/about_signin_internals.cc
@@ -359,7 +359,7 @@ std::unique_ptr<base::DictionaryValue> AboutSigninInternals::GetSigninStatus() {
void AboutSigninInternals::OnAccessTokenRequested(
const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes) {
+ const signin::ScopeSet& scopes) {
TokenInfo* token = signin_status_.FindToken(account_id, consumer_id, scopes);
if (token) {
*token = TokenInfo(consumer_id, scopes);
@@ -374,7 +374,7 @@ void AboutSigninInternals::OnAccessTokenRequested(
void AboutSigninInternals::OnAccessTokenRequestCompleted(
const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes,
+ const signin::ScopeSet& scopes,
GoogleServiceAuthError error,
base::Time expiration_time) {
TokenInfo* token = signin_status_.FindToken(account_id, consumer_id, scopes);
@@ -428,7 +428,7 @@ void AboutSigninInternals::OnEndBatchOfRefreshTokenStateChanges() {
void AboutSigninInternals::OnAccessTokenRemovedFromCache(
const CoreAccountId& account_id,
- const identity::ScopeSet& scopes) {
+ const signin::ScopeSet& scopes) {
for (const std::unique_ptr<TokenInfo>& token :
signin_status_.token_info_map[account_id]) {
if (token->scopes == scopes)
@@ -490,7 +490,7 @@ void AboutSigninInternals::OnAccountsInCookieUpdated(
}
AboutSigninInternals::TokenInfo::TokenInfo(const std::string& consumer_id,
- const identity::ScopeSet& scopes)
+ const signin::ScopeSet& scopes)
: consumer_id(consumer_id),
scopes(scopes),
request_time(base::Time::Now()),
@@ -576,7 +576,7 @@ AboutSigninInternals::SigninStatus::~SigninStatus() {}
AboutSigninInternals::TokenInfo* AboutSigninInternals::SigninStatus::FindToken(
const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes) {
+ const signin::ScopeSet& scopes) {
for (const std::unique_ptr<TokenInfo>& token : token_info_map[account_id]) {
if (token->consumer_id == consumer_id && token->scopes == scopes)
return token.get();
diff --git a/chromium/components/signin/core/browser/about_signin_internals.h b/chromium/components/signin/core/browser/about_signin_internals.h
index 9b34c7d9895..1b715f2dd3a 100644
--- a/chromium/components/signin/core/browser/about_signin_internals.h
+++ b/chromium/components/signin/core/browser/about_signin_internals.h
@@ -21,7 +21,7 @@
#include "components/signin/core/browser/signin_internals_util.h"
#include "components/signin/public/base/signin_client.h"
#include "components/signin/public/identity_manager/identity_manager.h"
-#include "services/identity/public/cpp/scope_set.h"
+#include "components/signin/public/identity_manager/scope_set.h"
namespace signin {
struct AccountsInCookieJarInfo;
@@ -100,7 +100,7 @@ class AboutSigninInternals : public KeyedService,
private:
// Encapsulates diagnostic information about tokens for different services.
struct TokenInfo {
- TokenInfo(const std::string& consumer_id, const identity::ScopeSet& scopes);
+ TokenInfo(const std::string& consumer_id, const signin::ScopeSet& scopes);
~TokenInfo();
std::unique_ptr<base::DictionaryValue> ToValue() const;
@@ -111,7 +111,7 @@ class AboutSigninInternals : public KeyedService,
void Invalidate();
std::string consumer_id; // service that requested the token.
- identity::ScopeSet scopes; // Scoped that are requested.
+ signin::ScopeSet scopes; // Scoped that are requested.
base::Time request_time;
base::Time receive_time;
base::Time expiration_time;
@@ -154,7 +154,7 @@ class AboutSigninInternals : public KeyedService,
TokenInfo* FindToken(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes);
+ const signin::ScopeSet& scopes);
void AddRefreshTokenEvent(const RefreshTokenEvent& event);
@@ -185,14 +185,14 @@ class AboutSigninInternals : public KeyedService,
// IdentityManager::DiagnosticsObserver implementations.
void OnAccessTokenRequested(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes) override;
+ const signin::ScopeSet& scopes) override;
void OnAccessTokenRequestCompleted(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes,
+ const signin::ScopeSet& scopes,
GoogleServiceAuthError error,
base::Time expiration_time) override;
void OnAccessTokenRemovedFromCache(const CoreAccountId& account_id,
- const identity::ScopeSet& scopes) override;
+ const signin::ScopeSet& scopes) override;
void OnRefreshTokenUpdatedForAccountFromSource(
const CoreAccountId& account_id,
bool is_refresh_token_valid,
diff --git a/chromium/components/signin/core/browser/account_reconcilor.cc b/chromium/components/signin/core/browser/account_reconcilor.cc
index ff5b0e6982c..9d255485221 100644
--- a/chromium/components/signin/core/browser/account_reconcilor.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor.cc
@@ -21,7 +21,6 @@
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
-#include "components/signin/core/browser/consistency_cookie_manager_base.h"
#include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/base/signin_client.h"
#include "components/signin/public/base/signin_metrics.h"
@@ -33,10 +32,6 @@
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"
-#if defined(OS_ANDROID)
-#include "components/signin/core/browser/consistency_cookie_manager_android.h"
-#endif
-
using signin::AccountReconcilorDelegate;
using signin_metrics::AccountReconcilorState;
@@ -243,6 +238,7 @@ AccountReconcilor::AccountReconcilor(
error_during_last_reconcile_(GoogleServiceAuthError::AuthErrorNone()),
reconcile_is_noop_(true),
set_accounts_in_progress_(false),
+ log_out_in_progress_(false),
chrome_accounts_changed_(false),
account_reconcilor_lock_count_(0),
reconcile_on_unblock_(false),
@@ -282,17 +278,12 @@ void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) {
}
}
-void AccountReconcilor::SetConsistencyCookieManager(
- std::unique_ptr<signin::ConsistencyCookieManagerBase>
- consistency_cookie_manager) {
- consistency_cookie_manager_ = std::move(consistency_cookie_manager);
-}
-
void AccountReconcilor::EnableReconcile() {
- SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED);
RegisterWithAllDependencies();
if (IsIdentityManagerReady())
StartReconcile();
+ else
+ SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED);
}
void AccountReconcilor::DisableReconcile(bool logout_all_accounts) {
@@ -455,7 +446,9 @@ void AccountReconcilor::PerformLogoutAllAccountsAction() {
return;
VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction";
identity_manager_->GetAccountsCookieMutator()->LogOutAllAccounts(
- delegate_->GetGaiaApiSource());
+ delegate_->GetGaiaApiSource(),
+ base::BindOnce(&AccountReconcilor::OnLogOutFromCookieCompleted,
+ weak_factory_.GetWeakPtr()));
}
void AccountReconcilor::StartReconcile() {
@@ -471,6 +464,9 @@ void AccountReconcilor::StartReconcile() {
return;
}
+ // TODO(crbug.com/967603): remove when root cause is found.
+ CHECK(delegate_);
+ CHECK(client_);
if (!delegate_->IsReconcileEnabled() || !client_->AreSigninCookiesAllowed()) {
VLOG(1) << "AccountReconcilor::StartReconcile: !enabled or no cookies";
SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_OK);
@@ -548,6 +544,7 @@ void AccountReconcilor::FinishReconcileWithMultiloginEndpoint(
// instead.
PerformLogoutAllAccountsAction();
gaia_accounts.clear();
+ // TODO(alexilin): Asynchronously wait until the logout is complete.
OnSetAccountsInCookieCompleted(
signin::SetAccountsInCookieResult::kSuccess);
DCHECK(!is_reconcile_started_);
@@ -761,6 +758,7 @@ void AccountReconcilor::FinishReconcile(
// Really messed up state. Blow away the gaia cookie completely and
// rebuild it, making sure the primary account as specified by the
// IdentityManager is the first session in the gaia cookie.
+ log_out_in_progress_ = true;
PerformLogoutAllAccountsAction();
gaia_accounts.clear();
}
@@ -823,6 +821,7 @@ void AccountReconcilor::FinishReconcile(
void AccountReconcilor::AbortReconcile() {
VLOG(1) << "AccountReconcilor::AbortReconcile: try again later";
+ log_out_in_progress_ = false;
add_to_cookie_.clear();
CalculateIfReconcileIsDone();
@@ -833,7 +832,8 @@ void AccountReconcilor::AbortReconcile() {
void AccountReconcilor::CalculateIfReconcileIsDone() {
base::TimeDelta duration = base::Time::Now() - reconcile_start_time_;
// Record the duration if reconciliation was underway and now it is over.
- if (is_reconcile_started_ && add_to_cookie_.empty()) {
+ if (is_reconcile_started_ && add_to_cookie_.empty() &&
+ !log_out_in_progress_) {
bool was_last_reconcile_successful =
(error_during_last_reconcile_.state() ==
GoogleServiceAuthError::State::NONE);
@@ -855,7 +855,7 @@ void AccountReconcilor::CalculateIfReconcileIsDone() {
}
}
- is_reconcile_started_ = !add_to_cookie_.empty();
+ is_reconcile_started_ = !add_to_cookie_.empty() || log_out_in_progress_;
if (!is_reconcile_started_)
VLOG(1) << "AccountReconcilor::CalculateIfReconcileIsDone: done";
}
@@ -946,6 +946,23 @@ void AccountReconcilor::OnAddAccountToCookieCompleted(
}
}
+void AccountReconcilor::OnLogOutFromCookieCompleted(
+ const GoogleServiceAuthError& error) {
+ VLOG(1) << "AccountReconcilor::OnLogOutFromCookieCompleted: "
+ << "Error was " << error.ToString();
+
+ if (is_reconcile_started_) {
+ if (error.state() != GoogleServiceAuthError::State::NONE &&
+ !error_during_last_reconcile_.IsPersistentError()) {
+ error_during_last_reconcile_ = error;
+ }
+
+ log_out_in_progress_ = false;
+ CalculateIfReconcileIsDone();
+ ScheduleStartReconcileIfChromeAccountsChanged();
+ }
+}
+
void AccountReconcilor::IncrementLockCount() {
DCHECK_GE(account_reconcilor_lock_count_, 0);
++account_reconcilor_lock_count_;
diff --git a/chromium/components/signin/core/browser/account_reconcilor.h b/chromium/components/signin/core/browser/account_reconcilor.h
index df65ed4fe55..aa326c8c93f 100644
--- a/chromium/components/signin/core/browser/account_reconcilor.h
+++ b/chromium/components/signin/core/browser/account_reconcilor.h
@@ -30,7 +30,6 @@
namespace signin {
class AccountReconcilorDelegate;
-class ConsistencyCookieManagerBase;
enum class SetAccountsInCookieResult;
}
@@ -99,10 +98,6 @@ class AccountReconcilor : public KeyedService,
// construction.
void Initialize(bool start_reconcile_if_tokens_available);
- void SetConsistencyCookieManager(
- std::unique_ptr<signin::ConsistencyCookieManagerBase>
- consistency_cookie_manager);
-
// Enables and disables the reconciliation.
void EnableReconcile();
void DisableReconcile(bool logout_all_gaia_accounts);
@@ -178,6 +173,8 @@ class AccountReconcilor : public KeyedService,
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMirrorTest,
GetAccountsFromCookieSuccess);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMirrorTest,
+ EnableReconcileWhileAlreadyRunning);
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMirrorTest,
GetAccountsFromCookieFailure);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMirrorTest,
ExtraCookieChangeNotification);
@@ -287,6 +284,7 @@ class AccountReconcilor : public KeyedService,
void OnAddAccountToCookieCompleted(const CoreAccountId& account_id,
const GoogleServiceAuthError& error);
void OnSetAccountsInCookieCompleted(signin::SetAccountsInCookieResult result);
+ void OnLogOutFromCookieCompleted(const GoogleServiceAuthError& error);
// Lock related methods.
void IncrementLockCount();
@@ -346,6 +344,7 @@ class AccountReconcilor : public KeyedService,
// Used during reconcile action.
std::vector<CoreAccountId> add_to_cookie_; // Progress of AddAccount calls.
bool set_accounts_in_progress_; // Progress of SetAccounts calls.
+ bool log_out_in_progress_; // Progress of LogOut calls.
bool chrome_accounts_changed_;
// Used for the Lock.
@@ -373,9 +372,6 @@ class AccountReconcilor : public KeyedService,
signin_metrics::AccountReconcilorState state_;
- std::unique_ptr<signin::ConsistencyCookieManagerBase>
- consistency_cookie_manager_;
-
base::WeakPtrFactory<AccountReconcilor> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(AccountReconcilor);
diff --git a/chromium/components/signin/core/browser/account_reconcilor_unittest.cc b/chromium/components/signin/core/browser/account_reconcilor_unittest.cc
index 722e5733a1e..ad3a178b11a 100644
--- a/chromium/components/signin/core/browser/account_reconcilor_unittest.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -21,7 +21,6 @@
#include "build/build_config.h"
#include "components/prefs/pref_service.h"
#include "components/signin/core/browser/account_reconcilor.h"
-#include "components/signin/core/browser/mice_account_reconcilor_delegate.h"
#include "components/signin/core/browser/mirror_account_reconcilor_delegate.h"
#include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/base/list_accounts_test_utils.h"
@@ -144,10 +143,6 @@ class DummyAccountReconcilorWithDelegate : public AccountReconcilor {
bool dice_migration_completed) {
switch (account_consistency) {
case signin::AccountConsistencyMethod::kMirror:
-#if defined(OS_ANDROID)
- if (base::FeatureList::IsEnabled(signin::kMiceFeature))
- return std::make_unique<signin::MiceAccountReconcilorDelegate>();
-#endif
return std::make_unique<signin::MirrorAccountReconcilorDelegate>(
identity_manager);
case signin::AccountConsistencyMethod::kDisabled:
@@ -260,14 +255,17 @@ class AccountReconcilorTest : public ::testing::Test {
const CoreAccountId& account_id,
const GoogleServiceAuthError& error);
- void SimulateCookieContentSettingsChanged(
- content_settings::Observer* observer,
- const ContentSettingsPattern& primary_pattern);
-
void SimulateSetAccountsInCookieCompleted(
AccountReconcilor* reconcilor,
signin::SetAccountsInCookieResult result);
+ void SimulateLogOutFromCookieCompleted(AccountReconcilor* reconcilor,
+ const GoogleServiceAuthError& error);
+
+ void SimulateCookieContentSettingsChanged(
+ content_settings::Observer* observer,
+ const ContentSettingsPattern& primary_pattern);
+
void SetAccountConsistency(signin::AccountConsistencyMethod method);
// Should never be called before |SetAccountConsistency|.
@@ -292,21 +290,6 @@ class AccountReconcilorTest : public ::testing::Test {
DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTest);
};
-#if defined(OS_ANDROID)
-// Same as AccountReconcilorTest, with Mice enabled.
-class AccountReconcilorMiceTest : public AccountReconcilorTest {
- public:
- AccountReconcilorMiceTest() {
- SetAccountConsistency(signin::AccountConsistencyMethod::kMirror);
- scoped_feature_list_.InitAndEnableFeature(signin::kMiceFeature);
- }
-
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
- DISALLOW_COPY_AND_ASSIGN(AccountReconcilorMiceTest);
-};
-#endif
-
class AccountReconcilorMirrorTest : public AccountReconcilorTest {
public:
AccountReconcilorMirrorTest() {
@@ -404,6 +387,12 @@ void AccountReconcilorTest::SimulateSetAccountsInCookieCompleted(
reconcilor->OnSetAccountsInCookieCompleted(result);
}
+void AccountReconcilorTest::SimulateLogOutFromCookieCompleted(
+ AccountReconcilor* reconcilor,
+ const GoogleServiceAuthError& error) {
+ reconcilor->OnLogOutFromCookieCompleted(error);
+}
+
void AccountReconcilorTest::SimulateCookieContentSettingsChanged(
content_settings::Observer* observer,
const ContentSettingsPattern& primary_pattern) {
@@ -695,8 +684,11 @@ class BaseAccountReconcilorTestTable : public AccountReconcilorTest {
ASSERT_TRUE(reconcilor->delegate_->IsAccountConsistencyEnforced());
reconcilor->StartReconcile();
for (int i = 0; gaia_api_calls_[i] != '\0'; ++i) {
- if (gaia_api_calls_[i] == 'X')
+ if (gaia_api_calls_[i] == 'X') {
+ SimulateLogOutFromCookieCompleted(
+ reconcilor, GoogleServiceAuthError::AuthErrorNone());
continue;
+ }
CoreAccountId account_id =
PickAccountIdForAccount(accounts_[gaia_api_calls_[i]].gaia_id,
accounts_[gaia_api_calls_[i]].email);
@@ -1381,6 +1373,8 @@ TEST_P(AccountReconcilorDiceEndpointParamTest,
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
if (!IsMultiloginEnabled()) {
+ SimulateLogOutFromCookieCompleted(reconcilor,
+ GoogleServiceAuthError::AuthErrorNone());
SimulateAddAccountToCookieCompleted(
reconcilor, account_id_1, GoogleServiceAuthError::AuthErrorNone());
SimulateAddAccountToCookieCompleted(
@@ -1872,193 +1866,6 @@ INSTANTIATE_TEST_SUITE_P(
::testing::ValuesIn(GenerateTestCasesFromParams(kActiveDirectoryParams)));
#endif // defined(OS_CHROMEOS)
-#if defined(OS_ANDROID)
-// clang-format off
-const std::vector<AccountReconcilorTestTableParam> kMiceParams = {
-// This table encodes the initial state and expectations of a reconcile.
-// See kDiceParams for documentation of the syntax.
-// -------------------------------------------------------------------------
-// Tokens | Cookies | First Run | Gaia calls | Tokens after | Cookies after
-// -------------------------------------------------------------------------
-{ "A", "A", IsFirstReconcile::kBoth, "", "A", "A"},
-{ "A", "B", IsFirstReconcile::kBoth, "U", "A", "A"},
-{ "A", "", IsFirstReconcile::kBoth, "U", "A", "A"},
-{ "A", "xA", IsFirstReconcile::kBoth, "U", "A", "A"},
-{ "A", "AxB", IsFirstReconcile::kBoth, "U", "A", "A"},
-{ "xA", "A", IsFirstReconcile::kBoth, "X", "xA", ""},
-{ "xA", "xA", IsFirstReconcile::kBoth, "", "xA", "xA"},
-{ "xA", "xB", IsFirstReconcile::kBoth, "X", "xA", ""},
-{ "xA", "", IsFirstReconcile::kBoth, "", "xA", ""},
-{ "", "A", IsFirstReconcile::kBoth, "X", "", ""},
-{ "", "xA", IsFirstReconcile::kBoth, "X", "", ""},
-};
-// clang-format on
-
-// Parameterized version of AccountReconcilorTest that tests Mice implementation
-// with Multilogin endpoint.
-class AccountReconcilorTestMiceMultilogin : public AccountReconcilorTestTable {
- public:
- AccountReconcilorTestMiceMultilogin() = default;
-
- protected:
- base::test::ScopedFeatureList scoped_feature_list_;
-
- private:
- DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTestMiceMultilogin);
-};
-
-// Checks one row of the kMiceParams table above.
-TEST_P(AccountReconcilorTestMiceMultilogin, TableRowTest) {
- // Enable Mirror.
- SetAccountConsistency(signin::AccountConsistencyMethod::kMirror);
- scoped_feature_list_.InitAndEnableFeature(signin::kMiceFeature);
-
- // Setup cookies.
- std::vector<Cookie> cookies = ParseCookieString(GetParam().cookies);
- ConfigureCookieManagerService(cookies);
-
- // Setup tokens. This triggers listing cookies so we need to setup cookies
- // before that.
- SetupTokens(GetParam().tokens);
-
- // Call list accounts now so that the next call completes synchronously.
- identity_test_env()->identity_manager()->GetAccountsInCookieJar();
- base::RunLoop().RunUntilIdle();
-
- // Setup expectations.
- testing::InSequence mock_sequence;
- bool logout_action = false;
- for (int i = 0; GetParam().gaia_api_calls[i] != '\0'; ++i) {
- if (GetParam().gaia_api_calls[i] == 'X') {
- logout_action = true;
- EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
- .Times(1);
- cookies.clear();
- continue;
- }
- if (GetParam().gaia_api_calls[i] == 'U') {
- std::vector<CoreAccountId> accounts_to_send;
- for (int i = 0; GetParam().cookies_after_reconcile[i] != '\0'; ++i) {
- char cookie = GetParam().cookies_after_reconcile[i];
- std::string account_to_send = GaiaIdForAccountKey(cookie);
- accounts_to_send.push_back(PickAccountIdForAccount(
- account_to_send,
- accounts_[GetParam().cookies_after_reconcile[i]].email));
- }
- const signin::MultiloginParameters params(
- gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
- accounts_to_send);
- EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params))
- .Times(1);
- }
- }
- if (!logout_action) {
- EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
- .Times(0);
- }
-
- // Reconcile.
- AccountReconcilor* reconcilor = GetMockReconcilor();
- ASSERT_TRUE(reconcilor);
- ASSERT_TRUE(reconcilor->first_execution_);
- reconcilor->first_execution_ =
- GetParam().is_first_reconcile == IsFirstReconcile::kFirst ? true : false;
- reconcilor->StartReconcile();
-
- SimulateSetAccountsInCookieCompleted(
- reconcilor, signin::SetAccountsInCookieResult::kSuccess);
-
- ASSERT_FALSE(reconcilor->is_reconcile_started_);
- ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
- VerifyCurrentTokens(ParseTokenString(GetParam().tokens_after_reconcile));
-
- testing::Mock::VerifyAndClearExpectations(GetMockReconcilor());
-
- // Another reconcile is sometimes triggered if Chrome accounts have
- // changed. Allow it to finish.
- EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(testing::_))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
- .WillRepeatedly(testing::Return());
- ConfigureCookieManagerService({});
- base::RunLoop().RunUntilIdle();
-}
-
-INSTANTIATE_TEST_SUITE_P(
- MiceTableMultilogin,
- AccountReconcilorTestMiceMultilogin,
- ::testing::ValuesIn(GenerateTestCasesFromParams(kMiceParams)));
-
-// Checks that the reconcilor state does:
-// RUNNING -> SCHEDULED -> RUNNING -> OK.
-TEST_F(AccountReconcilorMiceTest, AccountReconcilorStateScheduled) {
- class TestAccountReconcilorObserver
- : public testing::StrictMock<AccountReconcilor::Observer> {
- public:
- MOCK_METHOD1(OnStateChanged, void(AccountReconcilorState state));
- };
-
- AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
- signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
-
- EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(testing::_));
-
- // The reconcilor should run twice without going to the OK state in between.
- // OK only happens at the end.
- TestAccountReconcilorObserver observer;
- testing::InSequence mock_sequence;
- EXPECT_CALL(observer, OnStateChanged(
- AccountReconcilorState::ACCOUNT_RECONCILOR_RUNNING))
- .Times(1);
- EXPECT_CALL(
- observer,
- OnStateChanged(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED))
- .Times(1);
- EXPECT_CALL(observer, OnStateChanged(
- AccountReconcilorState::ACCOUNT_RECONCILOR_RUNNING))
- .Times(1);
- EXPECT_CALL(observer,
- OnStateChanged(AccountReconcilorState::ACCOUNT_RECONCILOR_OK))
- .Times(1);
-
- AccountReconcilor* reconcilor = GetMockReconcilor();
- ASSERT_TRUE(reconcilor);
- ScopedObserver<AccountReconcilor, AccountReconcilor::Observer>
- scoped_observer(&observer);
- scoped_observer.Add(reconcilor);
-
- // Reconcile was scheduled when the account was added.
- EXPECT_EQ(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED,
- reconcilor->GetState());
-
- ASSERT_FALSE(reconcilor->is_reconcile_started_);
- reconcilor->StartReconcile();
- ASSERT_TRUE(reconcilor->is_reconcile_started_);
- EXPECT_EQ(AccountReconcilorState::ACCOUNT_RECONCILOR_RUNNING,
- reconcilor->GetState());
- base::RunLoop().RunUntilIdle();
-
- // The reconcilor started a request to add the account to the cookie, and is
- // waiting for the response.
-
- // Change the token while the reconcilor is running, to trigger another
- // reconcile after the current one.
- identity_test_env()->SetInvalidRefreshTokenForAccount(
- account_info.account_id);
-
- // Unblock the first reconcile.
- SimulateSetAccountsInCookieCompleted(
- reconcilor, signin::SetAccountsInCookieResult::kSuccess);
- // Wait until the first reconcile finishes, and a second reconcile is done.
- // The second reconcile will be a no-op.
- base::RunLoop().RunUntilIdle();
-
- ASSERT_FALSE(reconcilor->is_reconcile_started_);
- EXPECT_EQ(AccountReconcilorState::ACCOUNT_RECONCILOR_OK,
- reconcilor->GetState());
-}
-#endif // defined(OS_ANDROID)
-
// Tests that reconcile cannot start before the tokens are loaded, and is
// automatically started when tokens are loaded.
TEST_F(AccountReconcilorMirrorTest, TokensNotLoaded) {
@@ -2123,6 +1930,42 @@ TEST_F(AccountReconcilorMirrorTest, GetAccountsFromCookieSuccess) {
ASSERT_EQ(0u, accounts_in_cookie_jar_info.signed_out_accounts.size());
}
+// Checks that calling EnableReconcile() while the reconcilor is already running
+// doesn't have any effect. Regression test for https://crbug.com/1043651
+TEST_F(AccountReconcilorMirrorTest, EnableReconcileWhileAlreadyRunning) {
+ AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
+ const CoreAccountId account_id = account_info.account_id;
+ signin::SetListAccountsResponseOneAccountWithParams(
+ {account_info.email, account_info.gaia, false /* valid */,
+ false /* signed_out */, true /* verified */},
+ &test_url_loader_factory_);
+
+ std::vector<CoreAccountId> accounts_to_send = {account_id};
+ const signin::MultiloginParameters params(
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
+ accounts_to_send);
+ EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
+
+ AccountReconcilor* reconcilor = GetMockReconcilor();
+ ASSERT_TRUE(reconcilor);
+
+ ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED,
+ reconcilor->GetState());
+ reconcilor->StartReconcile();
+ EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
+ reconcilor->EnableReconcile();
+ EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
+ base::RunLoop().RunUntilIdle();
+ ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
+
+ signin::AccountsInCookieJarInfo accounts_in_cookie_jar_info =
+ identity_test_env()->identity_manager()->GetAccountsInCookieJar();
+ ASSERT_TRUE(accounts_in_cookie_jar_info.accounts_are_fresh);
+ ASSERT_EQ(1u, accounts_in_cookie_jar_info.signed_in_accounts.size());
+ ASSERT_EQ(account_id, accounts_in_cookie_jar_info.signed_in_accounts[0].id);
+ ASSERT_EQ(0u, accounts_in_cookie_jar_info.signed_out_accounts.size());
+}
+
TEST_F(AccountReconcilorMirrorTest, GetAccountsFromCookieFailure) {
ConnectProfileToAccount("user@gmail.com");
signin::SetListAccountsResponseWithUnexpectedServiceResponse(
@@ -2738,113 +2581,6 @@ TEST_P(AccountReconcilorMethodParamTest,
ASSERT_FALSE(reconcilor->is_reconcile_started_);
}
-// Checks that the reconcilor state does:
-// RUNNING -> SCHEDULED -> RUNNING -> OK.
-// This test is similar to
-// AccountReconcilorMiceTest.AccountReconctiorStateScheduled, but uses the
-// MergeSession endpoint. It also uses multiple accounts, because Mirror would
-// stop when the first account is in error.
-TEST_P(AccountReconcilorMethodParamTest, AccountReconcilorStateScheduled) {
- class TestAccountReconcilorObserver
- : public testing::StrictMock<AccountReconcilor::Observer> {
- public:
- MOCK_METHOD1(OnStateChanged, void(AccountReconcilorState state));
- };
-
- signin::AccountConsistencyMethod account_consistency = GetParam();
- SetAccountConsistency(account_consistency);
- AccountInfo account_info1 = ConnectProfileToAccount("user@gmail.com");
- AccountInfo account_info2 =
- identity_test_env()->MakeAccountAvailable("other@gmail.com");
- const CoreAccountId account_id1 = account_info1.account_id;
- const CoreAccountId account_id2 = account_info2.account_id;
- signin::SetListAccountsResponseOneAccount(
- account_info1.email, account_info1.gaia, &test_url_loader_factory_);
-
- AccountReconcilor* reconcilor = GetMockReconcilor();
- ASSERT_TRUE(reconcilor);
-
- if (!reconcilor->IsMultiloginEndpointEnabled()) {
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id2));
- } else {
- switch (account_consistency) {
- case signin::AccountConsistencyMethod::kMirror: {
- signin::MultiloginParameters params(
- gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
- {account_id1, account_id2});
- EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
- break;
- }
- case signin::AccountConsistencyMethod::kDice: {
- signin::MultiloginParameters params(
- gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER,
- {account_id2, account_id1});
- EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
- break;
- }
- case signin::AccountConsistencyMethod::kDisabled:
- NOTREACHED();
- break;
- }
- }
-
- // The reconcilor should run twice without going to the OK state in between.
- // OK only happens at the end.
- TestAccountReconcilorObserver observer;
- testing::InSequence mock_sequence;
- EXPECT_CALL(observer, OnStateChanged(
- AccountReconcilorState::ACCOUNT_RECONCILOR_RUNNING))
- .Times(1);
- EXPECT_CALL(
- observer,
- OnStateChanged(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED))
- .Times(1);
- EXPECT_CALL(observer, OnStateChanged(
- AccountReconcilorState::ACCOUNT_RECONCILOR_RUNNING))
- .Times(1);
- EXPECT_CALL(observer,
- OnStateChanged(AccountReconcilorState::ACCOUNT_RECONCILOR_OK))
- .Times(1);
-
- ScopedObserver<AccountReconcilor, AccountReconcilor::Observer>
- scoped_observer(&observer);
- scoped_observer.Add(reconcilor);
-
- // Reconcile was scheduled when the account was added.
- EXPECT_EQ(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED,
- reconcilor->GetState());
-
- ASSERT_FALSE(reconcilor->is_reconcile_started_);
- reconcilor->StartReconcile();
- ASSERT_TRUE(reconcilor->is_reconcile_started_);
- EXPECT_EQ(AccountReconcilorState::ACCOUNT_RECONCILOR_RUNNING,
- reconcilor->GetState());
- base::RunLoop().RunUntilIdle();
-
- // The reconcilor started a request to add the account to the cookie, and is
- // waiting for the response.
-
- // Change the token while the reconcilor is running, to trigger another
- // reconcile after the current one.
- identity_test_env()->RemoveRefreshTokenForAccount(account_id2);
-
- if (!reconcilor->IsMultiloginEndpointEnabled()) {
- SimulateAddAccountToCookieCompleted(
- reconcilor, account_id2, GoogleServiceAuthError::AuthErrorNone());
- } else {
- SimulateSetAccountsInCookieCompleted(
- reconcilor, signin::SetAccountsInCookieResult::kSuccess);
- }
-
- // Wait until the first reconcile finishes, and a second reconcile is done.
- // The second reconcile will be a no-op.
- base::RunLoop().RunUntilIdle();
-
- ASSERT_FALSE(reconcilor->is_reconcile_started_);
- EXPECT_EQ(AccountReconcilorState::ACCOUNT_RECONCILOR_OK,
- reconcilor->GetState());
-}
-
TEST_F(AccountReconcilorMirrorTest,
AddAccountToCookieCompletedWithBogusAccount) {
AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
diff --git a/chromium/components/signin/core/browser/android/BUILD.gn b/chromium/components/signin/core/browser/android/BUILD.gn
index 15af61d18d3..62fef1b70e0 100644
--- a/chromium/components/signin/core/browser/android/BUILD.gn
+++ b/chromium/components/signin/core/browser/android/BUILD.gn
@@ -6,10 +6,9 @@ import("//build/config/android/rules.gni")
generate_jni("jni_headers") {
sources = [
- "java/src/org/chromium/components/signin/AccountManagerFacade.java",
+ "java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java",
"java/src/org/chromium/components/signin/AccountTrackerService.java",
"java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java",
- "java/src/org/chromium/components/signin/ConsistencyCookieManager.java",
]
}
@@ -26,37 +25,36 @@ android_library("java") {
"//ui/android:ui_java",
]
- java_files = [
- "java/src/org/chromium/components/signin/AccountIdProvider.java",
+ sources = [
"java/src/org/chromium/components/signin/AccountManagerDelegate.java",
"java/src/org/chromium/components/signin/AccountManagerDelegateException.java",
"java/src/org/chromium/components/signin/AccountManagerFacade.java",
+ "java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java",
"java/src/org/chromium/components/signin/AccountManagerResult.java",
- "java/src/org/chromium/components/signin/AccountsChangeObserver.java",
"java/src/org/chromium/components/signin/AccountTrackerService.java",
+ "java/src/org/chromium/components/signin/AccountUtils.java",
+ "java/src/org/chromium/components/signin/AccountsChangeObserver.java",
"java/src/org/chromium/components/signin/AuthException.java",
"java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java",
"java/src/org/chromium/components/signin/ChildAccountStatus.java",
"java/src/org/chromium/components/signin/ChromeSigninController.java",
- "java/src/org/chromium/components/signin/ConsistencyCookieManager.java",
"java/src/org/chromium/components/signin/GmsAvailabilityException.java",
"java/src/org/chromium/components/signin/GmsJustUpdatedException.java",
- "java/src/org/chromium/components/signin/util/PatternMatcher.java",
"java/src/org/chromium/components/signin/MutableObservableValue.java",
"java/src/org/chromium/components/signin/ObservableValue.java",
"java/src/org/chromium/components/signin/ProfileDataSource.java",
- "java/src/org/chromium/components/signin/SigninActivityMonitor.java",
"java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java",
+ "java/src/org/chromium/components/signin/util/PatternMatcher.java",
]
annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
}
junit_binary("components_signin_junit_tests") {
- java_files = [
+ sources = [
"junit/src/org/chromium/components/signin/test/AccountManagerFacadeRobolectricTest.java",
- "junit/src/org/chromium/components/signin/test/PatternMatcherTest.java",
"junit/src/org/chromium/components/signin/test/ObservableValueTest.java",
+ "junit/src/org/chromium/components/signin/test/PatternMatcherTest.java",
]
deps = [
":java",
@@ -77,13 +75,14 @@ android_library("signin_javatests") {
"//base:base_java",
"//base:base_java_test_support",
"//third_party/android_deps:androidx_annotation_annotation_java",
+ "//third_party/android_deps:androidx_test_monitor_java",
"//third_party/android_support_test_runner:rules_java",
"//third_party/android_support_test_runner:runner_java",
"//third_party/jsr-305:jsr_305_javalib",
"//third_party/junit",
]
- java_files = [ "javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java" ]
+ sources = [ "javatests/src/org/chromium/components/signin/test/AccountManagerFacadeTest.java" ]
}
android_library("signin_java_test_support") {
@@ -97,7 +96,7 @@ android_library("signin_java_test_support") {
"//third_party/junit",
]
- java_files = [
+ sources = [
"javatests/src/org/chromium/components/signin/test/util/AccountHolder.java",
"javatests/src/org/chromium/components/signin/test/util/AccountManagerTestRule.java",
"javatests/src/org/chromium/components/signin/test/util/FakeAccountManagerDelegate.java",
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountIdProvider.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountIdProvider.java
deleted file mode 100644
index d01d7b3edc6..00000000000
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountIdProvider.java
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright 2014 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.
-
-package org.chromium.components.signin;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.google.android.gms.auth.GoogleAuthException;
-import com.google.android.gms.auth.GoogleAuthUtil;
-import com.google.android.gms.common.ConnectionResult;
-import com.google.android.gms.common.GoogleApiAvailability;
-
-import org.chromium.base.ContextUtils;
-import org.chromium.base.Log;
-import org.chromium.base.StrictModeContext;
-import org.chromium.base.ThreadUtils;
-
-import java.io.IOException;
-
-/**
- * Returns a stable id that can be used to identify a Google Account. This
- * id does not change if the email address associated to the account changes,
- * nor does it change depending on whether the email has dots or varying
- * capitalization.
- */
-public class AccountIdProvider {
- private static AccountIdProvider sProvider;
-
- protected AccountIdProvider() {
- // should not be initialized outside getInstance().
- }
-
- /**
- * Returns a stable id for the account associated with the given email address.
- * If an account with the given email address is not installed on the device
- * then null is returned.
- *
- * This method will throw IllegalStateException if called on the main thread.
- *
- * @param accountName The email address of a Google account.
- */
- public String getAccountId(String accountName) {
- try {
- return GoogleAuthUtil.getAccountId(ContextUtils.getApplicationContext(), accountName);
- } catch (IOException | GoogleAuthException ex) {
- Log.e("cr.AccountIdProvider", "AccountIdProvider.getAccountId", ex);
- return null;
- }
- }
-
- /**
- * Returns whether the AccountIdProvider can be used.
- * Since the AccountIdProvider queries Google Play services, this basically checks whether
- * Google Play services is available.
- */
- public boolean canBeUsed() {
- // TODO(http://crbug.com/577190): Remove StrictMode override.
- try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) {
- int resultCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
- ContextUtils.getApplicationContext());
- return resultCode == ConnectionResult.SUCCESS;
- }
- }
-
- /**
- * Gets the global account Id provider.
- */
- public static AccountIdProvider getInstance() {
- ThreadUtils.assertOnUiThread();
- if (sProvider == null) sProvider = new AccountIdProvider();
- return sProvider;
- }
-
- /**
- * For testing purposes only, allows to set the provider even if it has already been
- * initialized.
- */
- @VisibleForTesting
- public static void setInstanceForTest(AccountIdProvider provider) {
- ThreadUtils.assertOnUiThread();
- sProvider = provider;
- }
-}
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
index 279e5e5967a..3e4f343bee4 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerDelegate.java
@@ -111,4 +111,22 @@ public interface AccountManagerDelegate {
default ProfileDataSource getProfileDataSource() {
return null;
}
+
+ /**
+ * Returns the Gaia id for the account associated with the given email address.
+ * If an account with the given email address is not installed on the device
+ * then null is returned.
+ *
+ * This method will throw IllegalStateException if called on the main thread.
+ *
+ * @param accountEmail The email address of a Google account.
+ */
+ @WorkerThread
+ @Nullable
+ String getAccountGaiaId(String accountEmail);
+
+ /**
+ * Checks whether Google Play services is available.
+ */
+ boolean isGooglePlayServicesAvailable();
}
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
index 5e4157122d3..cb781dc9d38 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java
@@ -29,8 +29,7 @@ import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.ObserverList;
import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.metrics.CachedMetrics;
+import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.task.AsyncTask;
import org.chromium.components.signin.util.PatternMatcher;
@@ -38,23 +37,15 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicReference;
-import java.util.regex.Pattern;
/**
* AccountManagerFacade wraps our access of AccountManager in Android.
*
- * Use the {@link #initializeAccountManagerFacade} to instantiate it.
- * After initialization, instance get be acquired by calling {@link #get}.
*/
public class AccountManagerFacade {
private static final String TAG = "Sync_Signin";
- private static final Pattern AT_SYMBOL = Pattern.compile("@");
- private static final String GMAIL_COM = "gmail.com";
- private static final String GOOGLEMAIL_COM = "googlemail.com";
- public static final String GOOGLE_ACCOUNT_TYPE = "com.google";
/**
* An account feature (corresponding to a Gaia service flag) that specifies whether the account
@@ -73,12 +64,6 @@ public class AccountManagerFacade {
@VisibleForTesting
public static final String ACCOUNT_RESTRICTION_PATTERNS_KEY = "RestrictAccountsToPatterns";
- private static AccountManagerFacade sInstance;
- private static AccountManagerFacade sTestingInstance;
-
- private static final AtomicReference<AccountManagerFacade> sAtomicInstance =
- new AtomicReference<>();
-
private final AccountManagerDelegate mDelegate;
private final ObserverList<AccountsChangeObserver> mObservers = new ObserverList<>();
@@ -89,8 +74,6 @@ public class AccountManagerFacade {
private final AtomicReference<AccountManagerResult<List<Account>>> mFilteredAccounts =
new AtomicReference<>();
private final CountDownLatch mPopulateAccountCacheLatch = new CountDownLatch(1);
- private final CachedMetrics.TimesHistogramSample mPopulateAccountCacheWaitingTimeHistogram =
- new CachedMetrics.TimesHistogramSample("Signin.AndroidPopulateAccountCacheWaitingTime");
private final ArrayList<Runnable> mCallbacksWaitingForCachePopulation = new ArrayList<>();
@@ -101,7 +84,7 @@ public class AccountManagerFacade {
/**
* @param delegate the AccountManagerDelegate to use as a backend
*/
- private AccountManagerFacade(AccountManagerDelegate delegate) {
+ AccountManagerFacade(AccountManagerDelegate delegate) {
ThreadUtils.assertOnUiThread();
mDelegate = delegate;
mDelegate.registerObservers();
@@ -115,65 +98,6 @@ public class AccountManagerFacade {
}
/**
- * Initializes AccountManagerFacade singleton instance. Can only be called once.
- * Tests can override the instance with {@link #overrideAccountManagerFacadeForTests}.
- *
- * @param delegate the AccountManagerDelegate to use
- */
- @MainThread
- public static void initializeAccountManagerFacade(AccountManagerDelegate delegate) {
- ThreadUtils.assertOnUiThread();
- if (sInstance != null) {
- throw new IllegalStateException("AccountManagerFacade is already initialized!");
- }
- sInstance = new AccountManagerFacade(delegate);
- if (sTestingInstance != null) return;
- sAtomicInstance.set(sInstance);
- }
-
- /**
- * Overrides AccountManagerFacade singleton instance for tests. Only for use in Tests.
- * Overrides any previous or future calls to {@link #initializeAccountManagerFacade}.
- *
- * @param delegate the AccountManagerDelegate to use
- */
- @VisibleForTesting
- @AnyThread
- public static void overrideAccountManagerFacadeForTests(AccountManagerDelegate delegate) {
- ThreadUtils.runOnUiThreadBlocking(() -> {
- sTestingInstance = new AccountManagerFacade(delegate);
- sAtomicInstance.set(sTestingInstance);
- });
- }
-
- /**
- * Resets custom AccountManagerFacade set with {@link #overrideAccountManagerFacadeForTests}.
- * Only for use in Tests.
- */
- @VisibleForTesting
- @AnyThread
- public static void resetAccountManagerFacadeForTests() {
- ThreadUtils.runOnUiThreadBlocking(() -> {
- sTestingInstance = null;
- sAtomicInstance.set(sInstance);
- });
- }
-
- /**
- * Singleton instance getter. Singleton must be initialized before calling this by
- * {@link #initializeAccountManagerFacade} or {@link #overrideAccountManagerFacadeForTests}.
- *
- * @return a singleton instance
- */
- @AnyThread
- @CalledByNative
- public static AccountManagerFacade get() {
- AccountManagerFacade instance = sAtomicInstance.get();
- assert instance != null : "AccountManagerFacade is not initialized!";
- return instance;
- }
-
- /**
* Adds an observer to receive accounts change notifications.
* @param observer the observer to add.
*/
@@ -196,14 +120,6 @@ public class AccountManagerFacade {
}
/**
- * Creates an Account object for the given name.
- */
- @AnyThread
- public static Account createAccountFromName(String name) {
- return new Account(name, GOOGLE_ACCOUNT_TYPE);
- }
-
- /**
* Runs a callback after the account list cache is populated. In the callback
* {@link #getGoogleAccounts()} and similar methods are guaranteed to return instantly (without
* blocking and waiting for the cache to be populated). If the cache has already been populated,
@@ -264,14 +180,6 @@ public class AccountManagerFacade {
* Asynchronous version of {@link #tryGetGoogleAccountNames()}.
*/
@MainThread
- public void tryGetGoogleAccountNames(final Callback<List<String>> callback) {
- runAfterCacheIsPopulated(() -> callback.onResult(tryGetGoogleAccountNames()));
- }
-
- /**
- * Asynchronous version of {@link #tryGetGoogleAccountNames()}.
- */
- @MainThread
public void getGoogleAccountNames(
final Callback<AccountManagerResult<List<String>>> callback) {
runAfterCacheIsPopulated(() -> {
@@ -306,7 +214,8 @@ public class AccountManagerFacade {
mPopulateAccountCacheLatch.await();
maybeAccounts = mFilteredAccounts.get();
if (ThreadUtils.runningOnUiThread()) {
- mPopulateAccountCacheWaitingTimeHistogram.record(
+ RecordHistogram.recordTimesHistogram(
+ "Signin.AndroidPopulateAccountCacheWaitingTime",
SystemClock.elapsedRealtime() - now);
}
} catch (InterruptedException e) {
@@ -317,14 +226,6 @@ public class AccountManagerFacade {
}
/**
- * Asynchronous version of {@link #getGoogleAccounts()}.
- */
- @MainThread
- public void getGoogleAccounts(Callback<AccountManagerResult<List<Account>>> callback) {
- runAfterCacheIsPopulated(() -> callback.onResult(mFilteredAccounts.get()));
- }
-
- /**
* Retrieves all Google accounts on the device.
* Returns an empty array if an error occurs while getting account list.
*/
@@ -346,45 +247,15 @@ public class AccountManagerFacade {
}
/**
- * Determine whether there are any Google accounts on the device.
- * Returns false if an error occurs while getting account list.
- */
- @AnyThread
- public boolean hasGoogleAccounts() {
- return !tryGetGoogleAccounts().isEmpty();
- }
-
- /**
- * Asynchronous version of {@link #hasGoogleAccounts()}.
- */
- @MainThread
- public void hasGoogleAccounts(final Callback<Boolean> callback) {
- runAfterCacheIsPopulated(() -> callback.onResult(hasGoogleAccounts()));
- }
-
- private String canonicalizeName(String name) {
- String[] parts = AT_SYMBOL.split(name);
- if (parts.length != 2) return name;
-
- if (GOOGLEMAIL_COM.equalsIgnoreCase(parts[1])) {
- parts[1] = GMAIL_COM;
- }
- if (GMAIL_COM.equalsIgnoreCase(parts[1])) {
- parts[0] = parts[0].replace(".", "");
- }
- return (parts[0] + "@" + parts[1]).toLowerCase(Locale.US);
- }
-
- /**
* Returns the account if it exists; null if account doesn't exists or an error occurs
* while getting account list.
*/
@AnyThread
public Account getAccountFromName(String accountName) {
- String canonicalName = canonicalizeName(accountName);
+ String canonicalName = AccountUtils.canonicalizeName(accountName);
List<Account> accounts = tryGetGoogleAccounts();
for (Account account : accounts) {
- if (canonicalizeName(account.name).equals(canonicalName)) {
+ if (AccountUtils.canonicalizeName(account.name).equals(canonicalName)) {
return account;
}
}
@@ -392,14 +263,6 @@ public class AccountManagerFacade {
}
/**
- * Asynchronous version of {@link #getAccountFromName(String)}.
- */
- @MainThread
- public void getAccountFromName(String accountName, final Callback<Account> callback) {
- runAfterCacheIsPopulated(() -> callback.onResult(getAccountFromName(accountName)));
- }
-
- /**
* Returns whether an account exists with the given name.
* Returns false if an error occurs while getting account list.
*/
@@ -409,23 +272,13 @@ public class AccountManagerFacade {
}
/**
- * Asynchronous version of {@link #hasAccountForName(String)}.
- */
- // TODO(maxbogue): Remove once this function is used outside of tests.
- @VisibleForTesting
- @MainThread
- public void hasAccountForName(String accountName, final Callback<Boolean> callback) {
- runAfterCacheIsPopulated(() -> callback.onResult(hasAccountForName(accountName)));
- }
-
- /**
* @return Whether or not there is an account authenticator for Google accounts.
*/
@AnyThread
public boolean hasGoogleAccountAuthenticator() {
AuthenticatorDescription[] descs = mDelegate.getAuthenticatorTypes();
for (AuthenticatorDescription desc : descs) {
- if (GOOGLE_ACCOUNT_TYPE.equals(desc.type)) return true;
+ if (AccountUtils.GOOGLE_ACCOUNT_TYPE.equals(desc.type)) return true;
}
return false;
}
@@ -539,6 +392,28 @@ public class AccountManagerFacade {
return mUpdatePendingState;
}
+ /**
+ * Returns the Gaia id for the account associated with the given email address.
+ * If an account with the given email address is not installed on the device
+ * then null is returned.
+ *
+ * This method will throw IllegalStateException if called on the main thread.
+ *
+ * @param accountEmail The email address of a Google account.
+ */
+ @WorkerThread
+ @Nullable
+ public String getAccountGaiaId(String accountEmail) {
+ return mDelegate.getAccountGaiaId(accountEmail);
+ }
+
+ /**
+ * Checks whether Google Play services is available.
+ */
+ boolean isGooglePlayServicesAvailable() {
+ return mDelegate.isGooglePlayServicesAvailable();
+ }
+
private boolean hasFeature(Account account, String feature) {
return mDelegate.hasFeatures(account, new String[] {feature});
}
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java
new file mode 100644
index 00000000000..a9224de2e2d
--- /dev/null
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java
@@ -0,0 +1,85 @@
+// Copyright 2020 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.
+package org.chromium.components.signin;
+
+import androidx.annotation.AnyThread;
+import androidx.annotation.MainThread;
+import androidx.annotation.VisibleForTesting;
+
+import org.chromium.base.ThreadUtils;
+import org.chromium.base.annotations.CalledByNative;
+
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * AccountManagerFacadeProvider is intended to group all the
+ * AccountManagerFacade instance manipulation methods in one place.
+ */
+public class AccountManagerFacadeProvider {
+ private static final AtomicReference<AccountManagerFacade> sAtomicInstance =
+ new AtomicReference<>();
+ private static AccountManagerFacade sInstance;
+ private static AccountManagerFacade sTestingInstance;
+
+ private AccountManagerFacadeProvider() {}
+
+ /**
+ * Initializes AccountManagerFacade singleton instance. Can only be called once.
+ * Tests can override the instance with {@link #overrideAccountManagerFacadeForTests}.
+ *
+ * @param delegate the AccountManagerDelegate to use
+ */
+ @MainThread
+ public static void initializeAccountManagerFacade(AccountManagerDelegate delegate) {
+ ThreadUtils.assertOnUiThread();
+ if (sInstance != null) {
+ throw new IllegalStateException("AccountManagerFacade is already initialized!");
+ }
+ sInstance = new AccountManagerFacade(delegate);
+ if (sTestingInstance != null) return;
+ sAtomicInstance.set(sInstance);
+ }
+
+ /**
+ * Overrides AccountManagerFacade singleton instance for tests. Only for use in Tests.
+ * Overrides any previous or future calls to {@link #initializeAccountManagerFacade}.
+ *
+ * @param delegate the AccountManagerDelegate to use
+ */
+ @VisibleForTesting
+ @AnyThread
+ public static void overrideAccountManagerFacadeForTests(AccountManagerDelegate delegate) {
+ ThreadUtils.runOnUiThreadBlocking(() -> {
+ sTestingInstance = new AccountManagerFacade(delegate);
+ sAtomicInstance.set(sTestingInstance);
+ });
+ }
+
+ /**
+ * Resets custom AccountManagerFacade set with {@link #overrideAccountManagerFacadeForTests}.
+ * Only for use in Tests.
+ */
+ @VisibleForTesting
+ @AnyThread
+ public static void resetAccountManagerFacadeForTests() {
+ ThreadUtils.runOnUiThreadBlocking(() -> {
+ sTestingInstance = null;
+ sAtomicInstance.set(sInstance);
+ });
+ }
+
+ /**
+ * Singleton instance getter. Singleton must be initialized before calling this by
+ * {@link #initializeAccountManagerFacade} or {@link #overrideAccountManagerFacadeForTests}.
+ *
+ * @return a singleton instance
+ */
+ @AnyThread
+ @CalledByNative
+ public static AccountManagerFacade getInstance() {
+ AccountManagerFacade instance = sAtomicInstance.get();
+ assert instance != null : "AccountManagerFacade is not initialized!";
+ return instance;
+ }
+}
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java
index d04128bd215..fd16e63876d 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java
@@ -121,9 +121,9 @@ public class AccountTrackerService {
ThreadUtils.assertOnUiThread();
mSystemAccountsChanged = false;
mSyncForceRefreshedForTest = false;
-
- final AccountIdProvider accountIdProvider = AccountIdProvider.getInstance();
- if (accountIdProvider.canBeUsed()) {
+ final AccountManagerFacade accountManagerFacade =
+ AccountManagerFacadeProvider.getInstance();
+ if (accountManagerFacade.isGooglePlayServicesAvailable()) {
mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_IN_PROGRESS;
} else {
mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_NOT_STARTED;
@@ -133,10 +133,10 @@ public class AccountTrackerService {
if (mAccountsChangeObserver == null) {
mAccountsChangeObserver =
() -> invalidateAccountSeedStatus(false /* don't reseed right now */);
- AccountManagerFacade.get().addObserver(mAccountsChangeObserver);
+ accountManagerFacade.addObserver(mAccountsChangeObserver);
}
- AccountManagerFacade.get().tryGetGoogleAccounts(accounts -> {
+ accountManagerFacade.tryGetGoogleAccounts(accounts -> {
new AsyncTask<String[][]>() {
@Override
public String[][] doInBackground() {
@@ -147,7 +147,7 @@ public class AccountTrackerService {
String[][] accountIdNameMap = new String[2][accounts.size()];
for (int i = 0; i < accounts.size(); ++i) {
accountIdNameMap[0][i] =
- accountIdProvider.getAccountId(accounts.get(i).name);
+ accountManagerFacade.getAccountGaiaId(accounts.get(i).name);
accountIdNameMap[1][i] = accounts.get(i).name;
}
@@ -230,7 +230,7 @@ public class AccountTrackerService {
}
mSystemAccountsSeedingStatus = SystemAccountsSeedingStatus.SEEDING_VALIDATING;
- AccountManagerFacade.get().tryGetGoogleAccounts(accounts -> {
+ AccountManagerFacadeProvider.getInstance().tryGetGoogleAccounts(accounts -> {
if (mSystemAccountsChanged
|| mSystemAccountsSeedingStatus
!= SystemAccountsSeedingStatus.SEEDING_VALIDATING) {
@@ -257,8 +257,8 @@ public class AccountTrackerService {
@NativeMethods
interface Natives {
- public void seedAccountsInfo(
+ void seedAccountsInfo(
long nativeAccountTrackerService, String[] gaiaIds, String[] accountNames);
- public boolean areAccountsSeeded(long nativeAccountTrackerService, String[] accountNames);
+ boolean areAccountsSeeded(long nativeAccountTrackerService, String[] accountNames);
}
}
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountUtils.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountUtils.java
new file mode 100644
index 00000000000..7723c7501f7
--- /dev/null
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountUtils.java
@@ -0,0 +1,47 @@
+// Copyright 2020 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.
+
+package org.chromium.components.signin;
+
+import android.accounts.Account;
+
+import androidx.annotation.VisibleForTesting;
+
+import java.util.Locale;
+import java.util.regex.Pattern;
+
+/**
+ * AccountUtils groups some static util methods for account.
+ */
+public class AccountUtils {
+ private static final Pattern AT_SYMBOL = Pattern.compile("@");
+ private static final String GMAIL_COM = "gmail.com";
+ private static final String GOOGLEMAIL_COM = "googlemail.com";
+
+ @VisibleForTesting
+ public static final String GOOGLE_ACCOUNT_TYPE = "com.google";
+
+ /**
+ * Creates an Account object for the given name.
+ */
+ public static Account createAccountFromName(String name) {
+ return new Account(name, GOOGLE_ACCOUNT_TYPE);
+ }
+
+ /**
+ * Canonicalizes the account name.
+ */
+ static String canonicalizeName(String name) {
+ String[] parts = AT_SYMBOL.split(name);
+ if (parts.length != 2) return name;
+
+ if (GOOGLEMAIL_COM.equalsIgnoreCase(parts[1])) {
+ parts[1] = GMAIL_COM;
+ }
+ if (GMAIL_COM.equalsIgnoreCase(parts[1])) {
+ parts[0] = parts[0].replace(".", "");
+ }
+ return (parts[0] + "@" + parts[1]).toLowerCase(Locale.US);
+ }
+}
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java
index d9382f34d5e..730e5a8a173 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChildAccountInfoFetcher.java
@@ -40,7 +40,7 @@ public final class ChildAccountInfoFetcher {
long nativeAccountFetcherService, String accountId, String accountName) {
mNativeAccountFetcherService = nativeAccountFetcherService;
mAccountId = accountId;
- mAccount = AccountManagerFacade.createAccountFromName(accountName);
+ mAccount = AccountUtils.createAccountFromName(accountName);
// Register for notifications about flag changes in the future.
mAccountFlagsChangedReceiver = new BroadcastReceiver() {
@@ -70,7 +70,7 @@ public final class ChildAccountInfoFetcher {
private void fetch() {
Log.d(TAG, "Checking child account status for %s", mAccount.name);
- AccountManagerFacade.get().checkChildAccountStatus(
+ AccountManagerFacadeProvider.getInstance().checkChildAccountStatus(
mAccount, status -> setIsChildAccount(ChildAccountStatus.isChild(status)));
}
@@ -89,7 +89,7 @@ public final class ChildAccountInfoFetcher {
@CalledByNative
private static void initializeForTests() {
AccountManagerDelegate delegate = new SystemAccountManagerDelegate();
- AccountManagerFacade.overrideAccountManagerFacadeForTests(delegate);
+ AccountManagerFacadeProvider.overrideAccountManagerFacadeForTests(delegate);
}
@NativeMethods
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java
index 4327b1bd892..f12d1ad56e7 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java
@@ -42,7 +42,7 @@ public class ChromeSigninController {
if (syncAccountName == null) {
return null;
}
- return AccountManagerFacade.createAccountFromName(syncAccountName);
+ return AccountUtils.createAccountFromName(syncAccountName);
}
public boolean isSignedIn() {
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ConsistencyCookieManager.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ConsistencyCookieManager.java
deleted file mode 100644
index 44fa6beb23a..00000000000
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ConsistencyCookieManager.java
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2019 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.
-
-package org.chromium.components.signin;
-
-import androidx.annotation.MainThread;
-
-import org.chromium.base.ThreadUtils;
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.base.annotations.JNINamespace;
-import org.chromium.base.annotations.NativeMethods;
-
-/**
- * Created by native code to get status of {@link AccountManagerFacade#isUpdatePending()} and
- * notifications when it changes.
- */
-public class ConsistencyCookieManager
- implements ObservableValue.Observer, AccountTrackerService.OnSystemAccountsSeededListener {
- private final long mNativeConsistencyCookieManager;
- private final AccountTrackerService mAccountTrackerService;
- private final AccountManagerFacade mAccountManagerFacade;
- private final SigninActivityMonitor mSigninActivityMonitor;
- private boolean mIsUpdatePending;
-
- private ConsistencyCookieManager(
- long nativeConsistencyCookieManager, AccountTrackerService accountTrackerService) {
- ThreadUtils.assertOnUiThread();
- mAccountTrackerService = accountTrackerService;
- mNativeConsistencyCookieManager = nativeConsistencyCookieManager;
- mAccountManagerFacade = AccountManagerFacade.get();
- mSigninActivityMonitor = SigninActivityMonitor.get();
-
- // For now, this class relies on the order of notifications sent by AccountManagerFacade and
- // AccountTrackerService. Whenever the account list changes, this class will get
- // notification from AccountManagerFacade.isUpdatePending(). This will change
- // mIsUpdatePending to true. By the time AccountManagerFacade finishes updating account list
- // and sets AccountManagerFacade.isUpdatePending() to false, AccountTrackerService should
- // have already invalidate account seed status, so mIsUpdatePending will stay false until
- // accounts are seeded to the native AccountTrackerService.
- // TODO(https://crbug.com/831257): Simplify this after seeding is reimplemented.
- mAccountTrackerService.addSystemAccountsSeededListener(this);
- mAccountManagerFacade.isUpdatePending().addObserver(this);
- mSigninActivityMonitor.hasOngoingActivity().addObserver(this);
-
- mIsUpdatePending = calculateIsUpdatePending();
- }
-
- @Override
- public void onSystemAccountsSeedingComplete() {
- onValueChanged();
- }
-
- @Override
- public void onValueChanged() {
- boolean state = calculateIsUpdatePending();
-
- if (mIsUpdatePending == state) return;
- mIsUpdatePending = state;
- ConsistencyCookieManagerJni.get().onIsUpdatePendingChanged(mNativeConsistencyCookieManager);
- }
-
- private boolean calculateIsUpdatePending() {
- return mAccountManagerFacade.isUpdatePending().get()
- || mSigninActivityMonitor.hasOngoingActivity().get()
- || !mAccountTrackerService.areSystemAccountsSeeded();
- }
-
- @CalledByNative
- @MainThread
- private static ConsistencyCookieManager create(
- long nativeConsistencyCookieManager, AccountTrackerService accountTrackerService) {
- return new ConsistencyCookieManager(nativeConsistencyCookieManager, accountTrackerService);
- }
-
- @CalledByNative
- @MainThread
- private void destroy() {
- ThreadUtils.assertOnUiThread();
- mAccountTrackerService.removeSystemAccountsSeededListener(this);
- mSigninActivityMonitor.hasOngoingActivity().removeObserver(this);
- mAccountManagerFacade.isUpdatePending().removeObserver(this);
- }
-
- @CalledByNative
- @MainThread
- private boolean getIsUpdatePending() {
- ThreadUtils.assertOnUiThread();
- return mIsUpdatePending;
- }
-
- @JNINamespace("signin")
- @NativeMethods
- interface Natives {
- void onIsUpdatePendingChanged(long nativeConsistencyCookieManagerAndroid);
- }
-}
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ObservableValue.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ObservableValue.java
index 94114a89eee..99d450d8bc4 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ObservableValue.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/ObservableValue.java
@@ -4,9 +4,8 @@
package org.chromium.components.signin;
-import android.support.v4.util.ObjectsCompat;
-
import androidx.annotation.MainThread;
+import androidx.core.util.ObjectsCompat;
import org.chromium.base.ObserverList;
import org.chromium.base.ThreadUtils;
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SigninActivityMonitor.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SigninActivityMonitor.java
deleted file mode 100644
index 7fe5018d0b4..00000000000
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SigninActivityMonitor.java
+++ /dev/null
@@ -1,68 +0,0 @@
-// Copyright 2019 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.
-
-package org.chromium.components.signin;
-
-import android.annotation.SuppressLint;
-
-import androidx.annotation.MainThread;
-
-import org.chromium.base.ThreadUtils;
-
-/**
- * Monitors external activities started from sign-in flows (for example, activity to add an account
- * to the device). Activities have to be launched using {@link #startSigninActivity}.
- */
-public class SigninActivityMonitor {
- @SuppressLint("StaticFieldLeak")
- private static SigninActivityMonitor sInstance;
-
- private int mActivityCounter;
- private MutableObservableValue<Boolean> mHasOngoingActivity =
- new MutableObservableValue<>(false);
-
- private SigninActivityMonitor() {}
-
- /**
- * Returns a singleton instance of the SigninActivityMonitor.
- */
- @MainThread
- public static SigninActivityMonitor get() {
- ThreadUtils.assertOnUiThread();
- if (sInstance == null) {
- sInstance = new SigninActivityMonitor();
- }
- return sInstance;
- }
-
- /**
- * Returns whether there are any ongoing sign-in activities.
- */
- public ObservableValue<Boolean> hasOngoingActivity() {
- return mHasOngoingActivity;
- }
-
- // TODO(https://crbug.com/953765): Make this private.
- /**
- * Should be invoked when a signin activity is started.
- */
- public void activityStarted() {
- assert mActivityCounter >= 0;
-
- ++mActivityCounter;
- if (mActivityCounter == 1) mHasOngoingActivity.set(true);
- }
-
- // TODO(https://crbug.com/953765): Make this private.
- /**
- * Should be invoked when a signin activity is finished. There should be a strict parity between
- * {@link #activityStarted()} and {@link #activityFinished()} calls.
- */
- public void activityFinished() {
- assert mActivityCounter > 0;
-
- --mActivityCounter;
- if (mActivityCounter == 0) mHasOngoingActivity.set(false);
- }
-}
diff --git a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
index d7220206927..4fb1f3d8f89 100644
--- a/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
+++ b/chromium/components/signin/core/browser/android/java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java
@@ -24,6 +24,8 @@ import android.os.PatternMatcher;
import android.os.Process;
import android.os.SystemClock;
+import androidx.annotation.Nullable;
+
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException;
@@ -35,6 +37,7 @@ import org.chromium.base.Callback;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.ObserverList;
+import org.chromium.base.StrictModeContext;
import org.chromium.base.ThreadUtils;
import org.chromium.base.library_loader.LibraryLoader;
import org.chromium.base.metrics.RecordHistogram;
@@ -133,7 +136,7 @@ public class SystemAccountManagerDelegate implements AccountManagerDelegate {
@Override
public String getAuthToken(Account account, String authTokenScope) throws AuthException {
assert !ThreadUtils.runningOnUiThread();
- assert AccountManagerFacade.GOOGLE_ACCOUNT_TYPE.equals(account.type);
+ assert AccountUtils.GOOGLE_ACCOUNT_TYPE.equals(account.type);
try {
return GoogleAuthUtil.getTokenWithNotification(
ContextUtils.getApplicationContext(), account, authTokenScope, null);
@@ -244,6 +247,27 @@ public class SystemAccountManagerDelegate implements AccountManagerDelegate {
account, "android", emptyOptions, activity, realCallback, null);
}
+ @Nullable
+ @Override
+ public String getAccountGaiaId(String accountEmail) {
+ try {
+ return GoogleAuthUtil.getAccountId(ContextUtils.getApplicationContext(), accountEmail);
+ } catch (IOException | GoogleAuthException ex) {
+ Log.e(TAG, "SystemAccountManagerDelegate.getAccountGaiaId", ex);
+ return null;
+ }
+ }
+
+ @Override
+ public boolean isGooglePlayServicesAvailable() {
+ // TODO(http://crbug.com/577190): Remove StrictMode override.
+ try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) {
+ int resultCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(
+ ContextUtils.getApplicationContext());
+ return resultCode == ConnectionResult.SUCCESS;
+ }
+ }
+
protected boolean hasGetAccountsPermission() {
return ApiCompatibilityUtils.checkPermission(ContextUtils.getApplicationContext(),
Manifest.permission.GET_ACCOUNTS, Process.myPid(), Process.myUid())
diff --git a/chromium/components/signin/core/browser/chrome_connected_header_helper.cc b/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
index ec98e9741ac..c40f6c2477e 100644
--- a/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
+++ b/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
@@ -169,12 +169,6 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
const GURL& url,
const std::string& gaia_id,
int profile_mode_mask) {
-#if defined(OS_ANDROID)
- bool is_mice_enabled = base::FeatureList::IsEnabled(kMiceFeature);
-#else
- bool is_mice_enabled = false;
-#endif
-
// If we are on mobile or desktop, an empty |account_id| corresponds to the user
// not signed into Sync. Do not enforce account consistency, unless Mice is
// enabled on Android.
@@ -183,7 +177,7 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
// filtered upstream and we want to enforce account consistency in Public
// Sessions and Active Directory logins.
#if !defined(OS_CHROMEOS)
- if (gaia_id.empty() && !is_mice_enabled)
+ if (gaia_id.empty())
return std::string();
#endif // !defined(OS_CHROMEOS)
@@ -201,9 +195,8 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
account_consistency_ == AccountConsistencyMethod::kMirror;
parts.push_back(base::StringPrintf("%s=%s", kEnableAccountConsistencyAttrName,
is_mirror_enabled ? "true" : "false"));
- parts.push_back(base::StringPrintf("%s=%s",
- kConsistencyEnabledByDefaultAttrName,
- is_mice_enabled ? "true" : "false"));
+ parts.push_back(base::StringPrintf(
+ "%s=%s", kConsistencyEnabledByDefaultAttrName, "false"));
return base::JoinString(parts, is_header_request ? "," : ":");
}
diff --git a/chromium/components/signin/core/browser/consistency_cookie_manager_android.cc b/chromium/components/signin/core/browser/consistency_cookie_manager_android.cc
deleted file mode 100644
index cd1f0cca6ea..00000000000
--- a/chromium/components/signin/core/browser/consistency_cookie_manager_android.cc
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 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 "components/signin/core/browser/consistency_cookie_manager_android.h"
-
-#include "components/signin/core/browser/android/jni_headers/ConsistencyCookieManager_jni.h"
-#include "components/signin/public/identity_manager/identity_manager.h"
-
-namespace signin {
-
-ConsistencyCookieManagerAndroid::ConsistencyCookieManagerAndroid(
- IdentityManager* identity_manager,
- SigninClient* signin_client,
- AccountReconcilor* reconcilor)
- : ConsistencyCookieManagerBase(signin_client, reconcilor) {
- JNIEnv* env = base::android::AttachCurrentThread();
- base::android::ScopedJavaLocalRef<jobject> java_ref =
- Java_ConsistencyCookieManager_create(
- env, reinterpret_cast<intptr_t>(this),
- identity_manager->LegacyGetAccountTrackerServiceJavaObject());
- java_ref_.Reset(env, java_ref.obj());
- is_update_pending_in_java_ =
- Java_ConsistencyCookieManager_getIsUpdatePending(env, java_ref_);
-
- UpdateCookie();
-}
-
-ConsistencyCookieManagerAndroid::~ConsistencyCookieManagerAndroid() {
- JNIEnv* env = base::android::AttachCurrentThread();
- Java_ConsistencyCookieManager_destroy(env, java_ref_);
-}
-
-void ConsistencyCookieManagerAndroid::OnIsUpdatePendingChanged(JNIEnv* env) {
- bool is_update_pending_in_java =
- Java_ConsistencyCookieManager_getIsUpdatePending(env, java_ref_);
- if (is_update_pending_in_java == is_update_pending_in_java_)
- return;
- is_update_pending_in_java_ = is_update_pending_in_java;
- UpdateCookie();
-}
-
-std::string ConsistencyCookieManagerAndroid::CalculateCookieValue() {
- if (is_update_pending_in_java_) {
- return kStateUpdating;
- }
- return ConsistencyCookieManagerBase::CalculateCookieValue();
-}
-
-} // namespace signin
diff --git a/chromium/components/signin/core/browser/consistency_cookie_manager_android.h b/chromium/components/signin/core/browser/consistency_cookie_manager_android.h
deleted file mode 100644
index 6fa0f2e2e11..00000000000
--- a/chromium/components/signin/core/browser/consistency_cookie_manager_android.h
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2019 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 COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_ANDROID_H_
-#define COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_ANDROID_H_
-
-#include "base/android/scoped_java_ref.h"
-#include "base/macros.h"
-#include "components/signin/core/browser/consistency_cookie_manager_base.h"
-
-class SigninClient;
-
-namespace signin {
-
-class IdentityManager;
-
-// ConsistencyCookieManagerAndroid subclasses ConsistencyCookieManagerBase to
-// watch whether there are pending updates to the account list on the Java side.
-class ConsistencyCookieManagerAndroid : public ConsistencyCookieManagerBase {
- public:
- ConsistencyCookieManagerAndroid(IdentityManager* identity_manager,
- SigninClient* signin_client,
- AccountReconcilor* reconcilor);
-
- ~ConsistencyCookieManagerAndroid() override;
-
- void OnIsUpdatePendingChanged(JNIEnv* env);
-
- protected:
- std::string CalculateCookieValue() override;
-
- private:
- bool is_update_pending_in_java_ = false;
- base::android::ScopedJavaGlobalRef<jobject> java_ref_;
-
- DISALLOW_COPY_AND_ASSIGN(ConsistencyCookieManagerAndroid);
-};
-
-} // namespace signin
-
-#endif // COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_ANDROID_H_
diff --git a/chromium/components/signin/core/browser/consistency_cookie_manager_base.cc b/chromium/components/signin/core/browser/consistency_cookie_manager_base.cc
deleted file mode 100644
index 92dee2a07bc..00000000000
--- a/chromium/components/signin/core/browser/consistency_cookie_manager_base.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// Copyright 2019 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 "components/signin/core/browser/consistency_cookie_manager_base.h"
-
-#include "base/logging.h"
-#include "base/time/time.h"
-#include "components/signin/public/base/signin_client.h"
-#include "google_apis/gaia/gaia_urls.h"
-#include "net/cookies/canonical_cookie.h"
-#include "net/cookies/cookie_options.h"
-#include "services/network/public/mojom/cookie_manager.mojom.h"
-#include "url/gurl.h"
-
-namespace signin {
-
-const char kCookieName[] = "CHROME_ID_CONSISTENCY_STATE";
-const char ConsistencyCookieManagerBase::kStateConsistent[] = "Consistent";
-const char ConsistencyCookieManagerBase::kStateInconsistent[] = "Inconsistent";
-const char ConsistencyCookieManagerBase::kStateUpdating[] = "Updating";
-
-ConsistencyCookieManagerBase::ConsistencyCookieManagerBase(
- SigninClient* signin_client,
- AccountReconcilor* reconcilor)
- : account_reconcilor_state_(reconcilor->GetState()),
- signin_client_(signin_client),
- account_reconcilor_observer_(this) {
- DCHECK(signin_client_);
- DCHECK(reconcilor);
-
- account_reconcilor_observer_.Add(reconcilor);
-}
-
-ConsistencyCookieManagerBase::~ConsistencyCookieManagerBase() = default;
-
-void ConsistencyCookieManagerBase::OnStateChanged(
- signin_metrics::AccountReconcilorState state) {
- if (state == account_reconcilor_state_)
- return;
- account_reconcilor_state_ = state;
- UpdateCookie();
-}
-
-std::string ConsistencyCookieManagerBase::CalculateCookieValue() {
- switch (account_reconcilor_state_) {
- case signin_metrics::ACCOUNT_RECONCILOR_OK:
- return kStateConsistent;
- case signin_metrics::ACCOUNT_RECONCILOR_RUNNING:
- case signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED:
- return kStateUpdating;
- case signin_metrics::ACCOUNT_RECONCILOR_ERROR:
- return kStateInconsistent;
- case signin_metrics::ACCOUNT_RECONCILOR_HISTOGRAM_COUNT:
- NOTREACHED();
- return {};
- }
-}
-
-void ConsistencyCookieManagerBase::UpdateCookie() {
- std::string cookie_value = CalculateCookieValue();
- DCHECK(!cookie_value.empty());
-
- // Update the cookie with the new value.
- network::mojom::CookieManager* cookie_manager =
- signin_client_->GetCookieManager();
- base::Time now = base::Time::Now();
- base::Time expiry = now + base::TimeDelta::FromDays(2 * 365); // Two years.
- net::CanonicalCookie cookie(
- kCookieName, cookie_value, GaiaUrls::GetInstance()->gaia_url().host(),
- /*path=*/"/", /*creation=*/now, /*expiration=*/expiry,
- /*last_access=*/now, /*secure=*/true, /*httponly=*/false,
- net::CookieSameSite::LAX_MODE, net::COOKIE_PRIORITY_DEFAULT);
- net::CookieOptions cookie_options;
- // Permit to set SameSite cookies.
- cookie_options.set_same_site_cookie_context(
- net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
- cookie_manager->SetCanonicalCookie(
- cookie, "https", cookie_options,
- network::mojom::CookieManager::SetCanonicalCookieCallback());
-}
-
-} // namespace signin
diff --git a/chromium/components/signin/core/browser/consistency_cookie_manager_base.h b/chromium/components/signin/core/browser/consistency_cookie_manager_base.h
deleted file mode 100644
index 7c1d551c4c0..00000000000
--- a/chromium/components/signin/core/browser/consistency_cookie_manager_base.h
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2019 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 COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_BASE_H_
-#define COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_BASE_H_
-
-#include "base/macros.h"
-#include "base/scoped_observer.h"
-#include "components/signin/core/browser/account_reconcilor.h"
-#include "components/signin/public/base/signin_metrics.h"
-
-class SigninClient;
-
-namespace signin {
-
-// The ConsistencyCookieManagerBase checks if:
-// - the account reconcilor is running
-// - the accounts on the device are updating
-// - the user has started to interact with device account settings (from Chrome)
-// If one of these conditions is true, then this object sets a cookie on Gaia
-// with a "Updating" value.
-//
-// Otherwise the value of the cookie is "Consistent" if the accounts are
-// consistent (web accounts match device accounts) or "Inconsistent".
-//
-// Subclasses have to call UpdateCookie() at the end of the constructor.
-class ConsistencyCookieManagerBase : public AccountReconcilor::Observer {
- public:
- ~ConsistencyCookieManagerBase() override;
-
- protected:
- static const char kStateConsistent[];
- static const char kStateInconsistent[];
- static const char kStateUpdating[];
-
- ConsistencyCookieManagerBase(SigninClient* signin_client,
- AccountReconcilor* reconcilor);
-
- // Calculates the cookie value solely based on the reconcilor state.
- virtual std::string CalculateCookieValue();
-
- // Gets the new value using CalculateCookieValue and sets the cookie.
- void UpdateCookie();
-
- private:
- // AccountReconcilor::Observer:
- void OnStateChanged(signin_metrics::AccountReconcilorState state) override;
-
- signin_metrics::AccountReconcilorState account_reconcilor_state_ =
- signin_metrics::ACCOUNT_RECONCILOR_OK;
- SigninClient* signin_client_ = nullptr;
- ScopedObserver<AccountReconcilor, AccountReconcilor::Observer>
- account_reconcilor_observer_;
-
- DISALLOW_COPY_AND_ASSIGN(ConsistencyCookieManagerBase);
-};
-
-} // namespace signin
-
-#endif // COMPONENTS_SIGNIN_CORE_BROWSER_CONSISTENCY_COOKIE_MANAGER_BASE_H_
diff --git a/chromium/components/signin/core/browser/consistency_cookie_manager_unittest.cc b/chromium/components/signin/core/browser/consistency_cookie_manager_unittest.cc
deleted file mode 100644
index b0cbd10dc9e..00000000000
--- a/chromium/components/signin/core/browser/consistency_cookie_manager_unittest.cc
+++ /dev/null
@@ -1,132 +0,0 @@
-// Copyright 2019 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 "components/signin/core/browser/consistency_cookie_manager_base.h"
-
-#include <memory>
-#include <string>
-
-#include "base/test/scoped_feature_list.h"
-#include "base/test/task_environment.h"
-#include "components/signin/core/browser/account_reconcilor.h"
-#include "components/signin/core/browser/account_reconcilor_delegate.h"
-#include "components/signin/public/base/account_consistency_method.h"
-#include "components/signin/public/base/test_signin_client.h"
-#include "components/signin/public/identity_manager/identity_test_environment.h"
-#include "components/sync_preferences/testing_pref_service_syncable.h"
-#include "google_apis/gaia/gaia_urls.h"
-#include "services/network/test/test_cookie_manager.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace signin {
-namespace {
-
-// GMock matcher that checks that the consistency cookie has the expected value.
-MATCHER_P(CookieHasValueMatcher, value, "") {
- net::CookieOptions cookie_options;
- cookie_options.set_same_site_cookie_context(
- net::CookieOptions::SameSiteCookieContext::SAME_SITE_LAX);
- return arg.Name() == "CHROME_ID_CONSISTENCY_STATE" && arg.Value() == value &&
- arg.IncludeForRequestURL(GaiaUrls::GetInstance()->gaia_url(),
- cookie_options)
- .IsInclude();
-}
-
-MATCHER(SetPermittedInContext, "") {
- const net::CanonicalCookie& cookie = testing::get<0>(arg);
- const net::CookieOptions& cookie_options = testing::get<1>(arg);
- return cookie.IsSetPermittedInContext(cookie_options).IsInclude();
-}
-
-class MockCookieManager
- : public testing::StrictMock<network::TestCookieManager> {
- public:
- // Adds a GMock expectation that the consistency cookie will be set with the
- // specified value.
- void ExpectSetCookieCall(const std::string& value) {
- EXPECT_CALL(*this, SetCanonicalCookie(CookieHasValueMatcher(value), "https",
- testing::_, testing::_))
- .With(testing::Args<0, 2>(SetPermittedInContext()));
- }
-
- MOCK_METHOD4(
- SetCanonicalCookie,
- void(const net::CanonicalCookie& cookie,
- const std::string& source_scheme,
- const net::CookieOptions& cookie_options,
- network::mojom::CookieManager::SetCanonicalCookieCallback callback));
-};
-
-class FakeConsistencyCookieManager : public ConsistencyCookieManagerBase {
- public:
- FakeConsistencyCookieManager(SigninClient* signin_client,
- AccountReconcilor* reconcilor)
- : ConsistencyCookieManagerBase(signin_client, reconcilor) {
- UpdateCookie();
- }
-};
-
-class ConsistencyCookieManagerTest : public ::testing::Test {
- public:
- ConsistencyCookieManagerTest()
- : signin_client_(&pref_service_),
- identity_test_env_(/*test_url_loader_factory=*/nullptr,
- &pref_service_,
- AccountConsistencyMethod::kMirror,
- &signin_client_) {
- scoped_feature_list_.InitAndEnableFeature(kMiceFeature);
- std::unique_ptr<MockCookieManager> cookie_manager =
- std::make_unique<MockCookieManager>();
- mock_cookie_manager_ = cookie_manager.get();
- signin_client_.set_cookie_manager(std::move(cookie_manager));
- reconcilor_ = std::make_unique<AccountReconcilor>(
- identity_test_env_.identity_manager(), &signin_client_,
- std::make_unique<AccountReconcilorDelegate>());
- reconcilor_->Initialize(/*start_reconcile_if_tokens_available=*/false);
- }
-
- ~ConsistencyCookieManagerTest() override { reconcilor_->Shutdown(); }
-
- SigninClient* signin_client() { return &signin_client_; }
- AccountReconcilor* reconcilor() { return reconcilor_.get(); }
-
- MockCookieManager* mock_cookie_manager() {
- DCHECK_EQ(mock_cookie_manager_, signin_client_.GetCookieManager());
- return mock_cookie_manager_;
- }
-
- private:
- base::test::ScopedFeatureList scoped_feature_list_;
- base::test::TaskEnvironment task_environment_;
- sync_preferences::TestingPrefServiceSyncable pref_service_;
-
- // Owned by signin_client_.
- MockCookieManager* mock_cookie_manager_ = nullptr;
-
- TestSigninClient signin_client_;
- IdentityTestEnvironment identity_test_env_;
- std::unique_ptr<AccountReconcilor> reconcilor_;
-};
-
-// Tests that the cookie is updated when the account reconcilor state changes.
-TEST_F(ConsistencyCookieManagerTest, AccountReconcilorState) {
- // AccountReconcilor::Initialize() creates the ConsistencyCookieManager.
- mock_cookie_manager()->ExpectSetCookieCall("Consistent");
- reconcilor()->SetConsistencyCookieManager(
- std::make_unique<FakeConsistencyCookieManager>(signin_client(),
- reconcilor()));
- testing::Mock::VerifyAndClearExpectations(mock_cookie_manager());
- ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor()->GetState());
-
- // Trigger a state change in the reconcilor, and check that the cookie was
- // updated accordingly. Calling EnableReconcile() will cause the reconcilor
- // state to change to SCHEDULED then OK.
- mock_cookie_manager()->ExpectSetCookieCall("Updating");
- mock_cookie_manager()->ExpectSetCookieCall("Consistent");
- reconcilor()->EnableReconcile();
-}
-
-} // namespace
-} // namespace signin
diff --git a/chromium/components/signin/core/browser/cookie_reminter.cc b/chromium/components/signin/core/browser/cookie_reminter.cc
index d981950c1e9..cdad334c8d8 100644
--- a/chromium/components/signin/core/browser/cookie_reminter.cc
+++ b/chromium/components/signin/core/browser/cookie_reminter.cc
@@ -4,6 +4,7 @@
#include "components/signin/core/browser/cookie_reminter.h"
+#include "base/bind_helpers.h"
#include "base/metrics/histogram_macros.h"
#include "base/syslog_logging.h"
#include "components/signin/public/identity_manager/accounts_cookie_mutator.h"
@@ -52,6 +53,7 @@ void CookieReminter::OnRefreshTokenUpdatedForAccount(
// Cookies are going to be reminted for all accounts.
accounts_requiring_cookie_remint_.clear();
identity_manager_->GetAccountsCookieMutator()->LogOutAllAccounts(
- gaia::GaiaSource::kChromeOS);
+ gaia::GaiaSource::kChromeOS,
+ signin::AccountsCookieMutator::LogOutFromCookieCompletedCallback());
}
}
diff --git a/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.cc b/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.cc
deleted file mode 100644
index 8b8c9369672..00000000000
--- a/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2019 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 "components/signin/core/browser/mice_account_reconcilor_delegate.h"
-
-#include "base/logging.h"
-
-namespace signin {
-
-MiceAccountReconcilorDelegate::MiceAccountReconcilorDelegate() = default;
-
-MiceAccountReconcilorDelegate::~MiceAccountReconcilorDelegate() = default;
-
-bool MiceAccountReconcilorDelegate::IsReconcileEnabled() const {
- return true;
-}
-
-bool MiceAccountReconcilorDelegate::IsAccountConsistencyEnforced() const {
- return true;
-}
-
-gaia::GaiaSource MiceAccountReconcilorDelegate::GetGaiaApiSource() const {
- return gaia::GaiaSource::kAccountReconcilorMirror;
-}
-
-CoreAccountId MiceAccountReconcilorDelegate::GetFirstGaiaAccountForReconcile(
- const std::vector<CoreAccountId>& chrome_accounts,
- const std::vector<gaia::ListedAccount>& gaia_accounts,
- const CoreAccountId& primary_account,
- bool first_execution,
- bool will_logout) const {
- // This flow is deprecated and will be removed when multilogin is fully
- // launched.
- NOTREACHED() << "Mice requires multilogin";
- return CoreAccountId();
-}
-
-std::vector<CoreAccountId>
-MiceAccountReconcilorDelegate::GetChromeAccountsForReconcile(
- const std::vector<CoreAccountId>& chrome_accounts,
- const CoreAccountId& primary_account,
- const std::vector<gaia::ListedAccount>& gaia_accounts,
- const gaia::MultiloginMode mode) const {
- if (chrome_accounts.empty())
- return {};
-
- // First account, by priority order:
- // - primary account
- // - first account on the device.
- // Warning: As a result, the reconciliation may change the default Gaia
- // account. It should be ensured that this is not surprising for the user.
- CoreAccountId new_first_account =
- base::Contains(chrome_accounts, primary_account) ? primary_account
- : chrome_accounts[0];
-
- // Minimize account shuffling and ensure that the number of accounts does not
- // exceed the limit.
- return ReorderChromeAccountsForReconcile(chrome_accounts, new_first_account,
- gaia_accounts);
-}
-
-gaia::MultiloginMode MiceAccountReconcilorDelegate::CalculateModeForReconcile(
- const std::vector<gaia::ListedAccount>& gaia_accounts,
- const CoreAccountId& primary_account,
- bool first_execution,
- bool primary_has_error) const {
- return gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER;
-}
-
-bool MiceAccountReconcilorDelegate::IsUnknownInvalidAccountInCookieAllowed()
- const {
- return false;
-}
-
-} // namespace signin
diff --git a/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.h b/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.h
deleted file mode 100644
index 28a71d00bc1..00000000000
--- a/chromium/components/signin/core/browser/mice_account_reconcilor_delegate.h
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2019 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 COMPONENTS_SIGNIN_CORE_BROWSER_MICE_ACCOUNT_RECONCILOR_DELEGATE_H_
-#define COMPONENTS_SIGNIN_CORE_BROWSER_MICE_ACCOUNT_RECONCILOR_DELEGATE_H_
-
-#include <string>
-#include <vector>
-
-#include "base/macros.h"
-#include "components/signin/core/browser/account_reconcilor_delegate.h"
-
-namespace signin {
-
-// AccountReconcilorDelegate specialized for Mice.
-class MiceAccountReconcilorDelegate : public AccountReconcilorDelegate {
- public:
- MiceAccountReconcilorDelegate();
- ~MiceAccountReconcilorDelegate() override;
-
- private:
- // AccountReconcilorDelegate:
- bool IsReconcileEnabled() const override;
- bool IsAccountConsistencyEnforced() const override;
- gaia::GaiaSource GetGaiaApiSource() const override;
- CoreAccountId GetFirstGaiaAccountForReconcile(
- const std::vector<CoreAccountId>& chrome_accounts,
- const std::vector<gaia::ListedAccount>& gaia_accounts,
- const CoreAccountId& primary_account,
- bool first_execution,
- bool will_logout) const override;
- std::vector<CoreAccountId> GetChromeAccountsForReconcile(
- const std::vector<CoreAccountId>& chrome_accounts,
- const CoreAccountId& primary_account,
- const std::vector<gaia::ListedAccount>& gaia_accounts,
- const gaia::MultiloginMode mode) const override;
- gaia::MultiloginMode CalculateModeForReconcile(
- const std::vector<gaia::ListedAccount>& gaia_accounts,
- const CoreAccountId& primary_account,
- bool first_execution,
- bool primary_has_error) const override;
- bool IsUnknownInvalidAccountInCookieAllowed() const override;
-
- DISALLOW_COPY_AND_ASSIGN(MiceAccountReconcilorDelegate);
-};
-
-} // namespace signin
-
-#endif // COMPONENTS_SIGNIN_CORE_BROWSER_MICE_ACCOUNT_RECONCILOR_DELEGATE_H_
diff --git a/chromium/components/signin/core/browser/mice_account_reconcilor_delegate_unittest.cc b/chromium/components/signin/core/browser/mice_account_reconcilor_delegate_unittest.cc
deleted file mode 100644
index b3947eaab72..00000000000
--- a/chromium/components/signin/core/browser/mice_account_reconcilor_delegate_unittest.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2019 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 "components/signin/core/browser/mice_account_reconcilor_delegate.h"
-
-#include <vector>
-
-#include "google_apis/gaia/gaia_auth_util.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace signin {
-
-namespace {
-
-// Returns a gaia::ListedAccount with the specified account id.
-gaia::ListedAccount BuildTestListedAccount(const std::string account_id,
- bool valid) {
- gaia::ListedAccount account;
- account.id = CoreAccountId(account_id);
- account.valid = valid;
- return account;
-}
-
-// Returns vector of account_id created from value
-std::vector<CoreAccountId> ToAccountIdList(
- const std::vector<std::string>& account_ids_value) {
- std::vector<CoreAccountId> account_ids;
- for (const auto& account_id_value : account_ids_value)
- account_ids.push_back(CoreAccountId(account_id_value));
- return account_ids;
-}
-
-} // namespace
-
-TEST(MiceAccountReconcilorDelegate, CalculateParametersForMultilogin) {
- MiceAccountReconcilorDelegate mice_delegate;
-
- const gaia::ListedAccount kA = BuildTestListedAccount("A", /*valid=*/true);
- const gaia::ListedAccount kB = BuildTestListedAccount("B", /*valid=*/false);
-
- struct TestParams {
- std::vector<std::string> chrome_accounts;
- std::string primary_account;
- std::vector<gaia::ListedAccount> gaia_accounts;
-
- std::vector<std::string> expected_accounts;
- };
-
- // clang-format off
- TestParams cases[] = {
- // chrome_accounts, primary_account, gaia_accounts, expected_accounts
- {{}, "", {}, {}},
- {{}, "", {kA, kB}, {}},
- {{"A"}, "", {}, {"A"}},
- {{"A"}, "", {kA, kB}, {"A"}},
- {{"A"}, "", {kB, kA}, {"A"}},
- {{"A", "B"}, "", {}, {"A", "B"}},
- {{"A", "B"}, "", {kA}, {"A", "B"}},
- {{"A", "B"}, "", {kB}, {"A", "B"}},
- {{"B", "C"}, "", {kA}, {"B", "C"}},
- {{"A", "B"}, "", {kA, kB}, {"A", "B"}},
- {{"A", "B"}, "", {kB, kA}, {"A", "B"}},
- {{"B", "C"}, "", {kA, kB}, {"B", "C"}},
- // Tests the reordering: B remains in 2nd place.
- {{"C", "D", "B"}, "", {kA, kB}, {"C", "B", "D"}},
- // With primary account.
- {{"A", "B"}, "B", {}, {"B", "A"}},
- {{"B", "A"}, "A", {kB, kA}, {"A", "B"}},
- {{"A", "B"}, "B", {kB, kA}, {"B", "A"}},
- };
- // clang-format on
-
- for (const auto& test : cases) {
- MultiloginParameters multilogin_parameters =
- mice_delegate.CalculateParametersForMultilogin(
- ToAccountIdList(test.chrome_accounts),
- CoreAccountId(test.primary_account), test.gaia_accounts, false,
- false);
- EXPECT_EQ(gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
- multilogin_parameters.mode);
- EXPECT_EQ(ToAccountIdList(test.expected_accounts),
- multilogin_parameters.accounts_to_send);
- }
-}
-
-} // namespace signin
diff --git a/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h b/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h
index bc465861119..691663954a3 100644
--- a/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h
+++ b/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h
@@ -27,6 +27,8 @@ class MirrorAccountReconcilorDelegate : public AccountReconcilorDelegate,
// |ChromeOSAccountReconcilorDelegate|.
bool IsReconcileEnabled() const override;
+ IdentityManager* GetIdentityManager() const { return identity_manager_; }
+
private:
// AccountReconcilorDelegate:
bool IsAccountConsistencyEnforced() const override;
diff --git a/chromium/components/signin/core/browser/resources/signin_internals.js b/chromium/components/signin/core/browser/resources/signin_internals.js
index 3f0e72974b7..c5bcefded93 100644
--- a/chromium/components/signin/core/browser/resources/signin_internals.js
+++ b/chromium/components/signin/core/browser/resources/signin_internals.js
@@ -16,11 +16,11 @@ chrome.signin = chrome.signin || {};
// TODO(vishwath): This function is identical to the one in sync_internals.js
// Merge both if possible.
-// Accepts a DOM node and sets its highlighted attribute oldVal != newVal
+// Accepts a DOM node and sets its highlighted attribute oldVal !== newVal
function highlightIfChanged(node, oldVal, newVal) {
const oldStr = oldVal.toString();
const newStr = newVal.toString();
- if (oldStr != '' && oldStr != newStr) {
+ if (oldStr !== '' && oldStr !== newStr) {
// Note the addListener function does not end up creating duplicate
// listeners. There can be only one listener per event at a time.
// Reference: https://developer.mozilla.org/en/DOM/element.addEventListener
@@ -39,10 +39,10 @@ function highlightIfAnyChanged(node, oldToNewValList) {
}
function setClassFromValue(value) {
- if (value == 0) {
+ if (value === 0) {
return 'zero';
}
- if (value == 'Successful') {
+ if (value === 'Successful') {
return 'ok';
}
@@ -68,7 +68,7 @@ Event.prototype.addListener = function(listener) {
// Remove a listener from the list.
Event.prototype.removeListener = function(listener) {
const i = this.findListener_(listener);
- if (i == -1) {
+ if (i === -1) {
return;
}
this.listeners_.splice(i, 1);
@@ -88,7 +88,7 @@ Event.prototype.hasListeners = function() {
// Returns the index of the given listener, or -1 if not found.
Event.prototype.findListener_ = function(listener) {
for (let i = 0; i < this.listeners_.length; i++) {
- if (this.listeners_[i] == listener) {
+ if (this.listeners_[i] === listener) {
return i;
}
}
diff --git a/chromium/components/signin/core/browser/signin_error_controller.h b/chromium/components/signin/core/browser/signin_error_controller.h
index 77324e7e752..4ada371004a 100644
--- a/chromium/components/signin/core/browser/signin_error_controller.h
+++ b/chromium/components/signin/core/browser/signin_error_controller.h
@@ -5,10 +5,8 @@
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_ERROR_CONTROLLER_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_ERROR_CONTROLLER_H_
-#include <set>
#include <string>
-#include "base/compiler_specific.h"
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/scoped_observer.h"
@@ -28,8 +26,8 @@ class SigninErrorController : public KeyedService,
// are in error state, only one of the errors is reported.
ANY_ACCOUNT,
- // Only errors on the primary account are reported. Other accounts are
- // ignored.
+ // Only errors on the primary account are reported. The primary account
+ // must have sync consent. Other accounts are ignored.
PRIMARY_ACCOUNT
};
diff --git a/chromium/components/signin/core/browser/signin_error_controller_unittest.cc b/chromium/components/signin/core/browser/signin_error_controller_unittest.cc
index 21fa1530d82..ea955f29cd3 100644
--- a/chromium/components/signin/core/browser/signin_error_controller_unittest.cc
+++ b/chromium/components/signin/core/browser/signin_error_controller_unittest.cc
@@ -110,6 +110,31 @@ TEST(SigninErrorControllerTest, AccountTransitionAnyAccount) {
ASSERT_FALSE(error_controller.HasError());
}
+// Verifies errors are reported in mode ANY_ACCOUNT even if the primary account
+// has not consented to the browser sync feature.
+TEST(SigninErrorControllerTest, UnconsentedPrimaryAccount) {
+ base::test::TaskEnvironment task_environment;
+ signin::IdentityTestEnvironment identity_test_env;
+
+ CoreAccountId test_account_id =
+ identity_test_env.MakeUnconsentedPrimaryAccountAvailable(kTestEmail)
+ .account_id;
+ SigninErrorController error_controller(
+ SigninErrorController::AccountMode::ANY_ACCOUNT,
+ identity_test_env.identity_manager());
+ ASSERT_FALSE(error_controller.HasError());
+
+ identity_test_env.UpdatePersistentErrorOfRefreshTokenForAccount(
+ test_account_id,
+ GoogleServiceAuthError(GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
+ EXPECT_TRUE(error_controller.HasError());
+ EXPECT_EQ(test_account_id, error_controller.error_account_id());
+
+ identity_test_env.UpdatePersistentErrorOfRefreshTokenForAccount(
+ test_account_id, GoogleServiceAuthError::AuthErrorNone());
+ EXPECT_FALSE(error_controller.HasError());
+}
+
// This test exercises behavior on signin/signout, which is not relevant on
// ChromeOS.
#if !defined(OS_CHROMEOS)
diff --git a/chromium/components/signin/core/browser/signin_header_helper.h b/chromium/components/signin/core/browser/signin_header_helper.h
index 20c4e4dcb8e..0c9cdf7c709 100644
--- a/chromium/components/signin/core/browser/signin_header_helper.h
+++ b/chromium/components/signin/core/browser/signin_header_helper.h
@@ -43,13 +43,16 @@ extern const char kDiceResponseHeader[];
// perform.
// A Java counterpart will be generated for this enum.
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.components.signin
+// NOTE: This enum is persisted to histograms. Do not change or reorder
+// values.
enum GAIAServiceType : int {
GAIA_SERVICE_TYPE_NONE = 0, // No Gaia response header.
GAIA_SERVICE_TYPE_SIGNOUT, // Logout all existing sessions.
GAIA_SERVICE_TYPE_INCOGNITO, // Open an incognito tab.
- GAIA_SERVICE_TYPE_ADDSESSION, // Add a secondary account.
+ GAIA_SERVICE_TYPE_ADDSESSION, // Add or re-authenticate an account.
GAIA_SERVICE_TYPE_SIGNUP, // Create a new account.
GAIA_SERVICE_TYPE_DEFAULT, // All other cases.
+ kMaxValue = GAIA_SERVICE_TYPE_DEFAULT
};
enum class DiceAction {
diff --git a/chromium/components/signin/core/browser/signin_header_helper_unittest.cc b/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
index 1dcb4c5352c..2f6e6a338b7 100644
--- a/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
+++ b/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
@@ -142,31 +142,12 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdChromeOS) {
// Tests that no Mirror request is returned when the user is not signed in (no
// account id), for non Chrome OS platforms.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestNoAccountId) {
-#if defined(OS_ANDROID)
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndDisableFeature(kMiceFeature);
-#endif
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "", "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), "", "");
}
#endif
-#if defined(OS_ANDROID)
-// Tests that Mirror request is returned on Android with Mice.
-TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdMice) {
- base::test::ScopedFeatureList scoped_feature_list;
- scoped_feature_list.InitAndEnableFeature(kMiceFeature);
- account_consistency_ = AccountConsistencyMethod::kMirror;
- CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "",
- "mode=0,enable_account_consistency=true,"
- "consistency_enabled_by_default=true");
- CheckMirrorCookieRequest(GURL("https://docs.google.com"), "",
- "mode=0:enable_account_consistency=true:"
- "consistency_enabled_by_default=true");
-}
-#endif
-
// Tests that no Mirror request is returned when the cookies aren't allowed to
// be set.
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
diff --git a/chromium/components/signin/internal/base/DEPS b/chromium/components/signin/internal/base/DEPS
index c079a1bff2c..5fa21919cc3 100644
--- a/chromium/components/signin/internal/base/DEPS
+++ b/chromium/components/signin/internal/base/DEPS
@@ -3,6 +3,6 @@ include_rules = [
specific_include_rules = {
"account_manager_facade_android.cc": [
- "+components/signin/core/browser/android/jni_headers/AccountManagerFacade_jni.h",
+ "+components/signin/core/browser/android/jni_headers/AccountManagerFacadeProvider_jni.h",
],
}
diff --git a/chromium/components/signin/internal/base/account_manager_facade_android.cc b/chromium/components/signin/internal/base/account_manager_facade_android.cc
index 83ca3fc562e..2cd58170d6b 100644
--- a/chromium/components/signin/internal/base/account_manager_facade_android.cc
+++ b/chromium/components/signin/internal/base/account_manager_facade_android.cc
@@ -4,9 +4,10 @@
#include "components/signin/internal/base/account_manager_facade_android.h"
-#include "components/signin/core/browser/android/jni_headers/AccountManagerFacade_jni.h"
+#include "components/signin/core/browser/android/jni_headers/AccountManagerFacadeProvider_jni.h"
base::android::ScopedJavaLocalRef<jobject>
AccountManagerFacadeAndroid::GetJavaObject() {
- return Java_AccountManagerFacade_get(base::android::AttachCurrentThread());
+ return Java_AccountManagerFacadeProvider_getInstance(
+ base::android::AttachCurrentThread());
}
diff --git a/chromium/components/signin/internal/identity_manager/BUILD.gn b/chromium/components/signin/internal/identity_manager/BUILD.gn
index fa402c9bc87..e7d0ccee66f 100644
--- a/chromium/components/signin/internal/identity_manager/BUILD.gn
+++ b/chromium/components/signin/internal/identity_manager/BUILD.gn
@@ -24,8 +24,6 @@ source_set("identity_manager") {
"diagnostics_provider_impl.h",
"gaia_cookie_manager_service.cc",
"gaia_cookie_manager_service.h",
- "oauth2_token_service_delegate_android.cc",
- "oauth2_token_service_delegate_android.h",
"oauth_multilogin_helper.cc",
"oauth_multilogin_helper.h",
"oauth_multilogin_token_fetcher.cc",
@@ -41,6 +39,8 @@ source_set("identity_manager") {
"profile_oauth2_token_service_builder.h",
"profile_oauth2_token_service_delegate.cc",
"profile_oauth2_token_service_delegate.h",
+ "profile_oauth2_token_service_delegate_android.cc",
+ "profile_oauth2_token_service_delegate_android.h",
"profile_oauth2_token_service_delegate_chromeos.cc",
"profile_oauth2_token_service_delegate_chromeos.h",
"profile_oauth2_token_service_delegate_ios.h",
@@ -73,9 +73,9 @@ source_set("identity_manager") {
if (is_android) {
deps += [
- "android:jni_headers",
"//components/signin/core/browser/android:jni_headers",
"//components/signin/internal/base",
+ "//components/signin/public/android:jni_headers",
]
}
@@ -130,11 +130,11 @@ source_set("unit_tests") {
"account_info_util_unittest.cc",
"account_tracker_service_unittest.cc",
"gaia_cookie_manager_service_unittest.cc",
- "oauth2_token_service_delegate_android_unittest.cc",
"oauth_multilogin_helper_unittest.cc",
"oauth_multilogin_token_fetcher_unittest.cc",
"primary_account_manager_unittest.cc",
"primary_account_policy_manager_impl_unittest.cc",
+ "profile_oauth2_token_service_delegate_android_unittest.cc",
"profile_oauth2_token_service_delegate_chromeos_unittest.cc",
"profile_oauth2_token_service_delegate_ios_unittest.mm",
"profile_oauth2_token_service_delegate_unittest.cc",
diff --git a/chromium/components/signin/internal/identity_manager/DEPS b/chromium/components/signin/internal/identity_manager/DEPS
index c621843ba1e..0381e12029d 100644
--- a/chromium/components/signin/internal/identity_manager/DEPS
+++ b/chromium/components/signin/internal/identity_manager/DEPS
@@ -14,4 +14,7 @@ specific_include_rules = {
"child_account_info_fetcher_android.cc": [
"+components/signin/core/browser/android/jni_headers/ChildAccountInfoFetcher_jni.h",
],
+ "profile_oauth2_token_service_delegate_android.cc": [
+ "+components/signin/public/android/jni_headers/ProfileOAuth2TokenServiceDelegate_jni.h",
+ ]
}
diff --git a/chromium/components/signin/internal/identity_manager/account_fetcher_service.cc b/chromium/components/signin/internal/identity_manager/account_fetcher_service.cc
index b68852ce51f..39dbbb3fb5c 100644
--- a/chromium/components/signin/internal/identity_manager/account_fetcher_service.cc
+++ b/chromium/components/signin/internal/identity_manager/account_fetcher_service.cc
@@ -23,6 +23,7 @@
#include "components/signin/public/base/avatar_icon_util.h"
#include "components/signin/public/base/signin_client.h"
#include "components/signin/public/base/signin_switches.h"
+#include "net/http/http_status_code.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#if defined(OS_ANDROID)
@@ -74,8 +75,11 @@ void AccountFetcherService::Initialize(
DCHECK(image_decoder);
DCHECK(!image_decoder_);
image_decoder_ = std::move(image_decoder);
- last_updated_ = signin_client_->GetPrefs()->GetTime(
- AccountFetcherService::kLastUpdatePref);
+ repeating_timer_ = std::make_unique<signin::PersistentRepeatingTimer>(
+ signin_client_->GetPrefs(), AccountFetcherService::kLastUpdatePref,
+ kRefreshFromTokenServiceDelay,
+ base::Bind(&AccountFetcherService::RefreshAllAccountInfo,
+ base::Unretained(this), false));
// Tokens may have already been loaded and we will not receive a
// notification-on-registration for |token_service_->AddObserver(this)| few
@@ -161,7 +165,7 @@ void AccountFetcherService::MaybeEnableNetworkFetches() {
return;
if (!network_fetches_enabled_) {
network_fetches_enabled_ = true;
- ScheduleNextRefresh();
+ repeating_timer_->Start();
}
RefreshAllAccountInfo(true);
#if defined(OS_ANDROID)
@@ -169,29 +173,6 @@ void AccountFetcherService::MaybeEnableNetworkFetches() {
#endif
}
-void AccountFetcherService::RefreshAllAccountsAndScheduleNext() {
- DCHECK(network_fetches_enabled_);
- RefreshAllAccountInfo(false);
- last_updated_ = base::Time::Now();
- signin_client_->GetPrefs()->SetTime(AccountFetcherService::kLastUpdatePref,
- last_updated_);
- ScheduleNextRefresh();
-}
-
-void AccountFetcherService::ScheduleNextRefresh() {
- DCHECK(!timer_.IsRunning());
- DCHECK(network_fetches_enabled_);
-
- const base::TimeDelta time_since_update = base::Time::Now() - last_updated_;
- if (time_since_update > kRefreshFromTokenServiceDelay) {
- RefreshAllAccountsAndScheduleNext();
- } else {
- timer_.Start(FROM_HERE, kRefreshFromTokenServiceDelay - time_since_update,
- this,
- &AccountFetcherService::RefreshAllAccountsAndScheduleNext);
- }
-}
-
// Starts fetching user information. This is called periodically to refresh.
void AccountFetcherService::StartFetchingUserInfo(
const CoreAccountId& account_id) {
@@ -273,13 +254,23 @@ AccountFetcherService::GetOrCreateImageFetcher() {
void AccountFetcherService::FetchAccountImage(const CoreAccountId& account_id) {
DCHECK(signin_client_);
- std::string picture_url_string =
- account_tracker_service_->GetAccountInfo(account_id).picture_url;
+ AccountInfo account_info =
+ account_tracker_service_->GetAccountInfo(account_id);
+ std::string picture_url_string = account_info.picture_url;
+
GURL picture_url(picture_url_string);
if (!picture_url.is_valid()) {
DVLOG(1) << "Invalid avatar picture URL: \"" + picture_url_string + "\"";
return;
}
+ GURL image_url_with_size(signin::GetAvatarImageURLWithOptions(
+ picture_url, signin::kAccountInfoImageSize, true /* no_silhouette */));
+
+ if (image_url_with_size.spec() ==
+ account_info.last_downloaded_image_url_with_size) {
+ return;
+ }
+
net::NetworkTrafficAnnotationTag traffic_annotation =
net::DefineNetworkTrafficAnnotation("accounts_image_fetcher", R"(
semantics {
@@ -302,14 +293,14 @@ void AccountFetcherService::FetchAccountImage(const CoreAccountId& account_id) {
"uploaded or saved; this request merely downloads the web account"
"profile image."
})");
- GURL image_url_with_size(signin::GetAvatarImageURLWithOptions(
- picture_url, signin::kAccountInfoImageSize, true /* no_silhouette */));
- auto callback = base::BindRepeating(&AccountFetcherService::OnImageFetched,
- base::Unretained(this), account_id);
+
+ auto callback = base::BindOnce(&AccountFetcherService::OnImageFetched,
+ base::Unretained(this), account_id,
+ image_url_with_size.spec());
image_fetcher::ImageFetcherParams params(traffic_annotation,
kImageFetcherUmaClient);
- GetOrCreateImageFetcher()->FetchImage(image_url_with_size, callback,
- std::move(params));
+ GetOrCreateImageFetcher()->FetchImage(image_url_with_size,
+ std::move(callback), std::move(params));
}
void AccountFetcherService::OnUserInfoFetchFailure(
@@ -368,7 +359,13 @@ void AccountFetcherService::OnRefreshTokensLoaded() {
void AccountFetcherService::OnImageFetched(
const CoreAccountId& account_id,
+ const std::string& image_url_with_size,
const gfx::Image& image,
- const image_fetcher::RequestMetadata&) {
- account_tracker_service_->SetAccountImage(account_id, image);
+ const image_fetcher::RequestMetadata& metadata) {
+ if (metadata.http_response_code != net::HTTP_OK) {
+ DCHECK(image.IsEmpty());
+ return;
+ }
+ account_tracker_service_->SetAccountImage(account_id, image_url_with_size,
+ image);
}
diff --git a/chromium/components/signin/internal/identity_manager/account_fetcher_service.h b/chromium/components/signin/internal/identity_manager/account_fetcher_service.h
index 6e22e2fd24a..b827ba002b7 100644
--- a/chromium/components/signin/internal/identity_manager/account_fetcher_service.h
+++ b/chromium/components/signin/internal/identity_manager/account_fetcher_service.h
@@ -16,6 +16,7 @@
#include "base/timer/timer.h"
#include "build/build_config.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service_observer.h"
+#include "components/signin/public/base/persistent_repeating_timer.h"
class AccountInfoFetcher;
class AccountTrackerService;
@@ -100,8 +101,6 @@ class AccountFetcherService : public ProfileOAuth2TokenServiceObserver {
friend class AccountInfoFetcher;
void RefreshAllAccountInfo(bool only_fetch_if_invalid);
- void RefreshAllAccountsAndScheduleNext();
- void ScheduleNextRefresh();
#if defined(OS_ANDROID)
// Called on all account state changes. Decides whether to fetch new child
@@ -138,6 +137,7 @@ class AccountFetcherService : public ProfileOAuth2TokenServiceObserver {
void FetchAccountImage(const CoreAccountId& account_id);
void OnImageFetched(const CoreAccountId& account_id,
+ const std::string& image_url_with_size,
const gfx::Image& image,
const image_fetcher::RequestMetadata& image_metadata);
@@ -149,8 +149,7 @@ class AccountFetcherService : public ProfileOAuth2TokenServiceObserver {
bool refresh_tokens_loaded_ = false;
bool shutdown_called_ = false;
bool enable_account_removal_for_test_ = false;
- base::Time last_updated_;
- base::OneShotTimer timer_;
+ std::unique_ptr<signin::PersistentRepeatingTimer> repeating_timer_;
#if defined(OS_ANDROID)
CoreAccountId child_request_account_id_;
diff --git a/chromium/components/signin/internal/identity_manager/account_tracker_service.cc b/chromium/components/signin/internal/identity_manager/account_tracker_service.cc
index 413b94d26e1..aec0f43225b 100644
--- a/chromium/components/signin/internal/identity_manager/account_tracker_service.cc
+++ b/chromium/components/signin/internal/identity_manager/account_tracker_service.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/callback.h"
#include "base/command_line.h"
+#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
@@ -17,6 +18,7 @@
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
+#include "base/task/thread_pool.h"
#include "base/task_runner_util.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/trace_event/trace_event.h"
@@ -25,6 +27,7 @@
#include "components/prefs/scoped_user_pref_update.h"
#include "components/signin/internal/identity_manager/account_info_util.h"
#include "components/signin/public/base/signin_pref_names.h"
+#include "components/signin/public/base/signin_switches.h"
#include "ui/gfx/image/image.h"
#if defined(OS_ANDROID)
@@ -33,7 +36,6 @@
#endif
namespace {
-
const char kAccountKeyPath[] = "account_id";
const char kAccountEmailPath[] = "email";
const char kAccountGaiaPath[] = "gaia";
@@ -42,6 +44,8 @@ const char kAccountFullNamePath[] = "full_name";
const char kAccountGivenNamePath[] = "given_name";
const char kAccountLocalePath[] = "locale";
const char kAccountPictureURLPath[] = "picture_url";
+const char kLastDownloadedImageURLWithSizePath[] =
+ "last_downloaded_image_url_with_size";
const char kAccountChildAccountStatusPath[] = "is_child_account";
const char kAdvancedProtectionAccountStatusPath[] =
"is_under_advanced_protection";
@@ -70,7 +74,7 @@ gfx::Image ReadImage(const base::FilePath& image_path) {
}
// Saves |png_data| to disk at |image_path|.
-void SaveImage(scoped_refptr<base::RefCountedMemory> png_data,
+bool SaveImage(scoped_refptr<base::RefCountedMemory> png_data,
const base::FilePath& image_path) {
base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
base::BlockingType::MAY_BLOCK);
@@ -78,12 +82,14 @@ void SaveImage(scoped_refptr<base::RefCountedMemory> png_data,
base::FilePath dir = image_path.DirName();
if (!base::DirectoryExists(dir) && !base::CreateDirectory(dir)) {
LOG(ERROR) << "Failed to create parent directory of: " << image_path;
- return;
+ return false;
}
if (base::WriteFile(image_path, png_data->front_as<char>(),
png_data->size()) == -1) {
LOG(ERROR) << "Failed to save image to file: " << image_path;
+ return false;
}
+ return true;
}
// Removes the image at path |image_path|.
@@ -124,8 +130,8 @@ void AccountTrackerService::Initialize(PrefService* pref_service,
if (!user_data_dir_.empty()) {
// |image_storage_task_runner_| is a sequenced runner because we want to
// avoid read and write operations to the same file at the same time.
- image_storage_task_runner_ = base::CreateSequencedTaskRunner(
- {base::ThreadPool(), base::MayBlock(), base::TaskPriority::USER_VISIBLE,
+ image_storage_task_runner_ = base::ThreadPool::CreateSequencedTaskRunner(
+ {base::MayBlock(), base::TaskPriority::USER_VISIBLE,
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN});
LoadAccountImagesFromDisk();
}
@@ -183,7 +189,7 @@ AccountInfo AccountTrackerService::FindAccountInfoByEmail(
// static
bool AccountTrackerService::IsMigrationSupported() {
#if defined(OS_CHROMEOS)
- return false;
+ return base::FeatureList::IsEnabled(switches::kAccountIdMigration);
#else
return true;
#endif
@@ -261,19 +267,22 @@ void AccountTrackerService::SetAccountInfoFromUserInfo(
SaveToPrefs(account_info);
}
-void AccountTrackerService::SetAccountImage(const CoreAccountId& account_id,
- const gfx::Image& image) {
+void AccountTrackerService::SetAccountImage(
+ const CoreAccountId& account_id,
+ const std::string& image_url_with_size,
+ const gfx::Image& image) {
if (!base::Contains(accounts_, account_id))
return;
AccountInfo& account_info = accounts_[account_id];
account_info.account_image = image;
- SaveAccountImageToDisk(account_id, image);
+ account_info.last_downloaded_image_url_with_size = image_url_with_size;
+ SaveAccountImageToDisk(account_id, image, image_url_with_size);
NotifyAccountUpdated(account_info);
}
void AccountTrackerService::SetIsChildAccount(const CoreAccountId& account_id,
bool is_child_account) {
- DCHECK(base::Contains(accounts_, account_id));
+ DCHECK(base::Contains(accounts_, account_id)) << account_id.ToString();
AccountInfo& account_info = accounts_[account_id];
if (account_info.is_child_account == is_child_account)
return;
@@ -286,7 +295,7 @@ void AccountTrackerService::SetIsChildAccount(const CoreAccountId& account_id,
void AccountTrackerService::SetIsAdvancedProtectionAccount(
const CoreAccountId& account_id,
bool is_under_advanced_protection) {
- DCHECK(base::Contains(accounts_, account_id));
+ DCHECK(base::Contains(accounts_, account_id)) << account_id.ToString();
AccountInfo& account_info = accounts_[account_id];
if (account_info.is_under_advanced_protection == is_under_advanced_protection)
return;
@@ -308,6 +317,10 @@ void AccountTrackerService::SetOnAccountRemovedCallback(
on_account_removed_callback_ = callback;
}
+void AccountTrackerService::CommitPendingAccountChanges() {
+ pref_service_->CommitPendingWrite();
+}
+
void AccountTrackerService::MigrateToGaiaId() {
DCHECK_EQ(GetMigrationState(), MIGRATION_IN_PROGRESS);
@@ -411,6 +424,10 @@ void AccountTrackerService::OnAccountImageLoaded(
accounts_[account_id].account_image.IsEmpty()) {
AccountInfo& account_info = accounts_[account_id];
account_info.account_image = image;
+ if (account_info.account_image.IsEmpty()) {
+ account_info.last_downloaded_image_url_with_size = std::string();
+ OnAccountImageUpdated(account_id, std::string(), true);
+ }
NotifyAccountUpdated(account_info);
}
}
@@ -430,12 +447,42 @@ void AccountTrackerService::LoadAccountImagesFromDisk() {
void AccountTrackerService::SaveAccountImageToDisk(
const CoreAccountId& account_id,
- const gfx::Image& image) {
+ const gfx::Image& image,
+ const std::string& image_url_with_size) {
if (!image_storage_task_runner_)
return;
- image_storage_task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&SaveImage, image.As1xPNGBytes(),
- GetImagePathFor(account_id)));
+
+ PostTaskAndReplyWithResult(
+ image_storage_task_runner_.get(), FROM_HERE,
+ base::BindOnce(&SaveImage, image.As1xPNGBytes(),
+ GetImagePathFor(account_id)),
+ base::BindOnce(&AccountTrackerService::OnAccountImageUpdated,
+ weak_factory_.GetWeakPtr(), account_id,
+ image_url_with_size));
+}
+
+void AccountTrackerService::OnAccountImageUpdated(
+ const CoreAccountId& account_id,
+ const std::string& image_url_with_size,
+ bool success) {
+ if (!success || !pref_service_)
+ return;
+
+ base::DictionaryValue* dict = nullptr;
+ ListPrefUpdate update(pref_service_, prefs::kAccountInfo);
+ for (size_t i = 0; i < update->GetSize(); ++i, dict = nullptr) {
+ if (update->GetDictionary(i, &dict)) {
+ std::string value;
+ if (dict->GetString(kAccountKeyPath, &value) &&
+ value == account_id.ToString())
+ break;
+ }
+ }
+
+ if (!dict) {
+ return;
+ }
+ dict->SetString(kLastDownloadedImageURLWithSizePath, image_url_with_size);
}
void AccountTrackerService::RemoveAccountImageFromDisk(
@@ -479,6 +526,8 @@ void AccountTrackerService::LoadFromPrefs() {
account_info.locale = value;
if (dict->GetString(kAccountPictureURLPath, &value))
account_info.picture_url = value;
+ if (dict->GetString(kLastDownloadedImageURLWithSizePath, &value))
+ account_info.last_downloaded_image_url_with_size = value;
bool is_child_account = false;
if (dict->GetBoolean(kAccountChildAccountStatusPath, &is_child_account))
@@ -564,6 +613,9 @@ void AccountTrackerService::SaveToPrefs(const AccountInfo& account_info) {
account_info.is_child_account);
dict->SetBoolean(kAdvancedProtectionAccountStatusPath,
account_info.is_under_advanced_protection);
+ // |kLastDownloadedImageURLWithSizePath| should only be set after the GAIA
+ // picture is successufly saved to disk. Otherwise, there is no guarantee that
+ // |kLastDownloadedImageURLWithSizePath| matches the picture on disk.
}
void AccountTrackerService::RemoveFromPrefs(const AccountInfo& account_info) {
@@ -640,6 +692,13 @@ CoreAccountId AccountTrackerService::SeedAccountInfo(AccountInfo info) {
SaveToPrefs(account_info);
}
+
+ if (!already_exists && !info.account_image.IsEmpty()) {
+ SetAccountImage(account_info.account_id,
+ account_info.last_downloaded_image_url_with_size,
+ info.account_image);
+ }
+
return info.account_id;
}
diff --git a/chromium/components/signin/internal/identity_manager/account_tracker_service.h b/chromium/components/signin/internal/identity_manager/account_tracker_service.h
index 5ba22774038..e6f29106fd4 100644
--- a/chromium/components/signin/internal/identity_manager/account_tracker_service.h
+++ b/chromium/components/signin/internal/identity_manager/account_tracker_service.h
@@ -18,6 +18,7 @@
#include "base/sequence_checker.h"
#include "base/timer/timer.h"
#include "build/build_config.h"
+#include "components/prefs/scoped_user_pref_update.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "google_apis/gaia/core_account_id.h"
#include "google_apis/gaia/gaia_auth_util.h"
@@ -50,6 +51,7 @@ void SimulateSuccessfulFetchOfAccountInfo(IdentityManager*,
const std::string&);
void SimulateAccountImageFetch(signin::IdentityManager*,
const CoreAccountId&,
+ const std::string& image_url_with_size,
const gfx::Image&);
} // namespace signin
@@ -150,6 +152,10 @@ class AccountTrackerService {
// valid GaiaId gets removed from |accounts_| (i.e. stops being tracked).
void SetOnAccountRemovedCallback(AccountInfoCallback callback);
+ // Flushes the account changes to disk. The flush happens asynchronously and
+ // this function does not block on disk IO.
+ void CommitPendingAccountChanges();
+
protected:
// Available to be called in tests.
void SetAccountInfoFromUserInfo(const CoreAccountId& account_id,
@@ -158,6 +164,7 @@ class AccountTrackerService {
// Updates the account image. Does nothing if |account_id| does not exist in
// |accounts_|.
void SetAccountImage(const CoreAccountId& account_id,
+ const std::string& image_url_with_size,
const gfx::Image& image);
private:
@@ -174,6 +181,7 @@ class AccountTrackerService {
const std::string&);
friend void signin::SimulateAccountImageFetch(signin::IdentityManager*,
const CoreAccountId&,
+ const std::string&,
const gfx::Image&);
void NotifyAccountUpdated(const AccountInfo& account_info);
@@ -192,7 +200,11 @@ class AccountTrackerService {
void OnAccountImageLoaded(const CoreAccountId& account_id, gfx::Image image);
void LoadAccountImagesFromDisk();
void SaveAccountImageToDisk(const CoreAccountId& account_id,
- const gfx::Image& image);
+ const gfx::Image& image,
+ const std::string& image_url_with_size);
+ void OnAccountImageUpdated(const CoreAccountId& account_id,
+ const std::string& image_url_with_size,
+ bool success);
void RemoveAccountImageFromDisk(const CoreAccountId& account_id);
// Migrate accounts to be keyed by gaia id instead of normalized email.
diff --git a/chromium/components/signin/internal/identity_manager/account_tracker_service_unittest.cc b/chromium/components/signin/internal/identity_manager/account_tracker_service_unittest.cc
index 72550c91a18..839d60231ce 100644
--- a/chromium/components/signin/internal/identity_manager/account_tracker_service_unittest.cc
+++ b/chromium/components/signin/internal/identity_manager/account_tracker_service_unittest.cc
@@ -444,18 +444,21 @@ TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfo_ImageSuccess) {
AccountKeyToEmail(kAccountKeyAlpha)),
}));
- EXPECT_TRUE(account_tracker()
- ->GetAccountInfo(AccountKeyToAccountId(kAccountKeyAlpha))
- .account_image.IsEmpty());
+ AccountInfo account_info = account_tracker()->GetAccountInfo(
+ AccountKeyToAccountId(kAccountKeyAlpha));
+ EXPECT_TRUE(account_info.account_image.IsEmpty());
+ EXPECT_TRUE(account_info.last_downloaded_image_url_with_size.empty());
ReturnAccountImageFetchSuccess(kAccountKeyAlpha);
EXPECT_TRUE(CheckAccountTrackerEvents({
TrackingEvent(UPDATED, AccountKeyToAccountId(kAccountKeyAlpha),
AccountKeyToGaiaId(kAccountKeyAlpha),
AccountKeyToEmail(kAccountKeyAlpha)),
}));
- EXPECT_FALSE(account_tracker()
- ->GetAccountInfo(AccountKeyToAccountId(kAccountKeyAlpha))
- .account_image.IsEmpty());
+ account_info = account_tracker()->GetAccountInfo(
+ AccountKeyToAccountId(kAccountKeyAlpha));
+ EXPECT_FALSE(account_info.account_image.IsEmpty());
+ EXPECT_EQ(account_info.last_downloaded_image_url_with_size,
+ AccountKeyToPictureURLWithSize(kAccountKeyAlpha));
}
TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfo_ImageFailure) {
@@ -468,13 +471,15 @@ TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfo_ImageFailure) {
AccountKeyToEmail(kAccountKeyAlpha)),
}));
- EXPECT_TRUE(account_tracker()
- ->GetAccountInfo(AccountKeyToAccountId(kAccountKeyAlpha))
- .account_image.IsEmpty());
+ AccountInfo account_info = account_tracker()->GetAccountInfo(
+ AccountKeyToAccountId(kAccountKeyAlpha));
+ EXPECT_TRUE(account_info.account_image.IsEmpty());
+ EXPECT_TRUE(account_info.last_downloaded_image_url_with_size.empty());
ReturnAccountImageFetchFailure(kAccountKeyAlpha);
- EXPECT_TRUE(account_tracker()
- ->GetAccountInfo(AccountKeyToAccountId(kAccountKeyAlpha))
- .account_image.IsEmpty());
+ account_info = account_tracker()->GetAccountInfo(
+ AccountKeyToAccountId(kAccountKeyAlpha));
+ EXPECT_TRUE(account_info.account_image.IsEmpty());
+ EXPECT_TRUE(account_info.last_downloaded_image_url_with_size.empty());
}
TEST_F(AccountTrackerServiceTest, TokenAvailable_UserInfo_Revoked) {
diff --git a/chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc b/chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc
index 5c769973d83..28a8a1f89c2 100644
--- a/chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc
+++ b/chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc
@@ -10,21 +10,35 @@
#include "components/signin/internal/identity_manager/account_tracker_service.h"
#include "components/signin/internal/identity_manager/gaia_cookie_manager_service.h"
#include "components/signin/public/base/multilogin_parameters.h"
+#include "components/signin/public/identity_manager/set_accounts_in_cookie_result.h"
#include "google_apis/gaia/core_account_id.h"
#include "google_apis/gaia/google_service_auth_error.h"
namespace signin {
+AccountsCookieMutatorImpl::MultiloginHelperWrapper::MultiloginHelperWrapper(
+ std::unique_ptr<OAuthMultiloginHelper> helper)
+ : helper_(std::move(helper)) {}
+
+AccountsCookieMutatorImpl::MultiloginHelperWrapper::~MultiloginHelperWrapper() =
+ default;
+
AccountsCookieMutatorImpl::AccountsCookieMutatorImpl(
+ SigninClient* signin_client,
+ ProfileOAuth2TokenService* token_service,
GaiaCookieManagerService* gaia_cookie_manager_service,
AccountTrackerService* account_tracker_service)
- : gaia_cookie_manager_service_(gaia_cookie_manager_service),
+ : signin_client_(signin_client),
+ token_service_(token_service),
+ gaia_cookie_manager_service_(gaia_cookie_manager_service),
account_tracker_service_(account_tracker_service) {
+ DCHECK(signin_client_);
+ DCHECK(token_service_);
DCHECK(gaia_cookie_manager_service_);
DCHECK(account_tracker_service_);
}
-AccountsCookieMutatorImpl::~AccountsCookieMutatorImpl() {}
+AccountsCookieMutatorImpl::~AccountsCookieMutatorImpl() = default;
void AccountsCookieMutatorImpl::AddAccountToCookie(
const CoreAccountId& account_id,
@@ -58,6 +72,32 @@ void AccountsCookieMutatorImpl::SetAccountsInCookie(
std::move(set_accounts_in_cookies_completed_callback));
}
+std::unique_ptr<AccountsCookieMutator::SetAccountsInCookieTask>
+AccountsCookieMutatorImpl::SetAccountsInCookieForPartition(
+ PartitionDelegate* partition_delegate,
+ const MultiloginParameters& parameters,
+ base::OnceCallback<void(SetAccountsInCookieResult)>
+ set_accounts_in_cookies_completed_callback) {
+ // The default partition must go through the GaiaCookieManagerService.
+ DCHECK_NE(signin_client_->GetCookieManager(),
+ partition_delegate->GetCookieManagerForPartition())
+ << "The default partition is passed to "
+ << "SetAccountsInCookieForPartition(). Use SetAccountsInCookie() "
+ << "instead.";
+
+ std::vector<GaiaCookieManagerService::AccountIdGaiaIdPair> accounts;
+ for (const auto& account_id : parameters.accounts_to_send) {
+ accounts.push_back(make_pair(
+ account_id, account_tracker_service_->GetAccountInfo(account_id).gaia));
+ }
+
+ return std::make_unique<MultiloginHelperWrapper>(
+ std::make_unique<OAuthMultiloginHelper>(
+ signin_client_, partition_delegate, token_service_, parameters.mode,
+ accounts, /*external_cc_result=*/std::string(),
+ std::move(set_accounts_in_cookies_completed_callback)));
+}
+
void AccountsCookieMutatorImpl::TriggerCookieJarUpdate() {
gaia_cookie_manager_service_->TriggerListAccounts();
}
@@ -68,8 +108,11 @@ void AccountsCookieMutatorImpl::ForceTriggerOnCookieChange() {
}
#endif
-void AccountsCookieMutatorImpl::LogOutAllAccounts(gaia::GaiaSource source) {
- gaia_cookie_manager_service_->LogOutAllAccounts(source);
+void AccountsCookieMutatorImpl::LogOutAllAccounts(
+ gaia::GaiaSource source,
+ LogOutFromCookieCompletedCallback completion_callback) {
+ gaia_cookie_manager_service_->LogOutAllAccounts(
+ source, std::move(completion_callback));
}
} // namespace signin
diff --git a/chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h b/chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h
index f363638b3e7..1f4d5f56a74 100644
--- a/chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h
+++ b/chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h
@@ -8,12 +8,16 @@
#include <string>
#include <vector>
+#include "base/callback_forward.h"
#include "base/macros.h"
#include "build/build_config.h"
+#include "components/signin/internal/identity_manager/oauth_multilogin_helper.h"
#include "components/signin/public/identity_manager/accounts_cookie_mutator.h"
class AccountTrackerService;
class GaiaCookieManagerService;
+class ProfileOAuth2TokenService;
+class SigninClient;
namespace gaia {
class GaiaSource;
@@ -25,6 +29,8 @@ namespace signin {
class AccountsCookieMutatorImpl : public AccountsCookieMutator {
public:
explicit AccountsCookieMutatorImpl(
+ SigninClient* signin_client,
+ ProfileOAuth2TokenService* token_service,
GaiaCookieManagerService* gaia_cookie_manager_service,
AccountTrackerService* account_tracker_service);
~AccountsCookieMutatorImpl() override;
@@ -46,15 +52,34 @@ class AccountsCookieMutatorImpl : public AccountsCookieMutator {
base::OnceCallback<void(SetAccountsInCookieResult)>
set_accounts_in_cookies_completed_callback) override;
+ std::unique_ptr<SetAccountsInCookieTask> SetAccountsInCookieForPartition(
+ PartitionDelegate* partition_delegate,
+ const MultiloginParameters& parameters,
+ base::OnceCallback<void(SetAccountsInCookieResult)>
+ set_accounts_in_cookies_completed_callback) override;
+
void TriggerCookieJarUpdate() override;
#if defined(OS_IOS)
void ForceTriggerOnCookieChange() override;
#endif
- void LogOutAllAccounts(gaia::GaiaSource source) override;
+ void LogOutAllAccounts(
+ gaia::GaiaSource source,
+ LogOutFromCookieCompletedCallback completion_callback) override;
private:
+ class MultiloginHelperWrapper : public SetAccountsInCookieTask {
+ public:
+ MultiloginHelperWrapper(std::unique_ptr<OAuthMultiloginHelper> helper);
+ ~MultiloginHelperWrapper() override;
+
+ private:
+ std::unique_ptr<OAuthMultiloginHelper> helper_;
+ };
+
+ SigninClient* signin_client_;
+ ProfileOAuth2TokenService* token_service_;
GaiaCookieManagerService* gaia_cookie_manager_service_;
AccountTrackerService* account_tracker_service_;
diff --git a/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.cc b/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.cc
index 6fa9e606e6d..a61eab0fec3 100644
--- a/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.cc
+++ b/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.cc
@@ -46,6 +46,12 @@ CoreAccountId AccountsMutatorImpl::AddOrUpdateAccount(
account_tracker_service_->SeedAccountInfo(gaia_id, email);
account_tracker_service_->SetIsAdvancedProtectionAccount(
account_id, is_under_advanced_protection);
+
+ // Flush the account changes to disk. Otherwise, in case of a browser crash,
+ // the account may be added to the token service but not to the account
+ // tracker, which is not intended.
+ account_tracker_service_->CommitPendingAccountChanges();
+
token_service_->UpdateCredentials(account_id, refresh_token, source);
return account_id;
diff --git a/chromium/components/signin/internal/identity_manager/android/BUILD.gn b/chromium/components/signin/internal/identity_manager/android/BUILD.gn
deleted file mode 100644
index a851e12d7a1..00000000000
--- a/chromium/components/signin/internal/identity_manager/android/BUILD.gn
+++ /dev/null
@@ -1,12 +0,0 @@
-import("//build/config/android/rules.gni")
-
-generate_jni("jni_headers") {
- namespace = "signin"
- sources = [
- "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java",
- "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java",
- "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java",
- "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java",
- "//components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/OAuth2TokenService.java",
- ]
-}
diff --git a/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc b/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc
index 7d1e64b1cc6..f01b138d04d 100644
--- a/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc
+++ b/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc
@@ -163,6 +163,12 @@ void GaiaCookieManagerService::GaiaCookieRequest::
std::move(add_account_to_cookie_completed_callback_).Run(account_id, error);
}
+void GaiaCookieManagerService::GaiaCookieRequest::
+ RunLogOutFromCookieCompletedCallback(const GoogleServiceAuthError& error) {
+ if (log_out_from_cookie_completed_callback_)
+ std::move(log_out_from_cookie_completed_callback_).Run(error);
+}
+
// static
GaiaCookieManagerService::GaiaCookieRequest
GaiaCookieManagerService::GaiaCookieRequest::CreateAddAccountRequest(
@@ -194,9 +200,12 @@ GaiaCookieManagerService::GaiaCookieRequest::CreateSetAccountsRequest(
// static
GaiaCookieManagerService::GaiaCookieRequest
GaiaCookieManagerService::GaiaCookieRequest::CreateLogOutRequest(
- gaia::GaiaSource source) {
- return GaiaCookieManagerService::GaiaCookieRequest(
+ gaia::GaiaSource source,
+ LogOutFromCookieCompletedCallback callback) {
+ GaiaCookieManagerService::GaiaCookieRequest request(
GaiaCookieRequestType::LOG_OUT, source);
+ request.log_out_from_cookie_completed_callback_ = std::move(callback);
+ return request;
}
// static
@@ -598,7 +607,9 @@ void GaiaCookieManagerService::ForceOnCookieChangeProcessing() {
net::CookieChangeCause::UNKNOWN_DELETION));
}
-void GaiaCookieManagerService::LogOutAllAccounts(gaia::GaiaSource source) {
+void GaiaCookieManagerService::LogOutAllAccounts(
+ gaia::GaiaSource source,
+ LogOutFromCookieCompletedCallback completion_callback) {
VLOG(1) << "GaiaCookieManagerService::LogOutAllAccounts";
bool log_out_queued = false;
@@ -638,13 +649,17 @@ void GaiaCookieManagerService::LogOutAllAccounts(gaia::GaiaSource source) {
}
if (!log_out_queued) {
- requests_.push_back(GaiaCookieRequest::CreateLogOutRequest(source));
+ requests_.push_back(GaiaCookieRequest::CreateLogOutRequest(
+ source, std::move(completion_callback)));
if (requests_.size() == 1) {
fetcher_retries_ = 0;
signin_client_->DelayNetworkCall(
base::BindOnce(&GaiaCookieManagerService::StartGaiaLogOut,
weak_ptr_factory_.GetWeakPtr()));
}
+ } else {
+ std::move(completion_callback)
+ .Run(GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
}
}
@@ -741,6 +756,12 @@ void GaiaCookieManagerService::SignalSetAccountsComplete(
requests_.front().RunSetAccountsInCookieCompletedCallback(result);
}
+void GaiaCookieManagerService::SignalLogOutComplete(
+ const GoogleServiceAuthError& error) {
+ DCHECK(requests_.front().request_type() == GaiaCookieRequestType::LOG_OUT);
+ requests_.front().RunLogOutFromCookieCompletedCallback(error);
+}
+
void GaiaCookieManagerService::SetGaiaAccountsInCookieUpdatedCallback(
GaiaAccountsInCookieUpdatedCallback callback) {
DCHECK(!gaia_accounts_updated_in_cookie_callback_);
@@ -910,6 +931,7 @@ void GaiaCookieManagerService::OnLogOutSuccess() {
RecordLogoutRequestState(LogoutRequestState::kSuccess);
MarkListAccountsStale();
+ SignalLogOutComplete(GoogleServiceAuthError::AuthErrorNone());
fetcher_backoff_.InformOfRequest(true);
HandleNextRequest();
}
@@ -931,9 +953,22 @@ void GaiaCookieManagerService::OnLogOutFailure(
return;
}
+ SignalLogOutComplete(error);
HandleNextRequest();
}
+std::unique_ptr<GaiaAuthFetcher>
+GaiaCookieManagerService::CreateGaiaAuthFetcherForPartition(
+ GaiaAuthConsumer* consumer) {
+ return signin_client_->CreateGaiaAuthFetcher(consumer,
+ gaia::GaiaSource::kChrome);
+}
+
+network::mojom::CookieManager*
+GaiaCookieManagerService::GetCookieManagerForPartition() {
+ return signin_client_->GetCookieManager();
+}
+
void GaiaCookieManagerService::InitializeListedAccountsIds() {
for (gaia::ListedAccount& account : listed_accounts_) {
DCHECK(account.id.empty());
@@ -1006,8 +1041,8 @@ void GaiaCookieManagerService::StartSetAccounts() {
}
oauth_multilogin_helper_ = std::make_unique<signin::OAuthMultiloginHelper>(
- signin_client_, token_service_, requests_.front().GetMultiloginMode(),
- requests_.front().GetAccounts(),
+ signin_client_, this, token_service_,
+ requests_.front().GetMultiloginMode(), requests_.front().GetAccounts(),
external_cc_result_fetcher_.GetExternalCcResult(),
base::BindOnce(&GaiaCookieManagerService::OnSetAccountsFinished,
weak_ptr_factory_.GetWeakPtr()));
diff --git a/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.h b/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.h
index ca91666a74e..64348eb13a0 100644
--- a/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.h
+++ b/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.h
@@ -21,6 +21,7 @@
#include "components/prefs/pref_registry_simple.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service.h"
#include "components/signin/public/base/signin_client.h"
+#include "components/signin/public/identity_manager/accounts_cookie_mutator.h"
#include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/gaia_auth_fetcher.h"
#include "google_apis/gaia/gaia_auth_util.h"
@@ -54,8 +55,10 @@ enum class SetAccountsInCookieResult;
// Also checks the External CC result to ensure no services that consume the
// GAIA cookie are blocked (such as youtube). This is executed once for the
// lifetime of this object, when the first call is made to AddAccountToCookie.
-class GaiaCookieManagerService : public GaiaAuthConsumer,
- public network::mojom::CookieChangeListener {
+class GaiaCookieManagerService
+ : public GaiaAuthConsumer,
+ public signin::AccountsCookieMutator::PartitionDelegate,
+ public network::mojom::CookieChangeListener {
public:
using AccountIdGaiaIdPair = std::pair<CoreAccountId, std::string>;
@@ -71,6 +74,8 @@ class GaiaCookieManagerService : public GaiaAuthConsumer,
typedef base::OnceCallback<void(const CoreAccountId&,
const GoogleServiceAuthError&)>
AddAccountToCookieCompletedCallback;
+ typedef base::OnceCallback<void(const GoogleServiceAuthError&)>
+ LogOutFromCookieCompletedCallback;
typedef base::RepeatingCallback<void(const std::vector<gaia::ListedAccount>&,
const std::vector<gaia::ListedAccount>&,
@@ -103,12 +108,16 @@ class GaiaCookieManagerService : public GaiaAuthConsumer,
void RunAddAccountToCookieCompletedCallback(
const CoreAccountId& account_id,
const GoogleServiceAuthError& error);
+ void RunLogOutFromCookieCompletedCallback(
+ const GoogleServiceAuthError& error);
static GaiaCookieRequest CreateAddAccountRequest(
const CoreAccountId& account_id,
gaia::GaiaSource source,
AddAccountToCookieCompletedCallback callback);
- static GaiaCookieRequest CreateLogOutRequest(gaia::GaiaSource source);
+ static GaiaCookieRequest CreateLogOutRequest(
+ gaia::GaiaSource source,
+ LogOutFromCookieCompletedCallback callback);
static GaiaCookieRequest CreateListAccountsRequest();
static GaiaCookieRequest CreateSetAccountsRequest(
gaia::MultiloginMode mode,
@@ -142,6 +151,7 @@ class GaiaCookieManagerService : public GaiaAuthConsumer,
set_accounts_in_cookie_completed_callback_;
AddAccountToCookieCompletedCallback
add_account_to_cookie_completed_callback_;
+ LogOutFromCookieCompletedCallback log_out_from_cookie_completed_callback_;
DISALLOW_COPY_AND_ASSIGN(GaiaCookieRequest);
};
@@ -256,7 +266,8 @@ class GaiaCookieManagerService : public GaiaAuthConsumer,
void CancelAll();
// Signout all accounts.
- void LogOutAllAccounts(gaia::GaiaSource source);
+ void LogOutAllAccounts(gaia::GaiaSource source,
+ LogOutFromCookieCompletedCallback callback);
// Call observers when setting accounts in cookie completes.
void SignalSetAccountsComplete(signin::SetAccountsInCookieResult result);
@@ -313,6 +324,9 @@ class GaiaCookieManagerService : public GaiaAuthConsumer,
const base::circular_deque<GaiaCookieRequest>::iterator& request,
const GoogleServiceAuthError& error);
+ // Calls the LogOutFromCookie completion callback.
+ void SignalLogOutComplete(const GoogleServiceAuthError& error);
+
// Marks the list account being staled, and for iOS only, it triggers to fetch
// the list of accounts (on iOS there is no OnCookieChange() notification).
void MarkListAccountsStale();
@@ -331,6 +345,11 @@ class GaiaCookieManagerService : public GaiaAuthConsumer,
void OnLogOutSuccess() override;
void OnLogOutFailure(const GoogleServiceAuthError& error) override;
+ // Overridden from signin::AccountsCookieMutator::PartitionDelegate.
+ std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcherForPartition(
+ GaiaAuthConsumer* consumer) override;
+ network::mojom::CookieManager* GetCookieManagerForPartition() override;
+
// Helper method to initialize listed accounts ids.
void InitializeListedAccountsIds();
diff --git a/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc b/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc
index ede9d344628..369811b3473 100644
--- a/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc
+++ b/chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/callback_helpers.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
@@ -41,6 +42,8 @@ const char kAccountId4[] = "account_id4";
using MockAddAccountToCookieCompletedCallback = base::MockCallback<
GaiaCookieManagerService::AddAccountToCookieCompletedCallback>;
+using MockLogOutFromCookieCompletedCallback = base::MockCallback<
+ GaiaCookieManagerService::LogOutFromCookieCompletedCallback>;
class MockObserver {
public:
@@ -454,7 +457,11 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsNoQueue) {
add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ MockLogOutFromCookieCompletedCallback log_out_from_cookie_completed;
+ EXPECT_CALL(log_out_from_cookie_completed, Run(no_error()));
+
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed.Get());
SimulateLogOutSuccess(&helper);
ASSERT_FALSE(helper.is_running());
}
@@ -473,7 +480,10 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsFails) {
add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ MockLogOutFromCookieCompletedCallback log_out_from_cookie_completed;
+ // A completion callback shouldn't be called.
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed.Get());
SimulateLogOutFailure(&helper, error());
// CookieManagerService is still running; it is retrying the failed logout.
ASSERT_TRUE(helper.is_running());
@@ -488,10 +498,13 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsAfterOneAddInQueue) {
MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed;
EXPECT_CALL(add_account_to_cookie_completed, Run(account_id2_, no_error()));
+ MockLogOutFromCookieCompletedCallback log_out_from_cookie_completed;
+ EXPECT_CALL(log_out_from_cookie_completed, Run(no_error()));
helper.AddAccountToCookie(account_id2_, gaia::GaiaSource::kChrome,
add_account_to_cookie_completed.Get());
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
SimulateLogOutSuccess(&helper);
@@ -508,13 +521,16 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsAfterTwoAddsInQueue) {
add_account_to_cookie_completed2;
EXPECT_CALL(add_account_to_cookie_completed1, Run(account_id1_, no_error()));
EXPECT_CALL(add_account_to_cookie_completed2, Run(account_id2_, canceled()));
+ MockLogOutFromCookieCompletedCallback log_out_from_cookie_completed;
+ EXPECT_CALL(log_out_from_cookie_completed, Run(no_error()));
helper.AddAccountToCookie(account_id1_, gaia::GaiaSource::kChrome,
add_account_to_cookie_completed1.Get());
// The Log Out should prevent this AddAccount from being fetched.
helper.AddAccountToCookie(account_id2_, gaia::GaiaSource::kChrome,
add_account_to_cookie_completed2.Get());
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
SimulateLogOutSuccess(&helper);
@@ -534,9 +550,16 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsTwice) {
add_account_to_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ MockLogOutFromCookieCompletedCallback log_out_from_cookie_completed1,
+ log_out_from_cookie_completed2;
+ EXPECT_CALL(log_out_from_cookie_completed1, Run(no_error()));
+ EXPECT_CALL(log_out_from_cookie_completed2, Run(canceled()));
+
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed1.Get());
// Only one LogOut will be fetched.
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed2.Get());
SimulateLogOutSuccess(&helper);
}
@@ -556,7 +579,11 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsBeforeAdd) {
add_account_to_cookie_completed2.Get());
SimulateMergeSessionSuccess(&helper, "token1");
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ MockLogOutFromCookieCompletedCallback log_out_from_cookie_completed;
+ EXPECT_CALL(log_out_from_cookie_completed, Run(no_error()));
+
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed.Get());
helper.AddAccountToCookie(account_id3_, gaia::GaiaSource::kChrome,
add_account_to_cookie_completed3.Get());
@@ -581,9 +608,16 @@ TEST_F(GaiaCookieManagerServiceTest, LogOutAllAccountsBeforeLogoutAndAdd) {
add_account_to_cookie_completed2.Get());
SimulateMergeSessionSuccess(&helper, "token1");
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ MockLogOutFromCookieCompletedCallback log_out_from_cookie_completed1,
+ log_out_from_cookie_completed2;
+ EXPECT_CALL(log_out_from_cookie_completed1, Run(no_error()));
+ EXPECT_CALL(log_out_from_cookie_completed2, Run(canceled()));
+
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed1.Get());
// Second LogOut will never be fetched.
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed2.Get());
helper.AddAccountToCookie(account_id3_, gaia::GaiaSource::kChrome,
add_account_to_cookie_completed3.Get());
@@ -605,13 +639,16 @@ TEST_F(GaiaCookieManagerServiceTest, PendingSigninThenSignout) {
MockAddAccountToCookieCompletedCallback add_account_to_cookie_completed3;
EXPECT_CALL(add_account_to_cookie_completed3, Run(account_id3_, no_error()));
+ MockLogOutFromCookieCompletedCallback log_out_from_cookie_completed;
+ EXPECT_CALL(log_out_from_cookie_completed, Run(no_error()));
// Total sign in 2 times, not enforcing ordered sequences.
EXPECT_CALL(helper, StartFetchingUbertoken()).Times(2);
helper.AddAccountToCookie(account_id1_, gaia::GaiaSource::kChrome,
add_account_to_cookie_completed1.Get());
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
SimulateLogOutSuccess(&helper);
@@ -632,11 +669,15 @@ TEST_F(GaiaCookieManagerServiceTest, CancelSignIn) {
EXPECT_CALL(add_account_to_cookie_completed2, Run(account_id2_, canceled()));
EXPECT_CALL(helper, StartFetchingLogOut());
+ MockLogOutFromCookieCompletedCallback log_out_from_cookie_completed;
+ EXPECT_CALL(log_out_from_cookie_completed, Run(no_error()));
+
helper.AddAccountToCookie(account_id1_, gaia::GaiaSource::kChrome,
add_account_to_cookie_completed1.Get());
helper.AddAccountToCookie(account_id2_, gaia::GaiaSource::kChrome,
add_account_to_cookie_completed2.Get());
- helper.LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ helper.LogOutAllAccounts(gaia::GaiaSource::kChrome,
+ log_out_from_cookie_completed.Get());
SimulateMergeSessionSuccess(&helper, "token1");
SimulateLogOutSuccess(&helper);
diff --git a/chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc b/chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
index 01c117c1a9d..00471573a28 100644
--- a/chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
+++ b/chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate_unittest.cc
@@ -10,6 +10,7 @@
#include <vector>
#include "base/bind.h"
+#include "base/bind_helpers.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/metrics/histogram_tester.h"
@@ -124,9 +125,8 @@ class MutableProfileOAuth2TokenServiceDelegateTest
web_database->LoadDatabase();
token_web_data_ =
new TokenWebData(web_database, base::ThreadTaskRunnerHandle::Get(),
- base::ThreadTaskRunnerHandle::Get(),
- WebDataServiceBase::ProfileErrorCallback());
- token_web_data_->Init();
+ base::ThreadTaskRunnerHandle::Get());
+ token_web_data_->Init(base::NullCallback());
}
void AddSuccessfulOAuhTokenResponse() {
diff --git a/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.cc b/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.cc
index 068076f824b..08d22b236cd 100644
--- a/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.cc
+++ b/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.cc
@@ -13,6 +13,7 @@
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "components/signin/internal/identity_manager/oauth_multilogin_token_fetcher.h"
+#include "components/signin/internal/identity_manager/profile_oauth2_token_service.h"
#include "components/signin/public/base/signin_client.h"
#include "components/signin/public/identity_manager/set_accounts_in_cookie_result.h"
#include "google_apis/gaia/google_service_auth_error.h"
@@ -20,6 +21,8 @@
#include "mojo/public/cpp/bindings/callback_helpers.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+namespace signin {
+
namespace {
constexpr int kMaxFetcherRetries = 3;
@@ -36,7 +39,7 @@ std::string FindTokenForAccount(
}
CoreAccountId FindAccountIdForGaiaId(
- const std::vector<GaiaCookieManagerService::AccountIdGaiaIdPair>& accounts,
+ const std::vector<OAuthMultiloginHelper::AccountIdGaiaIdPair>& accounts,
const std::string& gaia_id) {
for (const auto& account : accounts) {
if (gaia_id == account.second)
@@ -47,30 +50,31 @@ CoreAccountId FindAccountIdForGaiaId(
} // namespace
-namespace signin {
-
OAuthMultiloginHelper::OAuthMultiloginHelper(
SigninClient* signin_client,
+ AccountsCookieMutator::PartitionDelegate* partition_delegate,
ProfileOAuth2TokenService* token_service,
gaia::MultiloginMode mode,
- const std::vector<GaiaCookieManagerService::AccountIdGaiaIdPair>& accounts,
+ const std::vector<AccountIdGaiaIdPair>& accounts,
const std::string& external_cc_result,
base::OnceCallback<void(SetAccountsInCookieResult)> callback)
: signin_client_(signin_client),
+ partition_delegate_(partition_delegate),
token_service_(token_service),
mode_(mode),
accounts_(accounts),
external_cc_result_(external_cc_result),
callback_(std::move(callback)) {
DCHECK(signin_client_);
+ DCHECK(partition_delegate_);
DCHECK(token_service_);
DCHECK(!accounts_.empty());
DCHECK(callback_);
#ifndef NDEBUG
// Check that there is no duplicate accounts.
- std::set<GaiaCookieManagerService::AccountIdGaiaIdPair>
- accounts_no_duplicates(accounts_.begin(), accounts_.end());
+ std::set<AccountIdGaiaIdPair> accounts_no_duplicates(accounts_.begin(),
+ accounts_.end());
DCHECK_EQ(accounts_.size(), accounts_no_duplicates.size());
#endif
@@ -125,7 +129,7 @@ void OAuthMultiloginHelper::OnAccessTokensFailure(
void OAuthMultiloginHelper::StartFetchingMultiLogin() {
DCHECK_EQ(gaia_id_token_pairs_.size(), accounts_.size());
gaia_auth_fetcher_ =
- signin_client_->CreateGaiaAuthFetcher(this, gaia::GaiaSource::kChrome);
+ partition_delegate_->CreateGaiaAuthFetcherForPartition(this);
gaia_auth_fetcher_->StartOAuthMultilogin(mode_, gaia_id_token_pairs_,
external_cc_result_);
}
@@ -179,7 +183,7 @@ void OAuthMultiloginHelper::StartSettingCookies(
const OAuthMultiloginResult& result) {
DCHECK(cookies_to_set_.empty());
network::mojom::CookieManager* cookie_manager =
- signin_client_->GetCookieManager();
+ partition_delegate_->GetCookieManagerForPartition();
const std::vector<net::CanonicalCookie>& cookies = result.cookies();
for (const net::CanonicalCookie& cookie : cookies) {
@@ -196,7 +200,7 @@ void OAuthMultiloginHelper::StartSettingCookies(
options.set_include_httponly();
// Permit it to set a SameSite cookie if it wants to.
options.set_same_site_cookie_context(
- net::CookieOptions::SameSiteCookieContext::SAME_SITE_STRICT);
+ net::CookieOptions::SameSiteCookieContext::MakeInclusive());
cookie_manager->SetCanonicalCookie(
cookie, "https", options,
mojo::WrapCallbackWithDefaultInvokeIfNotRun(
diff --git a/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.h b/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.h
index 3e88ae58a2e..ab3e5d9be73 100644
--- a/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.h
+++ b/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.h
@@ -13,8 +13,8 @@
#include "base/callback_forward.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
-#include "components/signin/internal/identity_manager/gaia_cookie_manager_service.h"
#include "components/signin/internal/identity_manager/oauth_multilogin_token_fetcher.h"
+#include "components/signin/public/identity_manager/accounts_cookie_mutator.h"
#include "google_apis/gaia/core_account_id.h"
#include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/gaia_auth_fetcher.h"
@@ -23,7 +23,6 @@
class GaiaAuthFetcher;
class GoogleServiceAuthError;
class ProfileOAuth2TokenService;
-class SigninClient;
namespace signin {
@@ -37,12 +36,14 @@ enum class SetAccountsInCookieResult;
// It is safe to delete this object from within the callbacks.
class OAuthMultiloginHelper : public GaiaAuthConsumer {
public:
+ using AccountIdGaiaIdPair = std::pair<CoreAccountId, std::string>;
+
OAuthMultiloginHelper(
SigninClient* signin_client,
+ AccountsCookieMutator::PartitionDelegate* partition_delegate,
ProfileOAuth2TokenService* token_service,
gaia::MultiloginMode mode,
- const std::vector<GaiaCookieManagerService::AccountIdGaiaIdPair>&
- accounts,
+ const std::vector<AccountIdGaiaIdPair>& accounts,
const std::string& external_cc_result,
base::OnceCallback<void(SetAccountsInCookieResult)> callback);
@@ -73,13 +74,14 @@ class OAuthMultiloginHelper : public GaiaAuthConsumer {
net::CanonicalCookie::CookieInclusionStatus status);
SigninClient* signin_client_;
+ AccountsCookieMutator::PartitionDelegate* partition_delegate_;
ProfileOAuth2TokenService* token_service_;
int fetcher_retries_ = 0;
gaia::MultiloginMode mode_;
// Account ids to set in the cookie.
- const std::vector<GaiaCookieManagerService::AccountIdGaiaIdPair> accounts_;
+ const std::vector<AccountIdGaiaIdPair> accounts_;
// See GaiaCookieManagerService::ExternalCcResultFetcher for details.
const std::string external_cc_result_;
// Access tokens, in the same order as the account ids.
diff --git a/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper_unittest.cc b/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper_unittest.cc
index 70fe65f08da..3df6e758629 100644
--- a/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper_unittest.cc
+++ b/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper_unittest.cc
@@ -11,6 +11,7 @@
#include "components/prefs/testing_pref_service.h"
#include "components/signin/internal/identity_manager/fake_profile_oauth2_token_service.h"
#include "components/signin/public/base/test_signin_client.h"
+#include "components/signin/public/identity_manager/accounts_cookie_mutator.h"
#include "components/signin/public/identity_manager/set_accounts_in_cookie_result.h"
#include "google_apis/gaia/gaia_urls.h"
#include "services/network/test/test_cookie_manager.h"
@@ -162,24 +163,21 @@ class MockTokenService : public FakeProfileOAuth2TokenService {
} // namespace
-class OAuthMultiloginHelperTest : public testing::Test {
+class OAuthMultiloginHelperTest
+ : public testing::Test,
+ public AccountsCookieMutator::PartitionDelegate {
public:
OAuthMultiloginHelperTest()
: test_signin_client_(&pref_service_),
mock_token_service_(&pref_service_) {
- std::unique_ptr<MockCookieManager> cookie_manager =
- std::make_unique<MockCookieManager>();
- mock_cookie_manager_ = cookie_manager.get();
- test_signin_client_.set_cookie_manager(std::move(cookie_manager));
}
~OAuthMultiloginHelperTest() override = default;
std::unique_ptr<OAuthMultiloginHelper> CreateHelper(
- const std::vector<GaiaCookieManagerService::AccountIdGaiaIdPair>
- accounts) {
+ const std::vector<OAuthMultiloginHelper::AccountIdGaiaIdPair> accounts) {
return std::make_unique<OAuthMultiloginHelper>(
- &test_signin_client_, token_service(),
+ &test_signin_client_, this, token_service(),
gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER, accounts,
std::string(),
base::BindOnce(&OAuthMultiloginHelperTest::OnOAuthMultiloginFinished,
@@ -187,10 +185,9 @@ class OAuthMultiloginHelperTest : public testing::Test {
}
std::unique_ptr<OAuthMultiloginHelper> CreateHelperWithExternalCcResult(
- const std::vector<GaiaCookieManagerService::AccountIdGaiaIdPair>
- accounts) {
+ const std::vector<OAuthMultiloginHelper::AccountIdGaiaIdPair> accounts) {
return std::make_unique<OAuthMultiloginHelper>(
- &test_signin_client_, token_service(),
+ &test_signin_client_, this, token_service(),
gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER, accounts,
kExternalCcResult,
base::BindOnce(&OAuthMultiloginHelperTest::OnOAuthMultiloginFinished,
@@ -212,7 +209,7 @@ class OAuthMultiloginHelperTest : public testing::Test {
kExternalCcResult;
}
- MockCookieManager* cookie_manager() { return mock_cookie_manager_; }
+ MockCookieManager* cookie_manager() { return &mock_cookie_manager_; }
MockTokenService* token_service() { return &mock_token_service_; }
protected:
@@ -222,13 +219,24 @@ class OAuthMultiloginHelperTest : public testing::Test {
result_ = result;
}
+ // AccountsCookieMuator::PartitionDelegate:
+ std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcherForPartition(
+ GaiaAuthConsumer* consumer) override {
+ return test_signin_client_.CreateGaiaAuthFetcher(consumer,
+ gaia::GaiaSource::kChrome);
+ }
+
+ network::mojom::CookieManager* GetCookieManagerForPartition() override {
+ return &mock_cookie_manager_;
+ }
+
base::test::TaskEnvironment task_environment_;
bool callback_called_ = false;
SetAccountsInCookieResult result_;
TestingPrefServiceSimple pref_service_;
- MockCookieManager* mock_cookie_manager_; // Owned by test_signin_client_
+ MockCookieManager mock_cookie_manager_;
TestSigninClient test_signin_client_;
MockTokenService mock_token_service_;
};
diff --git a/chromium/components/signin/internal/identity_manager/primary_account_manager.cc b/chromium/components/signin/internal/identity_manager/primary_account_manager.cc
index aebcdb1d75a..3c80d8d09c4 100644
--- a/chromium/components/signin/internal/identity_manager/primary_account_manager.cc
+++ b/chromium/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -289,18 +289,32 @@ void PrimaryAccountManager::SignOutAndKeepAllAccounts(
StartSignOut(signout_source_metric, signout_delete_metric,
RemoveAccountsOption::kKeepAllAccounts);
}
+#endif // !defined(OS_CHROMEOS)
+
+#if defined(OS_CHROMEOS)
+void PrimaryAccountManager::RevokeSyncConsent() {
+ DCHECK(IsAuthenticated());
+ // TODO(https://crbug.com/1046746): Don't record metrics here.
+ StartSignOut(signin_metrics::ProfileSignout::USER_CLICKED_SIGNOUT_SETTINGS,
+ signin_metrics::SignoutDelete::KEEPING,
+ RemoveAccountsOption::kKeepAllAccounts,
+ /*assert_signout_allowed=*/true);
+}
+#endif // defined(OS_CHROMEOS)
void PrimaryAccountManager::StartSignOut(
signin_metrics::ProfileSignout signout_source_metric,
signin_metrics::SignoutDelete signout_delete_metric,
- RemoveAccountsOption remove_option) {
+ RemoveAccountsOption remove_option,
+ bool assert_signout_allowed) {
VLOG(1) << "StartSignOut: " << static_cast<int>(signout_source_metric) << ", "
<< static_cast<int>(signout_delete_metric) << ", "
<< static_cast<int>(remove_option);
client_->PreSignOut(
base::BindOnce(&PrimaryAccountManager::OnSignoutDecisionReached,
base::Unretained(this), signout_source_metric,
- signout_delete_metric, remove_option),
+ signout_delete_metric, remove_option,
+ assert_signout_allowed),
signout_source_metric);
}
@@ -308,8 +322,11 @@ void PrimaryAccountManager::OnSignoutDecisionReached(
signin_metrics::ProfileSignout signout_source_metric,
signin_metrics::SignoutDelete signout_delete_metric,
RemoveAccountsOption remove_option,
+ bool assert_signout_allowed,
SigninClient::SignoutDecision signout_decision) {
DCHECK(IsInitialized());
+ if (assert_signout_allowed)
+ DCHECK_EQ(SigninClient::SignoutDecision::ALLOW_SIGNOUT, signout_decision);
VLOG(1) << "OnSignoutDecisionReached: "
<< (signout_decision == SigninClient::SignoutDecision::ALLOW_SIGNOUT);
@@ -333,6 +350,7 @@ void PrimaryAccountManager::OnSignoutDecisionReached(
// may be components that don't listen for token service events when the
// profile is not connected to an account.
switch (remove_option) {
+#if !defined(OS_CHROMEOS)
case RemoveAccountsOption::kRemoveAllAccounts:
VLOG(0) << "Revoking all refresh tokens on server. Reason: sign out";
token_service_->RevokeAllCredentials(
@@ -346,6 +364,7 @@ void PrimaryAccountManager::OnSignoutDecisionReached(
signin_metrics::SourceForRefreshTokenOperation::
kPrimaryAccountManager_ClearAccount);
break;
+#endif
case RemoveAccountsOption::kKeepAllAccounts:
// Do nothing.
break;
@@ -355,6 +374,7 @@ void PrimaryAccountManager::OnSignoutDecisionReached(
observer.GoogleSignedOut(account_info);
}
+#if !defined(OS_CHROMEOS)
void PrimaryAccountManager::OnRefreshTokensLoaded() {
token_service_->RemoveObserver(this);
diff --git a/chromium/components/signin/internal/identity_manager/primary_account_manager.h b/chromium/components/signin/internal/identity_manager/primary_account_manager.h
index 6945d780379..b00f9381a92 100644
--- a/chromium/components/signin/internal/identity_manager/primary_account_manager.h
+++ b/chromium/components/signin/internal/identity_manager/primary_account_manager.h
@@ -54,23 +54,21 @@ class PrimaryAccountManager : public ProfileOAuth2TokenServiceObserver {
virtual void UnconsentedPrimaryAccountChanged(const CoreAccountInfo& info) {
}
-#if !defined(OS_CHROMEOS)
// Called whenever the currently signed-in user has been signed out.
virtual void GoogleSignedOut(const CoreAccountInfo& info) {}
-#endif
};
-#if !defined(OS_CHROMEOS)
// Used to remove accounts from the token service and the account tracker.
enum class RemoveAccountsOption {
// Do not remove accounts.
kKeepAllAccounts = 0,
+#if !defined(OS_CHROMEOS)
// Remove all the accounts.
kRemoveAllAccounts,
// Removes the authenticated account if it is in authentication error.
kRemoveAuthenticatedAccountIfInError
- };
#endif
+ };
PrimaryAccountManager(
SigninClient* client,
@@ -142,7 +140,14 @@ class PrimaryAccountManager : public ProfileOAuth2TokenServiceObserver {
void SignOutAndKeepAllAccounts(
signin_metrics::ProfileSignout signout_source_metric,
signin_metrics::SignoutDelete signout_delete_metric);
-#endif
+#endif // !defined(OS_CHROMEOS)
+
+#if defined(OS_CHROMEOS)
+ // Revokes sync consent from the primary account. The primary account must
+ // have sync consent. After the call a primary account will remain but it will
+ // not have sync consent.
+ void RevokeSyncConsent();
+#endif // defined(OS_CHROMEOS)
// Adds and removes observers.
void AddObserver(Observer* observer);
@@ -175,19 +180,22 @@ class PrimaryAccountManager : public ProfileOAuth2TokenServiceObserver {
void SetPrimaryAccountInternal(const CoreAccountInfo& account_info,
bool consented_to_sync);
-#if !defined(OS_CHROMEOS)
- // Starts the sign out process.
+ // Starts the sign out process. If |assert_signout_allowed| is true then
+ // the sign out process will DCHECK if user sign out is not allowed.
void StartSignOut(signin_metrics::ProfileSignout signout_source_metric,
signin_metrics::SignoutDelete signout_delete_metric,
- RemoveAccountsOption remove_option);
+ RemoveAccountsOption remove_option,
+ bool assert_signout_allowed = false);
// The sign out process which is started by SigninClient::PreSignOut()
void OnSignoutDecisionReached(
signin_metrics::ProfileSignout signout_source_metric,
signin_metrics::SignoutDelete signout_delete_metric,
RemoveAccountsOption remove_option,
+ bool assert_signout_allowed,
SigninClient::SignoutDecision signout_decision);
+#if !defined(OS_CHROMEOS)
// ProfileOAuth2TokenServiceObserver:
void OnRefreshTokensLoaded() override;
#endif
diff --git a/chromium/components/signin/internal/identity_manager/primary_account_manager_unittest.cc b/chromium/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
index 62544a7688e..e00eb5e070e 100644
--- a/chromium/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
+++ b/chromium/components/signin/internal/identity_manager/primary_account_manager_unittest.cc
@@ -480,3 +480,18 @@ TEST_F(PrimaryAccountManagerTest, SetUnconsentedPrimaryAccountInfo) {
EXPECT_EQ(CoreAccountInfo(), manager_->GetUnconsentedPrimaryAccountInfo());
EXPECT_EQ(CoreAccountInfo(), manager_->GetAuthenticatedAccountInfo());
}
+
+#if defined(OS_CHROMEOS)
+TEST_F(PrimaryAccountManagerTest, RevokeSyncConsent) {
+ CreatePrimaryAccountManager();
+ CoreAccountId account_id = AddToAccountTracker("gaia_id", "user@gmail.com");
+ manager_->SignIn("user@gmail.com");
+ EXPECT_TRUE(manager_->IsAuthenticated());
+
+ manager_->RevokeSyncConsent();
+ EXPECT_FALSE(manager_->IsAuthenticated());
+ EXPECT_TRUE(manager_->HasUnconsentedPrimaryAccount());
+ EXPECT_EQ(account_id,
+ manager_->GetUnconsentedPrimaryAccountInfo().account_id);
+}
+#endif // defined(OS_CHROMEOS)
diff --git a/chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.cc b/chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.cc
index 85de348118b..668f660289a 100644
--- a/chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.cc
+++ b/chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.cc
@@ -52,6 +52,19 @@ bool PrimaryAccountMutatorImpl::SetPrimaryAccount(
}
#if defined(OS_CHROMEOS)
+void PrimaryAccountMutatorImpl::RevokeSyncConsent() {
+ primary_account_manager_->RevokeSyncConsent();
+}
+
+void PrimaryAccountMutatorImpl::SetUnconsentedPrimaryAccount(
+ const CoreAccountId& account_id) {
+ // On Chrome OS the UPA can only be set once and never removed or changed.
+ DCHECK(!account_id.empty());
+ DCHECK(!primary_account_manager_->HasUnconsentedPrimaryAccount());
+ AccountInfo account_info = account_tracker_->GetAccountInfo(account_id);
+ primary_account_manager_->SetUnconsentedPrimaryAccountInfo(account_info);
+}
+
bool PrimaryAccountMutatorImpl::DeprecatedSetPrimaryAccountAndUpdateAccountInfo(
const std::string& gaia_id,
const std::string& email) {
diff --git a/chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.h b/chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.h
index 91806ee41ca..184c3ac4a5b 100644
--- a/chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.h
+++ b/chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.h
@@ -27,6 +27,8 @@ class PrimaryAccountMutatorImpl : public PrimaryAccountMutator {
// PrimaryAccountMutator implementation.
bool SetPrimaryAccount(const CoreAccountId& account_id) override;
#if defined(OS_CHROMEOS)
+ void RevokeSyncConsent() override;
+ void SetUnconsentedPrimaryAccount(const CoreAccountId& account_id) override;
bool DeprecatedSetPrimaryAccountAndUpdateAccountInfo(
const std::string& gaia_id,
const std::string& email) override;
diff --git a/chromium/components/signin/internal/identity_manager/primary_account_policy_manager_impl.cc b/chromium/components/signin/internal/identity_manager/primary_account_policy_manager_impl.cc
index f87e3b90655..bf35da6fc54 100644
--- a/chromium/components/signin/internal/identity_manager/primary_account_policy_manager_impl.cc
+++ b/chromium/components/signin/internal/identity_manager/primary_account_policy_manager_impl.cc
@@ -29,15 +29,16 @@ void PrimaryAccountPolicyManagerImpl::InitializePolicy(
local_state_pref_registrar_.Init(local_state);
local_state_pref_registrar_.Add(
prefs::kGoogleServicesUsernamePattern,
- base::Bind(&PrimaryAccountPolicyManagerImpl::
- OnGoogleServicesUsernamePatternChanged,
- weak_pointer_factory_.GetWeakPtr(),
- primary_account_manager));
+ base::BindRepeating(&PrimaryAccountPolicyManagerImpl::
+ OnGoogleServicesUsernamePatternChanged,
+ weak_pointer_factory_.GetWeakPtr(),
+ primary_account_manager));
}
signin_allowed_.Init(
prefs::kSigninAllowed, client_->GetPrefs(),
- base::Bind(&PrimaryAccountPolicyManagerImpl::OnSigninAllowedPrefChanged,
- base::Unretained(this), primary_account_manager));
+ base::BindRepeating(
+ &PrimaryAccountPolicyManagerImpl::OnSigninAllowedPrefChanged,
+ base::Unretained(this), primary_account_manager));
CoreAccountInfo account_info =
primary_account_manager->GetAuthenticatedAccountInfo();
diff --git a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc
index cb0cbf83191..f5dc498ddd6 100644
--- a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc
@@ -17,7 +17,7 @@
#if defined(OS_ANDROID)
#include "components/signin/internal/base/account_manager_facade_android.h"
-#include "components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h"
+#include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h"
#else
#include "components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.h"
#include "components/signin/public/webdata/token_web_data.h"
@@ -39,14 +39,14 @@ namespace {
#if defined(OS_ANDROID)
// TODO(crbug.com/986435) Provide AccountManagerFacade as a parameter once
// IdentityServicesProvider owns its instance management.
-std::unique_ptr<OAuth2TokenServiceDelegateAndroid> CreateAndroidOAuthDelegate(
- AccountTrackerService* account_tracker_service) {
+std::unique_ptr<ProfileOAuth2TokenServiceDelegateAndroid>
+CreateAndroidOAuthDelegate(AccountTrackerService* account_tracker_service) {
auto account_manager_facade =
- OAuth2TokenServiceDelegateAndroid::
+ ProfileOAuth2TokenServiceDelegateAndroid::
get_disable_interaction_with_system_accounts()
? nullptr
: AccountManagerFacadeAndroid::GetJavaObject();
- return std::make_unique<OAuth2TokenServiceDelegateAndroid>(
+ return std::make_unique<ProfileOAuth2TokenServiceDelegateAndroid>(
account_tracker_service, account_manager_facade);
}
#elif defined(OS_IOS)
diff --git a/chromium/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.cc b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
index 9b2fac4bf35..4e8dff2c4e2 100644
--- a/chromium/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.cc
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h"
+#include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h"
#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
@@ -14,7 +14,7 @@
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
-#include "components/signin/internal/identity_manager/android/jni_headers/OAuth2TokenService_jni.h"
+#include "components/signin/public/android/jni_headers/ProfileOAuth2TokenServiceDelegate_jni.h"
#include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/identity_manager/account_info.h"
#include "google_apis/gaia/gaia_auth_util.h"
@@ -35,14 +35,14 @@ namespace {
// - the OAuth2 access token.
// - the expiry time of the token (may be null, indicating that the expiry
// time is unknown.
-typedef base::Callback<
+typedef base::OnceCallback<
void(const GoogleServiceAuthError&, const std::string&, const base::Time&)>
FetchOAuth2TokenCallback;
class AndroidAccessTokenFetcher : public OAuth2AccessTokenFetcher {
public:
AndroidAccessTokenFetcher(
- OAuth2TokenServiceDelegateAndroid* oauth2_token_service_delegate,
+ ProfileOAuth2TokenServiceDelegateAndroid* oauth2_token_service_delegate,
OAuth2AccessTokenConsumer* consumer,
const std::string& account_id);
~AndroidAccessTokenFetcher() override;
@@ -61,7 +61,7 @@ class AndroidAccessTokenFetcher : public OAuth2AccessTokenFetcher {
private:
std::string CombineScopes(const std::vector<std::string>& scopes);
- OAuth2TokenServiceDelegateAndroid* oauth2_token_service_delegate_;
+ ProfileOAuth2TokenServiceDelegateAndroid* oauth2_token_service_delegate_;
std::string account_id_;
bool request_was_cancelled_;
base::WeakPtrFactory<AndroidAccessTokenFetcher> weak_factory_;
@@ -70,7 +70,7 @@ class AndroidAccessTokenFetcher : public OAuth2AccessTokenFetcher {
};
AndroidAccessTokenFetcher::AndroidAccessTokenFetcher(
- OAuth2TokenServiceDelegateAndroid* oauth2_token_service_delegate,
+ ProfileOAuth2TokenServiceDelegateAndroid* oauth2_token_service_delegate,
OAuth2AccessTokenConsumer* consumer,
const std::string& account_id)
: OAuth2AccessTokenFetcher(consumer),
@@ -91,11 +91,11 @@ void AndroidAccessTokenFetcher::Start(const std::string& client_id,
ScopedJavaLocalRef<jstring> j_scope = ConvertUTF8ToJavaString(env, scope);
std::unique_ptr<FetchOAuth2TokenCallback> heap_callback(
new FetchOAuth2TokenCallback(
- base::Bind(&AndroidAccessTokenFetcher::OnAccessTokenResponse,
- weak_factory_.GetWeakPtr())));
+ base::BindOnce(&AndroidAccessTokenFetcher::OnAccessTokenResponse,
+ weak_factory_.GetWeakPtr())));
// Call into Java to get a new token.
- signin::Java_OAuth2TokenService_getAccessTokenFromNative(
+ signin::Java_ProfileOAuth2TokenServiceDelegate_getAccessTokenFromNative(
env, oauth2_token_service_delegate_->GetJavaObject(), j_username, j_scope,
reinterpret_cast<intptr_t>(heap_callback.release()));
}
@@ -138,21 +138,22 @@ std::string AndroidAccessTokenFetcher::CombineScopes(
} // namespace
// TODO(crbug.com/1009957) Remove disable_interation_with_system_accounts_
-// from OAuth2TokenServiceDelegateAndroid
-bool OAuth2TokenServiceDelegateAndroid::
+// from ProfileOAuth2TokenServiceDelegateAndroid
+bool ProfileOAuth2TokenServiceDelegateAndroid::
disable_interaction_with_system_accounts_ = false;
-OAuth2TokenServiceDelegateAndroid::OAuth2TokenServiceDelegateAndroid(
- AccountTrackerService* account_tracker_service,
- const base::android::JavaRef<jobject>& account_manager_facade)
+ProfileOAuth2TokenServiceDelegateAndroid::
+ ProfileOAuth2TokenServiceDelegateAndroid(
+ AccountTrackerService* account_tracker_service,
+ const base::android::JavaRef<jobject>& account_manager_facade)
: account_tracker_service_(account_tracker_service),
fire_refresh_token_loaded_(RT_LOAD_NOT_START) {
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::ctor";
+ DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::ctor";
DCHECK(account_tracker_service_);
JNIEnv* env = AttachCurrentThread();
base::android::ScopedJavaLocalRef<jobject> local_java_ref =
- signin::Java_OAuth2TokenService_create(
+ signin::Java_ProfileOAuth2TokenServiceDelegate_create(
env, reinterpret_cast<intptr_t>(this),
account_tracker_service_->GetJavaObject(), account_manager_facade);
java_ref_.Reset(env, local_java_ref.obj());
@@ -172,48 +173,52 @@ OAuth2TokenServiceDelegateAndroid::OAuth2TokenServiceDelegateAndroid(
}
}
-OAuth2TokenServiceDelegateAndroid::~OAuth2TokenServiceDelegateAndroid() {}
+ProfileOAuth2TokenServiceDelegateAndroid::
+ ~ProfileOAuth2TokenServiceDelegateAndroid() {}
-ScopedJavaLocalRef<jobject> OAuth2TokenServiceDelegateAndroid::GetJavaObject() {
+ScopedJavaLocalRef<jobject>
+ProfileOAuth2TokenServiceDelegateAndroid::GetJavaObject() {
return ScopedJavaLocalRef<jobject>(java_ref_);
}
-bool OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable(
+bool ProfileOAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable(
const CoreAccountId& account_id) const {
DCHECK(!disable_interaction_with_system_accounts_)
<< __FUNCTION__
<< " needs to interact with system accounts and cannot be used with "
"disable_interaction_with_system_accounts_";
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable"
- << " account= " << account_id;
+ DVLOG(1)
+ << "ProfileOAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable"
+ << " account= " << account_id;
std::string account_name = MapAccountIdToAccountName(account_id);
if (account_name.empty()) {
// This corresponds to the case when the account with id |account_id| is not
// present on the device and thus was not seeded.
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable"
- << " cannot find account name for account id " << account_id;
+ DVLOG(1)
+ << "ProfileOAuth2TokenServiceDelegateAndroid::RefreshTokenIsAvailable"
+ << " cannot find account name for account id " << account_id;
return false;
}
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> j_account_id =
ConvertUTF8ToJavaString(env, account_name);
jboolean refresh_token_is_available =
- signin::Java_OAuth2TokenService_hasOAuth2RefreshToken(env, java_ref_,
- j_account_id);
+ signin::Java_ProfileOAuth2TokenServiceDelegate_hasOAuth2RefreshToken(
+ env, java_ref_, j_account_id);
return refresh_token_is_available == JNI_TRUE;
}
-GoogleServiceAuthError OAuth2TokenServiceDelegateAndroid::GetAuthError(
+GoogleServiceAuthError ProfileOAuth2TokenServiceDelegateAndroid::GetAuthError(
const CoreAccountId& account_id) const {
auto it = errors_.find(account_id);
return (it == errors_.end()) ? GoogleServiceAuthError::AuthErrorNone()
: it->second;
}
-void OAuth2TokenServiceDelegateAndroid::UpdateAuthError(
+void ProfileOAuth2TokenServiceDelegateAndroid::UpdateAuthError(
const CoreAccountId& account_id,
const GoogleServiceAuthError& error) {
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::UpdateAuthError"
+ DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::UpdateAuthError"
<< " account=" << account_id << " error=" << error.ToString();
if (error.IsTransientError())
@@ -232,29 +237,13 @@ void OAuth2TokenServiceDelegateAndroid::UpdateAuthError(
FireAuthErrorChanged(account_id, error);
}
-std::vector<CoreAccountId> OAuth2TokenServiceDelegateAndroid::GetAccounts()
- const {
- std::vector<std::string> accounts;
- JNIEnv* env = AttachCurrentThread();
-
- // TODO(crbug.com/1028580) Pass |j_accounts| as a list of
- // org.chromium.components.signin.identitymanager.CoreAccountId and convert it
- // to CoreAccountId using ConvertFromJavaCoreAccountId.
- ScopedJavaLocalRef<jobjectArray> j_accounts =
- signin::Java_OAuth2TokenService_getAccounts(env);
-
- // TODO(fgorski): We may decide to filter out some of the accounts.
- base::android::AppendJavaStringArrayToStringVector(env, j_accounts,
- &accounts);
- std::vector<CoreAccountId> account_ids;
- for (auto& account : accounts)
- account_ids.push_back(CoreAccountId::FromString(account));
-
- return account_ids;
+std::vector<CoreAccountId>
+ProfileOAuth2TokenServiceDelegateAndroid::GetAccounts() const {
+ return accounts_;
}
std::vector<std::string>
-OAuth2TokenServiceDelegateAndroid::GetSystemAccountNames() {
+ProfileOAuth2TokenServiceDelegateAndroid::GetSystemAccountNames() {
DCHECK(!disable_interaction_with_system_accounts_)
<< __FUNCTION__
<< " needs to interact with system accounts and cannot be used with "
@@ -266,14 +255,15 @@ OAuth2TokenServiceDelegateAndroid::GetSystemAccountNames() {
// org.chromium.components.signin.identitymanager.CoreAccountId and convert it
// to CoreAccountId using ConvertFromJavaCoreAccountId.
ScopedJavaLocalRef<jobjectArray> j_accounts =
- signin::Java_OAuth2TokenService_getSystemAccountNames(env, java_ref_);
+ signin::Java_ProfileOAuth2TokenServiceDelegate_getSystemAccountNames(
+ env, java_ref_);
base::android::AppendJavaStringArrayToStringVector(env, j_accounts,
&account_names);
return account_names;
}
std::vector<CoreAccountId>
-OAuth2TokenServiceDelegateAndroid::GetSystemAccounts() {
+ProfileOAuth2TokenServiceDelegateAndroid::GetSystemAccounts() {
std::vector<CoreAccountId> ids;
for (const std::string& name : GetSystemAccountNames()) {
CoreAccountId id(MapAccountNameToAccountId(name));
@@ -284,7 +274,7 @@ OAuth2TokenServiceDelegateAndroid::GetSystemAccounts() {
}
std::vector<CoreAccountId>
-OAuth2TokenServiceDelegateAndroid::GetValidAccounts() {
+ProfileOAuth2TokenServiceDelegateAndroid::GetValidAccounts() {
std::vector<CoreAccountId> ids;
for (const CoreAccountId& id : GetAccounts()) {
if (ValidateAccountId(id))
@@ -293,21 +283,19 @@ OAuth2TokenServiceDelegateAndroid::GetValidAccounts() {
return ids;
}
-void OAuth2TokenServiceDelegateAndroid::SetAccounts(
+void ProfileOAuth2TokenServiceDelegateAndroid::SetAccounts(
const std::vector<CoreAccountId>& accounts) {
- JNIEnv* env = AttachCurrentThread();
- ScopedJavaLocalRef<jobjectArray> java_accounts(
- base::android::ToJavaArrayOfStrings(env, ToStringList(accounts)));
- signin::Java_OAuth2TokenService_setAccounts(env, java_accounts);
+ accounts_ = accounts;
}
std::unique_ptr<OAuth2AccessTokenFetcher>
-OAuth2TokenServiceDelegateAndroid::CreateAccessTokenFetcher(
+ProfileOAuth2TokenServiceDelegateAndroid::CreateAccessTokenFetcher(
const CoreAccountId& account_id,
scoped_refptr<network::SharedURLLoaderFactory> url_factory,
OAuth2AccessTokenConsumer* consumer) {
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::CreateAccessTokenFetcher"
- << " account= " << account_id;
+ DVLOG(1)
+ << "ProfileOAuth2TokenServiceDelegateAndroid::CreateAccessTokenFetcher"
+ << " account= " << account_id;
ValidateAccountId(account_id);
std::string account_name = MapAccountIdToAccountName(account_id);
DCHECK(!account_name.empty())
@@ -316,7 +304,7 @@ OAuth2TokenServiceDelegateAndroid::CreateAccessTokenFetcher(
account_name);
}
-void OAuth2TokenServiceDelegateAndroid::OnAccessTokenInvalidated(
+void ProfileOAuth2TokenServiceDelegateAndroid::OnAccessTokenInvalidated(
const CoreAccountId& account_id,
const std::string& client_id,
const OAuth2AccessTokenManager::ScopeSet& scopes,
@@ -329,11 +317,11 @@ void OAuth2TokenServiceDelegateAndroid::OnAccessTokenInvalidated(
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> j_access_token =
ConvertUTF8ToJavaString(env, access_token);
- signin::Java_OAuth2TokenService_invalidateAccessToken(env, java_ref_,
- j_access_token);
+ signin::Java_ProfileOAuth2TokenServiceDelegate_invalidateAccessToken(
+ env, java_ref_, j_access_token);
}
-void OAuth2TokenServiceDelegateAndroid::
+void ProfileOAuth2TokenServiceDelegateAndroid::
ReloadAllAccountsFromSystemWithPrimaryAccount(
const base::Optional<CoreAccountId>& primary_account_id) {
JNIEnv* env = AttachCurrentThread();
@@ -342,14 +330,12 @@ void OAuth2TokenServiceDelegateAndroid::
primary_account_id.has_value()
? ConvertUTF8ToJavaString(env, primary_account_id->ToString())
: nullptr;
- signin::Java_OAuth2TokenService_seedAndReloadAccountsWithPrimaryAccount(
- env, java_ref_, j_account_id);
+ signin::
+ Java_ProfileOAuth2TokenServiceDelegate_seedAndReloadAccountsWithPrimaryAccount(
+ env, java_ref_, j_account_id);
}
-// TODO(crbug.com/1028580) Pass |account_id| as a
-// org.chromium.components.signin.identitymanager.CoreAccountId and convert it
-// to CoreAccountId using ConvertFromJavaCoreAccountId.
-void OAuth2TokenServiceDelegateAndroid::
+void ProfileOAuth2TokenServiceDelegateAndroid::
ReloadAllAccountsWithPrimaryAccountAfterSeeding(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& account_id) {
@@ -361,11 +347,11 @@ void OAuth2TokenServiceDelegateAndroid::
UpdateAccountList(core_account_id, GetValidAccounts(), GetSystemAccounts());
}
-void OAuth2TokenServiceDelegateAndroid::UpdateAccountList(
+void ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList(
const base::Optional<CoreAccountId>& signed_in_account_id,
const std::vector<CoreAccountId>& prev_ids,
const std::vector<CoreAccountId>& curr_ids) {
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
+ DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
<< " sigined_in_account_id="
<< (signed_in_account_id.has_value()
? signed_in_account_id->ToString()
@@ -412,59 +398,53 @@ void OAuth2TokenServiceDelegateAndroid::UpdateAccountList(
!signed_in_account_id.has_value()) {
account_tracker_service_->SetMigrationDone();
}
-
- if (!last_update_accounts_time_.is_null()) {
- base::TimeDelta sample = base::Time::Now() - last_update_accounts_time_;
- UmaHistogramLongTimes("Signin.AndroidTimeBetweenUpdateAccountList", sample);
- }
- last_update_accounts_time_ = base::Time::Now();
}
-bool OAuth2TokenServiceDelegateAndroid::UpdateAccountList(
+bool ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList(
const base::Optional<CoreAccountId>& signed_in_id,
const std::vector<CoreAccountId>& prev_ids,
const std::vector<CoreAccountId>& curr_ids,
std::vector<CoreAccountId>* refreshed_ids,
std::vector<CoreAccountId>* revoked_ids) {
bool keep_accounts =
- base::FeatureList::IsEnabled(signin::kMiceFeature) ||
- (signed_in_id.has_value() && base::Contains(curr_ids, *signed_in_id));
+ signed_in_id.has_value() && base::Contains(curr_ids, *signed_in_id);
if (keep_accounts) {
// Revoke token for ids that have been removed from the device.
for (const CoreAccountId& prev_id : prev_ids) {
if (signed_in_id.has_value() && prev_id == *signed_in_id)
continue;
if (!base::Contains(curr_ids, prev_id)) {
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
- << "revoked=" << prev_id;
+ DVLOG(1)
+ << "ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
+ << "revoked=" << prev_id;
revoked_ids->push_back(prev_id);
}
}
if (signed_in_id.has_value()) {
// Always fire the primary signed in account first.
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
+ DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
<< "refreshed=" << *signed_in_id;
refreshed_ids->push_back(*signed_in_id);
}
for (const CoreAccountId& curr_id : curr_ids) {
if (signed_in_id.has_value() && curr_id == *signed_in_id)
continue;
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
+ DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
<< "refreshed=" << curr_id;
refreshed_ids->push_back(curr_id);
}
} else {
// Revoke all ids with signed in account first.
if (signed_in_id.has_value() && base::Contains(prev_ids, *signed_in_id)) {
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
+ DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
<< "revoked=" << *signed_in_id;
revoked_ids->push_back(*signed_in_id);
}
for (const CoreAccountId& prev_id : prev_ids) {
if (signed_in_id.has_value() && prev_id == *signed_in_id)
continue;
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
+ DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
<< "revoked=" << prev_id;
revoked_ids->push_back(prev_id);
}
@@ -472,8 +452,9 @@ bool OAuth2TokenServiceDelegateAndroid::UpdateAccountList(
return keep_accounts;
}
-void OAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoaded() {
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoaded";
+void ProfileOAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoaded() {
+ DVLOG(1)
+ << "ProfileOAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoaded";
DCHECK_EQ(signin::LoadCredentialsState::LOAD_CREDENTIALS_IN_PROGRESS,
load_credentials_state());
set_load_credentials_state(
@@ -481,8 +462,8 @@ void OAuth2TokenServiceDelegateAndroid::FireRefreshTokensLoaded() {
ProfileOAuth2TokenServiceDelegate::FireRefreshTokensLoaded();
}
-void OAuth2TokenServiceDelegateAndroid::RevokeAllCredentials() {
- DVLOG(1) << "OAuth2TokenServiceDelegateAndroid::RevokeAllCredentials";
+void ProfileOAuth2TokenServiceDelegateAndroid::RevokeAllCredentials() {
+ DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::RevokeAllCredentials";
ScopedBatchChange batch(this);
std::vector<CoreAccountId> accounts_to_revoke = GetAccounts();
@@ -494,14 +475,13 @@ void OAuth2TokenServiceDelegateAndroid::RevokeAllCredentials() {
FireRefreshTokenRevoked(account);
}
-void OAuth2TokenServiceDelegateAndroid::LoadCredentials(
+void ProfileOAuth2TokenServiceDelegateAndroid::LoadCredentials(
const CoreAccountId& primary_account_id) {
DCHECK_EQ(signin::LoadCredentialsState::LOAD_CREDENTIALS_NOT_STARTED,
load_credentials_state());
set_load_credentials_state(
signin::LoadCredentialsState::LOAD_CREDENTIALS_IN_PROGRESS);
- if (primary_account_id.empty() &&
- !base::FeatureList::IsEnabled(signin::kMiceFeature)) {
+ if (primary_account_id.empty()) {
FireRefreshTokensLoaded();
return;
}
@@ -513,12 +493,13 @@ void OAuth2TokenServiceDelegateAndroid::LoadCredentials(
}
}
-std::string OAuth2TokenServiceDelegateAndroid::MapAccountIdToAccountName(
+std::string ProfileOAuth2TokenServiceDelegateAndroid::MapAccountIdToAccountName(
const CoreAccountId& account_id) const {
return account_tracker_service_->GetAccountInfo(account_id).email;
}
-CoreAccountId OAuth2TokenServiceDelegateAndroid::MapAccountNameToAccountId(
+CoreAccountId
+ProfileOAuth2TokenServiceDelegateAndroid::MapAccountNameToAccountId(
const std::string& account_name) const {
CoreAccountId account_id =
account_tracker_service_->FindAccountInfoByEmail(account_name).account_id;
@@ -530,7 +511,7 @@ CoreAccountId OAuth2TokenServiceDelegateAndroid::MapAccountNameToAccountId(
namespace signin {
// Called from Java when fetching of an OAuth2 token is finished. The
// |authToken| param is only valid when |result| is true.
-void JNI_OAuth2TokenService_OnOAuth2TokenFetched(
+void JNI_ProfileOAuth2TokenServiceDelegate_OnOAuth2TokenFetched(
JNIEnv* env,
const JavaParamRef<jstring>& authToken,
jboolean isTransientError,
@@ -549,6 +530,6 @@ void JNI_OAuth2TokenService_OnOAuth2TokenFetched(
GoogleServiceAuthError::InvalidGaiaCredentialsReason::
CREDENTIALS_REJECTED_BY_SERVER);
}
- heap_callback->Run(err, token, base::Time());
+ std::move(*heap_callback).Run(err, token, base::Time());
}
} // namespace signin
diff --git a/chromium/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h
index 7aa85189ec8..63c267a2b65 100644
--- a/chromium/components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h
@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_OAUTH2_TOKEN_SERVICE_DELEGATE_ANDROID_H_
-#define COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_OAUTH2_TOKEN_SERVICE_DELEGATE_ANDROID_H_
+#ifndef COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PROFILE_OAUTH2_TOKEN_SERVICE_DELEGATE_ANDROID_H_
+#define COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PROFILE_OAUTH2_TOKEN_SERVICE_DELEGATE_ANDROID_H_
#include <map>
#include <memory>
@@ -14,7 +14,6 @@
#include "base/android/scoped_java_ref.h"
#include "base/callback.h"
#include "base/macros.h"
-#include "base/time/time.h"
#include "components/signin/internal/identity_manager/account_tracker_service.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h"
@@ -27,16 +26,16 @@
// See |ProfileOAuth2TokenServiceDelegate| for usage details.
//
// Note: requests should be started from the UI thread.
-class OAuth2TokenServiceDelegateAndroid
+class ProfileOAuth2TokenServiceDelegateAndroid
: public ProfileOAuth2TokenServiceDelegate {
public:
- OAuth2TokenServiceDelegateAndroid(
+ ProfileOAuth2TokenServiceDelegateAndroid(
AccountTrackerService* account_tracker_service,
const base::android::JavaRef<jobject>& account_manager_facade);
- ~OAuth2TokenServiceDelegateAndroid() override;
+ ~ProfileOAuth2TokenServiceDelegateAndroid() override;
- // Creates a new instance of the OAuth2TokenServiceDelegateAndroid.
- static OAuth2TokenServiceDelegateAndroid* Create();
+ // Creates a new instance of the ProfileOAuth2TokenServiceDelegateAndroid.
+ static ProfileOAuth2TokenServiceDelegateAndroid* Create();
// Returns a reference to the corresponding Java OAuth2TokenService object.
base::android::ScopedJavaLocalRef<jobject> GetJavaObject() override;
@@ -45,7 +44,7 @@ class OAuth2TokenServiceDelegateAndroid
// tests. This prevents the token service from building the java objects
// which require prior initialization (AccountManagerFacade)
// TODO(crbug.com/1009957) Remove disable_interation_with_system_accounts_
- // from OAuth2TokenServiceDelegateAndroid
+ // from ProfileOAuth2TokenServiceDelegateAndroid
static void set_disable_interaction_with_system_accounts() {
disable_interaction_with_system_accounts_ = true;
}
@@ -72,8 +71,8 @@ class OAuth2TokenServiceDelegateAndroid
const base::Optional<CoreAccountId>& primary_account_id) override;
// Resumes the reload of accounts once the account seeding is complete.
- // TODO(crbug.com/934688) Once OAuth2TokenService.java is internalized, use
- // CoreAccountId instead of String.
+ // TODO(crbug.com/934688) Once ProfileOAuth2TokenServiceDelegate.java is
+ // internalized, use CoreAccountId instead of String.
void ReloadAllAccountsWithPrimaryAccountAfterSeeding(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& account_id);
@@ -130,25 +129,27 @@ class OAuth2TokenServiceDelegateAndroid
std::vector<CoreAccountId> GetSystemAccounts();
// As |GetAccounts| but with only validated account IDs.
std::vector<CoreAccountId> GetValidAccounts();
- // Set accounts using Java's Oauth2TokenService.setAccounts.
+ // Set accounts that have been advertised by OnRefreshTokenAvailable.
virtual void SetAccounts(const std::vector<CoreAccountId>& accounts);
base::android::ScopedJavaGlobalRef<jobject> java_ref_;
+ // Accounts that have been advertised by OnRefreshTokenAvailable.
+ std::vector<CoreAccountId> accounts_;
+
// Maps account_id to the last error for that account.
std::map<CoreAccountId, GoogleServiceAuthError> errors_;
AccountTrackerService* account_tracker_service_;
RefreshTokenLoadStatus fire_refresh_token_loaded_;
- base::Time last_update_accounts_time_;
// For testing, disables the creation of the java counterpart, see
// set_disable_interaction_with_system_accounts().
// TODO(crbug.com/1009957) Remove disable_interation_with_system_accounts_
- // from OAuth2TokenServiceDelegateAndroid
+ // from ProfileOAuth2TokenServiceDelegateAndroid
static bool disable_interaction_with_system_accounts_;
- DISALLOW_COPY_AND_ASSIGN(OAuth2TokenServiceDelegateAndroid);
+ DISALLOW_COPY_AND_ASSIGN(ProfileOAuth2TokenServiceDelegateAndroid);
};
-#endif // COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_OAUTH2_TOKEN_SERVICE_DELEGATE_ANDROID_H_
+#endif // COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PROFILE_OAUTH2_TOKEN_SERVICE_DELEGATE_ANDROID_H_
diff --git a/chromium/components/signin/internal/identity_manager/oauth2_token_service_delegate_android_unittest.cc b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android_unittest.cc
index a9de2f5aaea..0ae09eb25b8 100644
--- a/chromium/components/signin/internal/identity_manager/oauth2_token_service_delegate_android_unittest.cc
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android_unittest.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h"
+#include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -19,11 +19,12 @@ namespace signin {
namespace {
const std::vector<CoreAccountId> kEmptyVector;
class OAuth2TokenServiceDelegateAndroidForTest
- : public OAuth2TokenServiceDelegateAndroid {
+ : public ProfileOAuth2TokenServiceDelegateAndroid {
public:
OAuth2TokenServiceDelegateAndroidForTest(
AccountTrackerService* account_tracker_service)
- : OAuth2TokenServiceDelegateAndroid(account_tracker_service, nullptr) {}
+ : ProfileOAuth2TokenServiceDelegateAndroid(account_tracker_service,
+ nullptr) {}
MOCK_METHOD1(SetAccounts, void(const std::vector<CoreAccountId>&));
};
diff --git a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
index d93f2428cf9..ea2e8027964 100644
--- a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm
@@ -22,7 +22,7 @@
#include "components/signin/public/identity_manager/account_info.h"
#include "components/signin/public/identity_manager/ios/device_accounts_provider.h"
#include "google_apis/gaia/oauth2_access_token_fetcher.h"
-#include "net/url_request/url_request_status.h"
+#include "net/base/net_errors.h"
#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
@@ -59,8 +59,7 @@ GoogleServiceAuthError GetGoogleServiceAuthErrorFromNSError(
GoogleServiceAuthError::SERVICE_UNAVAILABLE);
case kAuthenticationErrorCategoryNetworkServerErrors:
// Just set the connection error state to FAILED.
- return GoogleServiceAuthError::FromConnectionError(
- net::URLRequestStatus::FAILED);
+ return GoogleServiceAuthError::FromConnectionError(net::ERR_FAILED);
case kAuthenticationErrorCategoryUserCancellationErrors:
return GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
case kAuthenticationErrorCategoryUnknownIdentityErrors:
diff --git a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm
index b0eeef2cb63..cc1995dea29 100644
--- a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios_unittest.mm
@@ -18,7 +18,6 @@
#include "google_apis/gaia/oauth2_access_token_consumer.h"
#include "google_apis/gaia/oauth2_access_token_fetcher.h"
#include "google_apis/gaia/oauth2_access_token_manager_test_util.h"
-#include "net/url_request/test_url_fetcher_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
@@ -34,8 +33,7 @@ class ProfileOAuth2TokenServiceIOSDelegateTest
public ProfileOAuth2TokenServiceObserver {
public:
ProfileOAuth2TokenServiceIOSDelegateTest()
- : factory_(nullptr),
- client_(&prefs_),
+ : client_(&prefs_),
token_available_count_(0),
token_revoked_count_(0),
tokens_loaded_count_(0),
@@ -54,8 +52,6 @@ class ProfileOAuth2TokenServiceIOSDelegateTest
prefs::kTokenServiceExcludedSecondaryAccounts);
fake_provider_ = new FakeDeviceAccountsProvider();
- factory_.SetFakeResponse(GaiaUrls::GetInstance()->oauth2_revoke_url(), "",
- net::HTTP_OK, net::URLRequestStatus::SUCCESS);
oauth2_delegate_.reset(new ProfileOAuth2TokenServiceIOSDelegate(
&client_, base::WrapUnique(fake_provider_), &account_tracker_));
oauth2_delegate_->AddObserver(this);
@@ -106,7 +102,6 @@ class ProfileOAuth2TokenServiceIOSDelegateTest
protected:
base::test::TaskEnvironment task_environment_;
- net::FakeURLFetcherFactory factory_;
TestingPrefServiceSimple prefs_;
TestSigninClient client_;
AccountTrackerService account_tracker_;
diff --git a/chromium/components/signin/ios/OWNERS b/chromium/components/signin/ios/OWNERS
index eaea7716829..04f4beaa435 100644
--- a/chromium/components/signin/ios/OWNERS
+++ b/chromium/components/signin/ios/OWNERS
@@ -1,3 +1,4 @@
+fernandex@chromium.org
jlebel@chromium.org
msarda@chromium.org
diff --git a/chromium/components/signin/ios/browser/account_consistency_service.mm b/chromium/components/signin/ios/browser/account_consistency_service.mm
index 1febb6d9902..46e194e456e 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service.mm
+++ b/chromium/components/signin/ios/browser/account_consistency_service.mm
@@ -154,7 +154,7 @@ void AccountConsistencyHandler::WebStateDestroyed() {
// Designated initializer. |callback| will be called every time a navigation has
// finished. |callback| must not be empty.
-- (instancetype)initWithCallback:(const base::Closure&)callback
+- (instancetype)initWithCallback:(const base::RepeatingClosure&)callback
NS_DESIGNATED_INITIALIZER;
- (instancetype)init NS_UNAVAILABLE;
@@ -162,10 +162,10 @@ void AccountConsistencyHandler::WebStateDestroyed() {
@implementation AccountConsistencyNavigationDelegate {
// Callback that will be called every time a navigation has finished.
- base::Closure _callback;
+ base::RepeatingClosure _callback;
}
-- (instancetype)initWithCallback:(const base::Closure&)callback {
+- (instancetype)initWithCallback:(const base::RepeatingClosure&)callback {
self = [super init];
if (self) {
DCHECK(!callback.is_null());
@@ -426,9 +426,9 @@ WKWebView* AccountConsistencyService::GetWKWebView() {
if (!web_view_) {
web_view_ = BuildWKWebView();
navigation_delegate_ = [[AccountConsistencyNavigationDelegate alloc]
- initWithCallback:base::Bind(&AccountConsistencyService::
- FinishedApplyingCookieRequest,
- base::Unretained(this), true)];
+ initWithCallback:base::BindRepeating(&AccountConsistencyService::
+ FinishedApplyingCookieRequest,
+ base::Unretained(this), true)];
[web_view_ setNavigationDelegate:navigation_delegate_];
}
return web_view_;
diff --git a/chromium/components/signin/ios/browser/wait_for_network_callback_helper_unittest.cc b/chromium/components/signin/ios/browser/wait_for_network_callback_helper_unittest.cc
index e23d22f65d3..c46fb6a5dd2 100644
--- a/chromium/components/signin/ios/browser/wait_for_network_callback_helper_unittest.cc
+++ b/chromium/components/signin/ios/browser/wait_for_network_callback_helper_unittest.cc
@@ -31,8 +31,8 @@ TEST_F(WaitForNetworkCallbackHelperTest, CallbackInvokedImmediately) {
network_change_notifier_->SetConnectionType(
net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI);
callback_helper_.HandleCallback(
- base::Bind(&WaitForNetworkCallbackHelperTest::CallbackFunction,
- base::Unretained(this)));
+ base::BindOnce(&WaitForNetworkCallbackHelperTest::CallbackFunction,
+ base::Unretained(this)));
EXPECT_EQ(1, num_callbacks_invoked_);
}
@@ -40,11 +40,11 @@ TEST_F(WaitForNetworkCallbackHelperTest, CallbackInvokedLater) {
network_change_notifier_->SetConnectionType(
net::NetworkChangeNotifier::ConnectionType::CONNECTION_NONE);
callback_helper_.HandleCallback(
- base::Bind(&WaitForNetworkCallbackHelperTest::CallbackFunction,
- base::Unretained(this)));
+ base::BindOnce(&WaitForNetworkCallbackHelperTest::CallbackFunction,
+ base::Unretained(this)));
callback_helper_.HandleCallback(
- base::Bind(&WaitForNetworkCallbackHelperTest::CallbackFunction,
- base::Unretained(this)));
+ base::BindOnce(&WaitForNetworkCallbackHelperTest::CallbackFunction,
+ base::Unretained(this)));
EXPECT_EQ(0, num_callbacks_invoked_);
network_change_notifier_->SetConnectionType(
diff --git a/chromium/components/signin/public/android/BUILD.gn b/chromium/components/signin/public/android/BUILD.gn
new file mode 100644
index 00000000000..3212a290ec5
--- /dev/null
+++ b/chromium/components/signin/public/android/BUILD.gn
@@ -0,0 +1,38 @@
+import("//build/config/android/rules.gni")
+
+android_library("java") {
+ deps = [
+ "//base:base_java",
+ "//base:jni_java",
+ "//components/signin/core/browser/android:java",
+ "//net/android:net_java",
+ "//third_party/android_deps:android_support_v4_java",
+ "//third_party/android_deps:androidx_annotation_annotation_java",
+ ]
+
+ srcjar_deps = [
+ "//components/signin/public/base:signin_metrics_enum_javagen",
+ "//components/signin/public/identity_manager:identity_manager_enum_javagen",
+ ]
+
+ sources = [
+ "java/src/org/chromium/components/signin/base/CoreAccountId.java",
+ "java/src/org/chromium/components/signin/base/CoreAccountInfo.java",
+ "java/src/org/chromium/components/signin/identitymanager/IdentityManager.java",
+ "java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java",
+ "java/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegate.java",
+ ]
+
+ annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
+}
+
+generate_jni("jni_headers") {
+ namespace = "signin"
+ sources = [
+ "java/src/org/chromium/components/signin/base/CoreAccountId.java",
+ "java/src/org/chromium/components/signin/base/CoreAccountInfo.java",
+ "java/src/org/chromium/components/signin/identitymanager/IdentityManager.java",
+ "java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java",
+ "java/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegate.java",
+ ]
+}
diff --git a/chromium/components/signin/public/identity_manager/android/DEPS b/chromium/components/signin/public/android/DEPS
index dba4bd1200e..93b627e9c9d 100644
--- a/chromium/components/signin/public/identity_manager/android/DEPS
+++ b/chromium/components/signin/public/android/DEPS
@@ -1,18 +1,20 @@
specific_include_rules = {
"CoreAccountInfo.java": [
- "+components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java"
+ "+components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountUtils.java",
],
"IdentityManager.java": [
"+components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java",
],
- "OAuth2TokenService.java": [
- "+components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java",
+ "ProfileOAuth2TokenServiceDelegate.java": [
"+components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountTrackerService.java",
- "+components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java",
+ "+components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java",
+ "+components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java",
"+components/signin/core/browser/android/java/src/org/chromium/components/signin/AuthException.java",
+ "+components/signin/core/browser/android/java/src/org/chromium/components/signin/ChromeSigninController.java",
],
- "OAuth2TokenServiceTest.java": [
+ "ProfileOAuth2TokenServiceDelegateTest.java": [
"+components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacade.java",
+ "+components/signin/core/browser/android/java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java",
"+components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/AccountHolder.java",
"+components/signin/core/browser/android/javatests/src/org/chromium/components/signin/test/util/AccountManagerTestRule.java",
],
diff --git a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/base/CoreAccountId.java
index bd963cce960..bf4ee4df93a 100644
--- a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java
+++ b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/base/CoreAccountId.java
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-package org.chromium.components.signin.identitymanager;
+package org.chromium.components.signin.base;
import androidx.annotation.NonNull;
diff --git a/chromium/components/signin/public/android/java/src/org/chromium/components/signin/base/CoreAccountInfo.java b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/base/CoreAccountInfo.java
new file mode 100644
index 00000000000..8d1cce892f1
--- /dev/null
+++ b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/base/CoreAccountInfo.java
@@ -0,0 +1,124 @@
+// Copyright 2019 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.
+
+package org.chromium.components.signin.base;
+
+import android.accounts.Account;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import org.chromium.base.annotations.CalledByNative;
+import org.chromium.components.signin.AccountUtils;
+
+/**
+ * Structure storing the core information about a Google account that is always known. The {@link
+ * CoreAccountInfo} for a given user is almost always the same but it may change in some rare cases.
+ * For example, the email will change if the user changes email.
+ * This class has a native counterpart called CoreAccountInfo.
+ */
+public class CoreAccountInfo {
+ private final CoreAccountId mId;
+ private final String mEmail;
+ private final String mGaiaId;
+
+ /**
+ * Constructs a CoreAccountInfo with the provided parameters
+ * @param id A CoreAccountId associated with the account, equal to either email or gaiaId.
+ * @param email The email of the account.
+ * @param gaiaId String representation of the Gaia ID. Must not be an email address.
+ */
+ @CalledByNative
+ public CoreAccountInfo(
+ @NonNull CoreAccountId id, @NonNull String email, @NonNull String gaiaId) {
+ assert id != null;
+ assert email != null;
+ assert gaiaId != null;
+ assert !gaiaId.contains("@");
+
+ mId = id;
+ mEmail = email;
+ mGaiaId = gaiaId;
+ }
+
+ /**
+ * Returns a unique identifier of the current account.
+ */
+ @CalledByNative
+ public CoreAccountId getId() {
+ return mId;
+ }
+
+ /**
+ * Returns the email of the current account.
+ */
+ @CalledByNative
+ public String getEmail() {
+ return mEmail;
+ }
+
+ /**
+ * Returns the string representation of the Gaia ID
+ */
+ @CalledByNative
+ public String getGaiaId() {
+ return mGaiaId;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("CoreAccountInfo{id[%s], name[%s]}", getId(), getEmail());
+ }
+
+ @Override
+ public int hashCode() {
+ int result = 31 * mId.hashCode() + mEmail.hashCode();
+ return 31 * result + mGaiaId.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof CoreAccountInfo)) return false;
+ CoreAccountInfo other = (CoreAccountInfo) obj;
+ return mId.equals(other.mId) && mEmail.equals(other.mEmail)
+ && mGaiaId.equals(other.mGaiaId);
+ }
+
+ /**
+ * Null-checking helper to create {@link Account} from a possibly null {@link CoreAccountInfo}.
+ *
+ * @return {@link Account} for the argument if it is not null, null otherwise.
+ */
+ public static @Nullable Account getAndroidAccountFrom(@Nullable CoreAccountInfo accountInfo) {
+ return accountInfo == null ? null
+ : AccountUtils.createAccountFromName(accountInfo.getEmail());
+ }
+
+ /**
+ * Null-checking helper to get an account id from a possibly null {@link CoreAccountInfo}.
+ *
+ * @return {@link #getId()} for the argument if it is not null, null otherwise.
+ */
+ public static @Nullable CoreAccountId getIdFrom(@Nullable CoreAccountInfo accountInfo) {
+ return accountInfo == null ? null : accountInfo.getId();
+ }
+
+ /**
+ * Null-checking helper to get an email from a possibly null {@link CoreAccountInfo}.
+ *
+ * @return {@link #getEmail()} for the argument if it is not null, null otherwise.
+ */
+ public static @Nullable String getEmailFrom(@Nullable CoreAccountInfo accountInfo) {
+ return accountInfo == null ? null : accountInfo.getEmail();
+ }
+
+ /**
+ * Null-checking helper to get a GaiaId from a possibly null {@link CoreAccountInfo}.
+ *
+ * @return {@link #getGaiaId()} ()} for the argument if it is not null, null otherwise.
+ */
+ public static @Nullable String getGaiaIdFrom(@Nullable CoreAccountInfo accountInfo) {
+ return accountInfo == null ? null : accountInfo.getGaiaId();
+ }
+}
diff --git a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
index ce35cfd6199..1fdcf187457 100644
--- a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
+++ b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityManager.java
@@ -5,15 +5,16 @@
package org.chromium.components.signin.identitymanager;
import android.accounts.Account;
-import android.support.annotation.MainThread;
-import android.support.annotation.Nullable;
+import androidx.annotation.MainThread;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
import org.chromium.base.ObserverList;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.components.signin.AccountManagerFacade;
+import org.chromium.components.signin.base.CoreAccountInfo;
/**
* IdentityManager provides access to native IdentityManager's public API to java components.
@@ -42,10 +43,11 @@ public class IdentityManager {
/**
* A simple callback for getAccessToken.
*/
- public interface GetAccessTokenCallback extends OAuth2TokenService.GetAccessTokenCallback {}
+ public interface GetAccessTokenCallback
+ extends ProfileOAuth2TokenServiceDelegate.GetAccessTokenCallback {}
private long mNativeIdentityManager;
- private OAuth2TokenService mOAuth2TokenService;
+ private ProfileOAuth2TokenServiceDelegate mProfileOAuth2TokenServiceDelegate;
private final ObserverList<Observer> mObservers = new ObserverList<>();
@@ -53,16 +55,17 @@ public class IdentityManager {
* Called by native to create an instance of IdentityManager.
*/
@CalledByNative
- private static IdentityManager create(
- long nativeIdentityManager, OAuth2TokenService oAuth2TokenService) {
+ private static IdentityManager create(long nativeIdentityManager,
+ ProfileOAuth2TokenServiceDelegate profileOAuth2TokenServiceDelegate) {
assert nativeIdentityManager != 0;
- return new IdentityManager(nativeIdentityManager, oAuth2TokenService);
+ return new IdentityManager(nativeIdentityManager, profileOAuth2TokenServiceDelegate);
}
@VisibleForTesting
- public IdentityManager(long nativeIdentityManager, OAuth2TokenService oAuth2TokenService) {
+ public IdentityManager(long nativeIdentityManager,
+ ProfileOAuth2TokenServiceDelegate profileOAuth2TokenServiceDelegate) {
mNativeIdentityManager = nativeIdentityManager;
- mOAuth2TokenService = oAuth2TokenService;
+ mProfileOAuth2TokenServiceDelegate = profileOAuth2TokenServiceDelegate;
}
/**
@@ -112,7 +115,7 @@ public class IdentityManager {
* Returns whether the user's primary account is available.
*/
public boolean hasPrimaryAccount() {
- return IdentityManagerJni.get().hasPrimaryAccount(mNativeIdentityManager);
+ return getPrimaryAccountInfo() != null;
}
/**
@@ -133,14 +136,6 @@ public class IdentityManager {
}
/**
- * Provides access to the account ID of the user's primary account. Returns null if no such info
- * is available.
- */
- public @Nullable CoreAccountId getPrimaryAccountId() {
- return IdentityManagerJni.get().getPrimaryAccountId(mNativeIdentityManager);
- }
-
- /**
* Looks up and returns information for account with given |email_address|. If the account
* cannot be found, return a null value.
*/
@@ -160,9 +155,9 @@ public class IdentityManager {
*/
@MainThread
public void getAccessToken(Account account, String scope, GetAccessTokenCallback callback) {
- assert mOAuth2TokenService != null;
+ assert mProfileOAuth2TokenServiceDelegate != null;
// TODO(crbug.com/934688) The following should call a JNI method instead.
- mOAuth2TokenService.getAccessToken(account, scope, callback);
+ mProfileOAuth2TokenServiceDelegate.getAccessToken(account, scope, callback);
}
/**
@@ -182,7 +177,8 @@ public class IdentityManager {
public static void getAccessTokenWithFacade(AccountManagerFacade accountManagerFacade,
Account account, String scope, GetAccessTokenCallback callback) {
// TODO(crbug.com/934688) The following should call a JNI method instead.
- OAuth2TokenService.getAccessTokenWithFacade(accountManagerFacade, account, scope, callback);
+ ProfileOAuth2TokenServiceDelegate.getAccessTokenWithFacade(
+ accountManagerFacade, account, scope, callback);
}
/**
@@ -191,10 +187,10 @@ public class IdentityManager {
*/
@MainThread
public void invalidateAccessToken(String accessToken) {
- assert mOAuth2TokenService != null;
+ assert mProfileOAuth2TokenServiceDelegate != null;
// TODO(crbug.com/934688) The following should call a JNI method instead.
- mOAuth2TokenService.invalidateAccessToken(accessToken);
+ mProfileOAuth2TokenServiceDelegate.invalidateAccessToken(accessToken);
}
/**
@@ -213,18 +209,17 @@ public class IdentityManager {
public static void getNewAccessTokenWithFacade(AccountManagerFacade accountManagerFacade,
Account account, @Nullable String oldToken, String scope,
GetAccessTokenCallback callback) {
- OAuth2TokenService.getNewAccessTokenWithFacade(
+ ProfileOAuth2TokenServiceDelegate.getNewAccessTokenWithFacade(
accountManagerFacade, account, oldToken, scope, callback);
}
@NativeMethods
- interface Natives {
- public @Nullable CoreAccountInfo getPrimaryAccountInfo(long nativeIdentityManager);
- public @Nullable CoreAccountId getPrimaryAccountId(long nativeIdentityManager);
- public boolean hasPrimaryAccount(long nativeIdentityManager);
- public @Nullable CoreAccountInfo
- findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
+ public interface Natives {
+ @Nullable
+ CoreAccountInfo getPrimaryAccountInfo(long nativeIdentityManager);
+ @Nullable
+ CoreAccountInfo findExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
long nativeIdentityManager, String email);
- public CoreAccountInfo[] getAccountsWithRefreshTokens(long nativeIdentityManager);
+ CoreAccountInfo[] getAccountsWithRefreshTokens(long nativeIdentityManager);
}
}
diff --git a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java
index 45f09282836..79974fe1539 100644
--- a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java
+++ b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java
@@ -8,6 +8,7 @@ import androidx.annotation.Nullable;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods;
+import org.chromium.components.signin.base.CoreAccountId;
import org.chromium.components.signin.metrics.SignoutDelete;
import org.chromium.components.signin.metrics.SignoutReason;
diff --git a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/OAuth2TokenService.java b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegate.java
index 00c1ea72897..d5947bec72d 100644
--- a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/OAuth2TokenService.java
+++ b/chromium/components/signin/public/android/java/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegate.java
@@ -11,7 +11,6 @@ import androidx.annotation.MainThread;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
-import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.StrictModeContext;
import org.chromium.base.ThreadUtils;
@@ -19,31 +18,27 @@ import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.task.AsyncTask;
import org.chromium.components.signin.AccountManagerFacade;
+import org.chromium.components.signin.AccountManagerFacadeProvider;
import org.chromium.components.signin.AccountTrackerService;
import org.chromium.components.signin.AuthException;
import org.chromium.net.NetworkChangeNotifier;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
/**
- * Java instance for the native OAuth2TokenService.
+ * Java instance for the native ProfileOAuth2TokenServiceDelegate.
* <p/>
* This class forwards calls to request or invalidate access tokens made by native code to
* AccountManagerFacade and forwards callbacks to native code.
* <p/>
*/
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
-public final class OAuth2TokenService
+public final class ProfileOAuth2TokenServiceDelegate
implements AccountTrackerService.OnSystemAccountsSeededListener {
private static final String TAG = "OAuth2TokenService";
- public static final String STORED_ACCOUNTS_KEY = "google.services.stored_accounts";
-
/**
* A simple callback for getAccessToken.
*/
@@ -66,20 +61,20 @@ public final class OAuth2TokenService
private static final String OAUTH2_SCOPE_PREFIX = "oauth2:";
- private final long mNativeOAuth2TokenServiceDelegate;
+ private final long mNativeProfileOAuth2TokenServiceDelegate;
private final AccountTrackerService mAccountTrackerService;
private final AccountManagerFacade mAccountManagerFacade;
private boolean mPendingUpdate;
- // TODO(crbug.com/934688) Once OAuth2TokenService.java is internalized, use CoreAccountId
- // instead of String.
+ // TODO(crbug.com/934688) Once ProfileOAuth2TokenServiceDelegate.java is internalized, use
+ // CoreAccountId instead of String.
private String mPendingUpdateAccountId;
@VisibleForTesting
- public OAuth2TokenService(long nativeOAuth2TokenServiceDelegate,
+ ProfileOAuth2TokenServiceDelegate(long nativeProfileOAuth2TokenServiceDelegateDelegate,
AccountTrackerService accountTrackerService,
AccountManagerFacade accountManagerFacade) {
- mNativeOAuth2TokenServiceDelegate = nativeOAuth2TokenServiceDelegate;
+ mNativeProfileOAuth2TokenServiceDelegate = nativeProfileOAuth2TokenServiceDelegateDelegate;
mAccountTrackerService = accountTrackerService;
mAccountManagerFacade = accountManagerFacade;
@@ -90,12 +85,14 @@ public final class OAuth2TokenService
}
@CalledByNative
- private static OAuth2TokenService create(long nativeOAuth2TokenServiceDelegate,
+ private static ProfileOAuth2TokenServiceDelegate create(
+ long nativeProfileOAuth2TokenServiceDelegateDelegate,
AccountTrackerService accountTrackerService,
AccountManagerFacade accountManagerFacade) {
- assert nativeOAuth2TokenServiceDelegate != 0;
- return new OAuth2TokenService(
- nativeOAuth2TokenServiceDelegate, accountTrackerService, accountManagerFacade);
+ assert nativeProfileOAuth2TokenServiceDelegateDelegate != 0;
+ return new ProfileOAuth2TokenServiceDelegate(
+ nativeProfileOAuth2TokenServiceDelegateDelegate, accountTrackerService,
+ accountManagerFacade);
}
private Account getAccountOrNullFromUsername(String username) {
@@ -118,8 +115,8 @@ public final class OAuth2TokenService
@CalledByNative
@VisibleForTesting
String[] getSystemAccountNames() {
- // TODO(https://crbug.com/768366): Remove this after adding cache to account manager facade.
- // This function is called by native code on UI thread.
+ // TODO(https://crbug.com/768366): Remove this after adding cache to account manager
+ // facade. This function is called by native code on UI thread.
try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
List<String> accountNames = mAccountManagerFacade.tryGetGoogleAccountNames();
return accountNames.toArray(new String[accountNames.size()]);
@@ -127,22 +124,11 @@ public final class OAuth2TokenService
}
/**
- * Called by native to list the accounts Id with OAuth2 refresh tokens.
- * This can differ from getSystemAccountNames as the user add/remove accounts
- * from the OS. updateAccountList should be called to keep these two
- * in sync.
- */
- @CalledByNative
- @VisibleForTesting
- static String[] getAccounts() {
- return getStoredAccounts();
- }
-
- /**
* Called by native to retrieve OAuth2 tokens.
* @param username The native username (email address).
* @param scope The scope to get an auth token for (without Android-style 'oauth2:' prefix).
- * @param nativeCallback The pointer to the native callback that should be run upon completion.
+ * @param nativeCallback The pointer to the native callback that should be run upon
+ * completion.
*/
@MainThread
@CalledByNative
@@ -151,7 +137,8 @@ public final class OAuth2TokenService
Account account = getAccountOrNullFromUsername(username);
if (account == null) {
ThreadUtils.postOnUiThread(() -> {
- OAuth2TokenServiceJni.get().onOAuth2TokenFetched(null, false, nativeCallback);
+ ProfileOAuth2TokenServiceDelegateJni.get().onOAuth2TokenFetched(
+ null, false, nativeCallback);
});
return;
}
@@ -159,20 +146,21 @@ public final class OAuth2TokenService
getAccessToken(account, oauth2Scope, new GetAccessTokenCallback() {
@Override
public void onGetTokenSuccess(String token) {
- OAuth2TokenServiceJni.get().onOAuth2TokenFetched(token, false, nativeCallback);
+ ProfileOAuth2TokenServiceDelegateJni.get().onOAuth2TokenFetched(
+ token, false, nativeCallback);
}
@Override
public void onGetTokenFailure(boolean isTransientError) {
- OAuth2TokenServiceJni.get().onOAuth2TokenFetched(
+ ProfileOAuth2TokenServiceDelegateJni.get().onOAuth2TokenFetched(
null, isTransientError, nativeCallback);
}
});
}
/**
- * Call this method to retrieve an OAuth2 access token for the given account and scope. Please
- * note that this method expects a scope with 'oauth2:' prefix.
+ * Call this method to retrieve an OAuth2 access token for the given account and scope.
+ * Please note that this method expects a scope with 'oauth2:' prefix.
* @param account the account to get the access token for.
* @param scope The scope to get an auth token for (with Android-style 'oauth2:' prefix).
* @param callback called on successful and unsuccessful fetching of auth token.
@@ -283,10 +271,11 @@ public final class OAuth2TokenService
}
// Temporarily allowing disk read while fixing. TODO: http://crbug.com/618096.
- // This function is called in RefreshTokenIsAvailable of OAuth2TokenService which is
- // expected to be called in the UI thread synchronously.
+ // This function is called in RefreshTokenIsAvailable of
+ // ProfileOAuth2TokenServiceDelegate which is expected to be called in the UI thread
+ // synchronously.
try (StrictModeContext ignored = StrictModeContext.allowDiskReads()) {
- return AccountManagerFacade.get().hasAccountForName(accountName);
+ return AccountManagerFacadeProvider.getInstance().hasAccountForName(accountName);
}
}
@@ -317,28 +306,8 @@ public final class OAuth2TokenService
}
private void reloadAllAccountsWithPrimaryAccountAfterSeeding(@Nullable String accountId) {
- OAuth2TokenServiceJni.get().reloadAllAccountsWithPrimaryAccountAfterSeeding(
- mNativeOAuth2TokenServiceDelegate, accountId);
- }
-
- private static String[] getStoredAccounts() {
- Set<String> accounts =
- ContextUtils.getAppSharedPreferences().getStringSet(STORED_ACCOUNTS_KEY, null);
- return accounts == null ? new String[] {} : accounts.toArray(new String[0]);
- }
-
- /**
- * Called by native to save the account IDs that have associated OAuth2 refresh tokens.
- * This is called during updateAccountList to sync with getSystemAccountNames.
- * @param accounts IDs to save.
- */
- @CalledByNative
- private static void setAccounts(String[] accounts) {
- Set<String> set = new HashSet<>(Arrays.asList(accounts));
- ContextUtils.getAppSharedPreferences()
- .edit()
- .putStringSet(STORED_ACCOUNTS_KEY, set)
- .apply();
+ ProfileOAuth2TokenServiceDelegateJni.get().reloadAllAccountsWithPrimaryAccountAfterSeeding(
+ mNativeProfileOAuth2TokenServiceDelegate, accountId);
}
private interface AuthTask<T> {
@@ -350,8 +319,8 @@ public final class OAuth2TokenService
/**
* A helper class to encapsulate network connection retry logic for AuthTasks.
*
- * The task will be run on the background thread. If it encounters a transient error, it will
- * wait for a network change and retry up to MAX_TRIES times.
+ * The task will be run on the background thread. If it encounters a transient error, it
+ * will wait for a network change and retry up to MAX_TRIES times.
*/
private static class ConnectionRetry<T>
implements NetworkChangeNotifier.ConnectionTypeObserver {
@@ -423,6 +392,6 @@ public final class OAuth2TokenService
interface Natives {
void onOAuth2TokenFetched(String authToken, boolean isTransientError, long nativeCallback);
void reloadAllAccountsWithPrimaryAccountAfterSeeding(
- long nativeOAuth2TokenServiceDelegateAndroid, @Nullable String accountId);
+ long nativeProfileOAuth2TokenServiceDelegateAndroid, @Nullable String accountId);
}
}
diff --git a/chromium/components/signin/public/identity_manager/android/javatests/src/org/chromium/components/signin/identitymanager/OAuth2TokenServiceTest.java b/chromium/components/signin/public/android/javatests/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegateTest.java
index 69838c18a1e..4b200a921a3 100644
--- a/chromium/components/signin/public/identity_manager/android/javatests/src/org/chromium/components/signin/identitymanager/OAuth2TokenServiceTest.java
+++ b/chromium/components/signin/public/android/javatests/src/org/chromium/components/signin/identitymanager/ProfileOAuth2TokenServiceDelegateTest.java
@@ -20,26 +20,28 @@ import org.chromium.base.test.BaseJUnit4ClassRunner;
import org.chromium.base.test.util.AdvancedMockContext;
import org.chromium.base.test.util.Feature;
import org.chromium.components.signin.AccountManagerFacade;
+import org.chromium.components.signin.AccountManagerFacadeProvider;
import org.chromium.components.signin.test.util.AccountHolder;
import org.chromium.components.signin.test.util.AccountManagerTestRule;
import java.util.Arrays;
import java.util.concurrent.CountDownLatch;
-/** Tests for OAuth2TokenService. */
+/** Tests for ProfileOAuth2TokenServiceDelegate. */
@RunWith(BaseJUnit4ClassRunner.class)
-public class OAuth2TokenServiceTest {
+public class ProfileOAuth2TokenServiceDelegateTest {
private AdvancedMockContext mContext;
@Rule
public AccountManagerTestRule mAccountManagerTestRule = new AccountManagerTestRule();
- private OAuth2TokenService mOAuth2TokenService;
+ private ProfileOAuth2TokenServiceDelegate mProfileOAuth2TokenServiceDelegate;
/**
* Class handling GetAccessToken callbacks and providing a blocking {@link
* #getToken()}.
*/
- class GetAccessTokenCallbackForTest implements OAuth2TokenService.GetAccessTokenCallback {
+ class GetAccessTokenCallbackForTest
+ implements ProfileOAuth2TokenServiceDelegate.GetAccessTokenCallback {
private String mToken;
final CountDownLatch mTokenRetrievedCountDown = new CountDownLatch(1);
@@ -72,20 +74,21 @@ public class OAuth2TokenServiceTest {
@Before
public void setUp() {
mContext = new AdvancedMockContext(InstrumentationRegistry.getTargetContext());
- mOAuth2TokenService = new OAuth2TokenService(0 /*nativeOAuth2TokenServiceDelegate*/,
- null /* AccountTrackerService */, AccountManagerFacade.get());
+ mProfileOAuth2TokenServiceDelegate = new ProfileOAuth2TokenServiceDelegate(
+ 0 /*nativeProfileOAuth2TokenServiceDelegateDelegate*/,
+ null /* AccountTrackerService */, AccountManagerFacadeProvider.get());
}
@After
public void tearDown() {
- AccountManagerFacade.resetAccountManagerFacadeForTests();
+ AccountManagerFacadeProvider.resetAccountManagerFacadeForTests();
}
@Test
@SmallTest
@Feature({"Sync"})
public void testGetAccountsNoAccountsRegistered() {
- String[] accounts = OAuth2TokenService.getAccounts();
+ String[] accounts = ProfileOAuth2TokenServiceDelegate.getAccounts();
Assert.assertEquals("There should be no accounts registered", 0, accounts.length);
}
@@ -97,11 +100,11 @@ public class OAuth2TokenServiceTest {
AccountHolder accountHolder1 = AccountHolder.builder(account1).build();
mAccountManagerTestRule.addAccount(accountHolder1);
- String[] sysAccounts = mOAuth2TokenService.getSystemAccountNames();
+ String[] sysAccounts = mProfileOAuth2TokenServiceDelegate.getSystemAccountNames();
Assert.assertEquals("There should be one registered account", 1, sysAccounts.length);
Assert.assertEquals("The account should be " + account1, account1.name, sysAccounts[0]);
- String[] accounts = OAuth2TokenService.getAccounts();
+ String[] accounts = ProfileOAuth2TokenServiceDelegate.getAccounts();
Assert.assertEquals("There should be zero registered account", 0, accounts.length);
}
@@ -116,14 +119,14 @@ public class OAuth2TokenServiceTest {
AccountHolder accountHolder2 = AccountHolder.builder(account2).build();
mAccountManagerTestRule.addAccount(accountHolder2);
- String[] sysAccounts = mOAuth2TokenService.getSystemAccountNames();
+ String[] sysAccounts = mProfileOAuth2TokenServiceDelegate.getSystemAccountNames();
Assert.assertEquals("There should be one registered account", 2, sysAccounts.length);
Assert.assertTrue("The list should contain " + account1,
Arrays.asList(sysAccounts).contains(account1.name));
Assert.assertTrue("The list should contain " + account2,
Arrays.asList(sysAccounts).contains(account2.name));
- String[] accounts = OAuth2TokenService.getAccounts();
+ String[] accounts = ProfileOAuth2TokenServiceDelegate.getAccounts();
Assert.assertEquals("There should be zero registered account", 0, accounts.length);
}
@@ -157,8 +160,9 @@ public class OAuth2TokenServiceTest {
mAccountManagerTestRule.addAccount(accountHolder);
GetAccessTokenCallbackForTest callback = new GetAccessTokenCallbackForTest();
- ThreadUtils.runOnUiThreadBlocking(
- () -> { mOAuth2TokenService.getAccessToken(account, scope, callback); });
+ ThreadUtils.runOnUiThreadBlocking(() -> {
+ mProfileOAuth2TokenServiceDelegate.getAccessToken(account, scope, callback);
+ });
Assert.assertEquals(expectedToken, callback.getToken());
}
diff --git a/chromium/components/signin/public/base/BUILD.gn b/chromium/components/signin/public/base/BUILD.gn
index dea58bf1bb6..80f8a7229e5 100644
--- a/chromium/components/signin/public/base/BUILD.gn
+++ b/chromium/components/signin/public/base/BUILD.gn
@@ -27,6 +27,8 @@ static_library("base") {
"device_id_helper.h",
"multilogin_parameters.cc",
"multilogin_parameters.h",
+ "persistent_repeating_timer.cc",
+ "persistent_repeating_timer.h",
"signin_client.cc",
"signin_client.h",
"signin_metrics.cc",
@@ -56,9 +58,7 @@ static_library("base") {
if (is_android) {
java_cpp_enum("signin_metrics_enum_javagen") {
- sources = [
- "signin_metrics.h",
- ]
+ sources = [ "signin_metrics.h" ]
}
}
@@ -89,6 +89,7 @@ source_set("unit_tests") {
sources = [
"avatar_icon_util_unittest.cc",
"device_id_helper_unittest.cc",
+ "persistent_repeating_timer_unittest.cc",
"signin_metrics_unittest.cc",
]
@@ -96,6 +97,7 @@ source_set("unit_tests") {
":base",
"//base",
"//base/test:test_support",
+ "//components/prefs:test_support",
"//components/sync_preferences:test_support",
"//testing/gtest",
"//url",
diff --git a/chromium/components/signin/public/base/account_consistency_method.cc b/chromium/components/signin/public/base/account_consistency_method.cc
index c278657ef49..09b96305c94 100644
--- a/chromium/components/signin/public/base/account_consistency_method.cc
+++ b/chromium/components/signin/public/base/account_consistency_method.cc
@@ -9,8 +9,8 @@
namespace signin {
#if defined(OS_ANDROID)
-const base::Feature kMiceFeature{"MobileIdentityConsistency",
- base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kMobileIdentityConsistency{
+ "MobileIdentityConsistency", base::FEATURE_DISABLED_BY_DEFAULT};
#endif
} // namespace signin
diff --git a/chromium/components/signin/public/base/account_consistency_method.h b/chromium/components/signin/public/base/account_consistency_method.h
index 88786f1766c..2750d8a7811 100644
--- a/chromium/components/signin/public/base/account_consistency_method.h
+++ b/chromium/components/signin/public/base/account_consistency_method.h
@@ -17,12 +17,9 @@ namespace signin {
#if defined(OS_ANDROID)
// Mice is similar to Mirror but also works when the user is not opted into
// Sync.
-extern const base::Feature kMiceFeature;
+extern const base::Feature kMobileIdentityConsistency;
#endif
-// TODO(https://crbug.com/777774): Cleanup this enum and remove related
-// functions once Dice is fully rolled out, and/or Mirror code is removed on
-// desktop.
enum class AccountConsistencyMethod : int {
// No account consistency.
kDisabled,
diff --git a/chromium/components/signin/public/base/persistent_repeating_timer.cc b/chromium/components/signin/public/base/persistent_repeating_timer.cc
new file mode 100644
index 00000000000..cb5dada2c9b
--- /dev/null
+++ b/chromium/components/signin/public/base/persistent_repeating_timer.cc
@@ -0,0 +1,54 @@
+// Copyright 2020 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 "components/signin/public/base/persistent_repeating_timer.h"
+
+#include "base/callback.h"
+#include "components/prefs/pref_service.h"
+
+namespace signin {
+
+PersistentRepeatingTimer::PersistentRepeatingTimer(
+ PrefService* prefs,
+ const char* timer_last_update_pref_name,
+ base::TimeDelta delay,
+ base::RepeatingClosure task)
+ : prefs_(prefs),
+ last_fired_pref_name_(timer_last_update_pref_name),
+ delay_(delay),
+ user_task_(task) {}
+
+PersistentRepeatingTimer::~PersistentRepeatingTimer() = default;
+
+void PersistentRepeatingTimer::Start() {
+ if (timer_.IsRunning())
+ return; // Already started.
+
+ const base::TimeDelta time_since_update = base::Time::Now() - GetLastFired();
+ if (time_since_update >= delay_) {
+ OnTimerFired();
+ } else {
+ timer_.Start(FROM_HERE, delay_ - time_since_update,
+ base::Bind(&PersistentRepeatingTimer::OnTimerFired,
+ base::Unretained(this)));
+ }
+ DCHECK(timer_.IsRunning());
+}
+
+base::Time PersistentRepeatingTimer::GetLastFired() {
+ return prefs_->GetTime(last_fired_pref_name_);
+}
+
+void PersistentRepeatingTimer::SetLastFiredNow() {
+ prefs_->SetTime(last_fired_pref_name_, base::Time::Now());
+}
+
+void PersistentRepeatingTimer::OnTimerFired() {
+ DCHECK(!timer_.IsRunning());
+ SetLastFiredNow();
+ user_task_.Run();
+ Start();
+}
+
+} // namespace signin
diff --git a/chromium/components/signin/public/base/persistent_repeating_timer.h b/chromium/components/signin/public/base/persistent_repeating_timer.h
new file mode 100644
index 00000000000..df65983c3ea
--- /dev/null
+++ b/chromium/components/signin/public/base/persistent_repeating_timer.h
@@ -0,0 +1,54 @@
+// Copyright 2020 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 COMPONENTS_SIGNIN_PUBLIC_BASE_PERSISTENT_REPEATING_TIMER_H_
+#define COMPONENTS_SIGNIN_PUBLIC_BASE_PERSISTENT_REPEATING_TIMER_H_
+
+#include <string>
+
+#include "base/callback_forward.h"
+#include "base/time/time.h"
+#include "base/timer/timer.h"
+
+class PrefService;
+
+namespace signin {
+
+// This class fires a task repeatedly, across application restarts. The timer
+// stores the date of the last invocation in a preference, which is persisted
+// to disk.
+class PersistentRepeatingTimer {
+ public:
+ // The timer is not started at creation.
+ PersistentRepeatingTimer(PrefService* prefs,
+ const char* timer_last_update_pref_name,
+ base::TimeDelta delay,
+ base::RepeatingClosure task);
+
+ ~PersistentRepeatingTimer();
+
+ // Starts the timer. Calling Start() when the timer is running has no effect.
+ void Start();
+
+ private:
+ // Reads the date of the last event from the pref.
+ base::Time GetLastFired();
+
+ // Updates the pref with the current time.
+ void SetLastFiredNow();
+
+ // Called when |timer_| fires.
+ void OnTimerFired();
+
+ PrefService* prefs_;
+ std::string last_fired_pref_name_;
+ base::TimeDelta delay_;
+ base::RepeatingClosure user_task_;
+
+ base::RetainingOneShotTimer timer_;
+};
+
+} // namespace signin
+
+#endif // COMPONENTS_SIGNIN_PUBLIC_BASE_PERSISTENT_REPEATING_TIMER_H_
diff --git a/chromium/components/signin/public/base/persistent_repeating_timer_unittest.cc b/chromium/components/signin/public/base/persistent_repeating_timer_unittest.cc
new file mode 100644
index 00000000000..29783bde3be
--- /dev/null
+++ b/chromium/components/signin/public/base/persistent_repeating_timer_unittest.cc
@@ -0,0 +1,137 @@
+// Copyright 2020 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 "components/signin/public/base/persistent_repeating_timer.h"
+
+#include "base/test/task_environment.h"
+#include "components/prefs/pref_registry_simple.h"
+#include "components/prefs/testing_pref_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace signin {
+
+namespace {
+
+const char kLastUpdatedTimePref[] = "test.last_updated_time";
+constexpr base::TimeDelta kTestDelay = base::TimeDelta::FromHours(2);
+
+} // namespace
+
+class PersistentRepeatingTimerTest : public ::testing::Test {
+ public:
+ PersistentRepeatingTimerTest() {
+ pref_service_.registry()->RegisterTimePref(kLastUpdatedTimePref,
+ base::Time());
+ }
+
+ void RunTask() { ++call_count_; }
+
+ void CheckCallCount(int call_count) {
+ base::RunLoop().RunUntilIdle();
+ EXPECT_EQ(call_count, call_count_);
+ }
+
+ base::test::TaskEnvironment task_environment_{
+ base::test::TaskEnvironment::TimeSource::MOCK_TIME};
+ TestingPrefServiceSimple pref_service_;
+ int call_count_ = 0;
+};
+
+// Checks that the missing pref is treated like an old one.
+TEST_F(PersistentRepeatingTimerTest, MissingPref) {
+ PersistentRepeatingTimer timer(
+ &pref_service_, kLastUpdatedTimePref, kTestDelay,
+ base::Bind(&PersistentRepeatingTimerTest::RunTask,
+ base::Unretained(this)));
+ CheckCallCount(0);
+
+ // The task is run immediately on start.
+ timer.Start();
+ CheckCallCount(1);
+
+ task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
+ CheckCallCount(1);
+
+ // And after the delay.
+ task_environment_.FastForwardBy(kTestDelay);
+ CheckCallCount(2);
+}
+
+// Checks that spurious calls to Start() have no effect.
+TEST_F(PersistentRepeatingTimerTest, MultipleStarts) {
+ PersistentRepeatingTimer timer(
+ &pref_service_, kLastUpdatedTimePref, kTestDelay,
+ base::Bind(&PersistentRepeatingTimerTest::RunTask,
+ base::Unretained(this)));
+ CheckCallCount(0);
+
+ // The task is run immediately on start.
+ timer.Start();
+ CheckCallCount(1);
+ timer.Start();
+ CheckCallCount(1);
+
+ task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
+ CheckCallCount(1);
+ task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
+ timer.Start();
+ CheckCallCount(1);
+
+ // And after the delay.
+ task_environment_.FastForwardBy(kTestDelay);
+ CheckCallCount(2);
+ timer.Start();
+ CheckCallCount(2);
+}
+
+TEST_F(PersistentRepeatingTimerTest, RecentPref) {
+ pref_service_.SetTime(kLastUpdatedTimePref,
+ base::Time::Now() - base::TimeDelta::FromHours(1));
+
+ PersistentRepeatingTimer timer(
+ &pref_service_, kLastUpdatedTimePref, kTestDelay,
+ base::Bind(&PersistentRepeatingTimerTest::RunTask,
+ base::Unretained(this)));
+ CheckCallCount(0);
+
+ // The task is NOT run immediately on start.
+ timer.Start();
+ CheckCallCount(0);
+
+ task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
+ CheckCallCount(0);
+
+ // It is run after te delay.
+ task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
+ CheckCallCount(1);
+ task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
+ CheckCallCount(1);
+
+ task_environment_.FastForwardBy(base::TimeDelta::FromHours(1));
+ CheckCallCount(2);
+}
+
+TEST_F(PersistentRepeatingTimerTest, OldPref) {
+ pref_service_.SetTime(kLastUpdatedTimePref,
+ base::Time::Now() - base::TimeDelta::FromHours(10));
+
+ PersistentRepeatingTimer timer(
+ &pref_service_, kLastUpdatedTimePref, kTestDelay,
+ base::Bind(&PersistentRepeatingTimerTest::RunTask,
+ base::Unretained(this)));
+ CheckCallCount(0);
+
+ // The task is run immediately on start.
+ timer.Start();
+ CheckCallCount(1);
+
+ task_environment_.FastForwardBy(base::TimeDelta::FromMinutes(1));
+ CheckCallCount(1);
+
+ // And after the delay.
+ task_environment_.FastForwardBy(kTestDelay);
+ CheckCallCount(2);
+}
+
+} // namespace signin
diff --git a/chromium/components/signin/public/base/signin_pref_names.cc b/chromium/components/signin/public/base/signin_pref_names.cc
index 3d2a442d235..f935746e783 100644
--- a/chromium/components/signin/public/base/signin_pref_names.cc
+++ b/chromium/components/signin/public/base/signin_pref_names.cc
@@ -14,6 +14,11 @@ namespace prefs {
// Account Manager.
const char kAccountConsistencyMirrorRequired[] =
"account_consistency_mirror.required";
+
+// A boolean pref - should unauthenticated user should be logged out
+// automatically. Default value is false.
+const char kForceLogoutUnauthenticatedUserEnabled[] =
+ "profile.force_logout_unauthenticated_user_enabled";
#endif
// An integer property indicating the state of account id migration from
diff --git a/chromium/components/signin/public/base/signin_pref_names.h b/chromium/components/signin/public/base/signin_pref_names.h
index 1db578bdae0..fe4af3e4432 100644
--- a/chromium/components/signin/public/base/signin_pref_names.h
+++ b/chromium/components/signin/public/base/signin_pref_names.h
@@ -9,6 +9,7 @@ namespace prefs {
#if defined(OS_CHROMEOS)
extern const char kAccountConsistencyMirrorRequired[];
+extern const char kForceLogoutUnauthenticatedUserEnabled[];
#endif
extern const char kAccountIdMigrationState[];
extern const char kAccountInfo[];
diff --git a/chromium/components/signin/public/base/signin_switches.cc b/chromium/components/signin/public/base/signin_switches.cc
index fb905755f84..8fdcf18fb67 100644
--- a/chromium/components/signin/public/base/signin_switches.cc
+++ b/chromium/components/signin/public/base/signin_switches.cc
@@ -13,17 +13,12 @@ const char kClearTokenService[] = "clear-token-service";
// Disables sending signin scoped device id to LSO with refresh token request.
const char kDisableSigninScopedDeviceId[] = "disable-signin-scoped-device-id";
-#if !BUILDFLAG(ENABLE_MIRROR)
-// Command line flag for enabling account consistency. Default mode is disabled.
-// Mirror is a legacy mode in which Google accounts are always addded to Chrome,
-// and Chrome then adds them to the Google authentication cookies.
-// Dice is a new experiment in which Chrome is aware of the accounts in the
-// Google authentication cookies.
-const char kAccountConsistency[] = "account-consistency";
-
-// Values for the kAccountConsistency flag.
-const char kAccountConsistencyMirror[] = "mirror";
-const char kAccountConsistencyDice[] = "dice";
+#if defined(OS_CHROMEOS)
+const base::Feature kAccountIdMigration{"AccountIdMigration",
+ base::FEATURE_DISABLED_BY_DEFAULT};
#endif
+const base::Feature kOAuthRemoteConsent{"OAuthRemoteConsent",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+
} // namespace switches
diff --git a/chromium/components/signin/public/base/signin_switches.h b/chromium/components/signin/public/base/signin_switches.h
index 1397cbf4a40..d354b0a757d 100644
--- a/chromium/components/signin/public/base/signin_switches.h
+++ b/chromium/components/signin/public/base/signin_switches.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_SIGNIN_PUBLIC_BASE_SIGNIN_SWITCHES_H_
#define COMPONENTS_SIGNIN_PUBLIC_BASE_SIGNIN_SWITCHES_H_
+#include "base/feature_list.h"
#include "components/signin/public/base/signin_buildflags.h"
namespace switches {
@@ -18,14 +19,13 @@ namespace switches {
extern const char kClearTokenService[];
extern const char kDisableSigninScopedDeviceId[];
-#if !BUILDFLAG(ENABLE_MIRROR)
-// Note: Account consistency (Mirror) is already enabled on mobile platforms, so
-// this switch only exist on desktop platforms.
-extern const char kAccountConsistency[];
-extern const char kAccountConsistencyMirror[];
-extern const char kAccountConsistencyDice[];
+#if defined(OS_CHROMEOS)
+extern const base::Feature kAccountIdMigration;
#endif
+// Enables the remote consent flow for chrome.identity extension API.
+extern const base::Feature kOAuthRemoteConsent;
+
} // namespace switches
#endif // COMPONENTS_SIGNIN_PUBLIC_BASE_SIGNIN_SWITCHES_H_
diff --git a/chromium/components/signin/public/identity_manager/BUILD.gn b/chromium/components/signin/public/identity_manager/BUILD.gn
index 537e423ee9e..2e4dde69400 100644
--- a/chromium/components/signin/public/identity_manager/BUILD.gn
+++ b/chromium/components/signin/public/identity_manager/BUILD.gn
@@ -18,6 +18,7 @@ source_set("identity_manager") {
"accounts_in_cookie_jar_info.cc",
"accounts_in_cookie_jar_info.h",
"accounts_mutator.h",
+ "consent_level.h",
"device_accounts_synchronizer.h",
"diagnostics_provider.h",
"identity_manager.cc",
@@ -32,6 +33,7 @@ source_set("identity_manager") {
"primary_account_access_token_fetcher.cc",
"primary_account_access_token_fetcher.h",
"primary_account_mutator.h",
+ "scope_set.h",
"set_accounts_in_cookie_result.h",
"ubertoken_fetcher.cc",
"ubertoken_fetcher.h",
@@ -45,7 +47,6 @@ source_set("identity_manager") {
"//components/signin/public/base",
"//components/signin/public/base:signin_buildflags",
"//google_apis",
- "//services/identity/public/cpp:cpp_types",
"//ui/gfx",
]
@@ -66,8 +67,7 @@ source_set("identity_manager") {
}
if (is_android) {
- deps +=
- [ "//components/signin/internal/identity_manager/android:jni_headers" ]
+ deps += [ "//components/signin/public/android:jni_headers" ]
}
allow_circular_includes_from = [
@@ -79,9 +79,7 @@ source_set("identity_manager") {
if (is_android) {
java_cpp_enum("identity_manager_enum_javagen") {
- sources = [
- "primary_account_mutator.h",
- ]
+ sources = [ "primary_account_mutator.h" ]
}
}
diff --git a/chromium/components/signin/public/identity_manager/access_token_fetcher.cc b/chromium/components/signin/public/identity_manager/access_token_fetcher.cc
index df7671a2efb..4ed181b04f4 100644
--- a/chromium/components/signin/public/identity_manager/access_token_fetcher.cc
+++ b/chromium/components/signin/public/identity_manager/access_token_fetcher.cc
@@ -16,7 +16,7 @@ namespace signin {
AccessTokenFetcher::AccessTokenFetcher(const CoreAccountId& account_id,
const std::string& oauth_consumer_name,
ProfileOAuth2TokenService* token_service,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
TokenCallback callback,
Mode mode)
: AccessTokenFetcher(account_id,
@@ -32,7 +32,7 @@ AccessTokenFetcher::AccessTokenFetcher(
const std::string& oauth_consumer_name,
ProfileOAuth2TokenService* token_service,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
TokenCallback callback,
Mode mode)
: AccessTokenFetcher(account_id,
@@ -50,7 +50,7 @@ AccessTokenFetcher::AccessTokenFetcher(const CoreAccountId& account_id,
const std::string client_secret,
const std::string& oauth_consumer_name,
ProfileOAuth2TokenService* token_service,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
TokenCallback callback,
Mode mode)
: AccessTokenFetcher(account_id,
@@ -70,7 +70,7 @@ AccessTokenFetcher::AccessTokenFetcher(
const std::string& oauth_consumer_name,
ProfileOAuth2TokenService* token_service,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
TokenCallback callback,
Mode mode)
: OAuth2AccessTokenManager::Consumer(oauth_consumer_name),
diff --git a/chromium/components/signin/public/identity_manager/access_token_fetcher.h b/chromium/components/signin/public/identity_manager/access_token_fetcher.h
index 2f588f41488..fdfecbe4232 100644
--- a/chromium/components/signin/public/identity_manager/access_token_fetcher.h
+++ b/chromium/components/signin/public/identity_manager/access_token_fetcher.h
@@ -14,9 +14,9 @@
#include "base/scoped_observer.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service_observer.h"
+#include "components/signin/public/identity_manager/scope_set.h"
#include "google_apis/gaia/core_account_id.h"
#include "google_apis/gaia/oauth2_access_token_manager.h"
-#include "services/identity/public/cpp/scope_set.h"
namespace network {
class SharedURLLoaderFactory;
@@ -80,7 +80,7 @@ struct AccessTokenInfo;
// // wrapper API surfaces.
// MyClass::StartAccessTokenRequestForAccount(CoreAccountId account_id) {
// // Choose scopes to obtain for the access token.
-// identity::ScopeSet scopes;
+// ScopeSet scopes;
// scopes.insert(GaiaConstants::kMyFirstScope);
// scopes.insert(GaiaConstants::kMySecondScope);
@@ -165,7 +165,7 @@ class AccessTokenFetcher : public ProfileOAuth2TokenServiceObserver,
AccessTokenFetcher(const CoreAccountId& account_id,
const std::string& oauth_consumer_name,
ProfileOAuth2TokenService* token_service,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
TokenCallback callback,
Mode mode);
@@ -179,7 +179,7 @@ class AccessTokenFetcher : public ProfileOAuth2TokenServiceObserver,
const std::string& oauth_consumer_name,
ProfileOAuth2TokenService* token_service,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
TokenCallback callback,
Mode mode);
@@ -191,7 +191,7 @@ class AccessTokenFetcher : public ProfileOAuth2TokenServiceObserver,
const std::string client_secret,
const std::string& oauth_consumer_name,
ProfileOAuth2TokenService* token_service,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
TokenCallback callback,
Mode mode);
@@ -205,7 +205,7 @@ class AccessTokenFetcher : public ProfileOAuth2TokenServiceObserver,
const std::string& oauth_consumer_name,
ProfileOAuth2TokenService* token_service,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
TokenCallback callback,
Mode mode);
@@ -237,7 +237,7 @@ class AccessTokenFetcher : public ProfileOAuth2TokenServiceObserver,
const std::string client_secret_;
ProfileOAuth2TokenService* token_service_;
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
- const identity::ScopeSet scopes_;
+ const ScopeSet scopes_;
const Mode mode_;
// NOTE: This callback should only be invoked from |RunCallbackAndMaybeDie|,
diff --git a/chromium/components/signin/public/identity_manager/account_info.cc b/chromium/components/signin/public/identity_manager/account_info.cc
index 17c2856cf73..e9aef3c5f55 100644
--- a/chromium/components/signin/public/identity_manager/account_info.cc
+++ b/chromium/components/signin/public/identity_manager/account_info.cc
@@ -7,8 +7,8 @@
#if defined(OS_ANDROID)
#include "base/android/jni_string.h"
-#include "components/signin/internal/identity_manager/android/jni_headers/CoreAccountId_jni.h"
-#include "components/signin/internal/identity_manager/android/jni_headers/CoreAccountInfo_jni.h"
+#include "components/signin/public/android/jni_headers/CoreAccountId_jni.h"
+#include "components/signin/public/android/jni_headers/CoreAccountInfo_jni.h"
#endif
namespace {
@@ -153,7 +153,7 @@ CoreAccountInfo ConvertFromJavaCoreAccountInfo(
account.gaia = base::android::ConvertJavaStringToUTF8(
signin::Java_CoreAccountInfo_getGaiaId(env, j_core_account_info));
account.email = base::android::ConvertJavaStringToUTF8(
- signin::Java_CoreAccountInfo_getName(env, j_core_account_info));
+ signin::Java_CoreAccountInfo_getEmail(env, j_core_account_info));
return account;
}
diff --git a/chromium/components/signin/public/identity_manager/account_info.h b/chromium/components/signin/public/identity_manager/account_info.h
index 0c7f93def8e..93f6d86d311 100644
--- a/chromium/components/signin/public/identity_manager/account_info.h
+++ b/chromium/components/signin/public/identity_manager/account_info.h
@@ -61,6 +61,7 @@ struct AccountInfo : public CoreAccountInfo {
std::string hosted_domain;
std::string locale;
std::string picture_url;
+ std::string last_downloaded_image_url_with_size;
gfx::Image account_image;
bool is_child_account = false;
diff --git a/chromium/components/signin/public/identity_manager/accounts_cookie_mutator.h b/chromium/components/signin/public/identity_manager/accounts_cookie_mutator.h
index b60720e00b8..d29441121f8 100644
--- a/chromium/components/signin/public/identity_manager/accounts_cookie_mutator.h
+++ b/chromium/components/signin/public/identity_manager/accounts_cookie_mutator.h
@@ -15,6 +15,12 @@
struct CoreAccountId;
class GoogleServiceAuthError;
+namespace network {
+namespace mojom {
+class CookieManager;
+}
+} // namespace network
+
namespace signin {
struct MultiloginParameters;
@@ -24,12 +30,33 @@ enum class SetAccountsInCookieResult;
// accounts into the cookie jar tracking the list of logged-in Google sessions.
class AccountsCookieMutator {
public:
+ // Delegate class used to interact with storage partitions other than the
+ // default one. The default storage partition is managed by the SigninClient.
+ class PartitionDelegate {
+ public:
+ // Creates a new GaiaAuthFetcher for the partition.
+ virtual std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcherForPartition(
+ GaiaAuthConsumer* consumer) = 0;
+
+ // Returns the CookieManager for the partition.
+ virtual network::mojom::CookieManager* GetCookieManagerForPartition() = 0;
+ };
+
+ // Task handle for SetAccountsInCookieForPartition. Deleting this object
+ // cancels the task. Must not outlive the AccountsInCookieMutator.
+ class SetAccountsInCookieTask {
+ public:
+ virtual ~SetAccountsInCookieTask() = default;
+ };
+
AccountsCookieMutator() = default;
virtual ~AccountsCookieMutator() = default;
typedef base::OnceCallback<void(const CoreAccountId& account_id,
const GoogleServiceAuthError& error)>
AddAccountToCookieCompletedCallback;
+ typedef base::OnceCallback<void(const GoogleServiceAuthError& error)>
+ LogOutFromCookieCompletedCallback;
// Adds an account identified by |account_id| to the cookie responsible for
// tracking the list of logged-in Google sessions across the web.
@@ -67,6 +94,20 @@ class AccountsCookieMutator {
base::OnceCallback<void(SetAccountsInCookieResult)>
set_accounts_in_cookies_completed_callback) = 0;
+ // This is similar to SetAccountsInCookie, but allow specifying the partition
+ // where the cookies are set. This function must not be used with the default
+ // partition (use SetAccountsInCookie instead).
+ //
+ // The returned SetAccountsInCookieTask must not outlive the
+ // AccountsCookieMutator. If the task is deleted, all network requests are
+ // cancelled; the partition delegate and the callback will not be called.
+ virtual std::unique_ptr<SetAccountsInCookieTask>
+ SetAccountsInCookieForPartition(
+ PartitionDelegate* partition_delegate,
+ const MultiloginParameters& parameters,
+ base::OnceCallback<void(SetAccountsInCookieResult)>
+ set_accounts_in_cookies_completed_callback) = 0;
+
// Triggers a ListAccounts fetch. Can be used in circumstances where clients
// know that the contents of the Gaia cookie might have changed.
virtual void TriggerCookieJarUpdate() = 0;
@@ -82,7 +123,9 @@ class AccountsCookieMutator {
#endif
// Remove all accounts from the Gaia cookie.
- virtual void LogOutAllAccounts(gaia::GaiaSource source) = 0;
+ virtual void LogOutAllAccounts(
+ gaia::GaiaSource source,
+ LogOutFromCookieCompletedCallback completion_callback) = 0;
private:
DISALLOW_COPY_AND_ASSIGN(AccountsCookieMutator);
diff --git a/chromium/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc b/chromium/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc
index 42dc77d50d0..f12dcec9c08 100644
--- a/chromium/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc
+++ b/chromium/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc
@@ -26,6 +26,7 @@
#include "google_apis/gaia/gaia_constants.h"
#include "google_apis/gaia/gaia_urls.h"
#include "google_apis/gaia/google_service_auth_error.h"
+#include "services/network/test/test_cookie_manager.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -54,12 +55,15 @@ enum class AccountsCookiesMutatorAction {
kTriggerCookieJarUpdateNoAccounts,
kTriggerCookieJarUpdateOneAccount,
kTriggerOnCookieChangeNoAccounts,
+ kLogOutFromCookie,
};
} // namespace
namespace signin {
-class AccountsCookieMutatorTest : public testing::Test {
+class AccountsCookieMutatorTest
+ : public testing::Test,
+ public AccountsCookieMutator::PartitionDelegate {
public:
const CoreAccountId kTestUnavailableAccountId;
const CoreAccountId kTestOtherUnavailableAccountId;
@@ -128,6 +132,13 @@ class AccountsCookieMutatorTest : public testing::Test {
case AccountsCookiesMutatorAction::kTriggerOnCookieChangeNoAccounts:
SetListAccountsResponseNoAccounts(GetTestURLLoaderFactory());
break;
+ case AccountsCookiesMutatorAction::kLogOutFromCookie:
+ GetTestURLLoaderFactory()->AddResponse(
+ GaiaUrls::GetInstance()
+ ->LogOutURLWithSource(GaiaConstants::kChromeSource)
+ .spec(),
+ std::string(), net::HTTP_OK);
+ break;
}
}
@@ -146,10 +157,22 @@ class AccountsCookieMutatorTest : public testing::Test {
}
private:
+ // AccountsCookieMutator::PartitionDelegate
+ std::unique_ptr<GaiaAuthFetcher> CreateGaiaAuthFetcherForPartition(
+ GaiaAuthConsumer* consumer) override {
+ return test_signin_client_.CreateGaiaAuthFetcher(consumer,
+ gaia::GaiaSource::kChrome);
+ }
+
+ network::mojom::CookieManager* GetCookieManagerForPartition() override {
+ return &cookie_manager_for_partition_;
+ }
+
base::test::TaskEnvironment task_environment_;
sync_preferences::TestingPrefServiceSyncable prefs_;
TestSigninClient test_signin_client_;
IdentityTestEnvironment identity_test_env_;
+ network::TestCookieManager cookie_manager_for_partition_;
DISALLOW_COPY_AND_ASSIGN(AccountsCookieMutatorTest);
};
@@ -360,6 +383,64 @@ TEST_F(AccountsCookieMutatorTest, SetAccountsInCookie_AllExistingAccounts) {
run_loop.Run();
}
+// Test that trying to set a list of accounts in a partitionned cookie jar where
+// all of those accounts have refresh tokens in IdentityManager results in them
+// being successfully set.
+TEST_F(AccountsCookieMutatorTest,
+ SetAccountsInCookieForPartition_AllExistingAccounts) {
+ PrepareURLLoaderResponsesForAction(
+ AccountsCookiesMutatorAction::kSetAccountsInCookie);
+ PrepareURLLoaderResponsesForAction(
+ AccountsCookiesMutatorAction::kTriggerCookieJarUpdateNoAccounts);
+
+ CoreAccountId account_id = AddAcountWithRefreshToken(kTestAccountEmail);
+ CoreAccountId other_account_id =
+ AddAcountWithRefreshToken(kTestOtherAccountEmail);
+ base::RunLoop run_loop;
+ MultiloginParameters parameters = {
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
+ {account_id, other_account_id}};
+ std::unique_ptr<AccountsCookieMutator::SetAccountsInCookieTask> task =
+ accounts_cookie_mutator()->SetAccountsInCookieForPartition(
+ this, parameters,
+ base::BindOnce(
+ [](base::OnceClosure quit_closure,
+ SetAccountsInCookieResult result) {
+ EXPECT_EQ(result, SetAccountsInCookieResult::kSuccess);
+ std::move(quit_closure).Run();
+ },
+ run_loop.QuitClosure()));
+
+ identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+ account_id, kTestAccessToken,
+ base::Time::Now() + base::TimeDelta::FromHours(1));
+ identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+ other_account_id, kTestAccessToken,
+ base::Time::Now() + base::TimeDelta::FromHours(1));
+
+ run_loop.Run();
+}
+
+// Test that setting accounts in a partition can be cancelled.
+TEST_F(AccountsCookieMutatorTest, SetAccountsInCookieForPartition_Cancel) {
+ PrepareURLLoaderResponsesForAction(
+ AccountsCookiesMutatorAction::kSetAccountsInCookie);
+ PrepareURLLoaderResponsesForAction(
+ AccountsCookiesMutatorAction::kTriggerCookieJarUpdateNoAccounts);
+
+ CoreAccountId account_id = AddAcountWithRefreshToken(kTestAccountEmail);
+ CoreAccountId other_account_id =
+ AddAcountWithRefreshToken(kTestOtherAccountEmail);
+ MultiloginParameters parameters = {
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
+ {account_id, other_account_id}};
+ std::unique_ptr<AccountsCookieMutator::SetAccountsInCookieTask> task =
+ accounts_cookie_mutator()->SetAccountsInCookieForPartition(
+ this, parameters,
+ base::BindOnce([](SetAccountsInCookieResult) { NOTREACHED(); }));
+ task.reset();
+}
+
// Test triggering the update of a cookie jar with no accounts works.
TEST_F(AccountsCookieMutatorTest, TriggerCookieJarUpdate_NoListedAccounts) {
PrepareURLLoaderResponsesForAction(
@@ -432,19 +513,19 @@ TEST_F(AccountsCookieMutatorTest, ForceTriggerOnCookieChange) {
// Test that trying to log out all sessions generates the right network request.
TEST_F(AccountsCookieMutatorTest, LogOutAllAccounts) {
+ PrepareURLLoaderResponsesForAction(
+ AccountsCookiesMutatorAction::kLogOutFromCookie);
+
base::RunLoop run_loop;
- GetTestURLLoaderFactory()->SetInterceptor(base::BindRepeating(
- [](base::OnceClosure quit_closure,
- const network::ResourceRequest& request) {
- EXPECT_EQ(request.url.spec(),
- GaiaUrls::GetInstance()
- ->LogOutURLWithSource(GaiaConstants::kChromeSource)
- .spec());
- std::move(quit_closure).Run();
- },
- run_loop.QuitClosure()));
-
- accounts_cookie_mutator()->LogOutAllAccounts(gaia::GaiaSource::kChrome);
+ accounts_cookie_mutator()->LogOutAllAccounts(
+ gaia::GaiaSource::kChrome, base::BindOnce(
+ [](base::OnceClosure quit_closure,
+ const GoogleServiceAuthError& error) {
+ EXPECT_EQ(error.state(),
+ GoogleServiceAuthError::NONE);
+ std::move(quit_closure).Run();
+ },
+ run_loop.QuitClosure()));
run_loop.Run();
}
diff --git a/chromium/components/signin/public/identity_manager/android/BUILD.gn b/chromium/components/signin/public/identity_manager/android/BUILD.gn
deleted file mode 100644
index 48e7d17cf78..00000000000
--- a/chromium/components/signin/public/identity_manager/android/BUILD.gn
+++ /dev/null
@@ -1,45 +0,0 @@
-import("//build/config/android/rules.gni")
-
-android_library("java") {
- deps = [
- "//base:base_java",
- "//base:jni_java",
- "//components/signin/core/browser/android:java",
- "//net/android:net_java",
- "//third_party/android_deps:android_support_v4_java",
- "//third_party/android_deps:androidx_annotation_annotation_java",
- ]
-
- srcjar_deps = [
- "//components/signin/public/base:signin_metrics_enum_javagen",
- "//components/signin/public/identity_manager:identity_manager_enum_javagen",
- ]
-
- java_files = [
- "java/src/org/chromium/components/signin/identitymanager/CoreAccountId.java",
- "java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java",
- "java/src/org/chromium/components/signin/identitymanager/IdentityManager.java",
- "java/src/org/chromium/components/signin/identitymanager/IdentityMutator.java",
- "java/src/org/chromium/components/signin/identitymanager/OAuth2TokenService.java",
- ]
-
- annotation_processor_deps = [ "//base/android/jni_generator:jni_processor" ]
-}
-
-android_library("javatests") {
- testonly = true
- deps = [
- ":java",
- "//base:base_java",
- "//base:base_java_test_support",
- "//components/signin/core/browser/android:java",
- "//components/signin/core/browser/android:signin_java_test_support",
- "//third_party/android_deps:com_android_support_support_annotations_java",
- "//third_party/android_support_test_runner:rules_java",
- "//third_party/android_support_test_runner:runner_java",
- "//third_party/jsr-305:jsr_305_javalib",
- "//third_party/junit",
- ]
-
- java_files = [ "javatests/src/org/chromium/components/signin/identitymanager/OAuth2TokenServiceTest.java" ]
-}
diff --git a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java b/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java
deleted file mode 100644
index d72e0b52aaa..00000000000
--- a/chromium/components/signin/public/identity_manager/android/java/src/org/chromium/components/signin/identitymanager/CoreAccountInfo.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2019 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.
-
-package org.chromium.components.signin.identitymanager;
-
-import android.accounts.Account;
-
-import androidx.annotation.NonNull;
-
-import org.chromium.base.annotations.CalledByNative;
-import org.chromium.components.signin.AccountManagerFacade;
-
-/**
- * Structure storing the core information about a Google account that is always known. The {@link
- * CoreAccountInfo} for a given user is almost always the same but it may change in some rare cases.
- * For example, the {@link android.accounts.Account} will change if a user changes email.
- *
- * This class has a native counterpart called CoreAccountInfo. There are several differences between
- * these two classes:
- * - Android class additionally exposes {@link android.accounts.Account} object for interactions
- * with the system.
- * - Android class has the "account name" whereas the native class has "email". This is the same
- * string, only the naming in different.
- */
-public class CoreAccountInfo {
- private final CoreAccountId mId;
- private final Account mAccount;
- private final String mGaiaId;
-
- /**
- * Constructs a CoreAccountInfo with the provided parameters
- * @param id A CoreAccountId associated with the account, equal to either account.name or
- * gaiaId.
- * @param account Android account.
- * @param gaiaId String representation of the Gaia ID. Must not be an email address.
- */
- public CoreAccountInfo(
- @NonNull CoreAccountId id, @NonNull Account account, @NonNull String gaiaId) {
- assert id != null;
- assert account != null;
- assert gaiaId != null;
- assert !gaiaId.contains("@");
-
- mId = id;
- mAccount = account;
- mGaiaId = gaiaId;
- }
-
- @CalledByNative
- private CoreAccountInfo(
- @NonNull CoreAccountId id, @NonNull String name, @NonNull String gaiaId) {
- assert id != null;
- assert name != null;
- assert gaiaId != null;
- assert !gaiaId.contains("@");
-
- mId = id;
- mAccount = AccountManagerFacade.createAccountFromName(name);
- mGaiaId = gaiaId;
- }
-
- /**
- * Returns a unique identifier of the current account.
- */
- @CalledByNative
- public CoreAccountId getId() {
- return mId;
- }
-
- /**
- * Returns a name of the current account.
- */
- @CalledByNative
- public String getName() {
- return mAccount.name;
- }
-
- /**
- * Returns the string representation of the Gaia ID
- */
- @CalledByNative
- public String getGaiaId() {
- return mGaiaId;
- }
-
- /**
- * Returns {@link android.accounts.Account} object holding a name of the current account.
- */
- public Account getAccount() {
- return mAccount;
- }
-
- @Override
- public String toString() {
- return String.format("CoreAccountInfo{id[%s], name[%s]}", getId(), getName());
- }
-
- @Override
- public int hashCode() {
- return 31 * mId.hashCode() + mAccount.hashCode();
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof CoreAccountInfo)) return false;
- CoreAccountInfo other = (CoreAccountInfo) obj;
- return mId.equals(other.mId) && mAccount.equals(other.mAccount);
- }
-}
diff --git a/chromium/components/signin/public/identity_manager/consent_level.h b/chromium/components/signin/public/identity_manager/consent_level.h
new file mode 100644
index 00000000000..fc452fe1ce5
--- /dev/null
+++ b/chromium/components/signin/public/identity_manager/consent_level.h
@@ -0,0 +1,26 @@
+// Copyright 2020 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 COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_CONSENT_LEVEL_H_
+#define COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_CONSENT_LEVEL_H_
+
+namespace signin {
+
+// ConsentLevel is the required level of user consent for an identity operation
+// (for example to fetch an OAuth2 access token).
+enum class ConsentLevel {
+ // No specific consent required. In particular, browser sync consent is not
+ // required. Operations are allowed if the user is signed in to Chrome. See
+ // "unconsented primary account" in ./README.md.
+ kNotRequired,
+
+ // Chrome browser sync consent is required. Historically (before DICE and
+ // Project Butter) most operations implicitly required this consent. See
+ // "primary account" in ./README.md.
+ kSync
+};
+
+} // namespace signin
+
+#endif // COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_CONSENT_LEVEL_H_
diff --git a/chromium/components/signin/public/identity_manager/identity_manager.cc b/chromium/components/signin/public/identity_manager/identity_manager.cc
index 2f68233f856..47d00212a9a 100644
--- a/chromium/components/signin/public/identity_manager/identity_manager.cc
+++ b/chromium/components/signin/public/identity_manager/identity_manager.cc
@@ -23,8 +23,8 @@
#if defined(OS_ANDROID)
#include "base/android/jni_string.h"
-#include "components/signin/internal/identity_manager/android/jni_headers/IdentityManager_jni.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h"
+#include "components/signin/public/android/jni_headers/IdentityManager_jni.h"
#endif
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
@@ -111,35 +111,30 @@ void IdentityManager::RemoveObserver(Observer* observer) {
}
// TODO(862619) change return type to base::Optional<CoreAccountInfo>
-CoreAccountInfo IdentityManager::GetPrimaryAccountInfo() const {
+CoreAccountInfo IdentityManager::GetPrimaryAccountInfo(
+ ConsentLevel consent) const {
+ if (consent == ConsentLevel::kNotRequired) {
+ return primary_account_manager_->GetUnconsentedPrimaryAccountInfo();
+ }
return primary_account_manager_->GetAuthenticatedAccountInfo();
}
-CoreAccountId IdentityManager::GetPrimaryAccountId() const {
- return GetPrimaryAccountInfo().account_id;
+CoreAccountId IdentityManager::GetPrimaryAccountId(ConsentLevel consent) const {
+ return GetPrimaryAccountInfo(consent).account_id;
}
-bool IdentityManager::HasPrimaryAccount() const {
+bool IdentityManager::HasPrimaryAccount(ConsentLevel consent) const {
+ if (consent == ConsentLevel::kNotRequired) {
+ return primary_account_manager_->HasUnconsentedPrimaryAccount();
+ }
return primary_account_manager_->IsAuthenticated();
}
-CoreAccountId IdentityManager::GetUnconsentedPrimaryAccountId() const {
- return GetUnconsentedPrimaryAccountInfo().account_id;
-}
-
-CoreAccountInfo IdentityManager::GetUnconsentedPrimaryAccountInfo() const {
- return primary_account_manager_->GetUnconsentedPrimaryAccountInfo();
-}
-
-bool IdentityManager::HasUnconsentedPrimaryAccount() const {
- return primary_account_manager_->HasUnconsentedPrimaryAccount();
-}
-
std::unique_ptr<AccessTokenFetcher>
IdentityManager::CreateAccessTokenFetcherForAccount(
const CoreAccountId& account_id,
const std::string& oauth_consumer_name,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
AccessTokenFetcher::TokenCallback callback,
AccessTokenFetcher::Mode mode) {
return std::make_unique<AccessTokenFetcher>(account_id, oauth_consumer_name,
@@ -152,7 +147,7 @@ IdentityManager::CreateAccessTokenFetcherForAccount(
const CoreAccountId& account_id,
const std::string& oauth_consumer_name,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
AccessTokenFetcher::TokenCallback callback,
AccessTokenFetcher::Mode mode) {
return std::make_unique<AccessTokenFetcher>(
@@ -166,7 +161,7 @@ IdentityManager::CreateAccessTokenFetcherForClient(
const std::string& client_id,
const std::string& client_secret,
const std::string& oauth_consumer_name,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
AccessTokenFetcher::TokenCallback callback,
AccessTokenFetcher::Mode mode) {
return std::make_unique<AccessTokenFetcher>(
@@ -176,7 +171,7 @@ IdentityManager::CreateAccessTokenFetcherForClient(
void IdentityManager::RemoveAccessTokenFromCache(
const CoreAccountId& account_id,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
const std::string& access_token) {
token_service_->InvalidateAccessToken(account_id, scopes, access_token);
}
@@ -400,10 +395,6 @@ void IdentityManager::ForceRefreshOfExtendedAccountInfo(
account_fetcher_service_->ForceRefreshOfAccountInfo(account_id);
}
-bool IdentityManager::HasPrimaryAccount(JNIEnv* env) const {
- return HasPrimaryAccount();
-}
-
base::android::ScopedJavaLocalRef<jobject>
IdentityManager::GetPrimaryAccountInfo(JNIEnv* env) const {
if (HasPrimaryAccount())
@@ -411,13 +402,6 @@ IdentityManager::GetPrimaryAccountInfo(JNIEnv* env) const {
return nullptr;
}
-base::android::ScopedJavaLocalRef<jobject> IdentityManager::GetPrimaryAccountId(
- JNIEnv* env) const {
- if (HasPrimaryAccount())
- return ConvertToJavaCoreAccountId(env, GetPrimaryAccountId());
- return nullptr;
-}
-
base::android::ScopedJavaLocalRef<jobject> IdentityManager::
FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
JNIEnv* env,
@@ -436,8 +420,7 @@ IdentityManager::GetAccountsWithRefreshTokens(JNIEnv* env) const {
base::android::ScopedJavaLocalRef<jclass> coreaccountinfo_clazz =
base::android::GetClass(
- env,
- "org/chromium/components/signin/identitymanager/CoreAccountInfo");
+ env, "org/chromium/components/signin/base/CoreAccountInfo");
base::android::ScopedJavaLocalRef<jobjectArray> array(
env, env->NewObjectArray(accounts.size(), coreaccountinfo_clazz.obj(),
nullptr));
@@ -501,8 +484,13 @@ IdentityManager::ComputeUnconsentedPrimaryAccountInfo() const {
if (HasPrimaryAccount())
return GetPrimaryAccountInfo();
-#if defined(OS_CHROMEOS) || defined(OS_IOS) || defined(OS_ANDROID)
- // On ChromeOS and on mobile platforms, we support only the primary account as
+#if defined(OS_CHROMEOS)
+ // Chrome OS directly sets either the primary account or the unconsented
+ // primary account during login. The user is not allowed to sign out, so
+ // keep the value set at login (don't reset).
+ return base::nullopt;
+#elif defined(OS_IOS) || defined(OS_ANDROID)
+ // On iOS and Android platforms, we support only the primary account as
// the unconsented primary account. By this early return, we avoid an extra
// request to GAIA that lists cookie accounts.
return CoreAccountInfo();
@@ -521,12 +509,17 @@ IdentityManager::ComputeUnconsentedPrimaryAccountInfo() const {
// If cookies or tokens are not loaded, it is not possible to fully compute
// the unconsented primary account. However, if the current unconsented
// primary account is no longer valid, it has to be removed.
- CoreAccountId current_account = GetUnconsentedPrimaryAccountId();
+ CoreAccountId current_account =
+ GetPrimaryAccountId(ConsentLevel::kNotRequired);
if (!current_account.empty()) {
if (AreRefreshTokensLoaded() &&
!HasAccountWithRefreshToken(current_account)) {
return CoreAccountInfo();
}
+ if (!AreRefreshTokensLoaded() &&
+ unconsented_primary_account_revoked_during_load_) {
+ return CoreAccountInfo();
+ }
if (cookie_info.accounts_are_fresh &&
cookie_accounts[0].id != current_account) {
return CoreAccountInfo();
@@ -546,7 +539,6 @@ IdentityManager::ComputeUnconsentedPrimaryAccountInfo() const {
void IdentityManager::GoogleSigninSucceeded(
const CoreAccountInfo& account_info) {
- UpdateUnconsentedPrimaryAccount();
for (auto& observer : observer_list_) {
observer.OnPrimaryAccountSet(account_info);
}
@@ -566,10 +558,15 @@ void IdentityManager::UnconsentedPrimaryAccountChanged(
observer.OnUnconsentedPrimaryAccountChanged(account_info);
}
-#if !defined(OS_CHROMEOS)
void IdentityManager::GoogleSignedOut(const CoreAccountInfo& account_info) {
DCHECK(!HasPrimaryAccount());
DCHECK(!account_info.IsEmpty());
+ // This is needed for the case where the user chooses to start syncing
+ // with an account that is different then the unconsented primary account
+ // (not the first in cookies) but then cancel. In that case, the tokens stay
+ // the same. In all the other cases, either the token will be revoked which
+ // will trigger an update for the unconsented primary account or the
+ // primary account stays the same but the sync consent is revoked.
UpdateUnconsentedPrimaryAccount();
for (auto& observer : observer_list_) {
observer.OnPrimaryAccountCleared(account_info);
@@ -583,7 +580,6 @@ void IdentityManager::GoogleSignedOut(const CoreAccountInfo& account_info) {
}
#endif
}
-#endif // !defined(OS_CHROMEOS)
void IdentityManager::OnRefreshTokenAvailable(const CoreAccountId& account_id) {
UpdateUnconsentedPrimaryAccount();
@@ -596,6 +592,12 @@ void IdentityManager::OnRefreshTokenAvailable(const CoreAccountId& account_id) {
}
void IdentityManager::OnRefreshTokenRevoked(const CoreAccountId& account_id) {
+ if (!AreRefreshTokensLoaded() &&
+ HasPrimaryAccount(ConsentLevel::kNotRequired) &&
+ account_id == GetPrimaryAccountId(ConsentLevel::kNotRequired)) {
+ unconsented_primary_account_revoked_during_load_ = true;
+ }
+
UpdateUnconsentedPrimaryAccount();
for (auto& observer : observer_list_) {
observer.OnRefreshTokenRemovedForAccount(account_id);
@@ -647,7 +649,7 @@ void IdentityManager::OnGaiaCookieDeletedByUserAction() {
void IdentityManager::OnAccessTokenRequested(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes) {
+ const ScopeSet& scopes) {
for (auto& observer : diagnostics_observer_list_) {
observer.OnAccessTokenRequested(account_id, consumer_id, scopes);
}
@@ -656,7 +658,7 @@ void IdentityManager::OnAccessTokenRequested(const CoreAccountId& account_id,
void IdentityManager::OnFetchAccessTokenComplete(
const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
GoogleServiceAuthError error,
base::Time expiration_time) {
for (auto& observer : diagnostics_observer_list_)
@@ -665,7 +667,7 @@ void IdentityManager::OnFetchAccessTokenComplete(
}
void IdentityManager::OnAccessTokenRemoved(const CoreAccountId& account_id,
- const identity::ScopeSet& scopes) {
+ const ScopeSet& scopes) {
for (auto& observer : diagnostics_observer_list_)
observer.OnAccessTokenRemovedFromCache(account_id, scopes);
}
@@ -691,7 +693,6 @@ void IdentityManager::OnAccountUpdated(const AccountInfo& info) {
const CoreAccountId primary_account_id = GetPrimaryAccountId();
if (primary_account_id == info.account_id) {
primary_account_manager_->UpdateAuthenticatedAccountInfo();
- UpdateUnconsentedPrimaryAccount();
}
}
@@ -701,7 +702,6 @@ void IdentityManager::OnAccountUpdated(const AccountInfo& info) {
}
void IdentityManager::OnAccountRemoved(const AccountInfo& info) {
- UpdateUnconsentedPrimaryAccount();
for (auto& observer : observer_list_)
observer.OnExtendedAccountInfoRemoved(info);
}
diff --git a/chromium/components/signin/public/identity_manager/identity_manager.h b/chromium/components/signin/public/identity_manager/identity_manager.h
index f4576e21eb0..b6a365f0195 100644
--- a/chromium/components/signin/public/identity_manager/identity_manager.h
+++ b/chromium/components/signin/public/identity_manager/identity_manager.h
@@ -18,10 +18,11 @@
#include "components/signin/internal/identity_manager/profile_oauth2_token_service_observer.h"
#include "components/signin/public/identity_manager/access_token_fetcher.h"
#include "components/signin/public/identity_manager/account_info.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_mutator.h"
+#include "components/signin/public/identity_manager/scope_set.h"
#include "components/signin/public/identity_manager/ubertoken_fetcher.h"
#include "google_apis/gaia/oauth2_access_token_manager.h"
-#include "services/identity/public/cpp/scope_set.h"
#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
@@ -161,35 +162,31 @@ class IdentityManager : public KeyedService,
void RemoveObserver(Observer* observer);
// Provides access to the core information of the user's primary account.
+ // The primary account may or may not be blessed with the sync consent.
// Returns an empty struct if no such info is available, either because there
- // is no primary account yet or because the user signed out.
- CoreAccountInfo GetPrimaryAccountInfo() const;
+ // is no primary account yet or because the user signed out or the |consent|
+ // level required |ConsentLevel::kSync| was not granted.
+ // Returns a non-empty struct if the primary account exists and was granted
+ // the required consent level.
+ // TODO(1046746): Update (./README.md).
+ CoreAccountInfo GetPrimaryAccountInfo(
+ ConsentLevel consent = ConsentLevel::kSync) const;
// Provides access to the account ID of the user's primary account. Simple
// convenience wrapper over GetPrimaryAccountInfo().account_id.
- CoreAccountId GetPrimaryAccountId() const;
+ CoreAccountId GetPrimaryAccountId(
+ ConsentLevel consent = ConsentLevel::kSync) const;
- // Returns whether the user's primary account is available.
- bool HasPrimaryAccount() const;
-
- // Provides access to the core information of the user's unconsented primary
- // account (see ./README.md). Returns an empty info, if there is no such
- // account.
- CoreAccountInfo GetUnconsentedPrimaryAccountInfo() const;
-
- // Provides access to the account ID of the user's unconsented primary
- // account (see ./README.md). Returns an empty id if there is no such account.
- CoreAccountId GetUnconsentedPrimaryAccountId() const;
-
- // Returns whether the user's unconsented primary account (see ./README.md) is
- // available.
- bool HasUnconsentedPrimaryAccount() const;
+ // Returns whether the user's primary account is available. If consent is
+ // |ConsentLevel::kSyn| then true implies that the user has blessed this
+ // account for sync.
+ bool HasPrimaryAccount(ConsentLevel consent = ConsentLevel::kSync) const;
// Creates an AccessTokenFetcher given the passed-in information.
std::unique_ptr<AccessTokenFetcher> CreateAccessTokenFetcherForAccount(
const CoreAccountId& account_id,
const std::string& oauth_consumer_name,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
AccessTokenFetcher::TokenCallback callback,
AccessTokenFetcher::Mode mode) WARN_UNUSED_RESULT;
@@ -199,7 +196,7 @@ class IdentityManager : public KeyedService,
const CoreAccountId& account_id,
const std::string& oauth_consumer_name,
scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
AccessTokenFetcher::TokenCallback callback,
AccessTokenFetcher::Mode mode) WARN_UNUSED_RESULT;
@@ -211,7 +208,7 @@ class IdentityManager : public KeyedService,
const std::string& client_id,
const std::string& client_secret,
const std::string& oauth_consumer_name,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
AccessTokenFetcher::TokenCallback callback,
AccessTokenFetcher::Mode mode) WARN_UNUSED_RESULT;
@@ -220,7 +217,7 @@ class IdentityManager : public KeyedService,
// request for |account_id| and |scopes| will fetch a new token from the
// network. Otherwise, is a no-op.
void RemoveAccessTokenFromCache(const CoreAccountId& account_id,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
const std::string& access_token);
// Provides the information of all accounts that have refresh tokens.
@@ -335,20 +332,19 @@ class IdentityManager : public KeyedService,
// Called when receiving request for access token.
virtual void OnAccessTokenRequested(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes) {}
+ const ScopeSet& scopes) {}
// Called when an access token request is completed. Contains diagnostic
// information about the access token request.
virtual void OnAccessTokenRequestCompleted(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
GoogleServiceAuthError error,
base::Time expiration_time) {}
// Called when an access token was removed.
- virtual void OnAccessTokenRemovedFromCache(
- const CoreAccountId& account_id,
- const identity::ScopeSet& scopes) {}
+ virtual void OnAccessTokenRemovedFromCache(const CoreAccountId& account_id,
+ const ScopeSet& scopes) {}
// Called when a new refresh token is available. Contains diagnostic
// information about the source of the operation.
@@ -465,6 +461,9 @@ class IdentityManager : public KeyedService,
// These test helpers need to use some of the private methods below.
friend CoreAccountInfo SetPrimaryAccount(IdentityManager* identity_manager,
const std::string& email);
+ friend CoreAccountInfo SetUnconsentedPrimaryAccount(
+ IdentityManager* identity_manager,
+ const std::string& email);
friend void SetRefreshTokenForPrimaryAccount(
IdentityManager* identity_manager,
const std::string& token_value);
@@ -496,6 +495,7 @@ class IdentityManager : public KeyedService,
AccountInfo account_info);
friend void SimulateAccountImageFetch(IdentityManager* identity_manager,
const CoreAccountId& account_id,
+ const std::string& image_url_with_size,
const gfx::Image& image);
friend void SetFreshnessOfAccountsInGaiaCookie(
IdentityManager* identity_manager,
@@ -608,9 +608,7 @@ class IdentityManager : public KeyedService,
void GoogleSigninSucceeded(const CoreAccountInfo& account_info) override;
void UnconsentedPrimaryAccountChanged(
const CoreAccountInfo& account_info) override;
-#if !defined(OS_CHROMEOS)
void GoogleSignedOut(const CoreAccountInfo& account_info) override;
-#endif
// ProfileOAuth2TokenServiceObserver:
void OnRefreshTokenAvailable(const CoreAccountId& account_id) override;
@@ -630,14 +628,14 @@ class IdentityManager : public KeyedService,
// OAuth2AccessTokenManager::DiagnosticsObserver
void OnAccessTokenRequested(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes) override;
+ const ScopeSet& scopes) override;
void OnFetchAccessTokenComplete(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
GoogleServiceAuthError error,
base::Time expiration_time) override;
void OnAccessTokenRemoved(const CoreAccountId& account_id,
- const identity::ScopeSet& scopes) override;
+ const ScopeSet& scopes) override;
// ProfileOAuth2TokenService callbacks:
void OnRefreshTokenAvailableFromSource(const CoreAccountId& account_id,
@@ -674,6 +672,8 @@ class IdentityManager : public KeyedService,
base::ObserverList<DiagnosticsObserver, true>::Unchecked
diagnostics_observer_list_;
+ bool unconsented_primary_account_revoked_during_load_ = false;
+
#if defined(OS_ANDROID)
// Java-side IdentityManager object.
base::android::ScopedJavaGlobalRef<jobject> java_identity_manager_;
diff --git a/chromium/components/signin/public/identity_manager/identity_manager_builder.cc b/chromium/components/signin/public/identity_manager/identity_manager_builder.cc
index da113643252..1e95cac5140 100644
--- a/chromium/components/signin/public/identity_manager/identity_manager_builder.cc
+++ b/chromium/components/signin/public/identity_manager/identity_manager_builder.cc
@@ -147,6 +147,7 @@ std::unique_ptr<IdentityManager> BuildIdentityManager(
token_service.get(), primary_account_manager.get());
auto accounts_cookie_mutator = std::make_unique<AccountsCookieMutatorImpl>(
+ params->signin_client, token_service.get(),
gaia_cookie_manager_service.get(), account_tracker_service.get());
auto diagnostics_provider = std::make_unique<DiagnosticsProviderImpl>(
diff --git a/chromium/components/signin/public/identity_manager/identity_manager_unittest.cc b/chromium/components/signin/public/identity_manager/identity_manager_unittest.cc
index a7c1c59673e..95d178947c9 100644
--- a/chromium/components/signin/public/identity_manager/identity_manager_unittest.cc
+++ b/chromium/components/signin/public/identity_manager/identity_manager_unittest.cc
@@ -34,9 +34,11 @@
#include "components/signin/public/identity_manager/access_token_info.h"
#include "components/signin/public/identity_manager/accounts_cookie_mutator.h"
#include "components/signin/public/identity_manager/accounts_mutator.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/device_accounts_synchronizer.h"
#include "components/signin/public/identity_manager/identity_test_utils.h"
#include "components/signin/public/identity_manager/primary_account_mutator.h"
+#include "components/signin/public/identity_manager/scope_set.h"
#include "components/signin/public/identity_manager/set_accounts_in_cookie_result.h"
#include "components/signin/public/identity_manager/test_identity_manager_observer.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
@@ -99,7 +101,7 @@ class CustomFakeOAuth2AccessTokenManager : public FakeOAuth2AccessTokenManager {
// OAuth2AccessTokenManager:
void InvalidateAccessTokenImpl(const CoreAccountId& account_id,
const std::string& client_id,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
const std::string& access_token) override {
if (on_access_token_invalidated_callback_) {
EXPECT_EQ(expected_account_id_to_invalidate_, account_id);
@@ -176,22 +178,18 @@ class TestIdentityManagerDiagnosticsObserver
const std::string& token_requestor_consumer_id() {
return token_requestor_consumer_id_;
}
- const identity::ScopeSet& token_requestor_scopes() {
- return token_requestor_scopes_;
- }
+ const ScopeSet& token_requestor_scopes() { return token_requestor_scopes_; }
const CoreAccountId& token_remover_account_id() {
return token_remover_account_id_;
}
- const identity::ScopeSet& token_remover_scopes() {
- return token_remover_scopes_;
- }
+ const ScopeSet& token_remover_scopes() { return token_remover_scopes_; }
const CoreAccountId& on_access_token_request_completed_account_id() {
return access_token_request_completed_account_id_;
}
const std::string& on_access_token_request_completed_consumer_id() {
return access_token_request_completed_consumer_id_;
}
- const identity::ScopeSet& on_access_token_request_completed_scopes() {
+ const ScopeSet& on_access_token_request_completed_scopes() {
return access_token_request_completed_scopes_;
}
const GoogleServiceAuthError& on_access_token_request_completed_error() {
@@ -202,7 +200,7 @@ class TestIdentityManagerDiagnosticsObserver
// IdentityManager::DiagnosticsObserver:
void OnAccessTokenRequested(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes) override {
+ const ScopeSet& scopes) override {
token_requestor_account_id_ = account_id;
token_requestor_consumer_id_ = consumer_id;
token_requestor_scopes_ = scopes;
@@ -211,16 +209,15 @@ class TestIdentityManagerDiagnosticsObserver
std::move(on_access_token_requested_callback_).Run();
}
- void OnAccessTokenRemovedFromCache(
- const CoreAccountId& account_id,
- const identity::ScopeSet& scopes) override {
+ void OnAccessTokenRemovedFromCache(const CoreAccountId& account_id,
+ const ScopeSet& scopes) override {
token_remover_account_id_ = account_id;
token_remover_scopes_ = scopes;
}
void OnAccessTokenRequestCompleted(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
GoogleServiceAuthError error,
base::Time expiration_time) override {
access_token_request_completed_account_id_ = account_id;
@@ -238,11 +235,11 @@ class TestIdentityManagerDiagnosticsObserver
CoreAccountId token_requestor_account_id_;
std::string token_requestor_consumer_id_;
CoreAccountId token_remover_account_id_;
- identity::ScopeSet token_requestor_scopes_;
- identity::ScopeSet token_remover_scopes_;
+ ScopeSet token_requestor_scopes_;
+ ScopeSet token_remover_scopes_;
CoreAccountId access_token_request_completed_account_id_;
std::string access_token_request_completed_consumer_id_;
- identity::ScopeSet access_token_request_completed_scopes_;
+ ScopeSet access_token_request_completed_scopes_;
GoogleServiceAuthError access_token_request_completed_error_;
};
@@ -356,7 +353,8 @@ class IdentityManagerTest : public testing::Test {
}
auto accounts_cookie_mutator = std::make_unique<AccountsCookieMutatorImpl>(
- gaia_cookie_manager_service.get(), account_tracker_service.get());
+ &signin_client_, token_service.get(), gaia_cookie_manager_service.get(),
+ account_tracker_service.get());
auto diagnostics_provider = std::make_unique<DiagnosticsProviderImpl>(
token_service.get(), gaia_cookie_manager_service.get());
@@ -430,8 +428,8 @@ TEST_F(IdentityManagerTest, PrimaryAccountInfoAtStartup) {
EXPECT_EQ(kTestEmail, primary_account_info.email);
// Primary account is by definition also unconsented primary account.
- EXPECT_EQ(primary_account_info,
- identity_manager()->GetUnconsentedPrimaryAccountInfo());
+ EXPECT_EQ(primary_account_info, identity_manager()->GetPrimaryAccountInfo(
+ ConsentLevel::kNotRequired));
// There is no guarantee that this will be notified via callback on startup.
}
@@ -460,15 +458,15 @@ TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSignin) {
EXPECT_EQ(kTestGaiaId, primary_account_info.gaia);
EXPECT_EQ(kTestEmail, primary_account_info.email);
- EXPECT_EQ(primary_account_info,
- identity_manager()->GetUnconsentedPrimaryAccountInfo());
+ EXPECT_EQ(primary_account_info, identity_manager()->GetPrimaryAccountInfo(
+ ConsentLevel::kNotRequired));
CoreAccountId primary_account_id = identity_manager()->GetPrimaryAccountId();
EXPECT_EQ(primary_account_id, CoreAccountId(kTestGaiaId));
EXPECT_EQ(primary_account_id, primary_account_info.account_id);
- EXPECT_EQ(primary_account_id,
- identity_manager()->GetUnconsentedPrimaryAccountId());
+ EXPECT_EQ(primary_account_id, identity_manager()->GetPrimaryAccountId(
+ signin::ConsentLevel::kNotRequired));
}
// Test that the user signing out results in firing of the IdentityManager
@@ -497,14 +495,14 @@ TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSigninAndSignout) {
identity_manager()->GetPrimaryAccountInfo();
EXPECT_EQ("", primary_account_info.gaia);
EXPECT_EQ("", primary_account_info.email);
- EXPECT_EQ(primary_account_info,
- identity_manager()->GetUnconsentedPrimaryAccountInfo());
+ EXPECT_EQ(primary_account_info, identity_manager()->GetPrimaryAccountInfo(
+ ConsentLevel::kNotRequired));
CoreAccountId primary_account_id = identity_manager()->GetPrimaryAccountId();
EXPECT_TRUE(primary_account_id.empty());
EXPECT_EQ(primary_account_id, primary_account_info.account_id);
- EXPECT_EQ(primary_account_id,
- identity_manager()->GetUnconsentedPrimaryAccountId());
+ EXPECT_EQ(primary_account_id, identity_manager()->GetPrimaryAccountId(
+ signin::ConsentLevel::kNotRequired));
}
// Test that the primary account's core info remains tracked by the
@@ -528,32 +526,35 @@ TEST_F(IdentityManagerTest,
EXPECT_EQ(kTestGaiaId, primary_account_info.gaia);
EXPECT_EQ(kTestEmail, primary_account_info.email);
EXPECT_EQ(CoreAccountId(kTestGaiaId), primary_account_info.account_id);
- EXPECT_EQ(primary_account_info,
- identity_manager()->GetUnconsentedPrimaryAccountInfo());
+ EXPECT_EQ(primary_account_info, identity_manager()->GetPrimaryAccountInfo(
+ ConsentLevel::kNotRequired));
CoreAccountId primary_account_id = identity_manager()->GetPrimaryAccountId();
EXPECT_EQ(primary_account_id, CoreAccountId(kTestGaiaId));
- EXPECT_EQ(primary_account_id,
- identity_manager()->GetUnconsentedPrimaryAccountId());
+ EXPECT_EQ(primary_account_id, identity_manager()->GetPrimaryAccountId(
+ ConsentLevel::kNotRequired));
}
#endif // !defined(OS_CHROMEOS)
TEST_F(IdentityManagerTest, HasPrimaryAccount) {
EXPECT_TRUE(identity_manager()->HasPrimaryAccount());
- EXPECT_TRUE(identity_manager()->HasUnconsentedPrimaryAccount());
+ EXPECT_TRUE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
// Removing the account from the AccountTrackerService should not cause
// IdentityManager to think that there is no longer a primary account.
account_tracker()->RemoveAccount(identity_manager()->GetPrimaryAccountId());
EXPECT_TRUE(identity_manager()->HasPrimaryAccount());
- EXPECT_TRUE(identity_manager()->HasUnconsentedPrimaryAccount());
+ EXPECT_TRUE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
#if !defined(OS_CHROMEOS)
// Signing out should cause IdentityManager to recognize that there is no
// longer a primary account.
ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);
EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
- EXPECT_FALSE(identity_manager()->HasUnconsentedPrimaryAccount());
+ EXPECT_FALSE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
EXPECT_FALSE(identity_manager_observer()
->PrimaryAccountFromClearedCallback()
.IsEmpty());
@@ -791,7 +792,9 @@ TEST_F(IdentityManagerTest,
// The user still has a primary account.
EXPECT_EQ(identity_manager()->GetPrimaryAccountInfo().email, kTestEmail);
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo().email,
+ EXPECT_EQ(identity_manager()
+ ->GetPrimaryAccountInfo(ConsentLevel::kNotRequired)
+ .email,
kTestEmail);
// Add a refresh token for the primary account and check that it
@@ -814,7 +817,9 @@ TEST_F(IdentityManagerTest,
EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());
EXPECT_EQ(identity_manager()->GetPrimaryAccountInfo().email, kTestEmail);
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo().email,
+ EXPECT_EQ(identity_manager()
+ ->GetPrimaryAccountInfo(ConsentLevel::kNotRequired)
+ .email,
kTestEmail);
// Remove the token for the primary account and check that account2 is still
@@ -832,7 +837,9 @@ TEST_F(IdentityManagerTest,
EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
// The user still has a primary account.
EXPECT_EQ(identity_manager()->GetPrimaryAccountInfo().email, kTestEmail);
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo().email,
+ EXPECT_EQ(identity_manager()
+ ->GetPrimaryAccountInfo(ConsentLevel::kNotRequired)
+ .email,
kTestEmail);
}
@@ -840,7 +847,8 @@ TEST_F(
IdentityManagerTest,
HasPrimaryAccountWithRefreshTokenInteractionBetweenPrimaryAndSecondaryAccounts) {
EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
- EXPECT_TRUE(identity_manager()->HasUnconsentedPrimaryAccount());
+ EXPECT_TRUE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
// Add a refresh token for a secondary account and check that it doesn't
// impact the above state.
@@ -850,28 +858,32 @@ TEST_F(
SetRefreshTokenForAccount(identity_manager(), account_id2);
EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
- EXPECT_TRUE(identity_manager()->HasUnconsentedPrimaryAccount());
+ EXPECT_TRUE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
// Add a refresh token for the primary account and check that it
// *does* impact the stsate of HasPrimaryAccountWithRefreshToken().
SetRefreshTokenForPrimaryAccount(identity_manager());
EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());
- EXPECT_TRUE(identity_manager()->HasUnconsentedPrimaryAccount());
+ EXPECT_TRUE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
// Remove the token for the secondary account and check that this doesn't flip
// the state.
RemoveRefreshTokenForAccount(identity_manager(), account_id2);
EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());
- EXPECT_TRUE(identity_manager()->HasUnconsentedPrimaryAccount());
+ EXPECT_TRUE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
// Remove the token for the primary account and check that this flips the
// state.
RemoveRefreshTokenForPrimaryAccount(identity_manager());
EXPECT_FALSE(identity_manager()->HasPrimaryAccountWithRefreshToken());
- EXPECT_TRUE(identity_manager()->HasUnconsentedPrimaryAccount());
+ EXPECT_TRUE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
}
TEST_F(
@@ -1364,8 +1376,9 @@ TEST_F(IdentityManagerTest, IdentityManagerReflectsUpdatedEmailAddress) {
primary_account_info = identity_manager()->GetPrimaryAccountInfo();
EXPECT_EQ(kTestGaiaId, primary_account_info.gaia);
EXPECT_EQ(kTestEmailWithPeriod, primary_account_info.email);
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo(),
- primary_account_info);
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ primary_account_info);
}
#endif
@@ -1508,8 +1521,9 @@ TEST_F(
identity_manager(), test_url_loader_factory(), kTestEmail2, kTestGaiaId2);
EXPECT_EQ(kTestEmail2, expected_account_info.email);
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo(),
- expected_account_info);
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ expected_account_info);
EXPECT_EQ(
identity_manager_observer()->UnconsentedPrimaryAccountFromCallback(),
expected_account_info);
@@ -1530,8 +1544,9 @@ TEST_F(
// This is still an unconsented primary account, even with invalid refresh
// token.
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo(),
- expected_account_info);
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ expected_account_info);
EXPECT_EQ(
identity_manager_observer()->UnconsentedPrimaryAccountFromCallback(),
expected_account_info);
@@ -1552,11 +1567,14 @@ TEST_F(
// With no refresh token, there is no unconsented primary account any more.
CoreAccountInfo empty_info;
- EXPECT_FALSE(identity_manager()->HasUnconsentedPrimaryAccount());
+ EXPECT_FALSE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
EXPECT_EQ(
identity_manager_observer()->UnconsentedPrimaryAccountFromCallback(),
empty_info);
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo(), empty_info);
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ empty_info);
}
TEST_F(IdentityManagerTest, UnconsentedPrimaryAccountNotChangedOnSignout) {
@@ -1570,8 +1588,8 @@ TEST_F(IdentityManagerTest, UnconsentedPrimaryAccountNotChangedOnSignout) {
{{account_info.email, account_info.gaia}});
SetRefreshTokenForAccount(identity_manager(), account_info.account_id,
"refresh-token");
- EXPECT_EQ(account_info,
- identity_manager()->GetUnconsentedPrimaryAccountInfo());
+ EXPECT_EQ(account_info, identity_manager()->GetPrimaryAccountInfo(
+ ConsentLevel::kNotRequired));
EXPECT_EQ(account_info, identity_manager()->GetPrimaryAccountInfo());
EXPECT_TRUE(identity_manager()->HasPrimaryAccountWithRefreshToken());
@@ -1594,8 +1612,8 @@ TEST_F(IdentityManagerTest, UnconsentedPrimaryAccountNotChangedOnSignout) {
ClearPrimaryAccountPolicy::KEEP_ALL_ACCOUNTS);
// Primary account is cleared, but unconsented account is not.
EXPECT_FALSE(identity_manager()->HasPrimaryAccount());
- EXPECT_EQ(account_info,
- identity_manager()->GetUnconsentedPrimaryAccountInfo());
+ EXPECT_EQ(account_info, identity_manager()->GetPrimaryAccountInfo(
+ ConsentLevel::kNotRequired));
// OnUnconsentedPrimaryAccountChanged was not fired.
EXPECT_FALSE(observer.called_);
}
@@ -1609,8 +1627,9 @@ TEST_F(IdentityManagerTest,
identity_manager(), test_url_loader_factory(), kTestEmail2, kTestGaiaId2);
EXPECT_EQ(kTestEmail2, account_info.email);
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo(),
- account_info);
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ account_info);
// Make the cookies stale and remove the account.
signin::SetFreshnessOfAccountsInGaiaCookie(identity_manager(), false);
@@ -1619,8 +1638,9 @@ TEST_F(IdentityManagerTest,
identity_manager()->GetAccountsInCookieJar();
ASSERT_FALSE(cookie_info.accounts_are_fresh);
// Unconsented account was removed.
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo(),
- CoreAccountInfo());
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ CoreAccountInfo());
}
TEST_F(IdentityManagerTest,
@@ -1637,8 +1657,9 @@ TEST_F(IdentityManagerTest,
{{main_account_info.email, main_account_info.gaia},
{secondary_account_info.email, secondary_account_info.gaia}});
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo(),
- main_account_info);
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ main_account_info);
// Make the cookies stale and remove the main account.
signin::SetFreshnessOfAccountsInGaiaCookie(identity_manager(), false);
@@ -1648,8 +1669,46 @@ TEST_F(IdentityManagerTest,
identity_manager()->GetAccountsInCookieJar();
ASSERT_FALSE(cookie_info.accounts_are_fresh);
// Unconsented account was removed.
- EXPECT_EQ(identity_manager()->GetUnconsentedPrimaryAccountInfo(),
- CoreAccountInfo());
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ CoreAccountInfo());
+}
+
+TEST_F(IdentityManagerTest, UnconsentedPrimaryAccountDuringLoad) {
+ ClearPrimaryAccount(identity_manager(), ClearPrimaryAccountPolicy::DEFAULT);
+ // Add two accounts with cookies.
+ AccountInfo main_account_info =
+ MakeAccountAvailable(identity_manager(), kTestEmail2);
+ AccountInfo secondary_account_info =
+ MakeAccountAvailable(identity_manager(), kTestEmail3);
+ SetCookieAccounts(
+ identity_manager(), test_url_loader_factory(),
+ {{main_account_info.email, main_account_info.gaia},
+ {secondary_account_info.email, secondary_account_info.gaia}});
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ main_account_info);
+
+ // Set the token service in "loading" mode.
+ token_service()->set_all_credentials_loaded_for_testing(false);
+
+ // Unconsented primary account is available while tokens are not loaded.
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ main_account_info);
+ // Revoking an unrelated token doesn't change the unconsented primary account.
+ token_service()->RevokeCredentials(secondary_account_info.account_id);
+ EXPECT_EQ(
+ identity_manager()->GetPrimaryAccountInfo(ConsentLevel::kNotRequired),
+ main_account_info);
+ // Revoke the unconsented primary account.
+ token_service()->RevokeCredentials(main_account_info.account_id);
+ EXPECT_FALSE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
+ // Finish the token load.
+ token_service()->set_all_credentials_loaded_for_testing(true);
+ EXPECT_FALSE(
+ identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
}
#endif
diff --git a/chromium/components/signin/public/identity_manager/identity_mutator.cc b/chromium/components/signin/public/identity_manager/identity_mutator.cc
index 66c235db0ae..aa53dd1c432 100644
--- a/chromium/components/signin/public/identity_manager/identity_mutator.cc
+++ b/chromium/components/signin/public/identity_manager/identity_mutator.cc
@@ -11,7 +11,7 @@
#if defined(OS_ANDROID)
#include "base/android/jni_string.h"
-#include "components/signin/internal/identity_manager/android/jni_headers/IdentityMutator_jni.h"
+#include "components/signin/public/android/jni_headers/IdentityMutator_jni.h"
#include "components/signin/public/identity_manager/account_info.h"
#endif
diff --git a/chromium/components/signin/public/identity_manager/identity_test_environment.cc b/chromium/components/signin/public/identity_manager/identity_test_environment.cc
index 088157de9d8..8c6065b6c06 100644
--- a/chromium/components/signin/public/identity_manager/identity_test_environment.cc
+++ b/chromium/components/signin/public/identity_manager/identity_test_environment.cc
@@ -25,6 +25,7 @@
#include "components/signin/internal/identity_manager/primary_account_policy_manager_impl.h"
#include "components/signin/public/base/test_signin_client.h"
#include "components/signin/public/identity_manager/accounts_mutator.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/device_accounts_synchronizer.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/identity_test_utils.h"
@@ -209,7 +210,8 @@ IdentityTestEnvironment::BuildIdentityManagerForTests(
token_service.get(), gaia_cookie_manager_service.get());
auto accounts_cookie_mutator = std::make_unique<AccountsCookieMutatorImpl>(
- gaia_cookie_manager_service.get(), account_tracker_service.get());
+ signin_client, token_service.get(), gaia_cookie_manager_service.get(),
+ account_tracker_service.get());
std::unique_ptr<DeviceAccountsSynchronizer> device_accounts_synchronizer;
#if defined(OS_IOS)
@@ -251,6 +253,11 @@ CoreAccountInfo IdentityTestEnvironment::SetPrimaryAccount(
return signin::SetPrimaryAccount(identity_manager(), email);
}
+CoreAccountInfo IdentityTestEnvironment::SetUnconsentedPrimaryAccount(
+ const std::string& email) {
+ return signin::SetUnconsentedPrimaryAccount(identity_manager(), email);
+}
+
void IdentityTestEnvironment::SetRefreshTokenForPrimaryAccount() {
signin::SetRefreshTokenForPrimaryAccount(identity_manager());
}
@@ -268,6 +275,31 @@ AccountInfo IdentityTestEnvironment::MakePrimaryAccountAvailable(
return signin::MakePrimaryAccountAvailable(identity_manager(), email);
}
+AccountInfo IdentityTestEnvironment::MakeUnconsentedPrimaryAccountAvailable(
+ const std::string& email) {
+ DCHECK(!identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
+#if defined(OS_CHROMEOS)
+ // Chrome OS sets the unconsented primary account during login and does not
+ // allow signout.
+ AccountInfo account_info = MakeAccountAvailable(email);
+ identity_manager()->GetPrimaryAccountMutator()->SetUnconsentedPrimaryAccount(
+ account_info.account_id);
+#elif defined(OS_IOS) || defined(OS_ANDROID)
+ // iOS and Android only support the primary account.
+ AccountInfo account_info = MakePrimaryAccountAvailable(email);
+#else
+ // Desktop platforms.
+ AccountInfo account_info =
+ MakeAccountAvailableWithCookies(email, GetTestGaiaIdForEmail(email));
+ base::RunLoop().RunUntilIdle();
+#endif
+ DCHECK(identity_manager()->HasPrimaryAccount(ConsentLevel::kNotRequired));
+ DCHECK_EQ(email, identity_manager()
+ ->GetPrimaryAccountInfo(ConsentLevel::kNotRequired)
+ .email);
+ return account_info;
+}
+
void IdentityTestEnvironment::ClearPrimaryAccount(
ClearPrimaryAccountPolicy policy) {
signin::ClearPrimaryAccount(identity_manager(), policy);
@@ -349,7 +381,7 @@ void IdentityTestEnvironment::
const std::string& token,
const base::Time& expiration,
const std::string& id_token,
- const identity::ScopeSet& scopes) {
+ const ScopeSet& scopes) {
WaitForAccessTokenRequestIfNecessary(base::nullopt);
fake_token_service()->IssueTokenForScope(
scopes,
@@ -390,7 +422,7 @@ IdentityTestEnvironment::AccessTokenRequestState::operator=(
void IdentityTestEnvironment::OnAccessTokenRequested(
const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes) {
+ const ScopeSet& scopes) {
// Post a task to handle this access token request in order to support the
// case where the access token request is handled synchronously in the
// production code, in which case this callback could be coming in ahead
diff --git a/chromium/components/signin/public/identity_manager/identity_test_environment.h b/chromium/components/signin/public/identity_manager/identity_test_environment.h
index 5c8773399f1..e6487ed8341 100644
--- a/chromium/components/signin/public/identity_manager/identity_test_environment.h
+++ b/chromium/components/signin/public/identity_manager/identity_test_environment.h
@@ -14,6 +14,7 @@
#include "components/signin/public/base/signin_client.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/identity_test_utils.h"
+#include "components/signin/public/identity_manager/scope_set.h"
class FakeProfileOAuth2TokenService;
class IdentityTestEnvironmentProfileAdaptor;
@@ -90,6 +91,10 @@ class IdentityTestEnvironment : public IdentityManager::DiagnosticsObserver {
// CoreAccountInfo of the newly-set account.
CoreAccountInfo SetPrimaryAccount(const std::string& email);
+ // As above, but adds an "unconsented" primary account. See ./README.md for
+ // the distinction between primary and unconsented primary accounts.
+ CoreAccountInfo SetUnconsentedPrimaryAccount(const std::string& email);
+
// Sets a refresh token for the primary account (which must already be set).
// Before updating the refresh token, blocks until refresh tokens are loaded.
// After updating the token, blocks until the update is processed by
@@ -104,6 +109,8 @@ class IdentityTestEnvironment : public IdentityManager::DiagnosticsObserver {
// Removes any refresh token for the primary account, if present. Blocks until
// the refresh token is removed.
+ // NOTE: Call EnableRemovalOfExtendedAccountInfo() before this if the test
+ // expects IdentityManager::Observer::OnExtendedAccountInfoRemoved() to fire.
void RemoveRefreshTokenForPrimaryAccount();
// Makes the primary account available for the given email address, generating
@@ -114,6 +121,11 @@ class IdentityTestEnvironment : public IdentityManager::DiagnosticsObserver {
// Returns the AccountInfo of the newly-available account.
AccountInfo MakePrimaryAccountAvailable(const std::string& email);
+ // Like MakeAccountAvailable(), but adds an "unconsented" primary account. See
+ // ./README.md for the distinction between primary account and unconsented
+ // primary account.
+ AccountInfo MakeUnconsentedPrimaryAccountAvailable(const std::string& email);
+
// Combination of MakeAccountAvailable() and SetCookieAccounts() for a single
// account. It makes an account available for the given email address, and
// GAIA ID, setting the cookies and the refresh token that correspond uniquely
@@ -152,6 +164,8 @@ class IdentityTestEnvironment : public IdentityManager::DiagnosticsObserver {
// Removes any refresh token that is present for the given account. Blocks
// until the refresh token is removed.
// NOTE: See disclaimer at top of file re: direct usage.
+ // NOTE: Call EnableRemovalOfExtendedAccountInfo() before this if the test
+ // expects IdentityManager::Observer::OnExtendedAccountInfoRemoved() to fire.
void RemoveRefreshTokenForAccount(const CoreAccountId& account_id);
// Updates the persistent auth error set on |account_id| which must be a known
@@ -211,7 +225,7 @@ class IdentityTestEnvironment : public IdentityManager::DiagnosticsObserver {
const std::string& token,
const base::Time& expiration,
const std::string& id_token,
- const identity::ScopeSet& scopes);
+ const ScopeSet& scopes);
// Issues |error| in response to any access token request that either has (a)
// already occurred and has not been matched by a previous call to this or
@@ -321,7 +335,7 @@ class IdentityTestEnvironment : public IdentityManager::DiagnosticsObserver {
// IdentityManager::DiagnosticsObserver:
void OnAccessTokenRequested(const CoreAccountId& account_id,
const std::string& consumer_id,
- const identity::ScopeSet& scopes) override;
+ const ScopeSet& scopes) override;
// Handles the notification that an access token request was received for
// |account_id|. Invokes |on_access_token_request_callback_| if the latter
diff --git a/chromium/components/signin/public/identity_manager/identity_test_utils.cc b/chromium/components/signin/public/identity_manager/identity_test_utils.cc
index 10c95d01d0c..6d6cc547450 100644
--- a/chromium/components/signin/public/identity_manager/identity_test_utils.cc
+++ b/chromium/components/signin/public/identity_manager/identity_test_utils.cc
@@ -14,13 +14,14 @@
#include "components/signin/internal/identity_manager/profile_oauth2_token_service.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h"
#include "components/signin/public/base/list_accounts_test_utils.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
#include "components/signin/public/identity_manager/test_identity_manager_observer.h"
#include "google_apis/gaia/gaia_auth_util.h"
#include "google_apis/gaia/gaia_constants.h"
#if defined(OS_ANDROID)
-#include "components/signin/internal/identity_manager/oauth2_token_service_delegate_android.h"
+#include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h"
#endif
namespace signin {
@@ -74,6 +75,21 @@ void UpdateRefreshTokenForAccount(
run_loop.Run();
}
+// Ensures that an account for |email| exists in the AccountTrackerService,
+// seeding it if necessary. Returns AccountInfo for the account.
+AccountInfo EnsureAccountExists(AccountTrackerService* account_tracker_service,
+ const std::string& email) {
+ AccountInfo account_info =
+ account_tracker_service->FindAccountInfoByEmail(email);
+ if (account_info.account_id.empty()) {
+ std::string gaia_id = GetTestGaiaIdForEmail(email);
+ account_tracker_service->SeedAccountInfo(gaia_id, email);
+ account_info = account_tracker_service->FindAccountInfoByEmail(email);
+ DCHECK(!account_info.account_id.empty());
+ }
+ return account_info;
+}
+
} // namespace
CoreAccountInfo SetPrimaryAccount(IdentityManager* identity_manager,
@@ -83,18 +99,9 @@ CoreAccountInfo SetPrimaryAccount(IdentityManager* identity_manager,
identity_manager->GetPrimaryAccountManager();
DCHECK(!primary_account_manager->IsAuthenticated());
- AccountTrackerService* account_tracker_service =
- identity_manager->GetAccountTrackerService();
AccountInfo account_info =
- account_tracker_service->FindAccountInfoByEmail(email);
- if (account_info.account_id.empty()) {
- std::string gaia_id = GetTestGaiaIdForEmail(email);
- account_tracker_service->SeedAccountInfo(gaia_id, email);
- account_info = account_tracker_service->FindAccountInfoByEmail(email);
- }
-
- std::string gaia_id = account_info.gaia;
- DCHECK(!gaia_id.empty());
+ EnsureAccountExists(identity_manager->GetAccountTrackerService(), email);
+ DCHECK(!account_info.gaia.empty());
primary_account_manager->SignIn(email);
@@ -103,6 +110,27 @@ CoreAccountInfo SetPrimaryAccount(IdentityManager* identity_manager,
return identity_manager->GetPrimaryAccountInfo();
}
+CoreAccountInfo SetUnconsentedPrimaryAccount(IdentityManager* identity_manager,
+ const std::string& email) {
+ DCHECK(!identity_manager->HasPrimaryAccount(ConsentLevel::kNotRequired));
+
+ AccountInfo account_info =
+ EnsureAccountExists(identity_manager->GetAccountTrackerService(), email);
+ DCHECK(!account_info.gaia.empty());
+
+ PrimaryAccountManager* primary_account_manager =
+ identity_manager->GetPrimaryAccountManager();
+ primary_account_manager->SetUnconsentedPrimaryAccountInfo(account_info);
+
+ DCHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kNotRequired));
+ DCHECK_EQ(account_info.gaia,
+ identity_manager
+ ->GetPrimaryAccountInfo(signin::ConsentLevel::kNotRequired)
+ .gaia);
+ return identity_manager->GetPrimaryAccountInfo(
+ signin::ConsentLevel::kNotRequired);
+}
+
void SetRefreshTokenForPrimaryAccount(IdentityManager* identity_manager,
const std::string& token_value) {
DCHECK(identity_manager->HasPrimaryAccount());
@@ -313,10 +341,12 @@ void UpdateAccountInfoForAccount(IdentityManager* identity_manager,
void SimulateAccountImageFetch(IdentityManager* identity_manager,
const CoreAccountId& account_id,
+ const std::string& image_url_with_size,
const gfx::Image& image) {
AccountTrackerService* account_tracker_service =
identity_manager->GetAccountTrackerService();
- account_tracker_service->SetAccountImage(account_id, image);
+ account_tracker_service->SetAccountImage(account_id, image_url_with_size,
+ image);
}
void SetFreshnessOfAccountsInGaiaCookie(IdentityManager* identity_manager,
@@ -351,7 +381,7 @@ void DisableAccessTokenFetchRetries(IdentityManager* identity_manager) {
#if defined(OS_ANDROID)
void DisableInteractionWithSystemAccounts() {
- OAuth2TokenServiceDelegateAndroid::
+ ProfileOAuth2TokenServiceDelegateAndroid::
set_disable_interaction_with_system_accounts();
}
#endif
diff --git a/chromium/components/signin/public/identity_manager/identity_test_utils.h b/chromium/components/signin/public/identity_manager/identity_test_utils.h
index 710e2e478ee..46d26a5104b 100644
--- a/chromium/components/signin/public/identity_manager/identity_test_utils.h
+++ b/chromium/components/signin/public/identity_manager/identity_test_utils.h
@@ -53,6 +53,11 @@ class IdentityManager;
CoreAccountInfo SetPrimaryAccount(IdentityManager* identity_manager,
const std::string& email);
+// As above, but adds an "unconsented" primary account. See ./README.md for
+// the distinction between primary and unconsented primary accounts.
+CoreAccountInfo SetUnconsentedPrimaryAccount(IdentityManager* identity_manager,
+ const std::string& email);
+
// Sets a refresh token for the primary account (which must already be set).
// Blocks until the refresh token is set. If |token_value| is empty a default
// value will be used instead.
@@ -148,6 +153,7 @@ void UpdateAccountInfoForAccount(IdentityManager* identity_manager,
void SimulateAccountImageFetch(IdentityManager* identity_manager,
const CoreAccountId& account_id,
+ const std::string& image_url_with_size,
const gfx::Image& image);
// Sets whether the list of accounts in Gaia cookie jar is fresh and does not
diff --git a/chromium/components/signin/public/identity_manager/identity_utils.cc b/chromium/components/signin/public/identity_manager/identity_utils.cc
index 11061a1d694..ec9f6309b72 100644
--- a/chromium/components/signin/public/identity_manager/identity_utils.cc
+++ b/chromium/components/signin/public/identity_manager/identity_utils.cc
@@ -6,6 +6,7 @@
#include <string>
+#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/prefs/pref_service.h"
diff --git a/chromium/components/signin/public/identity_manager/identity_utils.h b/chromium/components/signin/public/identity_manager/identity_utils.h
index 62927ab4e7e..2ca8a7ec29a 100644
--- a/chromium/components/signin/public/identity_manager/identity_utils.h
+++ b/chromium/components/signin/public/identity_manager/identity_utils.h
@@ -1,18 +1,11 @@
// Copyright 2018 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.
-//
-// Functions that are shared between the Identity Service implementation and its
-// consumers. Currently in //components/signin because they are used by classes
-// in this component, which cannot depend on //services/identity to avoid a
-// dependency cycle. When these classes have no direct consumers and are moved
-// to //services/identity, these functions should correspondingly be moved to
-// //services/identity/public/cpp.
#ifndef COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_IDENTITY_UTILS_H_
#define COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_IDENTITY_UTILS_H_
-#include "base/strings/string_piece.h"
+#include <string>
class PrefService;
diff --git a/chromium/components/signin/public/identity_manager/ios/BUILD.gn b/chromium/components/signin/public/identity_manager/ios/BUILD.gn
index 0f06fb4a39b..7ab9b688998 100644
--- a/chromium/components/signin/public/identity_manager/ios/BUILD.gn
+++ b/chromium/components/signin/public/identity_manager/ios/BUILD.gn
@@ -10,9 +10,7 @@ source_set("ios") {
"device_accounts_provider.mm",
]
- public_deps = [
- "//base",
- ]
+ public_deps = [ "//base" ]
}
source_set("test_support") {
diff --git a/chromium/components/signin/public/identity_manager/objc/BUILD.gn b/chromium/components/signin/public/identity_manager/objc/BUILD.gn
index ba323fe7dae..950157c0990 100644
--- a/chromium/components/signin/public/identity_manager/objc/BUILD.gn
+++ b/chromium/components/signin/public/identity_manager/objc/BUILD.gn
@@ -9,7 +9,5 @@ source_set("objc") {
"identity_manager_observer_bridge.mm",
]
- public_deps = [
- "//components/signin/public/identity_manager",
- ]
+ public_deps = [ "//components/signin/public/identity_manager" ]
}
diff --git a/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.cc b/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.cc
index 4b0ce696467..56d1b5c2e89 100644
--- a/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.cc
+++ b/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.cc
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/logging.h"
#include "components/signin/public/identity_manager/access_token_info.h"
+#include "google_apis/gaia/core_account_id.h"
#include "google_apis/gaia/google_service_auth_error.h"
namespace signin {
@@ -16,15 +17,17 @@ namespace signin {
PrimaryAccountAccessTokenFetcher::PrimaryAccountAccessTokenFetcher(
const std::string& oauth_consumer_name,
IdentityManager* identity_manager,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
AccessTokenFetcher::TokenCallback callback,
- Mode mode)
+ Mode mode,
+ ConsentLevel consent)
: oauth_consumer_name_(oauth_consumer_name),
identity_manager_(identity_manager),
scopes_(scopes),
callback_(std::move(callback)),
access_token_retried_(false),
- mode_(mode) {
+ mode_(mode),
+ consent_(consent) {
if (mode_ == Mode::kImmediate || AreCredentialsAvailable()) {
StartAccessTokenRequest();
return;
@@ -36,12 +39,16 @@ PrimaryAccountAccessTokenFetcher::PrimaryAccountAccessTokenFetcher(
identity_manager_observer_.Add(identity_manager_);
}
-PrimaryAccountAccessTokenFetcher::~PrimaryAccountAccessTokenFetcher() {}
+PrimaryAccountAccessTokenFetcher::~PrimaryAccountAccessTokenFetcher() = default;
+
+CoreAccountId PrimaryAccountAccessTokenFetcher::GetAccountId() const {
+ return identity_manager_->GetPrimaryAccountId(consent_);
+}
bool PrimaryAccountAccessTokenFetcher::AreCredentialsAvailable() const {
DCHECK_EQ(Mode::kWaitUntilAvailable, mode_);
- return identity_manager_->HasPrimaryAccountWithRefreshToken();
+ return identity_manager_->HasAccountWithRefreshToken(GetAccountId());
}
void PrimaryAccountAccessTokenFetcher::StartAccessTokenRequest() {
@@ -63,7 +70,7 @@ void PrimaryAccountAccessTokenFetcher::StartAccessTokenRequest() {
// token available. AccessTokenFetcher used in
// |kWaitUntilRefreshTokenAvailable| mode would guarantee only the latter.
access_token_fetcher_ = identity_manager_->CreateAccessTokenFetcherForAccount(
- identity_manager_->GetPrimaryAccountId(), oauth_consumer_name_, scopes_,
+ GetAccountId(), oauth_consumer_name_, scopes_,
base::BindOnce(
&PrimaryAccountAccessTokenFetcher::OnAccessTokenFetchComplete,
base::Unretained(this)),
@@ -72,6 +79,23 @@ void PrimaryAccountAccessTokenFetcher::StartAccessTokenRequest() {
void PrimaryAccountAccessTokenFetcher::OnPrimaryAccountSet(
const CoreAccountInfo& primary_account_info) {
+ // When sync consent is not required the signin is handled in
+ // OnUnconsentedPrimaryAccountChanged() below.
+ if (consent_ == ConsentLevel::kNotRequired)
+ return;
+ DCHECK(!primary_account_info.account_id.empty());
+ ProcessSigninStateChange();
+}
+
+void PrimaryAccountAccessTokenFetcher::OnUnconsentedPrimaryAccountChanged(
+ const CoreAccountInfo& primary_account_info) {
+ // This method is called after both SetPrimaryAccount and
+ // SetUnconsentedPrimaryAccount.
+ if (consent_ == ConsentLevel::kSync)
+ return;
+ // We're only interested when the account is set.
+ if (primary_account_info.account_id.empty())
+ return;
ProcessSigninStateChange();
}
diff --git a/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.h b/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.h
index 7f09bc179f7..233116ea169 100644
--- a/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.h
+++ b/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.h
@@ -11,8 +11,10 @@
#include "base/macros.h"
#include "base/scoped_observer.h"
#include "components/signin/public/identity_manager/access_token_fetcher.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_manager.h"
-#include "services/identity/public/cpp/scope_set.h"
+#include "components/signin/public/identity_manager/scope_set.h"
+#include "google_apis/gaia/core_account_id.h"
class GoogleServiceAuthError;
@@ -67,7 +69,7 @@ struct AccessTokenInfo;
// // introducing wrapper API surfaces.
// MyClass::StartAccessTokenRequestForPrimaryAccount() {
// // Choose scopes to obtain for the access token.
-// identity::ScopeSet scopes;
+// ScopeSet scopes;
// scopes.insert(GaiaConstants::kMyFirstScope);
// scopes.insert(GaiaConstants::kMySecondScope);
@@ -149,11 +151,14 @@ class PrimaryAccountAccessTokenFetcher : public IdentityManager::Observer {
// the request completes (successful or not). If the
// PrimaryAccountAccessTokenFetcher is destroyed before the process completes,
// the callback is not called.
+ // |consent| defaults to kSync because historically having an "authenticated"
+ // account was tied to browser sync. See ./README.md.
PrimaryAccountAccessTokenFetcher(const std::string& oauth_consumer_name,
IdentityManager* identity_manager,
- const identity::ScopeSet& scopes,
+ const ScopeSet& scopes,
AccessTokenFetcher::TokenCallback callback,
- Mode mode);
+ Mode mode,
+ ConsentLevel consent = ConsentLevel::kSync);
~PrimaryAccountAccessTokenFetcher() override;
@@ -161,6 +166,10 @@ class PrimaryAccountAccessTokenFetcher : public IdentityManager::Observer {
bool access_token_request_retried() { return access_token_retried_; }
private:
+ // Returns the primary account ID. If consent is |kNotRequired| this may be
+ // the "unconsented" primary account ID.
+ CoreAccountId GetAccountId() const;
+
// Returns true iff there is a primary account with a refresh token. Should
// only be called in mode |kWaitUntilAvailable|.
bool AreCredentialsAvailable() const;
@@ -170,6 +179,8 @@ class PrimaryAccountAccessTokenFetcher : public IdentityManager::Observer {
// IdentityManager::Observer implementation.
void OnPrimaryAccountSet(
const CoreAccountInfo& primary_account_info) override;
+ void OnUnconsentedPrimaryAccountChanged(
+ const CoreAccountInfo& primary_account_info) override;
void OnRefreshTokenUpdatedForAccount(
const CoreAccountInfo& account_info) override;
@@ -183,7 +194,7 @@ class PrimaryAccountAccessTokenFetcher : public IdentityManager::Observer {
std::string oauth_consumer_name_;
IdentityManager* identity_manager_;
- identity::ScopeSet scopes_;
+ ScopeSet scopes_;
// Per the contract of this class, it is allowed for clients to delete this
// object as part of the invocation of |callback_|. Hence, this object must
@@ -202,6 +213,8 @@ class PrimaryAccountAccessTokenFetcher : public IdentityManager::Observer {
Mode mode_;
+ const ConsentLevel consent_;
+
DISALLOW_COPY_AND_ASSIGN(PrimaryAccountAccessTokenFetcher);
};
diff --git a/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher_unittest.cc b/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher_unittest.cc
index 2f9bfa34e85..dfa9378bf44 100644
--- a/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher_unittest.cc
+++ b/chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher_unittest.cc
@@ -11,6 +11,7 @@
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "components/signin/public/identity_manager/access_token_info.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -37,8 +38,8 @@ void OnAccessTokenFetchComplete(
} // namespace
-class PrimaryAccountAccessTokenFetcherTest : public testing::Test,
- public IdentityManager::Observer {
+class PrimaryAccountAccessTokenFetcherTest
+ : public testing::TestWithParam<ConsentLevel> {
public:
using TestTokenCallback =
StrictMock<MockCallback<AccessTokenFetcher::TokenCallback>>;
@@ -48,15 +49,24 @@ class PrimaryAccountAccessTokenFetcherTest : public testing::Test,
base::Time::Now() + base::TimeDelta::FromHours(1),
"id_token") {}
- ~PrimaryAccountAccessTokenFetcherTest() override {}
+ ~PrimaryAccountAccessTokenFetcherTest() override = default;
std::unique_ptr<PrimaryAccountAccessTokenFetcher> CreateFetcher(
AccessTokenFetcher::TokenCallback callback,
- PrimaryAccountAccessTokenFetcher::Mode mode) {
+ PrimaryAccountAccessTokenFetcher::Mode mode,
+ ConsentLevel consent) {
std::set<std::string> scopes{"scope"};
return std::make_unique<PrimaryAccountAccessTokenFetcher>(
"test_consumer", identity_test_env_.identity_manager(), scopes,
- std::move(callback), mode);
+ std::move(callback), mode, consent);
+ }
+
+ // Creates a fetcher with sync consent based on the test param.
+ std::unique_ptr<PrimaryAccountAccessTokenFetcher> CreateFetcher(
+ AccessTokenFetcher::TokenCallback callback,
+ PrimaryAccountAccessTokenFetcher::Mode mode) {
+ ConsentLevel consent = GetParam();
+ return CreateFetcher(std::move(callback), mode, consent);
}
IdentityTestEnvironment* identity_test_env() { return &identity_test_env_; }
@@ -79,7 +89,7 @@ class PrimaryAccountAccessTokenFetcherTest : public testing::Test,
AccessTokenInfo access_token_info_;
};
-TEST_F(PrimaryAccountAccessTokenFetcherTest, OneShotShouldReturnAccessToken) {
+TEST_P(PrimaryAccountAccessTokenFetcherTest, OneShotShouldReturnAccessToken) {
TestTokenCallback callback;
CoreAccountId account_id = SignIn();
@@ -98,7 +108,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest, OneShotShouldReturnAccessToken) {
access_token_info().id_token);
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
WaitAndRetryShouldReturnAccessToken) {
TestTokenCallback callback;
@@ -119,7 +129,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
access_token_info().id_token);
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldNotReplyIfDestroyed) {
+TEST_P(PrimaryAccountAccessTokenFetcherTest, ShouldNotReplyIfDestroyed) {
TestTokenCallback callback;
CoreAccountId account_id = SignIn();
@@ -138,7 +148,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldNotReplyIfDestroyed) {
access_token_info().id_token);
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest, OneShotCallsBackWhenSignedOut) {
+TEST_P(PrimaryAccountAccessTokenFetcherTest, OneShotCallsBackWhenSignedOut) {
base::RunLoop run_loop;
// Signed out -> we should get called back.
@@ -152,7 +162,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest, OneShotCallsBackWhenSignedOut) {
run_loop.Run();
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
OneShotCallsBackWhenNoRefreshToken) {
base::RunLoop run_loop;
@@ -169,7 +179,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
run_loop.Run();
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
WaitAndRetryNoCallbackWhenSignedOut) {
TestTokenCallback callback;
@@ -180,11 +190,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable);
}
-// Tests related to waiting for sign-in don't apply on ChromeOS (it doesn't have
-// that concept).
-#if !defined(OS_CHROMEOS)
-
-TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldWaitForSignIn) {
+TEST_P(PrimaryAccountAccessTokenFetcherTest, ShouldWaitForSignIn) {
TestTokenCallback callback;
// Not signed in, so this should wait for a sign-in to complete.
@@ -206,9 +212,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldWaitForSignIn) {
EXPECT_FALSE(fetcher->access_token_request_retried());
}
-#endif // !OS_CHROMEOS
-
-TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldWaitForRefreshToken) {
+TEST_P(PrimaryAccountAccessTokenFetcherTest, ShouldWaitForRefreshToken) {
TestTokenCallback callback;
CoreAccountId account_id =
@@ -235,7 +239,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest, ShouldWaitForRefreshToken) {
EXPECT_FALSE(fetcher->access_token_request_retried());
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
ShouldIgnoreRefreshTokensForOtherAccounts) {
TestTokenCallback callback;
@@ -254,7 +258,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
identity_test_env()->MakeAccountAvailable(account_id.ToString() + "3");
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
OneShotCanceledAccessTokenRequest) {
CoreAccountId account_id = SignIn();
@@ -274,7 +278,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED));
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
WaitAndRetryCanceledAccessTokenRequest) {
TestTokenCallback callback;
@@ -299,7 +303,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
access_token_info().id_token);
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
ShouldRetryCanceledAccessTokenRequestOnlyOnce) {
TestTokenCallback callback;
@@ -327,7 +331,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
#if !defined(OS_CHROMEOS)
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
ShouldNotRetryCanceledAccessTokenRequestIfSignedOut) {
TestTokenCallback callback;
@@ -352,7 +356,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
#endif // !OS_CHROMEOS
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
ShouldNotRetryCanceledAccessTokenRequestIfRefreshTokenRevoked) {
TestTokenCallback callback;
@@ -373,7 +377,7 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
identity_test_env()->RemoveRefreshTokenForPrimaryAccount();
}
-TEST_F(PrimaryAccountAccessTokenFetcherTest,
+TEST_P(PrimaryAccountAccessTokenFetcherTest,
ShouldNotRetryFailedAccessTokenRequest) {
TestTokenCallback callback;
@@ -395,4 +399,74 @@ TEST_F(PrimaryAccountAccessTokenFetcherTest,
GoogleServiceAuthError(GoogleServiceAuthError::SERVICE_UNAVAILABLE));
}
+// The above tests all use a consented primary account, so they should all work
+// whether or not sync consent is required.
+INSTANTIATE_TEST_SUITE_P(All,
+ PrimaryAccountAccessTokenFetcherTest,
+ testing::Values(ConsentLevel::kNotRequired,
+ ConsentLevel::kSync));
+
+#if defined(OS_CHROMEOS)
+// Chrome OS can directly set the unconsented primary account during login,
+// so it has additional tests.
+TEST_F(PrimaryAccountAccessTokenFetcherTest,
+ UnconsentedPrimaryAccountWithSyncConsentNotRequired) {
+ TestTokenCallback callback;
+
+ // Simulate login.
+ identity_test_env()->MakeUnconsentedPrimaryAccountAvailable("me@gmail.com");
+
+ // Perform an immediate fetch with consent not required.
+ auto fetcher = CreateFetcher(
+ callback.Get(), PrimaryAccountAccessTokenFetcher::Mode::kImmediate,
+ ConsentLevel::kNotRequired);
+
+ // We should get called back with the token.
+ EXPECT_CALL(callback, Run(GoogleServiceAuthError::AuthErrorNone(),
+ access_token_info()));
+ identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+ access_token_info().token, access_token_info().expiration_time,
+ access_token_info().id_token);
+}
+
+TEST_F(PrimaryAccountAccessTokenFetcherTest,
+ UnconsentedPrimaryAccountWithSyncConsentRequired) {
+ TestTokenCallback callback;
+
+ // Simulate login.
+ identity_test_env()->MakeUnconsentedPrimaryAccountAvailable("me@gmail.com");
+
+ // Try an immediate fetch with consent required.
+ auto fetcher = CreateFetcher(
+ callback.Get(), PrimaryAccountAccessTokenFetcher::Mode::kImmediate,
+ ConsentLevel::kSync);
+
+ // No token request generated because the account isn't consented.
+ EXPECT_FALSE(identity_test_env()->IsAccessTokenRequestPending());
+}
+
+TEST_F(PrimaryAccountAccessTokenFetcherTest,
+ ShouldWaitForUnconsentedAccountLogin) {
+ TestTokenCallback callback;
+
+ // Not logged in, so the fetcher waits for an account to become available.
+ auto fetcher =
+ CreateFetcher(callback.Get(),
+ PrimaryAccountAccessTokenFetcher::Mode::kWaitUntilAvailable,
+ ConsentLevel::kNotRequired);
+ EXPECT_FALSE(identity_test_env()->IsAccessTokenRequestPending());
+
+ // Simulate login.
+ identity_test_env()->MakeUnconsentedPrimaryAccountAvailable("me@gmail.com");
+
+ // Once the access token request is fulfilled, we should get called back with
+ // the access token.
+ EXPECT_CALL(callback, Run(GoogleServiceAuthError::AuthErrorNone(),
+ access_token_info()));
+ identity_test_env()->WaitForAccessTokenRequestIfNecessaryAndRespondWithToken(
+ access_token_info().token, access_token_info().expiration_time,
+ access_token_info().id_token);
+}
+#endif // defined(OS_CHROMEOS)
+
} // namespace signin
diff --git a/chromium/components/signin/public/identity_manager/primary_account_mutator.h b/chromium/components/signin/public/identity_manager/primary_account_mutator.h
index 0b23bde235c..6dfab8d8e2b 100644
--- a/chromium/components/signin/public/identity_manager/primary_account_mutator.h
+++ b/chromium/components/signin/public/identity_manager/primary_account_mutator.h
@@ -60,6 +60,19 @@ class PrimaryAccountMutator {
virtual bool SetPrimaryAccount(const CoreAccountId& account_id) = 0;
#if defined(OS_CHROMEOS)
+ // Revokes sync consent from the primary account. The primary account must
+ // have sync consent. After the call a primary account will remain but it will
+ // not have sync consent.
+ // TODO(https://crbug.com/1046746): Support non-Chrome OS platforms.
+ virtual void RevokeSyncConsent() = 0;
+
+ // Sets the account with |account_id| as the unconsented primary account
+ // (i.e. without implying browser sync consent). Requires that the account
+ // is known by the IdentityManager. See README.md for details on the meaning
+ // of "unconsented".
+ virtual void SetUnconsentedPrimaryAccount(
+ const CoreAccountId& account_id) = 0;
+
// Updates the info of the account corresponding to (|gaia_id|, |email|),
// marks it as the primary account, and returns whether the operation
// succeeded or not. Currently, this method is guaranteed to succeed.
diff --git a/chromium/components/signin/public/identity_manager/primary_account_mutator_unittest.cc b/chromium/components/signin/public/identity_manager/primary_account_mutator_unittest.cc
index f56a6d81b7e..780d722b140 100644
--- a/chromium/components/signin/public/identity_manager/primary_account_mutator_unittest.cc
+++ b/chromium/components/signin/public/identity_manager/primary_account_mutator_unittest.cc
@@ -11,11 +11,14 @@
#include "base/test/task_environment.h"
#include "components/signin/public/base/signin_metrics.h"
#include "components/signin/public/base/signin_pref_names.h"
+#include "components/signin/public/identity_manager/consent_level.h"
#include "components/signin/public/identity_manager/identity_test_environment.h"
#include "components/signin/public/identity_manager/identity_test_utils.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/platform_test.h"
+using signin::ConsentLevel;
+
namespace {
// Constants used by the different tests.
@@ -244,7 +247,7 @@ TEST_F(PrimaryAccountMutatorTest, SetPrimaryAccount) {
// enable those preconditions on that platform
#if !defined(OS_CHROMEOS)
// Checks that setting the primary account fails if the account is not known by
-// the identity service.
+// the identity system.
TEST_F(PrimaryAccountMutatorTest, SetPrimaryAccount_NoAccount) {
base::test::TaskEnvironment task_environment;
signin::IdentityTestEnvironment environment;
@@ -498,3 +501,32 @@ TEST_F(PrimaryAccountMutatorTest,
RemoveAccountExpectation::kRemovePrimary, AuthExpectation::kAuthError);
}
#endif // !defined(OS_CHROMEOS)
+
+#if defined(OS_CHROMEOS)
+TEST_F(PrimaryAccountMutatorTest, RevokeSyncConsent) {
+ base::test::TaskEnvironment task_environment;
+ signin::IdentityTestEnvironment environment;
+ signin::IdentityManager* identity_manager = environment.identity_manager();
+
+ class Observer : public signin::IdentityManager::Observer {
+ public:
+ void OnPrimaryAccountCleared(const CoreAccountInfo& info) override {
+ ++primary_account_cleared_;
+ }
+
+ int primary_account_cleared_ = 0;
+ } observer;
+ identity_manager->AddObserver(&observer);
+
+ environment.MakePrimaryAccountAvailable(kPrimaryAccountEmail);
+ ASSERT_TRUE(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
+ EXPECT_EQ(0, observer.primary_account_cleared_);
+
+ identity_manager->GetPrimaryAccountMutator()->RevokeSyncConsent();
+ EXPECT_FALSE(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
+ EXPECT_TRUE(identity_manager->HasPrimaryAccount(ConsentLevel::kNotRequired));
+ EXPECT_EQ(1, observer.primary_account_cleared_);
+
+ identity_manager->RemoveObserver(&observer);
+}
+#endif // defined(OS_CHROMEOS)
diff --git a/chromium/components/signin/public/identity_manager/scope_set.h b/chromium/components/signin/public/identity_manager/scope_set.h
new file mode 100644
index 00000000000..4f01c5d42ff
--- /dev/null
+++ b/chromium/components/signin/public/identity_manager/scope_set.h
@@ -0,0 +1,17 @@
+// Copyright 2017 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 COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_SCOPE_SET_H_
+#define COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_SCOPE_SET_H_
+
+#include <set>
+#include <string>
+
+namespace signin {
+
+using ScopeSet = std::set<std::string>;
+
+} // namespace signin
+
+#endif // COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_SCOPE_SET_H_
diff --git a/chromium/components/signin/public/webdata/BUILD.gn b/chromium/components/signin/public/webdata/BUILD.gn
index a301f77272d..b805aa0c636 100644
--- a/chromium/components/signin/public/webdata/BUILD.gn
+++ b/chromium/components/signin/public/webdata/BUILD.gn
@@ -24,9 +24,7 @@ static_library("webdata") {
source_set("unit_tests") {
testonly = true
- sources = [
- "token_service_table_unittest.cc",
- ]
+ sources = [ "token_service_table_unittest.cc" ]
deps = [
":webdata",
diff --git a/chromium/components/signin/public/webdata/token_web_data.cc b/chromium/components/signin/public/webdata/token_web_data.cc
index 9ecd6b68624..9d6077da0ab 100644
--- a/chromium/components/signin/public/webdata/token_web_data.cc
+++ b/chromium/components/signin/public/webdata/token_web_data.cc
@@ -72,10 +72,9 @@ TokenResult::~TokenResult() {}
TokenWebData::TokenWebData(
scoped_refptr<WebDatabaseService> wdbs,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
- scoped_refptr<base::SingleThreadTaskRunner> db_task_runner,
- const ProfileErrorCallback& callback)
- : WebDataServiceBase(wdbs, callback, ui_task_runner),
- token_backend_(new TokenWebDataBackend(db_task_runner)) {}
+ scoped_refptr<base::SingleThreadTaskRunner> db_task_runner)
+ : WebDataServiceBase(wdbs, std::move(ui_task_runner)),
+ token_backend_(new TokenWebDataBackend(std::move(db_task_runner))) {}
void TokenWebData::SetTokenForService(const std::string& service,
const std::string& token) {
@@ -106,7 +105,7 @@ WebDataServiceBase::Handle TokenWebData::GetAllTokens(
TokenWebData::TokenWebData(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> db_task_runner)
- : WebDataServiceBase(nullptr, ProfileErrorCallback(), ui_task_runner),
- token_backend_(new TokenWebDataBackend(db_task_runner)) {}
+ : WebDataServiceBase(nullptr, std::move(ui_task_runner)),
+ token_backend_(new TokenWebDataBackend(std::move(db_task_runner))) {}
TokenWebData::~TokenWebData() {}
diff --git a/chromium/components/signin/public/webdata/token_web_data.h b/chromium/components/signin/public/webdata/token_web_data.h
index 2992fe6caef..680b904ed7c 100644
--- a/chromium/components/signin/public/webdata/token_web_data.h
+++ b/chromium/components/signin/public/webdata/token_web_data.h
@@ -48,8 +48,7 @@ class TokenWebData : public WebDataServiceBase {
public:
TokenWebData(scoped_refptr<WebDatabaseService> wdbs,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
- scoped_refptr<base::SingleThreadTaskRunner> db_task_runner,
- const ProfileErrorCallback& callback);
+ scoped_refptr<base::SingleThreadTaskRunner> db_task_runner);
TokenWebData(scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> db_task_runner);