summaryrefslogtreecommitdiff
path: root/chromium/components/signin
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-09-03 13:32:17 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-10-01 14:31:55 +0200
commit21ba0c5d4bf8fba15dddd97cd693bad2358b77fd (patch)
tree91be119f694044dfc1ff9fdc054459e925de9df0 /chromium/components/signin
parent03c549e0392f92c02536d3f86d5e1d8dfa3435ac (diff)
downloadqtwebengine-chromium-21ba0c5d4bf8fba15dddd97cd693bad2358b77fd.tar.gz
BASELINE: Update Chromium to 92.0.4515.166
Change-Id: I42a050486714e9e54fc271f2a8939223a02ae364
Diffstat (limited to 'chromium/components/signin')
-rw-r--r--chromium/components/signin/OWNERS1
-rw-r--r--chromium/components/signin/core/browser/BUILD.gn27
-rw-r--r--chromium/components/signin/core/browser/DEPS10
-rw-r--r--chromium/components/signin/core/browser/about_signin_internals.cc24
-rw-r--r--chromium/components/signin/core/browser/account_investigator.cc6
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor.cc337
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor.h110
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor_delegate.cc4
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor_delegate.h6
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor_throttler.cc113
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor_throttler.h61
-rw-r--r--chromium/components/signin/core/browser/account_reconcilor_unittest.cc1017
-rw-r--r--chromium/components/signin/core/browser/chrome_connected_header_helper.cc19
-rw-r--r--chromium/components/signin/core/browser/chrome_connected_header_helper.h4
-rw-r--r--chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc7
-rw-r--r--chromium/components/signin/core/browser/dice_account_reconcilor_delegate.h6
-rw-r--r--chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc11
-rw-r--r--chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h1
-rw-r--r--chromium/components/signin/core/browser/signin_error_controller.h2
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper.cc8
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper.h17
-rw-r--r--chromium/components/signin/core/browser/signin_header_helper_unittest.cc109
-rw-r--r--chromium/components/signin/core/browser/signin_internals_util.h1
-rw-r--r--chromium/components/signin/internal/identity_manager/BUILD.gn11
-rw-r--r--chromium/components/signin/internal/identity_manager/account_info_util.cc8
-rw-r--r--chromium/components/signin/internal/identity_manager/account_info_util.h4
-rw-r--r--chromium/components/signin/internal/identity_manager/account_info_util_unittest.cc14
-rw-r--r--chromium/components/signin/internal/identity_manager/account_tracker_service.cc2
-rw-r--r--chromium/components/signin/internal/identity_manager/account_tracker_service_unittest.cc6
-rw-r--r--chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.cc9
-rw-r--r--chromium/components/signin/internal/identity_manager/accounts_cookie_mutator_impl.h2
-rw-r--r--chromium/components/signin/internal/identity_manager/accounts_mutator_impl.cc6
-rw-r--r--chromium/components/signin/internal/identity_manager/accounts_mutator_impl.h4
-rw-r--r--chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.cc5
-rw-r--r--chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.h1
-rw-r--r--chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.cc2
-rw-r--r--chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.h2
-rw-r--r--chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.cc36
-rw-r--r--chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service.h19
-rw-r--r--chromium/components/signin/internal/identity_manager/gaia_cookie_manager_service_unittest.cc150
-rw-r--r--chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc35
-rw-r--r--chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.h1
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_manager.cc3
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_manager.h3
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.cc49
-rw-r--r--chromium/components/signin/internal/identity_manager/primary_account_mutator_impl.h6
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.cc49
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.h8
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h3
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc8
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h6
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.cc19
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h2
-rw-r--r--chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.mm2
-rw-r--r--chromium/components/signin/ios/DIR_METADATA3
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service.h20
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service.mm139
-rw-r--r--chromium/components/signin/ios/browser/account_consistency_service_unittest.mm229
-rw-r--r--chromium/components/signin/ios/browser/features.cc3
-rw-r--r--chromium/components/signin/ios/browser/features.h3
-rw-r--r--chromium/components/signin/ios/browser/manage_accounts_delegate.h4
-rw-r--r--chromium/components/signin/public/android/BUILD.gn22
-rw-r--r--chromium/components/signin/public/android/DEPS1
-rw-r--r--chromium/components/signin/public/android/DIR_METADATA5
-rw-r--r--chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountManagerFacadeImplTest.java257
-rw-r--r--chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountRenameCheckerTest.java62
-rw-r--r--chromium/components/signin/public/android/junit/src/org/chromium/components/signin/ObservableValueTest.java109
-rw-r--r--chromium/components/signin/public/android/junit/src/org/chromium/components/signin/identitymanager/AccountInfoServiceTest.java5
-rw-r--r--chromium/components/signin/public/android/junit/src/org/chromium/components/signin/identitymanager/AccountTrackerServiceTest.java (renamed from chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountTrackerServiceTest.java)16
-rw-r--r--chromium/components/signin/public/base/account_consistency_method.cc16
-rw-r--r--chromium/components/signin/public/base/account_consistency_method.h14
-rw-r--r--chromium/components/signin/public/base/multilogin_parameters.cc3
-rw-r--r--chromium/components/signin/public/base/multilogin_parameters.h8
-rw-r--r--chromium/components/signin/public/base/signin_client.h5
-rw-r--r--chromium/components/signin/public/base/signin_metrics.cc13
-rw-r--r--chromium/components/signin/public/base/signin_metrics.h45
-rw-r--r--chromium/components/signin/public/base/signin_metrics_unittest.cc4
-rw-r--r--chromium/components/signin/public/base/signin_pref_names.cc4
-rw-r--r--chromium/components/signin/public/base/signin_pref_names.h1
-rw-r--r--chromium/components/signin/public/base/signin_switches.cc10
-rw-r--r--chromium/components/signin/public/base/signin_switches.h7
-rw-r--r--chromium/components/signin/public/base/test_signin_client.cc6
-rw-r--r--chromium/components/signin/public/base/test_signin_client.h6
-rw-r--r--chromium/components/signin/public/identity_manager/access_token_fetcher.cc1
-rw-r--r--chromium/components/signin/public/identity_manager/account_info.h2
-rw-r--r--chromium/components/signin/public/identity_manager/accounts_cookie_mutator.h4
-rw-r--r--chromium/components/signin/public/identity_manager/accounts_cookie_mutator_unittest.cc1
-rw-r--r--chromium/components/signin/public/identity_manager/accounts_mutator.h6
-rw-r--r--chromium/components/signin/public/identity_manager/accounts_mutator_unittest.cc14
-rw-r--r--chromium/components/signin/public/identity_manager/device_accounts_synchronizer.h4
-rw-r--r--chromium/components/signin/public/identity_manager/identity_manager.cc42
-rw-r--r--chromium/components/signin/public/identity_manager/identity_manager.h23
-rw-r--r--chromium/components/signin/public/identity_manager/identity_manager_builder.cc8
-rw-r--r--chromium/components/signin/public/identity_manager/identity_manager_builder.h28
-rw-r--r--chromium/components/signin/public/identity_manager/identity_manager_unittest.cc51
-rw-r--r--chromium/components/signin/public/identity_manager/identity_mutator.cc20
-rw-r--r--chromium/components/signin/public/identity_manager/identity_test_environment.cc26
-rw-r--r--chromium/components/signin/public/identity_manager/identity_test_environment.h6
-rw-r--r--chromium/components/signin/public/identity_manager/identity_test_utils.cc64
-rw-r--r--chromium/components/signin/public/identity_manager/identity_test_utils.h21
-rw-r--r--chromium/components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h1
-rw-r--r--chromium/components/signin/public/identity_manager/primary_account_access_token_fetcher.h2
-rw-r--r--chromium/components/signin/public/identity_manager/primary_account_mutator.h14
-rw-r--r--chromium/components/signin/public/identity_manager/primary_account_mutator_unittest.cc18
-rw-r--r--chromium/components/signin/public/webdata/token_web_data.cc17
-rw-r--r--chromium/components/signin/public/webdata/token_web_data.h2
106 files changed, 2012 insertions, 1759 deletions
diff --git a/chromium/components/signin/OWNERS b/chromium/components/signin/OWNERS
index e2126a9765d..9dfe6d9bb76 100644
--- a/chromium/components/signin/OWNERS
+++ b/chromium/components/signin/OWNERS
@@ -1,3 +1,4 @@
+alexilin@chromium.org
bsazonov@chromium.org
droger@chromium.org
msalama@chromium.org
diff --git a/chromium/components/signin/core/browser/BUILD.gn b/chromium/components/signin/core/browser/BUILD.gn
index ed063470251..13e7ce4a768 100644
--- a/chromium/components/signin/core/browser/BUILD.gn
+++ b/chromium/components/signin/core/browser/BUILD.gn
@@ -20,6 +20,8 @@ static_library("browser") {
"account_reconcilor.h",
"account_reconcilor_delegate.cc",
"account_reconcilor_delegate.h",
+ "account_reconcilor_throttler.cc",
+ "account_reconcilor_throttler.h",
"chrome_connected_header_helper.cc",
"chrome_connected_header_helper.h",
"cookie_reminter.cc",
@@ -84,13 +86,23 @@ static_library("browser") {
"active_directory_account_reconcilor_delegate.cc",
"active_directory_account_reconcilor_delegate.h",
]
- deps += [ "//chromeos/tpm:tpm" ]
+ deps += [
+ "//chromeos/crosapi/mojom",
+ "//chromeos/tpm:tpm",
+ ]
sources -= [
"signin_status_metrics_provider.cc",
"signin_status_metrics_provider_delegate.cc",
]
}
+ if (is_chromeos_lacros) {
+ deps += [
+ "//chromeos/crosapi/mojom",
+ "//chromeos/lacros",
+ ]
+ }
+
if (!enable_dice_support) {
sources -= [
"dice_account_reconcilor_delegate.cc",
@@ -138,13 +150,24 @@ source_set("unit_tests") {
]
if (is_chromeos_ash) {
- deps += [ "//chromeos/tpm:test_support" ]
+ deps += [
+ "//chromeos/crosapi/mojom",
+ "//chromeos/tpm:test_support",
+ ]
sources -= [
"account_investigator_unittest.cc",
"signin_status_metrics_provider_unittest.cc",
]
}
+ if (is_chromeos_lacros) {
+ deps += [
+ "//chromeos/crosapi/mojom",
+ "//chromeos/lacros",
+ "//chromeos/lacros:test_support",
+ ]
+ }
+
if (!enable_dice_support) {
sources -= [ "dice_account_reconcilor_delegate_unittest.cc" ]
}
diff --git a/chromium/components/signin/core/browser/DEPS b/chromium/components/signin/core/browser/DEPS
index 080a1d60ee4..9712cbfae5a 100644
--- a/chromium/components/signin/core/browser/DEPS
+++ b/chromium/components/signin/core/browser/DEPS
@@ -11,5 +11,15 @@ specific_include_rules = {
"account_reconcilor_unittest.cc": [
"+chromeos/tpm/install_attributes.h",
"+chromeos/tpm/stub_install_attributes.h"
+ ],
+ # TODO(crbug.com/1198528): remove Lacros deps after the rollout.
+ "chrome_connected_header_helper.cc": [
+ "+chromeos/lacros/lacros_chrome_service_impl.h",
+ "+chromeos/crosapi/mojom/crosapi.mojom.h"
+ ],
+ "signin_header_helper_unittest.cc": [
+ "+chromeos/lacros/lacros_chrome_service_delegate.h",
+ "+chromeos/lacros/lacros_chrome_service_impl.h",
+ "+chromeos/lacros/lacros_test_helper.h"
]
}
diff --git a/chromium/components/signin/core/browser/about_signin_internals.cc b/chromium/components/signin/core/browser/about_signin_internals.cc
index 95f1a3ce24e..ef2abc091b7 100644
--- a/chromium/components/signin/core/browser/about_signin_internals.cc
+++ b/chromium/components/signin/core/browser/about_signin_internals.cc
@@ -203,6 +203,17 @@ std::string GetAccountConsistencyDescription(
return "";
}
+std::string GetSigninStatusDescription(
+ signin::IdentityManager* identity_manager) {
+ if (!identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
+ return "Not Signed In";
+ } else if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)) {
+ return "Signed In, Consented for Sync";
+ } else {
+ return "Signed In, Not Consented for Sync";
+ }
+}
+
} // anonymous namespace
AboutSigninInternals::AboutSigninInternals(
@@ -615,11 +626,8 @@ AboutSigninInternals::SigninStatus::ToValue(
AddSection(signin_info.get(), "Basic Information");
AddSectionEntry(basic_info, "Account Consistency",
GetAccountConsistencyDescription(account_consistency));
- AddSectionEntry(
- basic_info, "Signin Status",
- identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)
- ? "Signed In"
- : "Not Signed In");
+ AddSectionEntry(basic_info, "Signin Status",
+ GetSigninStatusDescription(identity_manager));
signin::LoadCredentialsState load_tokens_state =
identity_manager->GetDiagnosticsProvider()
->GetDetailedStateOfLoadingOfRefreshTokens();
@@ -629,9 +637,9 @@ AboutSigninInternals::SigninStatus::ToValue(
basic_info, "Gaia cookies state",
GetGaiaCookiesStateAsString(GetGaiaCookiesState(signin_client)));
- if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync)) {
+ if (identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
CoreAccountInfo account_info =
- identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSync);
+ identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin);
AddSectionEntry(basic_info,
SigninStatusFieldToLabel(signin_internals_util::ACCOUNT_ID),
account_info.account_id.ToString());
@@ -644,7 +652,7 @@ AboutSigninInternals::SigninStatus::ToValue(
if (signin_error_controller->HasError()) {
const CoreAccountId error_account_id =
signin_error_controller->error_account_id();
- const base::Optional<AccountInfo> error_account_info =
+ const absl::optional<AccountInfo> error_account_info =
identity_manager
->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId(
error_account_id);
diff --git a/chromium/components/signin/core/browser/account_investigator.cc b/chromium/components/signin/core/browser/account_investigator.cc
index 4924dd4b2ca..870e30210eb 100644
--- a/chromium/components/signin/core/browser/account_investigator.cc
+++ b/chromium/components/signin/core/browser/account_investigator.cc
@@ -37,12 +37,12 @@ bool AreSame(const CoreAccountInfo& info, const ListedAccount& account) {
// Returns the extended info for the primary account (no consent required) if
// available.
-base::Optional<AccountInfo> GetExtendedAccountInfo(
+absl::optional<AccountInfo> GetExtendedAccountInfo(
signin::IdentityManager* identity_manager) {
CoreAccountId account_id =
identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSignin);
if (account_id.empty())
- return base::nullopt;
+ return absl::nullopt;
return identity_manager
->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId(
account_id);
@@ -244,7 +244,7 @@ void AccountInvestigator::DoPeriodicReport(
if (identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
const bool is_syncing =
identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSync);
- base::Optional<AccountInfo> info =
+ absl::optional<AccountInfo> info =
GetExtendedAccountInfo(identity_manager_);
signin_metrics::LogSignedInCookiesCountsPerPrimaryAccountType(
signed_in_accounts.size(), is_syncing, info->IsManaged());
diff --git a/chromium/components/signin/core/browser/account_reconcilor.cc b/chromium/components/signin/core/browser/account_reconcilor.cc
index 35deb4520ad..57bb3635d06 100644
--- a/chromium/components/signin/core/browser/account_reconcilor.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor.cc
@@ -17,6 +17,8 @@
#include "base/location.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_functions.h"
+#include "base/metrics/histogram_macros.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/string_util.h"
#include "base/threading/thread_task_runner_handle.h"
@@ -175,6 +177,26 @@ bool HasUnknownInvalidAccountInCookie(
} // namespace
+// static
+const char AccountReconcilor::kOperationHistogramName[] =
+ "Signin.Reconciler.Operation";
+
+// static
+const char AccountReconcilor::kTriggerLogoutHistogramName[] =
+ "Signin.Reconciler.Trigger.Logout";
+
+// static
+const char AccountReconcilor::kTriggerMultiloginHistogramName[] =
+ "Signin.Reconciler.Trigger.Multilogin";
+
+// static
+const char AccountReconcilor::kTriggerNoopHistogramName[] =
+ "Signin.Reconciler.Trigger.Noop";
+
+// static
+const char AccountReconcilor::kTriggerThrottledHistogramName[] =
+ "Signin.Reconciler.Trigger.Throttled";
+
AccountReconcilor::Lock::Lock(AccountReconcilor* reconcilor)
: reconcilor_(reconcilor->weak_factory_.GetWeakPtr()) {
DCHECK(reconcilor_);
@@ -208,20 +230,7 @@ AccountReconcilor::AccountReconcilor(
std::unique_ptr<signin::AccountReconcilorDelegate> delegate)
: delegate_(std::move(delegate)),
identity_manager_(identity_manager),
- client_(client),
- registered_with_identity_manager_(false),
- registered_with_content_settings_(false),
- is_reconcile_started_(false),
- first_execution_(true),
- 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),
- timer_(new base::OneShotTimer),
- state_(signin_metrics::ACCOUNT_RECONCILOR_OK) {
+ client_(client) {
VLOG(1) << "AccountReconcilor::AccountReconcilor";
DCHECK(delegate_);
delegate_->set_reconcilor(this);
@@ -253,14 +262,14 @@ void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) {
// Start a reconcile if the tokens are already loaded.
if (start_reconcile_if_tokens_available && IsIdentityManagerReady())
- StartReconcile();
+ StartReconcile(Trigger::kInitialized);
}
}
void AccountReconcilor::EnableReconcile() {
RegisterWithAllDependencies();
if (IsIdentityManagerReady())
- StartReconcile();
+ StartReconcile(Trigger::kEnableReconcile);
else
SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED);
}
@@ -360,7 +369,7 @@ void AccountReconcilor::OnContentSettingChanged(
}
VLOG(1) << "AccountReconcilor::OnContentSettingChanged";
- StartReconcile();
+ StartReconcile(Trigger::kCookieSettingChange);
}
void AccountReconcilor::OnEndBatchOfRefreshTokenStateChanges() {
@@ -368,11 +377,11 @@ void AccountReconcilor::OnEndBatchOfRefreshTokenStateChanges() {
<< "Reconcilor state: " << is_reconcile_started_;
// Remember that accounts have changed if a reconcile is already started.
chrome_accounts_changed_ = is_reconcile_started_;
- StartReconcile();
+ StartReconcile(Trigger::kTokenChange);
}
void AccountReconcilor::OnRefreshTokensLoaded() {
- StartReconcile();
+ StartReconcile(Trigger::kTokensLoaded);
}
void AccountReconcilor::OnErrorStateOfRefreshTokenUpdatedForAccount(
@@ -389,19 +398,8 @@ void AccountReconcilor::OnErrorStateOfRefreshTokenUpdatedForAccount(
identity_manager_->GetAccountsCookieMutator()->TriggerCookieJarUpdate();
}
-void AccountReconcilor::PerformMergeAction(const CoreAccountId& account_id) {
- DCHECK(!IsMultiloginEndpointEnabled());
- reconcile_is_noop_ = false;
- VLOG(1) << "AccountReconcilor::PerformMergeAction: " << account_id;
- identity_manager_->GetAccountsCookieMutator()->AddAccountToCookie(
- account_id, delegate_->GetGaiaApiSource(),
- base::BindOnce(&AccountReconcilor::OnAddAccountToCookieCompleted,
- weak_factory_.GetWeakPtr()));
-}
-
void AccountReconcilor::PerformSetCookiesAction(
const signin::MultiloginParameters& parameters) {
- DCHECK(IsMultiloginEndpointEnabled());
reconcile_is_noop_ = false;
VLOG(1) << "AccountReconcilor::PerformSetCookiesAction: "
<< base::JoinString(ToStringList(parameters.accounts_to_send), " ");
@@ -424,7 +422,7 @@ void AccountReconcilor::PerformLogoutAllAccountsAction() {
weak_factory_.GetWeakPtr()));
}
-void AccountReconcilor::StartReconcile() {
+void AccountReconcilor::StartReconcile(Trigger trigger) {
if (WasShutDown())
return;
@@ -459,11 +457,11 @@ void AccountReconcilor::StartReconcile() {
// Begin reconciliation. Reset initial states.
SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_RUNNING);
- add_to_cookie_.clear();
reconcile_start_time_ = base::Time::Now();
is_reconcile_started_ = true;
error_during_last_reconcile_ = GoogleServiceAuthError::AuthErrorNone();
reconcile_is_noop_ = true;
+ trigger_ = trigger;
if (!timeout_.is_max()) {
timer_->Start(FROM_HERE, timeout_,
@@ -499,7 +497,6 @@ void AccountReconcilor::FinishReconcileWithMultiloginEndpoint(
const CoreAccountId& primary_account,
const std::vector<CoreAccountId>& chrome_accounts,
std::vector<gaia::ListedAccount>&& gaia_accounts) {
- DCHECK(IsMultiloginEndpointEnabled());
DCHECK(!set_accounts_in_progress_);
DCHECK(!log_out_in_progress_);
DCHECK_EQ(AccountReconcilorState::ACCOUNT_RECONCILOR_RUNNING, state_);
@@ -533,21 +530,37 @@ void AccountReconcilor::FinishReconcileWithMultiloginEndpoint(
primary_has_error);
}
if (CookieNeedsUpdate(parameters_for_multilogin, gaia_accounts)) {
- if (parameters_for_multilogin == kLogoutParameters) {
- // UPDATE mode does not support empty list of accounts, call logout
- // instead.
- log_out_in_progress_ = true;
- PerformLogoutAllAccountsAction();
+ // Verify the account reconcilor is not trapped into a loop of repeating the
+ // same request with the same params.
+ if (throttler_.TryMultiloginOperation(parameters_for_multilogin)) {
+ if (parameters_for_multilogin == kLogoutParameters) {
+ RecordReconcileOperation(trigger_, Operation::kLogout);
+ // UPDATE mode does not support empty list of accounts, call logout
+ // instead.
+ log_out_in_progress_ = true;
+ PerformLogoutAllAccountsAction();
+ } else {
+ // Reconcilor has to do some calls to gaia. is_reconcile_started_ is
+ // true and any StartReconcile() calls that are made in the meantime
+ // will be aborted until OnSetAccountsInCookieCompleted is called and
+ // is_reconcile_started_ is set to false.
+ RecordReconcileOperation(trigger_, Operation::kMultilogin);
+ set_accounts_in_progress_ = true;
+ PerformSetCookiesAction(parameters_for_multilogin);
+ }
} else {
- // Reconcilor has to do some calls to gaia. is_reconcile_started_ is true
- // and any StartReconcile() calls that are made in the meantime will be
- // aborted until OnSetAccountsInCookieCompleted is called and
- // is_reconcile_started_ is set to false.
- set_accounts_in_progress_ = true;
- PerformSetCookiesAction(parameters_for_multilogin);
+ // Too many requests with the same parameters led to a backoff time
+ // required between successive identical requests that has not yet passed.
+ error_during_last_reconcile_ =
+ GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
+ CalculateIfMultiloginReconcileIsDone();
+ ScheduleStartReconcileIfChromeAccountsChanged();
+ RecordReconcileOperation(trigger_, Operation::kThrottled);
}
} else {
// Nothing to do, accounts already match.
+ RecordReconcileOperation(trigger_, Operation::kNoop);
+ throttler_.Reset();
error_during_last_reconcile_ = GoogleServiceAuthError::AuthErrorNone();
CalculateIfMultiloginReconcileIsDone();
@@ -585,16 +598,13 @@ void AccountReconcilor::OnAccountsInCookieUpdated(
// let it complete. Adding accounts to the cookie will trigger new
// notifications anyway, and these will be handled in a new reconciliation
// cycle. See https://crbug.com/923716
- if (IsMultiloginEndpointEnabled()) {
- if (set_accounts_in_progress_)
- return;
- } else {
- if (!add_to_cookie_.empty())
- return;
- }
+ //
+ // TODO(droger): Should we also check if |logout_in_progress_|?
+ if (set_accounts_in_progress_)
+ return;
if (!is_reconcile_started_) {
- StartReconcile();
+ StartReconcile(Trigger::kCookieChange);
return;
}
@@ -652,13 +662,8 @@ void AccountReconcilor::OnAccountsInCookieUpdated(
return;
}
- if (IsMultiloginEndpointEnabled()) {
- FinishReconcileWithMultiloginEndpoint(primary_account, chrome_accounts,
- std::move(verified_gaia_accounts));
- } else {
- FinishReconcile(primary_account, chrome_accounts,
- std::move(verified_gaia_accounts));
- }
+ FinishReconcileWithMultiloginEndpoint(primary_account, chrome_accounts,
+ std::move(verified_gaia_accounts));
}
void AccountReconcilor::OnAccountsCookieDeletedByUserAction() {
@@ -726,149 +731,15 @@ void AccountReconcilor::OnReceivedManageAccountsResponse(
}
}
-void AccountReconcilor::FinishReconcile(
- const CoreAccountId& primary_account,
- const std::vector<CoreAccountId>& chrome_accounts,
- std::vector<gaia::ListedAccount>&& gaia_accounts) {
- DCHECK(!IsMultiloginEndpointEnabled());
- VLOG(1) << "AccountReconcilor::FinishReconcile";
- DCHECK(add_to_cookie_.empty());
- DCHECK(delegate_->IsUnknownInvalidAccountInCookieAllowed())
- << "Only supported in UPDATE mode";
-
- size_t number_gaia_accounts = gaia_accounts.size();
- // If there are any accounts in the gaia cookie but not in chrome, then
- // those accounts need to be removed from the cookie. This means we need
- // to blow the cookie away.
- int removed_from_cookie = 0;
- for (size_t i = 0; i < number_gaia_accounts; ++i) {
- if (gaia_accounts[i].valid &&
- !base::Contains(chrome_accounts, gaia_accounts[i].id)) {
- ++removed_from_cookie;
- }
- }
-
- CoreAccountId first_account = delegate_->GetFirstGaiaAccountForReconcile(
- chrome_accounts, gaia_accounts, primary_account, first_execution_,
- removed_from_cookie > 0);
- bool first_account_mismatch =
- (number_gaia_accounts > 0) && (first_account != gaia_accounts[0].id);
-
- bool rebuild_cookie = first_account_mismatch || (removed_from_cookie > 0);
- std::vector<gaia::ListedAccount> original_gaia_accounts = gaia_accounts;
- if (rebuild_cookie) {
- VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie";
- // 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();
- }
-
- if (first_account.empty()) {
- DCHECK(!delegate_->ShouldAbortReconcileIfPrimaryHasError());
- auto revoke_option =
- delegate_->ShouldRevokeTokensIfNoPrimaryAccount()
- ? AccountReconcilorDelegate::RevokeTokenOption::kRevoke
- : AccountReconcilorDelegate::RevokeTokenOption::kDoNotRevoke;
- reconcile_is_noop_ = !RevokeAllSecondaryTokens(
- identity_manager_, revoke_option, primary_account,
- signin_metrics::SourceForRefreshTokenOperation::
- kAccountReconcilor_Reconcile);
- } else {
- // Create a list of accounts that need to be added to the Gaia cookie.
- if (base::Contains(chrome_accounts, first_account)) {
- add_to_cookie_.push_back(first_account);
- } else {
- // If the first account is not empty and not in chrome_accounts, it is
- // impossible to rebuild it. It must be already the current default
- // account, and no logout can happen.
- DCHECK_EQ(gaia_accounts[0].id, first_account);
- DCHECK(!rebuild_cookie);
- }
- for (size_t i = 0; i < chrome_accounts.size(); ++i) {
- if (chrome_accounts[i] != first_account)
- add_to_cookie_.push_back(chrome_accounts[i]);
- }
- }
-
- // For each account known to chrome, PerformMergeAction() if the account is
- // not already in the cookie jar or its state is invalid, or signal merge
- // completed otherwise. Make a copy of |add_to_cookie_| since calls
- // to OnAddAccountToCookieCompleted() will change the array.
- std::vector<CoreAccountId> add_to_cookie_copy = add_to_cookie_;
- int added_to_cookie = 0;
- for (size_t i = 0; i < add_to_cookie_copy.size(); ++i) {
- if (ContainsGaiaAccount(gaia_accounts, add_to_cookie_copy[i])) {
- OnAddAccountToCookieCompleted(add_to_cookie_copy[i],
- GoogleServiceAuthError::AuthErrorNone());
- } else {
- PerformMergeAction(add_to_cookie_copy[i]);
- if (!ContainsGaiaAccount(original_gaia_accounts, add_to_cookie_copy[i])) {
- added_to_cookie++;
- }
- }
- }
-
- signin_metrics::LogSigninAccountReconciliation(
- chrome_accounts.size(), added_to_cookie, removed_from_cookie,
- !first_account_mismatch, first_execution_, number_gaia_accounts);
- first_execution_ = false;
- CalculateIfMergeSessionReconcileIsDone();
- if (!is_reconcile_started_)
- delegate_->OnReconcileFinished(first_account);
- ScheduleStartReconcileIfChromeAccountsChanged();
-}
-
void AccountReconcilor::AbortReconcile() {
VLOG(1) << "AccountReconcilor::AbortReconcile: try again later";
log_out_in_progress_ = false;
- if (IsMultiloginEndpointEnabled()) {
- set_accounts_in_progress_ = false;
- CalculateIfMultiloginReconcileIsDone();
- } else {
- add_to_cookie_.clear();
- CalculateIfMergeSessionReconcileIsDone();
- }
-
+ set_accounts_in_progress_ = false;
+ CalculateIfMultiloginReconcileIsDone();
DCHECK(!is_reconcile_started_);
DCHECK(!timer_->IsRunning());
}
-void AccountReconcilor::CalculateIfMergeSessionReconcileIsDone() {
- DCHECK(!IsMultiloginEndpointEnabled());
- 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() &&
- !log_out_in_progress_) {
- bool was_last_reconcile_successful =
- (error_during_last_reconcile_.state() ==
- GoogleServiceAuthError::State::NONE);
- signin_metrics::LogSigninAccountReconciliationDuration(
- duration, was_last_reconcile_successful);
-
- // Reconciliation has actually finished (and hence stop the timer), but it
- // may have ended in some failures. Pass this information to the
- // |delegate_|.
- timer_->Stop();
- if (!was_last_reconcile_successful) {
- // Note: This is the only call to |OnReconcileError| in this file. We MUST
- // make sure that we do not call |OnReconcileError| multiple times in the
- // same reconciliation batch.
- // The enclosing if-condition |is_reconcile_started_ &&
- // add_to_cookie_.empty()| represents the halting condition for one batch
- // of reconciliation.
- delegate_->OnReconcileError(error_during_last_reconcile_);
- }
- }
-
- is_reconcile_started_ = !add_to_cookie_.empty() || log_out_in_progress_;
- if (!is_reconcile_started_)
- VLOG(1)
- << "AccountReconcilor::CalculateIfMergeSessionReconcileIsDone: done";
-}
-
void AccountReconcilor::ScheduleStartReconcileIfChromeAccountsChanged() {
if (is_reconcile_started_)
return;
@@ -883,7 +754,8 @@ void AccountReconcilor::ScheduleStartReconcileIfChromeAccountsChanged() {
SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_SCHEDULED);
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(&AccountReconcilor::StartReconcile,
- base::Unretained(this)));
+ base::Unretained(this),
+ Trigger::kTokenChangeDuringReconcile));
} else if (error_during_last_reconcile_.state() ==
GoogleServiceAuthError::NONE) {
SetState(AccountReconcilorState::ACCOUNT_RECONCILOR_OK);
@@ -892,25 +764,12 @@ void AccountReconcilor::ScheduleStartReconcileIfChromeAccountsChanged() {
}
}
-// Remove the account from the list that is being merged.
-bool AccountReconcilor::MarkAccountAsAddedToCookie(
- const CoreAccountId& account_id) {
- for (auto i = add_to_cookie_.begin(); i != add_to_cookie_.end(); ++i) {
- if (account_id == *i) {
- add_to_cookie_.erase(i);
- return true;
- }
- }
- return false;
-}
-
bool AccountReconcilor::IsIdentityManagerReady() {
return identity_manager_->AreRefreshTokensLoaded();
}
void AccountReconcilor::OnSetAccountsInCookieCompleted(
signin::SetAccountsInCookieResult result) {
- DCHECK(IsMultiloginEndpointEnabled());
VLOG(1) << "AccountReconcilor::OnSetAccountsInCookieCompleted: "
<< "Error was " << static_cast<int>(result);
@@ -936,7 +795,6 @@ void AccountReconcilor::OnSetAccountsInCookieCompleted(
}
void AccountReconcilor::CalculateIfMultiloginReconcileIsDone() {
- DCHECK(IsMultiloginEndpointEnabled());
DCHECK(!set_accounts_in_progress_);
DCHECK(!log_out_in_progress_);
VLOG(1) << "AccountReconcilor::CalculateIfMultiloginReconcileIsDone: "
@@ -958,27 +816,6 @@ void AccountReconcilor::CalculateIfMultiloginReconcileIsDone() {
duration, was_last_reconcile_successful);
}
-void AccountReconcilor::OnAddAccountToCookieCompleted(
- const CoreAccountId& account_id,
- const GoogleServiceAuthError& error) {
- DCHECK(!IsMultiloginEndpointEnabled());
- VLOG(1) << "AccountReconcilor::OnAddAccountToCookieCompleted: "
- << "Account added: " << account_id << ", "
- << "Error was " << error.ToString();
- // Always listens to GaiaCookieManagerService. Only proceed if reconciling.
- if (is_reconcile_started_ && MarkAccountAsAddedToCookie(account_id)) {
- // We may have seen a series of errors during reconciliation. Delegates may
- // rely on the severity of the last seen error (see |OnReconcileError|) and
- // hence do not override a persistent error, if we have seen one.
- if (error.state() != GoogleServiceAuthError::State::NONE &&
- !error_during_last_reconcile_.IsPersistentError()) {
- error_during_last_reconcile_ = error;
- }
- CalculateIfMergeSessionReconcileIsDone();
- ScheduleStartReconcileIfChromeAccountsChanged();
- }
-}
-
void AccountReconcilor::OnLogOutFromCookieCompleted(
const GoogleServiceAuthError& error) {
VLOG(1) << "AccountReconcilor::OnLogOutFromCookieCompleted: "
@@ -995,13 +832,8 @@ void AccountReconcilor::OnLogOutFromCookieCompleted(
!error_during_last_reconcile_.IsPersistentError()) {
error_during_last_reconcile_ = error;
}
- if (IsMultiloginEndpointEnabled()) {
- CalculateIfMultiloginReconcileIsDone();
- ScheduleStartReconcileIfChromeAccountsChanged();
- } else {
- CalculateIfMergeSessionReconcileIsDone();
- ScheduleStartReconcileIfChromeAccountsChanged();
- }
+ CalculateIfMultiloginReconcileIsDone();
+ ScheduleStartReconcileIfChromeAccountsChanged();
}
}
@@ -1043,7 +875,7 @@ void AccountReconcilor::UnblockReconcile() {
observer.OnUnblockReconcile();
if (reconcile_on_unblock_) {
reconcile_on_unblock_ = false;
- StartReconcile();
+ StartReconcile(Trigger::kUnblockReconcile);
}
}
@@ -1064,15 +896,11 @@ void AccountReconcilor::HandleReconcileTimeout() {
// Will stop reconciliation and inform |delegate_| about
// |error_during_last_reconcile_|, through
- // |CalculateIfMergeSessionReconcileIsDone|.
+ // |CalculateIfReconcileIsDone|.
AbortReconcile();
DCHECK(!timer_->IsRunning());
}
-bool AccountReconcilor::IsMultiloginEndpointEnabled() const {
- return delegate_->IsMultiloginEndpointEnabled();
-}
-
bool AccountReconcilor::CookieNeedsUpdate(
const signin::MultiloginParameters& parameters,
const std::vector<gaia::ListedAccount>& existing_accounts) {
@@ -1118,3 +946,24 @@ void AccountReconcilor::SetState(AccountReconcilorState state) {
bool AccountReconcilor::WasShutDown() const {
return was_shut_down_;
}
+
+// static
+void AccountReconcilor::RecordReconcileOperation(Trigger trigger,
+ Operation operation) {
+ // Using the histogram macro for histogram that may be recorded in a loop.
+ UMA_HISTOGRAM_ENUMERATION(kOperationHistogramName, operation);
+ switch (operation) {
+ case Operation::kNoop:
+ base::UmaHistogramEnumeration(kTriggerNoopHistogramName, trigger);
+ break;
+ case Operation::kLogout:
+ base::UmaHistogramEnumeration(kTriggerLogoutHistogramName, trigger);
+ break;
+ case Operation::kMultilogin:
+ base::UmaHistogramEnumeration(kTriggerMultiloginHistogramName, trigger);
+ break;
+ case Operation::kThrottled:
+ UMA_HISTOGRAM_ENUMERATION(kTriggerThrottledHistogramName, trigger);
+ break;
+ }
+}
diff --git a/chromium/components/signin/core/browser/account_reconcilor.h b/chromium/components/signin/core/browser/account_reconcilor.h
index f31ab8d62db..fe573eeb0bd 100644
--- a/chromium/components/signin/core/browser/account_reconcilor.h
+++ b/chromium/components/signin/core/browser/account_reconcilor.h
@@ -5,10 +5,8 @@
#define COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_
#include <memory>
-#include <string>
#include <vector>
-#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/macros.h"
@@ -22,6 +20,7 @@
#include "components/content_settings/core/common/content_settings_pattern.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
+#include "components/signin/core/browser/account_reconcilor_throttler.h"
#include "components/signin/core/browser/signin_header_helper.h"
#include "components/signin/public/base/signin_client.h"
#include "components/signin/public/base/signin_metrics.h"
@@ -127,8 +126,6 @@ class AccountReconcilor : public KeyedService,
bool IsReconcileBlocked() const;
protected:
- void OnAddAccountToCookieCompleted(const CoreAccountId& account_id,
- const GoogleServiceAuthError& error);
void OnSetAccountsInCookieCompleted(signin::SetAccountsInCookieResult result);
void OnLogOutFromCookieCompleted(const GoogleServiceAuthError& error);
@@ -136,6 +133,8 @@ class AccountReconcilor : public KeyedService,
friend class AccountReconcilorTest;
friend class DiceBrowserTest;
friend class BaseAccountReconcilorTestTable;
+ friend class AccountReconcilorThrottlerTest;
+ friend class AccountReconcilorTestForceDiceMigration;
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTestForceDiceMigration,
TableRowTestCheckNoOp);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMirrorTest,
@@ -151,21 +150,18 @@ class AccountReconcilor : public KeyedService,
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTestMiceMultilogin, TableRowTest);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMiceTest,
AccountReconcilorStateScheduled);
- FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceEndpointParamTest,
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceTest,
DiceTokenServiceRegistration);
- FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceEndpointParamTest,
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceTest,
DiceReconcileWithoutSignin);
- FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceEndpointParamTest,
- DiceReconcileNoop);
- FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceEndpointParamTest,
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceTest, DiceReconcileNoop);
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceTest,
DiceLastKnownFirstAccount);
- FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceEndpointParamTest,
- UnverifiedAccountNoop);
- FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceEndpointParamTest,
- UnverifiedAccountMerge);
- FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceEndpointParamTest,
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceTest, UnverifiedAccountNoop);
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceTest, UnverifiedAccountMerge);
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceTest,
HandleSigninDuringReconcile);
- FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceEndpointParamTest,
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorDiceTest,
DiceReconcileReuseGaiaFirstAccount);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, DiceDeleteCookie);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMirrorTest, TokensNotLoaded);
@@ -229,6 +225,39 @@ class AccountReconcilor : public KeyedService,
TableRowTestMultilogin);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, ReconcileAfterShutdown);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, UnlockAfterShutdown);
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorThrottlerTest, RefillOneRequest);
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorThrottlerTest, RefillFiveRequests);
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorThrottlerTest,
+ NewRequestParamsPasses);
+ FRIEND_TEST_ALL_PREFIXES(AccountReconcilorThrottlerTest, BlockFiveRequests);
+
+ // Operation executed by the reconcilor.
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum class Operation {
+ kNoop = 0,
+ kLogout = 1,
+ kMultilogin = 2,
+ kThrottled = 3,
+
+ kMaxValue = kThrottled
+ };
+
+ // Event triggering a call to StartReconcile().
+ // These values are persisted to logs. Entries should not be renumbered and
+ // numeric values should never be reused.
+ enum class Trigger {
+ kInitialized = 0,
+ kTokensLoaded = 1,
+ kEnableReconcile = 2,
+ kUnblockReconcile = 3,
+ kTokenChange = 4,
+ kTokenChangeDuringReconcile = 5,
+ kCookieChange = 6,
+ kCookieSettingChange = 7,
+
+ kMaxValue = kCookieSettingChange
+ };
void set_timer_for_testing(std::unique_ptr<base::OneShotTimer> timer);
@@ -246,27 +275,22 @@ class AccountReconcilor : public KeyedService,
// All actions with side effects, only doing meaningful work if account
// consistency is enabled. Virtual so that they can be overridden in tests.
- virtual void PerformMergeAction(const CoreAccountId& account_id);
virtual void PerformLogoutAllAccountsAction();
virtual void PerformSetCookiesAction(
const signin::MultiloginParameters& parameters);
// Used during periodic reconciliation.
- void StartReconcile();
+ void StartReconcile(Trigger trigger);
// |gaia_accounts| are the accounts in the Gaia cookie.
void FinishReconcile(const CoreAccountId& primary_account,
const std::vector<CoreAccountId>& chrome_accounts,
std::vector<gaia::ListedAccount>&& gaia_accounts);
void AbortReconcile();
- void CalculateIfMergeSessionReconcileIsDone();
void ScheduleStartReconcileIfChromeAccountsChanged();
// Returns the list of valid accounts from the TokenService.
std::vector<CoreAccountId> LoadValidAccountsFromTokenService() const;
- // Note internally that this |account_id| is added to the cookie jar.
- bool MarkAccountAsAddedToCookie(const CoreAccountId& account_id);
-
// The reconcilor only starts when the token service is ready.
bool IsIdentityManagerReady();
@@ -300,9 +324,6 @@ class AccountReconcilor : public KeyedService,
void HandleReconcileTimeout();
- // Returns true is multilogin endpoint can be enabled.
- bool IsMultiloginEndpointEnabled() const;
-
// Returns true if current array of existing accounts in cookie is different
// from the desired one. If this returns false, the multilogin call would be a
// no-op.
@@ -316,7 +337,17 @@ class AccountReconcilor : public KeyedService,
// Returns whether Shutdown() was called.
bool WasShutDown() const;
+ static void RecordReconcileOperation(Trigger trigger, Operation operation);
+
+ // Histogram names.
+ static const char kOperationHistogramName[];
+ static const char kTriggerLogoutHistogramName[];
+ static const char kTriggerMultiloginHistogramName[];
+ static const char kTriggerNoopHistogramName[];
+ static const char kTriggerThrottledHistogramName[];
+
std::unique_ptr<signin::AccountReconcilorDelegate> delegate_;
+ AccountReconcilorThrottler throttler_;
// The IdentityManager associated with this reconcilor.
signin::IdentityManager* identity_manager_;
@@ -324,16 +355,17 @@ class AccountReconcilor : public KeyedService,
// The SigninClient associated with this reconcilor.
SigninClient* client_;
- bool registered_with_identity_manager_;
- bool registered_with_content_settings_;
+ bool registered_with_identity_manager_ = false;
+ bool registered_with_content_settings_ = false;
// True while the reconcilor is busy checking or managing the accounts in
// this profile.
- bool is_reconcile_started_;
+ bool is_reconcile_started_ = false;
base::Time reconcile_start_time_;
+ Trigger trigger_ = Trigger::kInitialized;
// True iff this is the first time the reconcilor is executing.
- bool first_execution_;
+ bool first_execution_ = true;
// 'Most severe' error encountered during the last attempt to reconcile. If
// the last reconciliation attempt was successful, this will be
@@ -343,23 +375,23 @@ class AccountReconcilor : public KeyedService,
// error is considered more severe than all non-persistent errors, but
// persistent (or non-persistent) errors do not have an internal severity
// ordering among themselves.
- GoogleServiceAuthError error_during_last_reconcile_;
+ GoogleServiceAuthError error_during_last_reconcile_ =
+ GoogleServiceAuthError::AuthErrorNone();
// Used for Dice migration: migration can happen if the accounts are
// consistent, which is indicated by reconcile being a no-op.
- bool reconcile_is_noop_;
+ bool reconcile_is_noop_ = true;
// 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_;
+ bool set_accounts_in_progress_ = false; // Progress of SetAccounts calls.
+ bool log_out_in_progress_ = false; // Progress of LogOut calls.
+ bool chrome_accounts_changed_ = false;
// Used for the Lock.
// StartReconcile() is blocked while this is > 0.
- int account_reconcilor_lock_count_;
+ int account_reconcilor_lock_count_ = 0;
// StartReconcile() should be started when the reconcilor is unblocked.
- bool reconcile_on_unblock_;
+ bool reconcile_on_unblock_ = false;
base::ObserverList<Observer, true>::Unchecked observer_list_;
@@ -371,14 +403,16 @@ class AccountReconcilor : public KeyedService,
// of reconciliation completing within a finite time. It is technically
// possible for account reconciliation to be running/waiting forever in cases
// such as a network connection not being present.
- std::unique_ptr<base::OneShotTimer> timer_;
+ std::unique_ptr<base::OneShotTimer> timer_ =
+ std::make_unique<base::OneShotTimer>();
base::TimeDelta timeout_;
// Greater than 0 when synced data is being deleted, and it is important to
// not invalidate the primary token while this is happening.
int synced_data_deletion_in_progress_count_ = 0;
- signin_metrics::AccountReconcilorState state_;
+ signin_metrics::AccountReconcilorState state_ =
+ signin_metrics::ACCOUNT_RECONCILOR_OK;
// Set to true when Shutdown() is called.
bool was_shut_down_ = false;
diff --git a/chromium/components/signin/core/browser/account_reconcilor_delegate.cc b/chromium/components/signin/core/browser/account_reconcilor_delegate.cc
index a16384a0d34..4c64dbd9875 100644
--- a/chromium/components/signin/core/browser/account_reconcilor_delegate.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor_delegate.cc
@@ -17,10 +17,6 @@ bool AccountReconcilorDelegate::IsReconcileEnabled() const {
return false;
}
-bool AccountReconcilorDelegate::IsMultiloginEndpointEnabled() const {
- return true;
-}
-
gaia::GaiaSource AccountReconcilorDelegate::GetGaiaApiSource() const {
NOTREACHED() << "Reconcile is not enabled, no Gaia API calls should be made.";
return gaia::GaiaSource::kChrome;
diff --git a/chromium/components/signin/core/browser/account_reconcilor_delegate.h b/chromium/components/signin/core/browser/account_reconcilor_delegate.h
index 7a6ecd71d66..7e6e287af9e 100644
--- a/chromium/components/signin/core/browser/account_reconcilor_delegate.h
+++ b/chromium/components/signin/core/browser/account_reconcilor_delegate.h
@@ -5,7 +5,6 @@
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_DELEGATE_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_DELEGATE_H_
-#include <string>
#include <vector>
#include "base/time/time.h"
@@ -40,11 +39,6 @@ class AccountReconcilorDelegate {
// false.
virtual bool IsReconcileEnabled() const;
- // Returns whether the OAuth multilogin endpoint can be used to build the Gaia
- // cookies.
- // Default implementation returns true.
- virtual bool IsMultiloginEndpointEnabled() const;
-
// Returns the value to set in the "source" parameter for Gaia API calls.
virtual gaia::GaiaSource GetGaiaApiSource() const;
diff --git a/chromium/components/signin/core/browser/account_reconcilor_throttler.cc b/chromium/components/signin/core/browser/account_reconcilor_throttler.cc
new file mode 100644
index 00000000000..1742ff043c7
--- /dev/null
+++ b/chromium/components/signin/core/browser/account_reconcilor_throttler.cc
@@ -0,0 +1,113 @@
+// Copyright 2021 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/account_reconcilor_throttler.h"
+
+#include "base/metrics/histogram_functions.h"
+
+namespace {
+MultiloginRequestType GetMultiloginRequestType(
+ const signin::MultiloginParameters& params) {
+ if (params.mode ==
+ gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER) {
+ return MultiloginRequestType::kPreserveCookieAccountsOrder;
+ }
+
+ // Update mode.
+ DCHECK_EQ(params.mode,
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER);
+ if (params.accounts_to_send.size())
+ return MultiloginRequestType::kUpdateCookieAccountsOrder;
+
+ // Accounts to send is empty.
+ return MultiloginRequestType::kLogoutAllAccounts;
+}
+} // namespace
+
+// static
+constexpr float AccountReconcilorThrottler::kMaxAllowedRequestsPerBucket;
+// static
+constexpr float AccountReconcilorThrottler::kRefillRequestsBucketRatePerMinute;
+
+AccountReconcilorThrottler::AccountReconcilorThrottler() {
+ Reset();
+}
+
+AccountReconcilorThrottler::~AccountReconcilorThrottler() {
+ RecordAndResetNumberOfRejectedRequests();
+}
+
+void AccountReconcilorThrottler::Reset() {
+ // Needed for the case when the reconcilor is a no op and calls reset.
+ RecordAndResetNumberOfRejectedRequests();
+ last_request_params_ = absl::nullopt;
+ available_requests_bucket_ = kMaxAllowedRequestsPerBucket;
+ last_refill_time_stamp_ = base::TimeTicks::Now();
+}
+
+bool AccountReconcilorThrottler::IsDifferentRequest(
+ const signin::MultiloginParameters& params) const {
+ return !last_request_params_.has_value() ||
+ params != last_request_params_.value();
+}
+
+bool AccountReconcilorThrottler::TryMultiloginOperation(
+ const signin::MultiloginParameters& params) {
+ if (IsDifferentRequest(params))
+ Reset();
+
+ RefillAllowedRequests();
+ if (available_requests_bucket_ < 1.0) {
+ ++consecutive_rejected_requests_;
+ return false;
+ }
+
+ RecordMultiloginOperation(params);
+ RecordAndResetNumberOfRejectedRequests();
+ return true;
+}
+
+void AccountReconcilorThrottler::RecordMultiloginOperation(
+ const signin::MultiloginParameters& params) {
+ DCHECK_GE(available_requests_bucket_, 1.0f);
+ last_request_params_ = params;
+ available_requests_bucket_ -= 1.0f;
+}
+
+void AccountReconcilorThrottler::RefillAllowedRequests() {
+ float refill_requests =
+ (base::TimeTicks::Now() - last_refill_time_stamp_).InSecondsF() / 60.0 *
+ kRefillRequestsBucketRatePerMinute;
+
+ available_requests_bucket_ =
+ std::min(available_requests_bucket_ + refill_requests,
+ kMaxAllowedRequestsPerBucket);
+ last_refill_time_stamp_ = base::TimeTicks::Now();
+}
+
+void AccountReconcilorThrottler::RecordAndResetNumberOfRejectedRequests() {
+ if (!consecutive_rejected_requests_)
+ return;
+
+ DCHECK(last_request_params_.has_value());
+ switch (GetMultiloginRequestType(last_request_params_.value())) {
+ case MultiloginRequestType::kPreserveCookieAccountsOrder:
+ base::UmaHistogramCounts1000(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.Preserve",
+ consecutive_rejected_requests_);
+ break;
+ case MultiloginRequestType::kUpdateCookieAccountsOrder:
+ base::UmaHistogramCounts1000(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.Update",
+ consecutive_rejected_requests_);
+ break;
+ case MultiloginRequestType::kLogoutAllAccounts:
+ base::UmaHistogramCounts1000(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.LogoutAll",
+ consecutive_rejected_requests_);
+ break;
+ }
+
+ consecutive_rejected_requests_ = 0;
+}
diff --git a/chromium/components/signin/core/browser/account_reconcilor_throttler.h b/chromium/components/signin/core/browser/account_reconcilor_throttler.h
new file mode 100644
index 00000000000..e4e2e02c2e4
--- /dev/null
+++ b/chromium/components/signin/core/browser/account_reconcilor_throttler.h
@@ -0,0 +1,61 @@
+// Copyright 2021 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_ACCOUNT_RECONCILOR_THROTTLER_H_
+#define COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_THROTTLER_H_
+
+#include "base/time/time.h"
+#include "components/signin/public/base/multilogin_parameters.h"
+
+// Used for UMA logging, do not remove or reorder values.
+enum class MultiloginRequestType {
+ kPreserveCookieAccountsOrder = 0,
+ kUpdateCookieAccountsOrder = 1,
+ kLogoutAllAccounts = 2,
+ kMaxValue = kLogoutAllAccounts,
+};
+
+// Helper class to avoid the account reconcilor from getting into a loop,
+// repeating the same request and generating a spike in the number of requests.
+class AccountReconcilorThrottler {
+ public:
+ AccountReconcilorThrottler();
+ ~AccountReconcilorThrottler();
+
+ AccountReconcilorThrottler(const AccountReconcilorThrottler&) = delete;
+ AccountReconcilorThrottler& operator=(const AccountReconcilorThrottler&) =
+ delete;
+
+ // The multilogin operation should be sent or blocked based on the result of
+ // this function. It returns true if not all the |available_requests_ >= 1.0|
+ // has been consumed, and consumes one of the available requests.
+ bool TryMultiloginOperation(const signin::MultiloginParameters& params);
+
+ // Any request passed to |IsMultiloginOperationAllowed()| after |Reset()| is
+ // called is considered as a new different request.
+ // |available_requests_bucket_| is reset to its max allowance.
+ void Reset();
+
+ // Max bucket size. The throttler tolerates up to 30 successive identical
+ // requests before throttling.
+ static constexpr float kMaxAllowedRequestsPerBucket = 30.0f;
+
+ // Requests bucket is refilled with the rate of 0.5 per minute. If all the
+ // available requests have been consumed, the reconcilor will need to wait for
+ // 2 minutes from the last request to perform another identical request.
+ static constexpr float kRefillRequestsBucketRatePerMinute = 0.5f;
+
+ private:
+ bool IsDifferentRequest(const signin::MultiloginParameters& params) const;
+ void RefillAllowedRequests();
+ void RecordMultiloginOperation(const signin::MultiloginParameters& params);
+ void RecordAndResetNumberOfRejectedRequests();
+
+ // Reset for every new request with different parameters.
+ float available_requests_bucket_;
+ base::TimeTicks last_refill_time_stamp_;
+ absl::optional<signin::MultiloginParameters> last_request_params_;
+ size_t consecutive_rejected_requests_ = 0;
+};
+
+#endif // COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_THROTTLER_H_
diff --git a/chromium/components/signin/core/browser/account_reconcilor_unittest.cc b/chromium/components/signin/core/browser/account_reconcilor_unittest.cc
index ac9d75d907d..4933f0b9bd4 100644
--- a/chromium/components/signin/core/browser/account_reconcilor_unittest.cc
+++ b/chromium/components/signin/core/browser/account_reconcilor_unittest.cc
@@ -175,7 +175,6 @@ class MockAccountReconcilor
SigninClient* client,
std::unique_ptr<signin::AccountReconcilorDelegate> delegate);
- MOCK_METHOD1(PerformMergeAction, void(const CoreAccountId& account_id));
MOCK_METHOD0(PerformLogoutAllAccountsAction, void());
MOCK_METHOD1(PerformSetCookiesAction,
void(const signin::MultiloginParameters& parameters));
@@ -252,10 +251,6 @@ class AccountReconcilorTest : public ::testing::Test {
CoreAccountId PickAccountIdForAccount(const std::string& gaia_id,
const std::string& username);
- void SimulateAddAccountToCookieCompleted(AccountReconcilor* reconcilor,
- const CoreAccountId& account_id,
- const GoogleServiceAuthError& error);
-
void SimulateSetAccountsInCookieCompleted(
AccountReconcilor* reconcilor,
signin::SetAccountsInCookieResult result);
@@ -379,13 +374,6 @@ CoreAccountId AccountReconcilorTest::PickAccountIdForAccount(
gaia_id, username);
}
-void AccountReconcilorTest::SimulateAddAccountToCookieCompleted(
- AccountReconcilor* reconcilor,
- const CoreAccountId& account_id,
- const GoogleServiceAuthError& error) {
- reconcilor->OnAddAccountToCookieCompleted(account_id, error);
-}
-
void AccountReconcilorTest::SimulateSetAccountsInCookieCompleted(
AccountReconcilor* reconcilor,
signin::SetAccountsInCookieResult result) {
@@ -437,9 +425,6 @@ struct AccountReconcilorTestTableParam {
const char* gaia_api_calls;
const char* tokens_after_reconcile;
const char* cookies_after_reconcile;
- const char* gaia_api_calls_multilogin;
- const char* tokens_after_reconcile_multilogin;
- const char* cookies_after_reconcile_multilogin;
// Int represents AccountReconcilorDelegate::InconsistencyReason.
const int inconsistency_reason;
};
@@ -480,26 +465,7 @@ void PrintTo(const AccountReconcilorTestTableParam& param, ::std::ostream* os) {
class BaseAccountReconcilorTestTable : public AccountReconcilorTest {
protected:
- BaseAccountReconcilorTestTable(const AccountReconcilorTestTableParam& param)
- : BaseAccountReconcilorTestTable(param.tokens,
- param.cookies,
- param.is_first_reconcile,
- param.gaia_api_calls,
- param.tokens_after_reconcile,
- param.cookies_after_reconcile) {}
-
- BaseAccountReconcilorTestTable(const char* tokens,
- const char* cookies,
- IsFirstReconcile is_first_reconcile,
- const char* gaia_api_calls,
- const char* tokens_after_reconcile,
- const char* cookies_after_reconcile)
- : tokens_(tokens),
- cookies_(cookies),
- is_first_reconcile_(is_first_reconcile),
- gaia_api_calls_(gaia_api_calls),
- tokens_after_reconcile_(tokens_after_reconcile),
- cookies_after_reconcile_(cookies_after_reconcile) {
+ BaseAccountReconcilorTestTable() {
accounts_['A'] = {"a@gmail.com",
signin::GetTestGaiaIdForEmail("a@gmail.com")};
accounts_['B'] = {"b@gmail.com",
@@ -634,111 +600,11 @@ class BaseAccountReconcilorTestTable : public AccountReconcilorTest {
identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
}
-#if BUILDFLAG(ENABLE_DICE_SUPPORT)
- void RunReconcile() {
- // Setup cookies.
- std::vector<Cookie> cookies = ParseCookieString(cookies_);
- ConfigureCookieManagerService(cookies);
-
- // Call list accounts now so that the next call completes synchronously.
- identity_test_env()->identity_manager()->GetAccountsInCookieJar();
- base::RunLoop().RunUntilIdle();
-
- // Setup tokens. This triggers listing cookies so we need to setup cookies
- // before that.
- SetupTokens(tokens_);
-
- // Setup expectations.
- testing::InSequence mock_sequence;
- bool logout_action = false;
- for (int i = 0; gaia_api_calls_[i] != '\0'; ++i) {
- if (gaia_api_calls_[i] == 'X') {
- logout_action = true;
- EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
- .Times(1);
- cookies.clear();
- continue;
- }
- std::string cookie(1, gaia_api_calls_[i]);
- CoreAccountId account_id_for_cookie = PickAccountIdForAccount(
- accounts_[cookie[0]].gaia_id, accounts_[cookie[0]].email);
- EXPECT_CALL(*GetMockReconcilor(),
- PerformMergeAction(account_id_for_cookie))
- .Times(1);
- // MergeSession fixes an existing cookie or appends it at the end.
- auto it =
- std::find(cookies.begin(), cookies.end(),
- Cookie{accounts_[cookie[0]].gaia_id, false /* is_valid */});
- if (it == cookies.end())
- cookies.push_back({accounts_[cookie[0]].gaia_id, true});
- else
- it->is_valid = true;
- }
- if (!logout_action) {
- EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
- .Times(0);
- }
-
- // Check the expected cookies after reconcile.
- std::vector<Cookie> expected_cookies =
- ParseCookieString(cookies_after_reconcile_);
- ASSERT_EQ(expected_cookies, cookies);
-
- // Reconcile.
- AccountReconcilor* reconcilor = GetMockReconcilor();
- ASSERT_TRUE(reconcilor->first_execution_);
- reconcilor->first_execution_ =
- is_first_reconcile_ == IsFirstReconcile::kFirst;
- reconcilor->StartReconcile();
- for (int i = 0; gaia_api_calls_[i] != '\0'; ++i) {
- 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);
- SimulateAddAccountToCookieCompleted(
- reconcilor, account_id, GoogleServiceAuthError::AuthErrorNone());
- }
- ASSERT_FALSE(reconcilor->is_reconcile_started_);
-
- if (tokens_ == tokens_after_reconcile_) {
- EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
- } else {
- // If the tokens were changed by the reconcile, a new reconcile should be
- // scheduled.
- EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED,
- reconcilor->GetState());
- }
-
- VerifyCurrentTokens(ParseTokenString(tokens_after_reconcile_));
-
- testing::Mock::VerifyAndClearExpectations(GetMockReconcilor());
-
- // Another reconcile is sometimes triggered if Chrome accounts have changed.
- // Allow it to finish.
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(testing::_))
- .WillRepeatedly(testing::Return());
- EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
- .WillRepeatedly(testing::Return());
- ConfigureCookieManagerService({});
- base::RunLoop().RunUntilIdle();
- }
-#endif // BUILDFLAG(ENABLE_DICE_SUPPORT)
-
std::string GaiaIdForAccountKey(char account_key) {
return accounts_[account_key].gaia_id;
}
std::map<char, Account> accounts_;
- const char* tokens_;
- const char* cookies_;
- IsFirstReconcile is_first_reconcile_;
- const char* gaia_api_calls_;
- const char* tokens_after_reconcile_;
- const char* cookies_after_reconcile_;
};
// Parameterized version of AccountReconcilorTest.
@@ -746,35 +612,24 @@ class AccountReconcilorTestTable
: public BaseAccountReconcilorTestTable,
public ::testing::WithParamInterface<AccountReconcilorTestTableParam> {
protected:
- AccountReconcilorTestTable() : BaseAccountReconcilorTestTable(GetParam()) {}
+ AccountReconcilorTestTable() = default;
// Checks that reconcile is idempotent.
void CheckReconcileIdempotent(
const std::vector<AccountReconcilorTestTableParam>& params,
- const AccountReconcilorTestTableParam& param,
- bool multilogin) {
+ const AccountReconcilorTestTableParam& param) {
// Simulate another reconcile based on the results of this one: find the
// corresponding row in the table and check that it does nothing.
for (const AccountReconcilorTestTableParam& row : params) {
if (row.is_first_reconcile == IsFirstReconcile::kFirst)
continue;
- if (!((strcmp(row.tokens, param.tokens_after_reconcile) == 0 &&
- strcmp(row.cookies, param.cookies_after_reconcile) == 0 &&
- !multilogin) ||
- (strcmp(row.tokens, param.tokens_after_reconcile_multilogin) == 0 &&
- strcmp(row.cookies, param.cookies_after_reconcile_multilogin) ==
- 0 &&
- multilogin))) {
+ if (!(strcmp(row.tokens, param.tokens_after_reconcile) == 0 &&
+ strcmp(row.cookies, param.cookies_after_reconcile) == 0)) {
continue;
}
- if (multilogin) {
- EXPECT_STREQ(row.tokens, row.tokens_after_reconcile_multilogin);
- EXPECT_STREQ(row.cookies, row.cookies_after_reconcile_multilogin);
- } else {
- EXPECT_STREQ(row.tokens, row.tokens_after_reconcile);
- EXPECT_STREQ(row.cookies, row.cookies_after_reconcile);
- }
+ EXPECT_STREQ(row.tokens, row.tokens_after_reconcile);
+ EXPECT_STREQ(row.cookies, row.cookies_after_reconcile);
return;
}
@@ -810,7 +665,8 @@ TEST_F(AccountReconcilorMirrorTest, Reauth) {
auto* account_mutator =
identity_test_env()->identity_manager()->GetPrimaryAccountMutator();
DCHECK(account_mutator);
- account_mutator->SetPrimaryAccount(account_info.account_id);
+ account_mutator->SetPrimaryAccount(account_info.account_id,
+ signin::ConsentLevel::kSync);
ASSERT_TRUE(reconcilor->IsRegisteredWithIdentityManager());
}
@@ -878,248 +734,285 @@ const std::vector<AccountReconcilorTestTableParam> kDiceParams = {
// x: The next cookie is marked "invalid".
// - First Run: true if this is the first reconcile (i.e. Chrome startup).
// -------------------------------------------------------------------------
- // Tokens|Cookies|First Run|Gaia calls|Tokens aft.|Cookies aft.|M.calls| M.Tokens aft.| M.Cookies aft.| AccountReconcilorDelegate::InconsistencyReason |
+ // Tokens|Cookies|First Run|Gaia calls|Tokens aft.|Cookies aft.|AccountReconcilorDelegate::InconsistencyReason |
// -------------------------------------------------------------------------
// First reconcile (Chrome restart): Rebuild the Gaia cookie to match the
// tokens. Make the Sync account the default account in the Gaia cookie.
// Sync enabled.
- { "", "A", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3},
- { "*AB", "AB", IsFirstReconcile::kBoth, "", "*AB", "AB", "", "*AB", "AB", 0},
- { "*A", "A", IsFirstReconcile::kBoth, "", "*A", "A", "", "*A" , "A", 0},
- { "*A", "", IsFirstReconcile::kBoth, "A", "*A", "A", "PA", "*A" , "A", 1},
- { "*A", "B", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A" , "A", 1},
- { "*A", "AB", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A" , "A", 5},
- { "*AB", "BA", IsFirstReconcile::kFirst, "XAB", "*AB", "AB", "UAB", "*AB", "AB", 7},
- { "*AB", "BA", IsFirstReconcile::kNotFirst, "", "*AB", "BA", "", "*AB", "BA", 0},
+ { "", "A", IsFirstReconcile::kBoth, "U", "", "", 3},
+ { "*AB", "AB", IsFirstReconcile::kBoth, "", "*AB", "AB", 0},
+ { "*A", "A", IsFirstReconcile::kBoth, "", "*A" , "A", 0},
+ { "*A", "", IsFirstReconcile::kBoth, "PA", "*A" , "A", 1},
+ { "*A", "B", IsFirstReconcile::kBoth, "UA", "*A" , "A", 1},
+ { "*A", "AB", IsFirstReconcile::kBoth, "UA", "*A" , "A", 5},
+ { "*AB", "BA", IsFirstReconcile::kFirst, "UAB", "*AB", "AB", 7},
+ { "*AB", "BA", IsFirstReconcile::kNotFirst,"", "*AB", "BA", 0},
- { "*AB", "A", IsFirstReconcile::kBoth, "B", "*AB", "AB", "PAB", "*AB", "AB", 4},
+ { "*AB", "A", IsFirstReconcile::kBoth, "PAB", "*AB", "AB", 4},
- { "*AB", "B", IsFirstReconcile::kFirst, "XAB", "*AB", "AB", "UAB", "*AB", "AB", 1},
- { "*AB", "B", IsFirstReconcile::kNotFirst, "A", "*AB", "BA", "PBA", "*AB", "BA", 1},
+ { "*AB", "B", IsFirstReconcile::kFirst, "UAB", "*AB", "AB", 1},
+ { "*AB", "B", IsFirstReconcile::kNotFirst,"PBA", "*AB", "BA", 1},
- { "*AB", "", IsFirstReconcile::kBoth, "AB", "*AB", "AB", "PAB", "*AB", "AB", 1},
+ { "*AB", "", IsFirstReconcile::kBoth, "PAB", "*AB", "AB", 1},
// Sync enabled, token error on primary.
- { "*xAB", "AB", IsFirstReconcile::kBoth, "X", "*xA", "" , "U", "*xA", "", 2},
- { "*xAB", "BA", IsFirstReconcile::kBoth, "XB", "*xAB", "B", "UB", "*xAB", "B", 2},
- { "*xAB", "A", IsFirstReconcile::kBoth, "X", "*xA", "" , "U", "*xA", "", 2},
- { "*xAB", "B", IsFirstReconcile::kBoth, "", "*xAB", "B", "", "*xAB", "B", 0},
- { "*xAB", "", IsFirstReconcile::kBoth, "B", "*xAB", "B", "PB", "*xAB", "B", 0},
+ { "*xAB", "AB", IsFirstReconcile::kBoth, "U", "*xA", "", 2},
+ { "*xAB", "BA", IsFirstReconcile::kBoth, "UB", "*xAB", "B", 2},
+ { "*xAB", "A", IsFirstReconcile::kBoth, "U", "*xA", "", 2},
+ { "*xAB", "B", IsFirstReconcile::kBoth, "", "*xAB", "B", 0},
+ { "*xAB", "", IsFirstReconcile::kBoth, "PB", "*xAB", "B", 0},
// Sync enabled, token error on secondary.
- { "*AxB", "AB", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A", "A", 5},
- { "*AxB", "A", IsFirstReconcile::kBoth, "", "*A", "A", "", "*A", "A", 0},
- { "*AxB", "", IsFirstReconcile::kBoth, "A", "*A", "A", "PA", "*A", "A", 1},
+ { "*AxB", "AB", IsFirstReconcile::kBoth, "UA", "*A", "A", 5},
+ { "*AxB", "A", IsFirstReconcile::kBoth, "", "*A", "A", 0},
+ { "*AxB", "", IsFirstReconcile::kBoth, "PA", "*A", "A", 1},
// The first account in cookies is swapped even when Chrome is running.
// The swap would happen at next startup anyway and doing it earlier avoids signing the user out.
- { "*AxB", "BA", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A", "A", 5},
- { "*AxB", "B", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A", "A", 1},
+ { "*AxB", "BA", IsFirstReconcile::kBoth, "UA", "*A", "A", 5},
+ { "*AxB", "B", IsFirstReconcile::kBoth, "UA", "*A", "A", 1},
// Sync enabled, token error on both accounts.
- { "*xAxB", "AB", IsFirstReconcile::kBoth, "X", "*xA", "", "U", "*xA", "", 2},
- { "*xAxB", "BA", IsFirstReconcile::kBoth, "X", "*xA", "", "U", "*xA", "", 2},
- { "*xAxB", "A", IsFirstReconcile::kBoth, "X", "*xA", "", "U", "*xA", "", 2},
- { "*xAxB", "B", IsFirstReconcile::kBoth, "X", "*xA", "", "U", "*xA", "", 5},
- { "*xAxB", "", IsFirstReconcile::kBoth, "", "*xA", "", "", "*xA", "", 0},
+ { "*xAxB", "AB", IsFirstReconcile::kBoth, "U", "*xA", "", 2},
+ { "*xAxB", "BA", IsFirstReconcile::kBoth, "U", "*xA", "", 2},
+ { "*xAxB", "A", IsFirstReconcile::kBoth, "U", "*xA", "", 2},
+ { "*xAxB", "B", IsFirstReconcile::kBoth, "U", "*xA", "", 5},
+ { "*xAxB", "", IsFirstReconcile::kBoth, "", "*xA", "", 0},
// Sync disabled.
- { "AB", "AB", IsFirstReconcile::kBoth, "", "AB", "AB", "", "AB", "AB", 0},
- { "AB", "BA", IsFirstReconcile::kBoth, "", "AB", "BA", "", "AB", "BA", 0},
- { "AB", "A", IsFirstReconcile::kBoth, "B", "AB", "AB", "PAB", "AB", "AB", 4},
- { "AB", "B", IsFirstReconcile::kBoth, "A", "AB", "BA", "PBA", "AB", "BA", 4},
- { "AB", "", IsFirstReconcile::kBoth, "AB", "AB", "AB", "PAB", "AB", "AB", 0},
+ { "AB", "AB", IsFirstReconcile::kBoth, "", "AB", "AB", 0},
+ { "AB", "BA", IsFirstReconcile::kBoth, "", "AB", "BA", 0},
+ { "AB", "A", IsFirstReconcile::kBoth, "PAB", "AB", "AB", 4},
+ { "AB", "B", IsFirstReconcile::kBoth, "PBA", "AB", "BA", 4},
+ { "AB", "", IsFirstReconcile::kBoth, "PAB", "AB", "AB", 0},
// Sync disabled, token error on first account.
- { "xAB", "AB", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 3},
- { "xAB", "AB", IsFirstReconcile::kNotFirst, "X", "", "" , "U", "", "", 3},
+ { "xAB", "AB", IsFirstReconcile::kFirst, "UB", "B", "B", 3},
+ { "xAB", "AB", IsFirstReconcile::kNotFirst, "U", "", "", 3},
- { "xAB", "BA", IsFirstReconcile::kBoth, "XB", "B", "B", "UB", "B", "B", 5},
+ { "xAB", "BA", IsFirstReconcile::kBoth, "UB", "B", "B", 5},
- { "xAB", "A", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 3},
- { "xAB", "A", IsFirstReconcile::kNotFirst, "X", "", "" , "U", "", "", 3},
+ { "xAB", "A", IsFirstReconcile::kFirst, "UB", "B", "B", 3},
+ { "xAB", "A", IsFirstReconcile::kNotFirst, "U", "", "", 3},
- { "xAB", "B", IsFirstReconcile::kBoth, "", "B", "B", "", "B", "B", 0},
+ { "xAB", "B", IsFirstReconcile::kBoth, "", "B", "B", 0},
- { "xAB", "", IsFirstReconcile::kBoth, "B", "B", "B", "PB", "B", "B", 0},
- // Sync disabled, token error on second account .
- { "AxB", "AB", IsFirstReconcile::kBoth, "XA", "A", "A", "UA", "A", "A", 5},
+ { "xAB", "", IsFirstReconcile::kBoth, "PB", "B", "B", 0},
+ // Sync disabled, token error on second account
+ { "AxB", "AB", IsFirstReconcile::kBoth, "UA", "A", "A", 5},
- { "AxB", "BA", IsFirstReconcile::kFirst, "XA", "A", "A", "UA", "A", "A", 3},
- { "AxB", "BA", IsFirstReconcile::kNotFirst, "X", "", "" , "U", "", "", 3},
+ { "AxB", "BA", IsFirstReconcile::kFirst, "UA", "A", "A", 3},
+ { "AxB", "BA", IsFirstReconcile::kNotFirst, "U", "", "", 3},
- { "AxB", "A", IsFirstReconcile::kBoth, "", "A", "A", "", "A", "A", 0},
+ { "AxB", "A", IsFirstReconcile::kBoth, "", "A", "A", 0},
- { "AxB", "B", IsFirstReconcile::kFirst, "XA", "A", "A", "UA", "A", "A", 3},
- { "AxB", "B", IsFirstReconcile::kNotFirst, "X", "", "" , "U", "", "", 3},
+ { "AxB", "B", IsFirstReconcile::kFirst, "UA", "A", "A", 3},
+ { "AxB", "B", IsFirstReconcile::kNotFirst, "U", "", "", 3},
- { "AxB", "", IsFirstReconcile::kBoth, "A", "A", "A", "PA", "A", "A", 0},
+ { "AxB", "", IsFirstReconcile::kBoth, "PA", "A", "A", 0},
// Sync disabled, token error on both accounts.
- { "xAxB", "AB", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3},
- { "xAxB", "BA", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3},
- { "xAxB", "A", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3},
- { "xAxB", "B", IsFirstReconcile::kBoth, "X", "", "", "U", "", "", 3},
- { "xAxB", "", IsFirstReconcile::kBoth, "", "", "", "", "", "", 0},
+ { "xAxB", "AB", IsFirstReconcile::kBoth, "U", "", "", 3},
+ { "xAxB", "BA", IsFirstReconcile::kBoth, "U", "", "", 3},
+ { "xAxB", "A", IsFirstReconcile::kBoth, "U", "", "", 3},
+ { "xAxB", "B", IsFirstReconcile::kBoth, "U", "", "", 3},
+ { "xAxB", "", IsFirstReconcile::kBoth, "", "", "", 0},
// Account marked as invalid in cookies.
// No difference between cookies and tokens, do not do do anything.
// Do not logout. Regression tests for http://crbug.com/854799
- { "", "xA", IsFirstReconcile::kBoth, "", "", "xA", "", "", "xA", 0},
- { "", "xAxB", IsFirstReconcile::kBoth, "", "", "xAxB", "", "", "xAxB", 0},
- { "xA", "xA", IsFirstReconcile::kBoth, "", "", "xA", "", "", "xA", 0},
- { "xAB", "xAB", IsFirstReconcile::kBoth, "", "B", "xAB", "", "B", "xAB", 0},
- { "AxB", "AxC", IsFirstReconcile::kBoth, "", "A", "AxC", "", "A", "AxC", 0},
- { "B", "xAB", IsFirstReconcile::kBoth, "", "B", "xAB", "", "B", "xAB", 0},
- { "*xA", "xA", IsFirstReconcile::kBoth, "", "*xA", "xA", "", "*xA", "xA", 0},
- { "*xA", "xB", IsFirstReconcile::kBoth, "", "*xA", "xB", "", "*xA", "xB", 0},
- { "*xAB", "xAB", IsFirstReconcile::kBoth, "", "*xAB", "xAB", "", "*xAB", "xAB", 0},
- { "*AxB", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", "", "*A", "xBA", 0},
+ { "", "xA", IsFirstReconcile::kBoth, "", "", "xA", 0},
+ { "", "xAxB", IsFirstReconcile::kBoth, "", "", "xAxB", 0},
+ { "xA", "xA", IsFirstReconcile::kBoth, "", "", "xA", 0},
+ { "xAB", "xAB", IsFirstReconcile::kBoth, "", "B", "xAB", 0},
+ { "AxB", "AxC", IsFirstReconcile::kBoth, "", "A", "AxC", 0},
+ { "B", "xAB", IsFirstReconcile::kBoth, "", "B", "xAB", 0},
+ { "*xA", "xA", IsFirstReconcile::kBoth, "", "*xA", "xA", 0},
+ { "*xA", "xB", IsFirstReconcile::kBoth, "", "*xA", "xB", 0},
+ { "*xAB", "xAB", IsFirstReconcile::kBoth, "", "*xAB", "xAB", 0},
+ { "*AxB", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", 0},
// Appending a new cookie after the invalid one.
- { "B", "xA", IsFirstReconcile::kBoth, "B", "B", "xAB", "PB", "B", "xAB", 4},
- { "xAB", "xA", IsFirstReconcile::kBoth, "B", "B", "xAB", "PB", "B", "xAB", 4},
+ { "B", "xA", IsFirstReconcile::kBoth, "PB", "B", "xAB", 4},
+ { "xAB", "xA", IsFirstReconcile::kBoth, "PB", "B", "xAB", 4},
// Refresh existing cookies.
- { "AB", "xAB", IsFirstReconcile::kBoth, "A", "AB", "AB", "PAB", "AB", "AB", 4},
- { "*AB", "xBxA", IsFirstReconcile::kNotFirst, "BA", "*AB", "BA", "PBA", "*AB", "BA", 1},
+ { "AB", "xAB", IsFirstReconcile::kBoth, "PAB", "AB", "AB", 4},
+ { "*AB", "xBxA", IsFirstReconcile::kNotFirst, "PBA", "*AB", "BA", 1},
// Appending and invalidating cookies at the same time.
- { "xAB", "xAC", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 6},
- { "xAB", "xAC", IsFirstReconcile::kNotFirst, "X", "", "", "U", "", "", 6},
+ { "xAB", "xAC", IsFirstReconcile::kFirst, "UB", "B", "B", 6},
+ { "xAB", "xAC", IsFirstReconcile::kNotFirst, "U", "", "", 6},
- { "xAB", "AxC", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 3},
- { "xAB", "AxC", IsFirstReconcile::kNotFirst, "X", "", "", "U", "", "", 3},
+ { "xAB", "AxC", IsFirstReconcile::kFirst, "UB", "B", "B", 3},
+ { "xAB", "AxC", IsFirstReconcile::kNotFirst, "U", "", "", 3},
- { "*xAB", "xABC", IsFirstReconcile::kFirst, "XB", "*xAB", "B", "UB", "*xAB", "B", 5},
- { "*xAB", "xABC", IsFirstReconcile::kNotFirst, "X", "*xA", "", "U", "*xA", "", 5},
+ { "*xAB", "xABC", IsFirstReconcile::kFirst, "UB", "*xAB", "B", 5},
+ { "*xAB", "xABC", IsFirstReconcile::kNotFirst, "U", "*xA", "", 5},
- { "xAB", "xABC", IsFirstReconcile::kFirst, "XB", "B", "B", "UB", "B", "B", 5},
- { "xAB", "xABC", IsFirstReconcile::kNotFirst, "X", "", "", "U", "", "", 5},
+ { "xAB", "xABC", IsFirstReconcile::kFirst, "UB", "B", "B", 5},
+ { "xAB", "xABC", IsFirstReconcile::kNotFirst, "U", "", "", 5},
// Miscellaneous cases.
- // Check that unknown Gaia accounts are signed out.
- { "*A", "AB", IsFirstReconcile::kBoth, "XA", "*A", "A", "UA", "*A", "A", 5},
+ // Check that unknown Gaia accounts are signed o.
+ { "*A", "AB", IsFirstReconcile::kBoth, "UA", "*A", "A", 5},
// Check that Gaia default account is kept in first position.
- { "AB", "BC", IsFirstReconcile::kBoth, "XBA", "AB", "BA", "UBA", "AB", "BA", 6},
+ { "AB", "BC", IsFirstReconcile::kBoth, "UBA", "AB", "BA", 6},
// Check that Gaia cookie order is preserved for B.
- { "*ABC", "CB", IsFirstReconcile::kFirst, "XABC", "*ABC", "ABC", "UABC", "*ABC", "ABC", 1},
+ { "*ABC", "CB", IsFirstReconcile::kFirst, "UABC", "*ABC", "ABC", 1},
// TODO(https://crbug.com/1129931): Merge session should do XCB instead.
- { "xABC", "ABC", IsFirstReconcile::kFirst, "XBC", "BC", "BC", "UCB", "BC", "CB", 1},
+ { "xABC", "ABC", IsFirstReconcile::kFirst, "UCB", "BC", "CB", 1},
// Check that order in the chrome_accounts is not important.
- { "A*B", "", IsFirstReconcile::kBoth, "BA", "A*B", "BA", "PBA", "A*B", "BA", 7},
- { "*xBA", "BA", IsFirstReconcile::kFirst, "X", "*xB", "" , "U", "*xB", "", 2},
+ { "A*B", "", IsFirstReconcile::kBoth, "PBA", "A*B", "BA", 7},
+ { "*xBA", "BA", IsFirstReconcile::kFirst, "U", "*xB", "", 2},
// Required for idempotency check.
- { "", "", IsFirstReconcile::kNotFirst, "", "", "", "", "", "", 0},
- { "", "xA", IsFirstReconcile::kNotFirst, "", "", "xA", "", "", "xA", 0},
- { "", "xB", IsFirstReconcile::kNotFirst, "", "", "xB", "", "", "xB", 0},
- { "", "xAxB", IsFirstReconcile::kNotFirst, "", "", "xAxB", "", "", "xAxB", 0},
- { "", "xBxA", IsFirstReconcile::kNotFirst, "", "", "xBxA", "", "", "xBxA", 0},
- { "*A", "A", IsFirstReconcile::kNotFirst, "", "*A", "A", "", "*A", "A", 0},
- { "*A", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", "", "*A", "xBA", 0},
- { "*A", "AxB", IsFirstReconcile::kNotFirst, "", "*A", "AxB", "", "*A", "AxB", 0},
- { "A", "A", IsFirstReconcile::kNotFirst, "", "A", "A", "", "A", "A", 0},
- { "A", "xBA", IsFirstReconcile::kNotFirst, "", "A", "xBA", "", "A", "xBA", 0},
- { "A", "AxB", IsFirstReconcile::kNotFirst, "", "A", "AxB", "", "A", "AxB", 0},
- { "B", "B", IsFirstReconcile::kNotFirst, "", "B", "B", "", "B", "B", 0},
- { "B", "xAB", IsFirstReconcile::kNotFirst, "", "B", "xAB", "", "B", "xAB", 0},
- { "B", "BxA", IsFirstReconcile::kNotFirst, "", "B", "BxA", "", "B", "BxA", 0},
- { "*xA", "", IsFirstReconcile::kNotFirst, "", "*xA", "", "", "*xA", "", 0},
- { "*xA", "xAxB", IsFirstReconcile::kNotFirst, "", "*xA", "xAxB", "", "*xA", "xAxB", 0},
- { "*xA", "xBxA", IsFirstReconcile::kNotFirst, "", "*xA", "xBxA", "", "*xA", "xBxA", 0},
- { "*xA", "xA", IsFirstReconcile::kNotFirst, "", "*xA", "xA", "", "*xA", "xA", 0},
- { "*xA", "xB", IsFirstReconcile::kNotFirst, "", "*xA", "xB", "", "*xA", "xB", 0},
- { "*xAB", "B", IsFirstReconcile::kNotFirst, "", "*xAB", "B", "", "*xAB", "B", 0},
- { "*xAB", "BxA", IsFirstReconcile::kNotFirst, "", "*xAB", "BxA", "", "*xAB", "BxA", 0},
- { "*xAB", "xAB", IsFirstReconcile::kNotFirst, "", "*xAB", "xAB", "", "*xAB", "xAB", 0},
- { "*xAB", "xABxC",IsFirstReconcile::kNotFirst, "", "*xAB", "xABxC", "", "*xAB", "xABxC", 0},
- { "*xB", "", IsFirstReconcile::kNotFirst, "", "*xB", "", "", "*xB", "", 0},
- { "A*B", "BA", IsFirstReconcile::kNotFirst, "", "A*B", "BA", "", "A*B", "BA", 0},
- { "A*B", "AB", IsFirstReconcile::kNotFirst, "", "A*B", "AB", "", "A*B", "AB", 0},
- { "A", "AxC", IsFirstReconcile::kNotFirst, "", "A", "AxC", "", "A", "AxC", 0},
- { "AB", "BxCA", IsFirstReconcile::kNotFirst, "", "AB", "BxCA", "", "AB", "BxCA", 0},
- { "B", "xABxC",IsFirstReconcile::kNotFirst, "", "B", "xABxC", "", "B", "xABxC", 0},
- { "B", "xAxCB",IsFirstReconcile::kNotFirst, "", "B", "xAxCB", "", "B", "xAxCB", 0},
- { "*ABC", "ACB", IsFirstReconcile::kNotFirst, "", "*ABC", "ACB", "", "*ABC", "ACB", 0},
- { "*ABC", "ABC", IsFirstReconcile::kNotFirst, "", "*ABC", "ABC", "", "*ABC", "ABC", 0},
- { "BC", "BC", IsFirstReconcile::kNotFirst, "", "BC", "BC", "", "BC", "BC", 0},
- { "BC", "CB", IsFirstReconcile::kNotFirst, "", "BC", "CB", "", "BC", "CB", 0},
+ { "", "", IsFirstReconcile::kNotFirst, "", "", "", 0},
+ { "", "xA", IsFirstReconcile::kNotFirst, "", "", "xA", 0},
+ { "", "xB", IsFirstReconcile::kNotFirst, "", "", "xB", 0},
+ { "", "xAxB", IsFirstReconcile::kNotFirst, "", "", "xAxB", 0},
+ { "", "xBxA", IsFirstReconcile::kNotFirst, "", "", "xBxA", 0},
+ { "*A", "A", IsFirstReconcile::kNotFirst, "", "*A", "A", 0},
+ { "*A", "xBA", IsFirstReconcile::kNotFirst, "", "*A", "xBA", 0},
+ { "*A", "AxB", IsFirstReconcile::kNotFirst, "", "*A", "AxB", 0},
+ { "A", "A", IsFirstReconcile::kNotFirst, "", "A", "A", 0},
+ { "A", "xBA", IsFirstReconcile::kNotFirst, "", "A", "xBA", 0},
+ { "A", "AxB", IsFirstReconcile::kNotFirst, "", "A", "AxB", 0},
+ { "B", "B", IsFirstReconcile::kNotFirst, "", "B", "B", 0},
+ { "B", "xAB", IsFirstReconcile::kNotFirst, "", "B", "xAB", 0},
+ { "B", "BxA", IsFirstReconcile::kNotFirst, "", "B", "BxA", 0},
+ { "*xA", "", IsFirstReconcile::kNotFirst, "", "*xA", "", 0},
+ { "*xA", "xAxB", IsFirstReconcile::kNotFirst, "", "*xA", "xAxB", 0},
+ { "*xA", "xBxA", IsFirstReconcile::kNotFirst, "", "*xA", "xBxA", 0},
+ { "*xA", "xA", IsFirstReconcile::kNotFirst, "", "*xA", "xA", 0},
+ { "*xA", "xB", IsFirstReconcile::kNotFirst, "", "*xA", "xB", 0},
+ { "*xAB", "B", IsFirstReconcile::kNotFirst, "", "*xAB", "B", 0},
+ { "*xAB", "BxA", IsFirstReconcile::kNotFirst, "", "*xAB", "BxA", 0},
+ { "*xAB", "xAB", IsFirstReconcile::kNotFirst, "", "*xAB", "xAB", 0},
+ { "*xAB", "xABxC",IsFirstReconcile::kNotFirst, "", "*xAB", "xABxC", 0},
+ { "*xB", "", IsFirstReconcile::kNotFirst, "", "*xB", "", 0},
+ { "A*B", "BA", IsFirstReconcile::kNotFirst, "", "A*B", "BA", 0},
+ { "A*B", "AB", IsFirstReconcile::kNotFirst, "", "A*B", "AB", 0},
+ { "A", "AxC", IsFirstReconcile::kNotFirst, "", "A", "AxC", 0},
+ { "AB", "BxCA", IsFirstReconcile::kNotFirst, "", "AB", "BxCA", 0},
+ { "B", "xABxC",IsFirstReconcile::kNotFirst, "", "B", "xABxC", 0},
+ { "B", "xAxCB",IsFirstReconcile::kNotFirst, "", "B", "xAxCB", 0},
+ { "*ABC", "ACB", IsFirstReconcile::kNotFirst, "", "*ABC", "ACB", 0},
+ { "*ABC", "ABC", IsFirstReconcile::kNotFirst, "", "*ABC", "ABC", 0},
+ { "BC", "BC", IsFirstReconcile::kNotFirst, "", "BC", "BC", 0},
+ { "BC", "CB", IsFirstReconcile::kNotFirst, "", "BC", "CB", 0},
};
// clang-format on
-// Parameterized version of AccountReconcilorTest that tests Dice
-// implementation with MergeSession endpoint.
-class AccountReconcilorTestDiceMergeSession
- : public AccountReconcilorTestTable {
+class AccountReconcilorTestForceDiceMigration
+ : public BaseAccountReconcilorTestTable,
+ public ::testing::WithParamInterface<ForceDiceMigrationTestTableParam> {
public:
- AccountReconcilorTestDiceMergeSession() = default;
+ AccountReconcilorTestForceDiceMigration() = default;
- protected:
- base::test::ScopedFeatureList scoped_feature_list_;
+ void RunReconcile() {
+ // Setup cookies.
+ std::vector<Cookie> cookies = ParseCookieString(GetParam().cookies);
+ ConfigureCookieManagerService(cookies);
+ std::vector<Cookie> cookies_after_reconcile = cookies;
- private:
- DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTestDiceMergeSession);
-};
+ // Call list accounts now so that the next call completes synchronously.
+ identity_test_env()->identity_manager()->GetAccountsInCookieJar();
+ base::RunLoop().RunUntilIdle();
-// Checks one row of the kDiceParams table above.
-TEST_P(AccountReconcilorTestDiceMergeSession, TableRowTest) {
- SetAccountConsistency(signin::AccountConsistencyMethod::kDice);
- scoped_feature_list_.InitAndDisableFeature(kUseMultiloginEndpoint);
+ // Setup tokens. This triggers listing cookies so we need to setup cookies
+ // before that.
+ SetupTokens(GetParam().tokens);
- // Enable Dice.
- SetAccountConsistency(signin::AccountConsistencyMethod::kDice);
+ // Setup expectations.
+ testing::InSequence mock_sequence;
+ bool should_logout;
+ if (GetParam().gaia_api_calls[0] != '\0') {
+ gaia::MultiloginMode mode =
+ GetParam().gaia_api_calls[0] == 'U'
+ ? gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER
+ : gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER;
+ // Generate expected array of accounts in cookies and set fake gaia
+ // response.
+ std::vector<CoreAccountId> accounts_to_send;
+ for (int i = 1; GetParam().gaia_api_calls[i] != '\0'; ++i) {
+ accounts_to_send.push_back(
+ CoreAccountId(accounts_[GetParam().gaia_api_calls[i]].gaia_id));
+ }
+ const signin::MultiloginParameters params(mode, accounts_to_send);
+ cookies_after_reconcile = FakeSetAccountsInCookie(params, cookies);
+ should_logout =
+ accounts_to_send.empty() &&
+ (mode ==
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER);
+ if (should_logout) {
+ EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
+ .Times(1);
+ } else {
+ EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params))
+ .Times(1);
+ }
+ }
+ // Reconcile.
+ AccountReconcilor* reconcilor = GetMockReconcilor();
+ ASSERT_TRUE(reconcilor);
+ ASSERT_TRUE(reconcilor->first_execution_);
+ reconcilor->first_execution_ = true;
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
+ if (GetParam().gaia_api_calls[0] != '\0') {
+ if (should_logout) {
+ SimulateLogOutFromCookieCompleted(
+ reconcilor, GoogleServiceAuthError::AuthErrorNone());
+ } else {
+ SimulateSetAccountsInCookieCompleted(
+ reconcilor, signin::SetAccountsInCookieResult::kSuccess);
+ }
+ }
- // Check that reconcile is idempotent: when called twice in a row it should do
- // nothing on the second call.
- CheckReconcileIdempotent(kDiceParams, GetParam(), /*multilogin=*/false);
- RunReconcile();
-}
+ ASSERT_FALSE(reconcilor->is_reconcile_started_);
+ if (GetParam().tokens == GetParam().tokens_after_reconcile) {
+ EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
+ } else {
+ // If the tokens were changed by the reconcile, a new reconcile should be
+ // scheduled.
+ EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED,
+ reconcilor->GetState());
+ }
+ VerifyCurrentTokens(ParseTokenString(GetParam().tokens_after_reconcile));
-INSTANTIATE_TEST_SUITE_P(
- DiceTable,
- AccountReconcilorTestDiceMergeSession,
- ::testing::ValuesIn(GenerateTestCasesFromParams(kDiceParams)));
+ std::vector<Cookie> cookies_after =
+ ParseCookieString(GetParam().cookies_after_reconcile);
+ EXPECT_EQ(cookies_after, cookies_after_reconcile);
-class AccountReconcilorTestForceDiceMigration
- : public BaseAccountReconcilorTestTable,
- public ::testing::WithParamInterface<ForceDiceMigrationTestTableParam> {
- public:
- AccountReconcilorTestForceDiceMigration()
- : BaseAccountReconcilorTestTable(GetParam().tokens,
- GetParam().cookies,
- IsFirstReconcile::kFirst,
- GetParam().gaia_api_calls,
- GetParam().tokens_after_reconcile,
- GetParam().cookies_after_reconcile) {
- // ForceDiceMigration is temporary and the migration was enabled in in
- // Q1 2020. It is expected to be removed in 2021 Q2.
- // Simply disable the OAuthmultilogin endpoint instead of migrating the
- // tests.
- scoped_feature_list_.InitAndDisableFeature(kUseMultiloginEndpoint);
+ 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());
+ ConfigureCookieManagerService({});
+ base::RunLoop().RunUntilIdle();
}
private:
- base::test::ScopedFeatureList scoped_feature_list_;
-
DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTestForceDiceMigration);
};
// clang-format off
const std::vector<ForceDiceMigrationTestTableParam> kForceDiceParams = {
- {"*A", "AB", "XA", "*A", "A" },
- {"*AxB", "AB", "XA", "*A", "A" },
- {"AxB", "AB", "XA", "A", "A" },
- {"xAxB", "AB", "X", "", "" },
+ {"*A", "AB", "UA", "*A", "A" },
+ {"*AxB", "AB", "UA", "*A", "A" },
+ {"AxB", "AB", "UA", "A", "A" },
+ {"xAxB", "AB", "U", "", "" },
{"*A", "", "", "*xA", "" },
- {"*A", "B", "X", "*xA", "" },
+ {"*A", "B", "U", "*xA", "" },
{"*AB", "B", "", "*xAB", "B" },
- {"*AxB", "B", "X", "*xA", "" },
+ {"*AxB", "B", "U", "*xA", "" },
{"*ABC", "CB", "", "*xABC", "CB" },
{"*AB", "A", "", "*A", "A" },
{"AB", "A", "", "A", "A" },
{"AB", "", "", "", "" },
{"xAB", "", "", "", "" },
- {"xAB", "A", "X", "", "" },
+ {"xAB", "A", "U", "", "" },
{"xAB", "xA", "", "", "xA" },
{"xAB", "B", "", "B", "B" },
- {"AxB", "B", "X", "", "" },
+ {"AxB", "B", "U", "", "" },
{"AxB", "", "", "", "" },
{"xAxB", "", "", "", "" },
{"B", "xA", "", "", "xA" },
{"AB", "xAB", "", "B", "xAB" },
- {"xAB", "xAC", "X", "", "" },
- {"xAB", "AxC", "X", "", "" },
- {"AB", "BC", "XB", "B", "B" },
+ {"xAB", "xAC", "U", "", "" },
+ {"xAB", "AxC", "U", "", "" },
+ {"AB", "BC", "UB", "B", "B" },
{"*AB", "", "", "*xA", "" },
{"*xAB", "", "", "*xA", "" },
{"*AxB", "", "", "*xA", "" },
@@ -1127,7 +1020,6 @@ const std::vector<ForceDiceMigrationTestTableParam> kForceDiceParams = {
};
// clang-format on
-// Checks one row of the kForceDiceParams table above.
TEST_P(AccountReconcilorTestForceDiceMigration, TableRowTest) {
SetAccountConsistency(signin::AccountConsistencyMethod::kDice);
EXPECT_FALSE(test_signin_client()->is_dice_migration_completed());
@@ -1143,7 +1035,8 @@ TEST_P(AccountReconcilorTestForceDiceMigration, TableRowTest) {
TEST_P(AccountReconcilorTestForceDiceMigration, TableRowTestCheckNoOp) {
SetAccountConsistency(signin::AccountConsistencyMethod::kDice);
// Setup cookies.
- std::vector<Cookie> cookies = ParseCookieString(cookies_after_reconcile_);
+ std::vector<Cookie> cookies =
+ ParseCookieString(GetParam().cookies_after_reconcile);
ConfigureCookieManagerService(cookies);
// Call list accounts now so that the next call completes synchronously.
@@ -1152,16 +1045,15 @@ TEST_P(AccountReconcilorTestForceDiceMigration, TableRowTestCheckNoOp) {
// Setup tokens. This triggers listing cookies so we need to setup cookies
// before that.
- SetupTokens(tokens_after_reconcile_);
+ SetupTokens(GetParam().tokens_after_reconcile);
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(testing::_)).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction()).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(testing::_))
.Times(0);
AccountReconcilor* reconcilor = GetMockReconcilor();
EXPECT_FALSE(reconcilor->delegate_->ShouldRevokeTokensNotInCookies());
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
@@ -1177,9 +1069,6 @@ class AccountReconcilorTestDiceMultilogin : public AccountReconcilorTestTable {
public:
AccountReconcilorTestDiceMultilogin() = default;
- protected:
- base::test::ScopedFeatureList scoped_feature_list_;
-
private:
DISALLOW_COPY_AND_ASSIGN(AccountReconcilorTestDiceMultilogin);
};
@@ -1187,9 +1076,8 @@ class AccountReconcilorTestDiceMultilogin : public AccountReconcilorTestTable {
// Checks one row of the kDiceParams table above.
TEST_P(AccountReconcilorTestDiceMultilogin, TableRowTest) {
SetAccountConsistency(signin::AccountConsistencyMethod::kDice);
- scoped_feature_list_.InitAndEnableFeature(kUseMultiloginEndpoint);
- CheckReconcileIdempotent(kDiceParams, GetParam(), /*multilogin=*/true);
+ CheckReconcileIdempotent(kDiceParams, GetParam());
// Setup cookies.
std::vector<Cookie> cookies = ParseCookieString(GetParam().cookies);
@@ -1206,18 +1094,18 @@ TEST_P(AccountReconcilorTestDiceMultilogin, TableRowTest) {
// Setup expectations.
testing::InSequence mock_sequence;
- bool should_logout;
- if (GetParam().gaia_api_calls_multilogin[0] != '\0') {
+ bool should_logout = false;
+ if (GetParam().gaia_api_calls[0] != '\0') {
gaia::MultiloginMode mode =
- GetParam().gaia_api_calls_multilogin[0] == 'U'
+ GetParam().gaia_api_calls[0] == 'U'
? gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER
: gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER;
// Generate expected array of accounts in cookies and set fake gaia
// response.
std::vector<CoreAccountId> accounts_to_send;
- for (int i = 1; GetParam().gaia_api_calls_multilogin[i] != '\0'; ++i) {
- accounts_to_send.push_back(CoreAccountId(
- accounts_[GetParam().gaia_api_calls_multilogin[i]].gaia_id));
+ for (int i = 1; GetParam().gaia_api_calls[i] != '\0'; ++i) {
+ accounts_to_send.push_back(
+ CoreAccountId(accounts_[GetParam().gaia_api_calls[i]].gaia_id));
}
const signin::MultiloginParameters params(mode, accounts_to_send);
cookies_after_reconcile = FakeSetAccountsInCookie(params, cookies);
@@ -1238,8 +1126,8 @@ TEST_P(AccountReconcilorTestDiceMultilogin, TableRowTest) {
ASSERT_TRUE(reconcilor->first_execution_);
reconcilor->first_execution_ =
GetParam().is_first_reconcile == IsFirstReconcile::kFirst ? true : false;
- reconcilor->StartReconcile();
- if (GetParam().gaia_api_calls_multilogin[0] != '\0') {
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
+ if (GetParam().gaia_api_calls[0] != '\0') {
if (should_logout) {
SimulateLogOutFromCookieCompleted(
reconcilor, GoogleServiceAuthError::AuthErrorNone());
@@ -1250,7 +1138,7 @@ TEST_P(AccountReconcilorTestDiceMultilogin, TableRowTest) {
}
ASSERT_FALSE(reconcilor->is_reconcile_started_);
- if (GetParam().tokens == GetParam().tokens_after_reconcile_multilogin) {
+ if (GetParam().tokens == GetParam().tokens_after_reconcile) {
EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
} else {
// If the tokens were changed by the reconcile, a new reconcile should be
@@ -1258,11 +1146,10 @@ TEST_P(AccountReconcilorTestDiceMultilogin, TableRowTest) {
EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED,
reconcilor->GetState());
}
- VerifyCurrentTokens(
- ParseTokenString(GetParam().tokens_after_reconcile_multilogin));
+ VerifyCurrentTokens(ParseTokenString(GetParam().tokens_after_reconcile));
std::vector<Cookie> cookies_after =
- ParseCookieString(GetParam().cookies_after_reconcile_multilogin);
+ ParseCookieString(GetParam().cookies_after_reconcile);
EXPECT_EQ(cookies_after, cookies_after_reconcile);
testing::Mock::VerifyAndClearExpectations(GetMockReconcilor());
@@ -1280,28 +1167,18 @@ INSTANTIATE_TEST_SUITE_P(
AccountReconcilorTestDiceMultilogin,
::testing::ValuesIn(GenerateTestCasesFromParams(kDiceParams)));
-class AccountReconcilorDiceEndpointParamTest
- : public AccountReconcilorTest,
- public ::testing::WithParamInterface<bool> {
+class AccountReconcilorDiceTest : public AccountReconcilorTest {
public:
- AccountReconcilorDiceEndpointParamTest() {
+ AccountReconcilorDiceTest() {
SetAccountConsistency(signin::AccountConsistencyMethod::kDice);
- if (IsMultiloginEnabled())
- scoped_feature_list_.InitAndEnableFeature(kUseMultiloginEndpoint);
- else
- scoped_feature_list_.InitAndDisableFeature(kUseMultiloginEndpoint);
}
- bool IsMultiloginEnabled() { return GetParam(); }
-
- protected:
- base::test::ScopedFeatureList scoped_feature_list_;
private:
- DISALLOW_COPY_AND_ASSIGN(AccountReconcilorDiceEndpointParamTest);
+ DISALLOW_COPY_AND_ASSIGN(AccountReconcilorDiceTest);
};
// Tests that the AccountReconcilor is always registered.
-TEST_P(AccountReconcilorDiceEndpointParamTest, DiceTokenServiceRegistration) {
+TEST_F(AccountReconcilorDiceTest, DiceTokenServiceRegistration) {
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
ASSERT_TRUE(reconcilor->IsRegisteredWithIdentityManager());
@@ -1320,7 +1197,7 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceTokenServiceRegistration) {
}
// Tests that reconcile starts even when Sync is not enabled.
-TEST_P(AccountReconcilorDiceEndpointParamTest, DiceReconcileWithoutSignin) {
+TEST_F(AccountReconcilorDiceTest, DiceReconcileWithoutSignin) {
// Add a token in Chrome but do not sign in. Making account available (setting
// a refresh token) triggers listing cookies so we need to setup cookies
// before that.
@@ -1328,44 +1205,34 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceReconcileWithoutSignin) {
const CoreAccountId account_id =
identity_test_env()->MakeAccountAvailable("user@gmail.com").account_id;
- if (!IsMultiloginEnabled()) {
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
- } else {
std::vector<CoreAccountId> accounts_to_send = {account_id};
const signin::MultiloginParameters params(
gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER,
accounts_to_send);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
- }
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
- if (!IsMultiloginEnabled()) {
- SimulateAddAccountToCookieCompleted(
- reconcilor, account_id, GoogleServiceAuthError::AuthErrorNone());
- } else {
- SimulateSetAccountsInCookieCompleted(
- reconcilor, signin::SetAccountsInCookieResult::kSuccess);
- }
+ SimulateSetAccountsInCookieCompleted(
+ reconcilor, signin::SetAccountsInCookieResult::kSuccess);
ASSERT_FALSE(reconcilor->is_reconcile_started_);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
}
// Checks that nothing happens when there is no Chrome account and no Gaia
// cookie.
-TEST_P(AccountReconcilorDiceEndpointParamTest, DiceReconcileNoop) {
+TEST_F(AccountReconcilorDiceTest, DiceReconcileNoop) {
// No Chrome account and no cookie.
signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(testing::_)).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction()).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(testing::_))
.Times(0);
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -1373,8 +1240,7 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceReconcileNoop) {
}
// Tests that the first Gaia account is re-used when possible.
-TEST_P(AccountReconcilorDiceEndpointParamTest,
- DiceReconcileReuseGaiaFirstAccount) {
+TEST_F(AccountReconcilorDiceTest, DiceReconcileReuseGaiaFirstAccount) {
// Add account "other" to the Gaia cookie.
signin::SetListAccountsResponseTwoAccounts(
"other@gmail.com", signin::GetTestGaiaIdForEmail("other@gmail.com"),
@@ -1395,13 +1261,6 @@ TEST_P(AccountReconcilorDiceEndpointParamTest,
ASSERT_TRUE(identity_manager->HasAccountWithRefreshToken(account_id_1));
ASSERT_TRUE(identity_manager->HasAccountWithRefreshToken(account_id_2));
- if (!IsMultiloginEnabled()) {
- testing::InSequence mock_sequence;
- EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction());
- // Account 2 is added first.
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id_2));
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id_1));
- } else {
std::vector<CoreAccountId> accounts_to_send = {account_id_2, account_id_1};
// Send accounts to Gaia in order of chrome accounts. Account 2 is added
// first.
@@ -1409,30 +1268,20 @@ TEST_P(AccountReconcilorDiceEndpointParamTest,
gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
accounts_to_send);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
- }
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
- if (!IsMultiloginEnabled()) {
- SimulateLogOutFromCookieCompleted(reconcilor,
- GoogleServiceAuthError::AuthErrorNone());
- SimulateAddAccountToCookieCompleted(
- reconcilor, account_id_1, GoogleServiceAuthError::AuthErrorNone());
- SimulateAddAccountToCookieCompleted(
- reconcilor, account_id_2, GoogleServiceAuthError::AuthErrorNone());
- } else {
SimulateSetAccountsInCookieCompleted(
reconcilor, signin::SetAccountsInCookieResult::kSuccess);
- }
ASSERT_FALSE(reconcilor->is_reconcile_started_);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
}
// Tests that the first account is kept in cache and reused when cookies are
// lost.
-TEST_P(AccountReconcilorDiceEndpointParamTest, DiceLastKnownFirstAccount) {
+TEST_F(AccountReconcilorDiceTest, DiceLastKnownFirstAccount) {
// Add accounts to the token service and the Gaia cookie in a different order.
// Making account available (setting a refresh token) triggers listing cookies
// so we need to setup cookies before that.
@@ -1459,14 +1308,13 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceLastKnownFirstAccount) {
// Do one reconcile. It should do nothing but to populating the last known
// account.
{
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(testing::_)).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
.Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(testing::_))
.Times(0);
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -1477,17 +1325,6 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceLastKnownFirstAccount) {
signin::SetListAccountsResponseNoAccounts(&test_url_loader_factory_);
identity_test_env()->SetFreshnessOfAccountsInGaiaCookie(false);
- if (!IsMultiloginEnabled()) {
- // Reconcile again and check that account_id_2 is added first.
- testing::InSequence mock_sequence;
-
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id_2))
- .Times(1);
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id_1))
- .Times(1);
- EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
- .Times(0);
- } else {
// Since Gaia can't know about cached account, make sure that we reorder
// chrome accounts accordingly even in PRESERVE mode.
std::vector<CoreAccountId> accounts_to_send = {account_id_2, account_id_1};
@@ -1495,27 +1332,19 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, DiceLastKnownFirstAccount) {
gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER,
accounts_to_send);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
- }
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
- if (!IsMultiloginEnabled()) {
- SimulateAddAccountToCookieCompleted(
- reconcilor, account_id_2, GoogleServiceAuthError::AuthErrorNone());
- SimulateAddAccountToCookieCompleted(
- reconcilor, account_id_1, GoogleServiceAuthError::AuthErrorNone());
- } else {
SimulateSetAccountsInCookieCompleted(
reconcilor, signin::SetAccountsInCookieResult::kSuccess);
- }
ASSERT_FALSE(reconcilor->is_reconcile_started_);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
}
// Checks that the reconcilor does not log out unverified accounts.
-TEST_P(AccountReconcilorDiceEndpointParamTest, UnverifiedAccountNoop) {
+TEST_F(AccountReconcilorDiceTest, UnverifiedAccountNoop) {
// Add a unverified account to the Gaia cookie.
signin::SetListAccountsResponseOneAccountWithParams(
{"user@gmail.com", "12345", true /* valid */, false /* signed_out */,
@@ -1523,13 +1352,12 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, UnverifiedAccountNoop) {
&test_url_loader_factory_);
// Check that nothing happens.
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(testing::_)).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction()).Times(0);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(testing::_))
.Times(0);
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -1538,7 +1366,7 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, UnverifiedAccountNoop) {
// Checks that the reconcilor does not log out unverified accounts when adding
// a new account to the Gaia cookie.
-TEST_P(AccountReconcilorDiceEndpointParamTest, UnverifiedAccountMerge) {
+TEST_F(AccountReconcilorDiceTest, UnverifiedAccountMerge) {
// Add a unverified account to the Gaia cookie.
signin::SetListAccountsResponseOneAccountWithParams(
{"user@gmail.com", "12345", true /* valid */, false /* signed_out */,
@@ -1549,14 +1377,6 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, UnverifiedAccountMerge) {
const CoreAccountId chrome_account_id =
identity_test_env()->MakeAccountAvailable("other@gmail.com").account_id;
- if (!IsMultiloginEnabled()) {
- // Check that the Chrome account is merged and the unverified account is not
- // logged out.
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(chrome_account_id))
- .Times(1);
- EXPECT_CALL(*GetMockReconcilor(), PerformLogoutAllAccountsAction())
- .Times(0);
- } else {
// In PRESERVE mode it is up to Gaia to not delete existing accounts in
// cookies and not sign out unveridied accounts.
std::vector<CoreAccountId> accounts_to_send = {chrome_account_id};
@@ -1564,27 +1384,17 @@ TEST_P(AccountReconcilorDiceEndpointParamTest, UnverifiedAccountMerge) {
gaia::MultiloginMode::MULTILOGIN_PRESERVE_COOKIE_ACCOUNTS_ORDER,
accounts_to_send);
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
- }
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
- if (!IsMultiloginEnabled()) {
- SimulateAddAccountToCookieCompleted(
- reconcilor, chrome_account_id, GoogleServiceAuthError::AuthErrorNone());
- } else {
SimulateSetAccountsInCookieCompleted(
reconcilor, signin::SetAccountsInCookieResult::kSuccess);
- }
ASSERT_FALSE(reconcilor->is_reconcile_started_);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
}
-INSTANTIATE_TEST_SUITE_P(TestDiceEndpoint,
- AccountReconcilorDiceEndpointParamTest,
- ::testing::ValuesIn({false, true}));
-
TEST_F(AccountReconcilorTest, DiceDeleteCookie) {
SetAccountConsistency(signin::AccountConsistencyMethod::kDice);
@@ -1761,7 +1571,7 @@ TEST_P(AccountReconcilorTestMirrorMultilogin, TableRowTest) {
ASSERT_TRUE(reconcilor->first_execution_);
reconcilor->first_execution_ =
GetParam().is_first_reconcile == IsFirstReconcile::kFirst ? true : false;
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
SimulateSetAccountsInCookieCompleted(
reconcilor, signin::SetAccountsInCookieResult::kSuccess);
@@ -1881,7 +1691,7 @@ TEST_P(AccountReconcilorTestActiveDirectory, TableRowTestMultilogin) {
ASSERT_TRUE(reconcilor->first_execution_);
reconcilor->first_execution_ =
GetParam().is_first_reconcile == IsFirstReconcile::kFirst ? true : false;
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
if (GetParam().gaia_api_calls[0] != '\0') {
if (should_logout) {
SimulateLogOutFromCookieCompleted(
@@ -1923,7 +1733,7 @@ TEST_F(AccountReconcilorMirrorTest, TokensNotLoaded) {
identity_test_env()->ResetToAccountsNotYetLoadedFromDiskState();
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
// No reconcile when tokens are not loaded.
ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -1937,6 +1747,7 @@ TEST_F(AccountReconcilorMirrorTest, TokensNotLoaded) {
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
ASSERT_TRUE(reconcilor->is_reconcile_started_);
+ EXPECT_EQ(AccountReconcilor::Trigger::kTokensLoaded, reconcilor->trigger_);
base::RunLoop().RunUntilIdle();
SimulateSetAccountsInCookieCompleted(
@@ -1965,7 +1776,7 @@ TEST_F(AccountReconcilorMirrorTest, GetAccountsFromCookieSuccess) {
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED,
reconcilor->GetState());
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
base::RunLoop().RunUntilIdle();
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
@@ -1999,7 +1810,7 @@ TEST_F(AccountReconcilorMirrorTest, EnableReconcileWhileAlreadyRunning) {
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED,
reconcilor->GetState());
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
reconcilor->EnableReconcile();
EXPECT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
@@ -2024,7 +1835,7 @@ TEST_F(AccountReconcilorMirrorTest, GetAccountsFromCookieFailure) {
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED,
reconcilor->GetState());
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
base::RunLoop().RunUntilIdle();
@@ -2061,7 +1872,7 @@ TEST_F(AccountReconcilorMirrorTest, ExtraCookieChangeNotification) {
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_SCHEDULED,
reconcilor->GetState());
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_RUNNING, reconcilor->GetState());
// Add extra cookie change notification. Reconcilor should ignore it.
@@ -2090,11 +1901,18 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileNoop) {
signin::SetListAccountsResponseOneAccount(
account_info.email, account_info.gaia, &test_url_loader_factory_);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
+
+ histogram_tester()->ExpectUniqueSample(
+ AccountReconcilor::kOperationHistogramName,
+ AccountReconcilor::Operation::kNoop, 1);
+ histogram_tester()->ExpectUniqueSample(
+ AccountReconcilor::kTriggerNoopHistogramName,
+ AccountReconcilor::Trigger::kCookieChange, 1);
}
TEST_F(AccountReconcilorMirrorTest, StartReconcileCookiesDisabled) {
@@ -2106,7 +1924,7 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileCookiesDisabled) {
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_FALSE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
@@ -2135,6 +1953,8 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileContentSettings) {
SimulateCookieContentSettingsChanged(reconcilor,
ContentSettingsPattern::Wildcard());
ASSERT_TRUE(reconcilor->is_reconcile_started_);
+ EXPECT_EQ(AccountReconcilor::Trigger::kCookieSettingChange,
+ reconcilor->trigger_);
}
TEST_F(AccountReconcilorMirrorTest, StartReconcileContentSettingsGaiaUrl) {
@@ -2202,7 +2022,7 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileNoopWithDots) {
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
}
@@ -2218,7 +2038,7 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileNoopMultiple) {
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
}
@@ -2240,7 +2060,7 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileAddToCookie) {
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
@@ -2255,6 +2075,19 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileAddToCookie) {
EXPECT_THAT(histogram_tester()->GetTotalCountsForPrefix(
"Signin.Reconciler.Duration.UpTo3mins.Success"),
testing::ContainerEq(expected_counts));
+
+ histogram_tester()->ExpectUniqueSample(
+ AccountReconcilor::kOperationHistogramName,
+ AccountReconcilor::Operation::kMultilogin, 1);
+ histogram_tester()->ExpectUniqueSample(
+ AccountReconcilor::kTriggerMultiloginHistogramName,
+ AccountReconcilor::Trigger::kCookieChange, 1);
+ histogram_tester()->ExpectTotalCount(
+ AccountReconcilor::kTriggerLogoutHistogramName, 0);
+ histogram_tester()->ExpectTotalCount(
+ AccountReconcilor::kTriggerNoopHistogramName, 0);
+ histogram_tester()->ExpectTotalCount(
+ AccountReconcilor::kTriggerThrottledHistogramName, 0);
}
TEST_F(AccountReconcilorTest, AuthErrorTriggersListAccount) {
@@ -2332,7 +2165,7 @@ TEST_F(AccountReconcilorMirrorTest, SignoutAfterErrorDoesNotRecordUma) {
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
@@ -2366,7 +2199,7 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileRemoveFromCookie) {
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
@@ -2389,7 +2222,7 @@ TEST_F(AccountReconcilorMirrorTest, TokenErrorOnPrimary) {
&test_url_loader_factory_);
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
@@ -2416,7 +2249,7 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileAddToCookieTwice) {
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(ml_params_1));
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
@@ -2443,6 +2276,7 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileAddToCookieTwice) {
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
+ EXPECT_EQ(AccountReconcilor::Trigger::kTokenChange, reconcilor->trigger_);
SimulateSetAccountsInCookieCompleted(
reconcilor, signin::SetAccountsInCookieResult::kSuccess);
@@ -2468,7 +2302,7 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileBadPrimary) {
EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(params));
AccountReconcilor* reconcilor = GetMockReconcilor();
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
@@ -2488,7 +2322,7 @@ TEST_F(AccountReconcilorMirrorTest, StartReconcileOnlyOnce) {
ASSERT_TRUE(reconcilor);
ASSERT_FALSE(reconcilor->is_reconcile_started_);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
@@ -2529,7 +2363,7 @@ TEST_F(AccountReconcilorMirrorTest, Lock) {
std::unique_ptr<AccountReconcilor::Lock> lock_1 =
std::make_unique<AccountReconcilor::Lock>(reconcilor);
EXPECT_EQ(1, reconcilor->account_reconcilor_lock_count_);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
// lock_1 is blocking the reconcile.
EXPECT_FALSE(reconcilor->is_reconcile_started_);
{
@@ -2551,6 +2385,8 @@ TEST_F(AccountReconcilorMirrorTest, Lock) {
EXPECT_EQ(1, observer.started_count_);
EXPECT_EQ(1, observer.unblocked_count_);
EXPECT_EQ(1, observer.blocked_count_);
+ EXPECT_EQ(AccountReconcilor::Trigger::kUnblockReconcile,
+ reconcilor->trigger_);
// Lock aborts current reconcile, and restarts it later.
{
@@ -2590,9 +2426,6 @@ TEST_P(AccountReconcilorMethodParamTest,
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
- if (!reconcilor->IsMultiloginEndpointEnabled()) {
- EXPECT_CALL(*GetMockReconcilor(), PerformMergeAction(account_id));
- } else {
switch (account_consistency) {
case signin::AccountConsistencyMethod::kMirror: {
signin::MultiloginParameters params(
@@ -2612,20 +2445,14 @@ TEST_P(AccountReconcilorMethodParamTest,
NOTREACHED();
break;
}
- }
ASSERT_FALSE(reconcilor->is_reconcile_started_);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
- if (!reconcilor->IsMultiloginEndpointEnabled()) {
- SimulateAddAccountToCookieCompleted(
- reconcilor, account_id, GoogleServiceAuthError::AuthErrorNone());
- } else {
SimulateSetAccountsInCookieCompleted(
reconcilor, signin::SetAccountsInCookieResult::kSuccess);
- }
ASSERT_FALSE(reconcilor->is_reconcile_started_);
}
@@ -2648,7 +2475,7 @@ TEST_F(AccountReconcilorMirrorTest,
ASSERT_TRUE(reconcilor);
ASSERT_FALSE(reconcilor->is_reconcile_started_);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
@@ -2685,7 +2512,7 @@ TEST_F(AccountReconcilorMirrorTest, NoLoopWithBadPrimary) {
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
@@ -2707,7 +2534,7 @@ TEST_F(AccountReconcilorMirrorTest, NoLoopWithBadPrimary) {
identity_test_env()->identity_manager(), account_id1, error);
// A second attempt to reconcile should be a noop.
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_FALSE(reconcilor->is_reconcile_started_);
testing::Mock::VerifyAndClearExpectations(GetMockReconcilor());
@@ -2740,7 +2567,7 @@ TEST_F(AccountReconcilorMirrorTest, WontMergeAccountsWithError) {
AccountReconcilor* reconcilor = GetMockReconcilor();
ASSERT_TRUE(reconcilor);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
base::RunLoop().RunUntilIdle();
ASSERT_TRUE(reconcilor->is_reconcile_started_);
@@ -2765,7 +2592,7 @@ TEST_F(AccountReconcilorTest, DelegateTimeoutIsCalled) {
base::MockOneShotTimer* timer = timer0.get();
reconcilor->set_timer_for_testing(std::move(timer0));
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
ASSERT_TRUE(timer->IsRunning());
@@ -2788,7 +2615,7 @@ TEST_F(AccountReconcilorMirrorTest, DelegateTimeoutIsNotCalled) {
base::MockOneShotTimer* timer = timer0.get();
reconcilor->set_timer_for_testing(std::move(timer0));
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
EXPECT_TRUE(reconcilor->is_reconcile_started_);
EXPECT_FALSE(timer->IsRunning());
}
@@ -2806,7 +2633,7 @@ TEST_F(AccountReconcilorTest, DelegateTimeoutIsNotCalledIfTimeoutIsNotReached) {
base::MockOneShotTimer* timer = timer0.get();
reconcilor->set_timer_for_testing(std::move(timer0));
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
ASSERT_TRUE(timer->IsRunning());
@@ -2870,13 +2697,23 @@ TEST_F(AccountReconcilorTest, MultiloginLogout) {
// No multilogin call.
EXPECT_CALL(*reconcilor, PerformSetCookiesAction(testing::_)).Times(0);
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
ASSERT_TRUE(reconcilor->is_reconcile_started_);
base::RunLoop().RunUntilIdle();
SimulateLogOutFromCookieCompleted(reconcilor,
GoogleServiceAuthError::AuthErrorNone());
EXPECT_FALSE(reconcilor->is_reconcile_started_);
ASSERT_EQ(signin_metrics::ACCOUNT_RECONCILOR_OK, reconcilor->GetState());
+ histogram_tester()->ExpectUniqueSample(
+ AccountReconcilor::kOperationHistogramName,
+ AccountReconcilor::Operation::kLogout, 1);
+ histogram_tester()->ExpectUniqueSample(
+ AccountReconcilor::kTriggerLogoutHistogramName,
+ AccountReconcilor::Trigger::kCookieChange, 1);
+ histogram_tester()->ExpectTotalCount(
+ AccountReconcilor::kTriggerThrottledHistogramName, 0);
+ histogram_tester()->ExpectTotalCount(
+ AccountReconcilor::kTriggerMultiloginHistogramName, 0);
}
// Reconcilor does not start after being shutdown. Regression test for
@@ -2887,7 +2724,8 @@ TEST_F(AccountReconcilorTest, ReconcileAfterShutdown) {
EXPECT_FALSE(reconcilor->WasShutDown());
reconcilor->Shutdown();
EXPECT_TRUE(reconcilor->WasShutDown());
- reconcilor->StartReconcile(); // This should not crash.
+ // This should not crash.
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
EXPECT_FALSE(reconcilor->is_reconcile_started_);
}
@@ -2901,10 +2739,229 @@ TEST_F(AccountReconcilorTest, UnlockAfterShutdown) {
// Reconcile does not start now because of the Lock, but is scheduled to start
// when the lock is released.
- reconcilor->StartReconcile();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
EXPECT_FALSE(reconcilor->is_reconcile_started_);
reconcilor->Shutdown();
lock.reset(); // This should not crash.
EXPECT_FALSE(reconcilor->is_reconcile_started_);
}
+
+class AccountReconcilorThrottlerTest : public AccountReconcilorTest {
+ public:
+ AccountReconcilorThrottlerTest() {
+#if BUILDFLAG(ENABLE_DICE_SUPPORT)
+ signin::AccountConsistencyMethod account_consistency =
+ signin::AccountConsistencyMethod::kDice;
+ SetAccountConsistency(account_consistency);
+#else
+ signin::AccountConsistencyMethod account_consistency =
+ signin::AccountConsistencyMethod::kMirror;
+ SetAccountConsistency(account_consistency);
+#endif
+ minutes_to_refill_per_request_ =
+ 1 / AccountReconcilorThrottler::kRefillRequestsBucketRatePerMinute;
+ }
+
+ void ConsumeRequests(size_t number_of_requests,
+ const signin::MultiloginParameters& expected_params) {
+ AccountReconcilor* reconcilor = GetMockReconcilor();
+ for (size_t i = 0; i < number_of_requests; ++i) {
+ EXPECT_CALL(*GetMockReconcilor(),
+ PerformSetCookiesAction(expected_params));
+ ASSERT_FALSE(reconcilor->is_reconcile_started_);
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
+ base::RunLoop().RunUntilIdle();
+ // Reconciliation not blocked.
+ ASSERT_TRUE(reconcilor->is_reconcile_started_);
+
+ SimulateSetAccountsInCookieCompleted(
+ reconcilor, signin::SetAccountsInCookieResult::kSuccess);
+ ASSERT_FALSE(reconcilor->is_reconcile_started_);
+ ASSERT_EQ(GoogleServiceAuthError::State::NONE,
+ reconcilor->error_during_last_reconcile_.state());
+ testing::Mock::VerifyAndClearExpectations(GetMockReconcilor());
+ }
+ }
+
+ void VerifyRequestsBlockedByThrottler() {
+ AccountReconcilor* reconcilor = GetMockReconcilor();
+ reconcilor->StartReconcile(AccountReconcilor::Trigger::kCookieChange);
+ base::RunLoop().RunUntilIdle();
+ // Reconciliation should fail.
+ ASSERT_FALSE(reconcilor->is_reconcile_started_);
+ ASSERT_EQ(GoogleServiceAuthError::State::REQUEST_CANCELED,
+ reconcilor->error_during_last_reconcile_.state());
+ }
+
+ void FastForwadTimeToRefillRequests(size_t number_of_requests) {
+ task_environment()->FastForwardBy(base::TimeDelta::FromMinutes(
+ minutes_to_refill_per_request_ * number_of_requests));
+ }
+
+ private:
+ size_t minutes_to_refill_per_request_;
+ DISALLOW_COPY_AND_ASSIGN(AccountReconcilorThrottlerTest);
+};
+
+TEST_F(AccountReconcilorThrottlerTest, RefillOneRequest) {
+ AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
+ const CoreAccountId account_id = account_info.account_id;
+ signin::SetListAccountsResponseOneAccount(
+ "other@gmail.com", signin::GetTestGaiaIdForEmail("other@gmail.com"),
+ &test_url_loader_factory_);
+
+ signin::MultiloginParameters params(
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
+ {account_id});
+
+ // Consume all available requests.
+ ConsumeRequests(AccountReconcilorThrottler::kMaxAllowedRequestsPerBucket,
+ params);
+ histogram_tester()->ExpectUniqueSample(
+ AccountReconcilor::kTriggerMultiloginHistogramName,
+ AccountReconcilor::Trigger::kCookieChange, 30);
+ histogram_tester()->ExpectTotalCount(
+ AccountReconcilor::kTriggerThrottledHistogramName, 0);
+
+ // At this point all the requests in the available request buckets should
+ // have been consumed.
+ VerifyRequestsBlockedByThrottler();
+
+ // Allow enough time to refill 1 request.
+ FastForwadTimeToRefillRequests(1);
+ ConsumeRequests(1, params);
+
+ // The blocked request recorded upon allowing a new request.
+ histogram_tester()->ExpectBucketCount(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.Update", 1, 1);
+ histogram_tester()->ExpectBucketCount(
+ AccountReconcilor::kOperationHistogramName,
+ AccountReconcilor::Operation::kThrottled, 1);
+ histogram_tester()->ExpectUniqueSample(
+ AccountReconcilor::kTriggerThrottledHistogramName,
+ AccountReconcilor::Trigger::kCookieChange, 1);
+ histogram_tester()->ExpectBucketCount(
+ AccountReconcilor::kOperationHistogramName,
+ AccountReconcilor::Operation::kMultilogin, 31);
+ histogram_tester()->ExpectUniqueSample(
+ AccountReconcilor::kTriggerMultiloginHistogramName,
+ AccountReconcilor::Trigger::kCookieChange, 31);
+ histogram_tester()->ExpectTotalCount(
+ AccountReconcilor::kTriggerLogoutHistogramName, 0);
+ histogram_tester()->ExpectTotalCount(
+ AccountReconcilor::kTriggerNoopHistogramName, 0);
+
+ // No Available requests.
+ VerifyRequestsBlockedByThrottler();
+
+ DeleteReconcilor();
+ histogram_tester()->ExpectBucketCount(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.Update", 1, 2);
+}
+
+TEST_F(AccountReconcilorThrottlerTest, RefillFiveRequests) {
+ AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
+ const CoreAccountId account_id = account_info.account_id;
+ signin::SetListAccountsResponseOneAccount(
+ "other@gmail.com", signin::GetTestGaiaIdForEmail("other@gmail.com"),
+ &test_url_loader_factory_);
+
+ signin::MultiloginParameters params(
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
+ {account_id});
+
+ // Consume all available requests.
+ ConsumeRequests(AccountReconcilorThrottler::kMaxAllowedRequestsPerBucket,
+ params);
+
+ // At this point all the requests in the available request buckets should
+ // have been consumed.
+ VerifyRequestsBlockedByThrottler();
+
+ // Allow enough time to refill 1 request.
+ FastForwadTimeToRefillRequests(5);
+ ConsumeRequests(5, params);
+
+ // The blocked request recorded upon allowing a new request.
+ histogram_tester()->ExpectBucketCount(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.Update", 1, 1);
+
+ // No Available requests.
+ VerifyRequestsBlockedByThrottler();
+
+ DeleteReconcilor();
+ histogram_tester()->ExpectBucketCount(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.Update", 1, 2);
+}
+
+TEST_F(AccountReconcilorThrottlerTest, NewRequestParamsPasses) {
+ AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
+ const CoreAccountId account_id = account_info.account_id;
+ signin::SetListAccountsResponseOneAccount(
+ "other@gmail.com", signin::GetTestGaiaIdForEmail("other@gmail.com"),
+ &test_url_loader_factory_);
+
+ signin::MultiloginParameters params(
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
+ {account_id});
+
+ // Consume all available requests.
+ ConsumeRequests(AccountReconcilorThrottler::kMaxAllowedRequestsPerBucket,
+ params);
+
+ // Next request should fail.
+ VerifyRequestsBlockedByThrottler();
+
+ // Trigger different params.
+ AccountReconcilor* reconcilor = GetMockReconcilor();
+ EXPECT_CALL(*GetMockReconcilor(), PerformSetCookiesAction(testing::_));
+ identity_test_env()->MakeAccountAvailable("other@gmail.com");
+ base::RunLoop().RunUntilIdle();
+ ASSERT_TRUE(reconcilor->is_reconcile_started_);
+ SimulateSetAccountsInCookieCompleted(
+ reconcilor, signin::SetAccountsInCookieResult::kSuccess);
+ ASSERT_FALSE(reconcilor->is_reconcile_started_);
+
+ histogram_tester()->ExpectBucketCount(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.Update", 1, 1);
+}
+
+TEST_F(AccountReconcilorThrottlerTest, BlockFiveRequests) {
+ AccountInfo account_info = ConnectProfileToAccount("user@gmail.com");
+ const CoreAccountId account_id = account_info.account_id;
+ signin::SetListAccountsResponseOneAccount(
+ "other@gmail.com", signin::GetTestGaiaIdForEmail("other@gmail.com"),
+ &test_url_loader_factory_);
+
+ signin::MultiloginParameters params(
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER,
+ {account_id});
+
+ // Consume all available requests.
+ ConsumeRequests(AccountReconcilorThrottler::kMaxAllowedRequestsPerBucket,
+ params);
+
+ // At this point all the requests in the available request buckets should
+ // have been consumed.
+ size_t rejected_requests = 5;
+ for (size_t i = 0; i < rejected_requests; ++i) {
+ VerifyRequestsBlockedByThrottler();
+ }
+
+ // Allow enough time to refill 1 request.
+ FastForwadTimeToRefillRequests(1);
+ ConsumeRequests(1, params);
+
+ // The blocked request recorded upon allowing a new request.
+ histogram_tester()->ExpectBucketCount(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.Update",
+ rejected_requests, 1);
+
+ // Allow a new request with no blocked requests in between.
+ FastForwadTimeToRefillRequests(1);
+ ConsumeRequests(1, params);
+ // The number of samples should remain 1.
+ histogram_tester()->ExpectTotalCount(
+ "Signin.Reconciler.RejectedRequestsDueToThrottler.Update", 1);
+}
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 1a5205a5fc2..ea3ac36f547 100644
--- a/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
+++ b/chromium/components/signin/core/browser/chrome_connected_header_helper.cc
@@ -20,7 +20,8 @@
#include "url/gurl.h"
#if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "components/signin/public/base/signin_switches.h"
+#include "chromeos/crosapi/mojom/crosapi.mojom.h"
+#include "chromeos/lacros/lacros_chrome_service_impl.h"
#endif
namespace signin {
@@ -39,7 +40,7 @@ const char kProfileModeAttrName[] = "mode";
const char kServiceTypeAttrName[] = "action";
const char kSupervisedAttrName[] = "supervised";
const char kSourceAttrName[] = "source";
-#if defined(OS_ANDROID) || defined(OS_IOS)
+#if defined(OS_ANDROID)
const char kEligibleForConsistency[] = "eligible_for_consistency";
const char kShowConsistencyPromo[] = "show_consistency_promo";
#endif
@@ -83,7 +84,7 @@ std::string ChromeConnectedHeaderHelper::BuildRequestCookieIfPossible(
// this information in the ChromeConnected cookie.
return chrome_connected_helper.BuildRequestHeader(
false /* is_header_request */, url, gaia_id,
- base::nullopt /* is_child_account */, profile_mode_mask, "" /* source */,
+ absl::nullopt /* is_child_account */, profile_mode_mask, "" /* source */,
false /* force_account_consistency */);
}
@@ -108,7 +109,7 @@ ManageAccountsParams ChromeConnectedHeaderHelper::BuildManageAccountsParams(
params.continue_url = value;
} else if (key_name == kIsSameTabAttrName) {
params.is_same_tab = value == "true";
-#if defined(OS_ANDROID) || defined(OS_IOS)
+#if defined(OS_ANDROID)
} else if (key_name == kShowConsistencyPromo) {
params.show_consistency_promo = value == "true";
#endif
@@ -187,7 +188,7 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
bool is_header_request,
const GURL& url,
const std::string& gaia_id,
- const base::Optional<bool>& is_child_account,
+ const absl::optional<bool>& is_child_account,
int profile_mode_mask,
const std::string& source,
bool force_account_consistency) {
@@ -203,16 +204,12 @@ std::string ChromeConnectedHeaderHelper::BuildRequestHeader(
// Sessions and Active Directory logins. Guest Sessions have already been
// filtered upstream and we want to enforce account consistency in Public
// Sessions and Active Directory logins.
-#if BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
force_account_consistency = true;
-#elif BUILDFLAG(IS_CHROMEOS_LACROS)
- if (base::FeatureList::IsEnabled(switches::kUseAccountManagerFacade)) {
- force_account_consistency = true;
- }
#endif
if (!force_account_consistency && gaia_id.empty()) {
-#if defined(OS_ANDROID) || defined(OS_IOS)
+#if defined(OS_ANDROID)
if (base::FeatureList::IsEnabled(kMobileIdentityConsistency) &&
gaia::IsGaiaSignonRealm(url.GetOrigin())) {
parts.push_back(
diff --git a/chromium/components/signin/core/browser/chrome_connected_header_helper.h b/chromium/components/signin/core/browser/chrome_connected_header_helper.h
index c17dc782c61..703f5d3747b 100644
--- a/chromium/components/signin/core/browser/chrome_connected_header_helper.h
+++ b/chromium/components/signin/core/browser/chrome_connected_header_helper.h
@@ -7,9 +7,9 @@
#include <string>
-#include "base/optional.h"
#include "components/signin/core/browser/signin_header_helper.h"
#include "components/signin/public/base/account_consistency_method.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
class GURL;
@@ -47,7 +47,7 @@ class ChromeConnectedHeaderHelper : public SigninHeaderHelper {
std::string BuildRequestHeader(bool is_header_request,
const GURL& url,
const std::string& gaia_id,
- const base::Optional<bool>& is_child_account,
+ const absl::optional<bool>& is_child_account,
int profile_mode_mask,
const std::string& source,
bool force_account_consistency);
diff --git a/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc b/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc
index 08dd3c8f0e7..ee59bfb477c 100644
--- a/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc
+++ b/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.cc
@@ -14,9 +14,6 @@
#include "components/signin/public/base/signin_client.h"
#include "components/signin/public/base/signin_pref_names.h"
-const base::Feature kUseMultiloginEndpoint{"UseMultiloginEndpoint",
- base::FEATURE_ENABLED_BY_DEFAULT};
-
namespace signin {
DiceAccountReconcilorDelegate::DiceAccountReconcilorDelegate(
@@ -31,10 +28,6 @@ bool DiceAccountReconcilorDelegate::IsReconcileEnabled() const {
return true;
}
-bool DiceAccountReconcilorDelegate::IsMultiloginEndpointEnabled() const {
- return base::FeatureList::IsEnabled(kUseMultiloginEndpoint);
-}
-
DiceAccountReconcilorDelegate::InconsistencyReason
DiceAccountReconcilorDelegate::GetInconsistencyReason(
const CoreAccountId& primary_account,
diff --git a/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.h b/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.h
index 534a2be68b8..55635846dd6 100644
--- a/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.h
+++ b/chromium/components/signin/core/browser/dice_account_reconcilor_delegate.h
@@ -5,17 +5,12 @@
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_DICE_ACCOUNT_RECONCILOR_DELEGATE_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_DICE_ACCOUNT_RECONCILOR_DELEGATE_H_
-#include <string>
-
#include "base/macros.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
#include "components/signin/public/base/account_consistency_method.h"
class SigninClient;
-// Enables usage of Gaia Auth Multilogin endpoint for identity consistency.
-extern const base::Feature kUseMultiloginEndpoint;
-
namespace signin {
// AccountReconcilorDelegate specialized for Dice.
@@ -27,7 +22,6 @@ class DiceAccountReconcilorDelegate : public AccountReconcilorDelegate {
// AccountReconcilorDelegate:
bool IsReconcileEnabled() const override;
- bool IsMultiloginEndpointEnabled() const override;
gaia::GaiaSource GetGaiaApiSource() const override;
CoreAccountId GetFirstGaiaAccountForReconcile(
const std::vector<CoreAccountId>& chrome_accounts,
diff --git a/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc b/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc
index 2accff2fc0e..c1185dcc5dd 100644
--- a/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc
+++ b/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.cc
@@ -39,12 +39,19 @@ bool MirrorAccountReconcilorDelegate::ShouldAbortReconcileIfPrimaryHasError()
ConsentLevel MirrorAccountReconcilorDelegate::GetConsentLevelForPrimaryAccount()
const {
-#if defined(OS_ANDROID)
+#if defined(OS_ANDROID) || defined(OS_IOS)
if (base::FeatureList::IsEnabled(kMobileIdentityConsistency)) {
return ConsentLevel::kSignin;
}
-#endif
return ConsentLevel::kSync;
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+ // Whenever Mirror is enabled on a Lacros Profile, the Primary Account may or
+ // may not have consented to Chrome Sync. But we want to enable
+ // `AccountReconcilor` regardless - for minting Gaia cookies.
+ return ConsentLevel::kSignin;
+#else
+ return ConsentLevel::kSync;
+#endif
}
CoreAccountId MirrorAccountReconcilorDelegate::GetFirstGaiaAccountForReconcile(
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 192325ee2f5..08ff4ecd9ee 100644
--- a/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h
+++ b/chromium/components/signin/core/browser/mirror_account_reconcilor_delegate.h
@@ -5,7 +5,6 @@
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_MIRROR_ACCOUNT_RECONCILOR_DELEGATE_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_MIRROR_ACCOUNT_RECONCILOR_DELEGATE_H_
-#include <string>
#include <vector>
#include "base/macros.h"
diff --git a/chromium/components/signin/core/browser/signin_error_controller.h b/chromium/components/signin/core/browser/signin_error_controller.h
index 8a5fcfb7dc9..3859c9bf97f 100644
--- a/chromium/components/signin/core/browser/signin_error_controller.h
+++ b/chromium/components/signin/core/browser/signin_error_controller.h
@@ -5,8 +5,6 @@
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_ERROR_CONTROLLER_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_SIGNIN_ERROR_CONTROLLER_H_
-#include <string>
-
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/scoped_observation.h"
diff --git a/chromium/components/signin/core/browser/signin_header_helper.cc b/chromium/components/signin/core/browser/signin_header_helper.cc
index d8fabb6b2bf..8188d319443 100644
--- a/chromium/components/signin/core/browser/signin_header_helper.cc
+++ b/chromium/components/signin/core/browser/signin_header_helper.cc
@@ -9,6 +9,7 @@
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/histogram_functions.h"
+#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "components/google/core/common/google_util.h"
#include "components/signin/core/browser/chrome_connected_header_helper.h"
@@ -24,6 +25,7 @@ namespace signin {
const char kChromeConnectedHeader[] = "X-Chrome-Connected";
const char kChromeManageAccountsHeader[] = "X-Chrome-Manage-Accounts";
+const char kAutoLoginHeader[] = "X-Auto-Login";
const char kDiceRequestHeader[] = "X-Chrome-ID-Consistency-Request";
const char kDiceResponseHeader[] = "X-Chrome-ID-Consistency-Response";
@@ -148,9 +150,9 @@ SigninHeaderHelper::ParseAccountConsistencyResponseHeader(
continue;
}
dictionary.insert(
- {field.substr(0, delim).as_string(),
+ {std::string(field.substr(0, delim)),
net::UnescapeURLComponent(
- field.substr(delim + 1).as_string(),
+ field.substr(delim + 1),
net::UnescapeRule::PATH_SEPARATORS |
net::UnescapeRule::URL_SPECIAL_CHARS_EXCEPT_PATH_SEPARATORS)});
}
@@ -167,7 +169,7 @@ void AppendOrRemoveMirrorRequestHeader(
RequestAdapter* request,
const GURL& redirect_url,
const std::string& gaia_id,
- const base::Optional<bool>& is_child_account,
+ const absl::optional<bool>& is_child_account,
AccountConsistencyMethod account_consistency,
const content_settings::CookieSettings* cookie_settings,
int profile_mode_mask,
diff --git a/chromium/components/signin/core/browser/signin_header_helper.h b/chromium/components/signin/core/browser/signin_header_helper.h
index bf76900e121..d87917cf169 100644
--- a/chromium/components/signin/core/browser/signin_header_helper.h
+++ b/chromium/components/signin/core/browser/signin_header_helper.h
@@ -40,6 +40,13 @@ extern const char kChromeManageAccountsHeader[];
extern const char kDiceRequestHeader[];
extern const char kDiceResponseHeader[];
+// The X-Auto-Login header detects when a user is prompted to enter their
+// credentials on the Gaia sign-in page. It is sent with an empty email if the
+// user is on the Gaia sign-in email page or a pre-filled email if the user has
+// selected an account on the AccountChooser. X-Auto-Login is not sent following
+// a reauth request.
+extern const char kAutoLoginHeader[];
+
// The ServiceType specified by Gaia in the response header accompanying the 204
// response. This indicates the action Chrome is supposed to lead the user to
// perform.
@@ -197,10 +204,6 @@ class SigninHeaderHelper {
const GURL& url,
const content_settings::CookieSettings* cookie_settings) = 0;
- protected:
- SigninHeaderHelper();
- virtual ~SigninHeaderHelper();
-
// Dictionary of fields in a account consistency response header.
using ResponseHeaderDictionary = std::multimap<std::string, std::string>;
@@ -209,6 +212,10 @@ class SigninHeaderHelper {
static ResponseHeaderDictionary ParseAccountConsistencyResponseHeader(
const std::string& header_value);
+ protected:
+ SigninHeaderHelper();
+ virtual ~SigninHeaderHelper();
+
// Returns whether the url is eligible for the request header.
virtual bool IsUrlEligibleForRequestHeader(const GURL& url) = 0;
@@ -238,7 +245,7 @@ void AppendOrRemoveMirrorRequestHeader(
RequestAdapter* request,
const GURL& redirect_url,
const std::string& gaia_id,
- const base::Optional<bool>& is_child_account,
+ const absl::optional<bool>& is_child_account,
AccountConsistencyMethod account_consistency,
const content_settings::CookieSettings* cookie_settings,
int profile_mode_mask,
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 b5e4ff3a984..ad5614f996d 100644
--- a/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
+++ b/chromium/components/signin/core/browser/signin_header_helper_unittest.cc
@@ -27,7 +27,9 @@
#include "url/gurl.h"
#if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "components/signin/public/base/signin_switches.h"
+#include "chromeos/lacros/lacros_chrome_service_delegate.h"
+#include "chromeos/lacros/lacros_chrome_service_impl.h"
+#include "chromeos/lacros/lacros_test_helper.h"
#endif
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
@@ -72,6 +74,14 @@ class SigninHeaderHelperTest : public testing::Test {
content_settings::CookieSettings::RegisterProfilePrefs(prefs_.registry());
HostContentSettingsMap::RegisterProfilePrefs(prefs_.registry());
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+ // TODO(crbug.com/1198528): remove this after the rollout.
+ if (!chromeos::LacrosChromeServiceImpl::Get()) {
+ scoped_lacros_test_helper_ =
+ std::make_unique<chromeos::ScopedLacrosServiceTestHelper>();
+ }
+#endif
+
settings_map_ = new HostContentSettingsMap(
&prefs_, false /* is_off_the_record */, false /* store_last_modified */,
false /* restore_session */);
@@ -93,7 +103,7 @@ class SigninHeaderHelperTest : public testing::Test {
net::HttpRequestHeaders CreateRequest(
const GURL& url,
const std::string& account_id,
- const base::Optional<bool>& is_child_account) {
+ const absl::optional<bool>& is_child_account) {
net::HttpRequestHeaders original_headers;
RequestAdapterWrapper request_adapter(url, original_headers);
AppendOrRemoveMirrorRequestHeader(
@@ -121,7 +131,7 @@ class SigninHeaderHelperTest : public testing::Test {
void CheckMirrorHeaderRequest(const GURL& url,
const std::string& account_id,
- const base::Optional<bool>& is_child_account,
+ const absl::optional<bool>& is_child_account,
const std::string& expected_request) {
net::HttpRequestHeaders headers =
CreateRequest(url, account_id, is_child_account);
@@ -132,7 +142,7 @@ class SigninHeaderHelperTest : public testing::Test {
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
void CheckDiceHeaderRequest(const GURL& url,
const std::string& account_id,
- const base::Optional<bool>& is_child_account,
+ const absl::optional<bool>& is_child_account,
const std::string& expected_mirror_request,
const std::string& expected_dice_request) {
net::HttpRequestHeaders headers =
@@ -144,7 +154,7 @@ class SigninHeaderHelperTest : public testing::Test {
}
#endif
- base::test::SingleThreadTaskEnvironment task_environment_;
+ base::test::TaskEnvironment task_environment_;
bool sync_enabled_ = false;
std::string device_id_ = kTestDeviceId;
@@ -154,6 +164,10 @@ class SigninHeaderHelperTest : public testing::Test {
sync_preferences::TestingPrefServiceSyncable prefs_;
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+ std::unique_ptr<chromeos::ScopedLacrosServiceTestHelper>
+ scoped_lacros_test_helper_;
+#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
scoped_refptr<HostContentSettingsMap> settings_map_;
scoped_refptr<content_settings::CookieSettings> cookie_settings_;
};
@@ -163,24 +177,25 @@ class SigninHeaderHelperTest : public testing::Test {
// account id).
TEST_F(SigninHeaderHelperTest, TestMirrorRequestNoAccountIdChromeOS) {
#if BUILDFLAG(IS_CHROMEOS_LACROS)
- if (!base::FeatureList::IsEnabled(switches::kUseAccountManagerFacade)) {
+ const crosapi::mojom::BrowserInitParams* init_params =
+ chromeos::LacrosChromeServiceImpl::Get()->init_params();
+ if (!init_params->use_new_account_manager)
return;
- }
#endif
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(
GURL("https://docs.google.com"), /*gaia_id=*/"",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), /*gaia_id=*/"",
"mode=0:enable_account_consistency=true:"
"consistency_enabled_by_default=false");
}
-#else // !BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
-#if defined(OS_ANDROID) || defined(OS_IOS)
-// Tests that eligible_for_consistency request is returned on mobile (Android,
-// iOS) when reaching to Gaia origin and there's no primary account. Only
+#else // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if defined(OS_ANDROID)
+// Tests that eligible_for_consistency request is returned on Android
+// when reaching to Gaia origin and there's no primary account. Only
// applicable when the Mobile Identity Consistency is enabled.
TEST_F(SigninHeaderHelperTest, TestEligibleForConsistencyRequestGaiaOrigin) {
base::test::ScopedFeatureList feature_list;
@@ -188,15 +203,15 @@ TEST_F(SigninHeaderHelperTest, TestEligibleForConsistencyRequestGaiaOrigin) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://accounts.google.com"), /*gaia_id=*/"",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,eligible_for_consistency=true");
CheckMirrorCookieRequest(GURL("https://accounts.google.com"), /*gaia_id=*/"",
"eligible_for_consistency=true");
}
-// Tests that eligible_for_consistency request is NOT returned on mobile
-// (Android, iOS) when reaching to NON-Gaia origin and there's no primary
-// account. Only applicable when the Mobile Identity Consistency is enabled.
+// Tests that eligible_for_consistency request is NOT returned on Android
+// when reaching to NON-Gaia origin and there's no primary account
+// Only applicable when the Mobile Identity Consistency is enabled.
TEST_F(SigninHeaderHelperTest,
TestNoEligibleForConsistencyRequestNonGaiaOrigin) {
base::test::ScopedFeatureList feature_list;
@@ -204,7 +219,7 @@ TEST_F(SigninHeaderHelperTest,
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), /*gaia_id=*/"",
- /*is_child_account=*/base::nullopt, "");
+ /*is_child_account=*/absl::nullopt, "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), /*gaia_id=*/"", "");
}
@@ -218,18 +233,18 @@ TEST_F(SigninHeaderHelperTest, TestForceAccountConsistencyMobile) {
force_account_consistency_ = true;
CheckMirrorHeaderRequest(
GURL("https://docs.google.com"), /*gaia_id=*/"",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
}
-#endif // defined(OS_ANDROID) || defined(OS_IOS)
+#endif // defined(OS_ANDROID)
// 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) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), /*gaia_id=*/"",
- /*is_child_account=*/base::nullopt, "");
+ /*is_child_account=*/absl::nullopt, "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), /*gaia_id=*/"", "");
}
#endif
@@ -240,7 +255,7 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
account_consistency_ = AccountConsistencyMethod::kMirror;
cookie_settings_->SetDefaultCookieSetting(CONTENT_SETTING_BLOCK);
CheckMirrorHeaderRequest(GURL("https://docs.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt, "");
+ /*is_child_account=*/absl::nullopt, "");
CheckMirrorCookieRequest(GURL("https://docs.google.com"), "0123456789", "");
}
@@ -248,7 +263,7 @@ TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestCookieSettingBlocked) {
TEST_F(SigninHeaderHelperTest, TestNoMirrorRequestExternalURL) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(GURL("https://foo.com"), "0123456789",
- /*is_child_account=*/base::nullopt, "");
+ /*is_child_account=*/absl::nullopt, "");
CheckMirrorCookieRequest(GURL("https://foo.com"), "0123456789", "");
}
@@ -258,7 +273,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleTLD) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(
GURL("https://google.fr"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorCookieRequest(GURL("https://google.de"), "0123456789",
@@ -272,7 +287,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleCom) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(
GURL("https://www.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorCookieRequest(GURL("https://www.google.com"), "0123456789",
@@ -287,7 +302,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComNoProfileConsistency) {
original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), GURL(), "0123456789",
- /*is_child_account=*/base::nullopt, account_consistency_,
+ /*is_child_account=*/absl::nullopt, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
CheckAccountConsistencyHeaderRequest(request_adapter.GetFinalHeaders(),
@@ -302,7 +317,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComProfileConsistency) {
original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), GURL(), "0123456789",
- /*is_child_account=*/base::nullopt, account_consistency_,
+ /*is_child_account=*/absl::nullopt, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
CheckAccountConsistencyHeaderRequest(
@@ -315,17 +330,17 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGoogleComSupervised) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckMirrorHeaderRequest(
GURL("https://www.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorHeaderRequest(
GURL("https://www.google.com"), "0123456789",
- /*is_child_account=*/base::Optional<bool>(true),
+ /*is_child_account=*/absl::optional<bool>(true),
"source=TestSource,mode=0,enable_account_consistency=true,"
"supervised=true,consistency_enabled_by_default=false");
CheckMirrorHeaderRequest(
GURL("https://www.google.com"), "0123456789",
- /*is_child_account=*/base::Optional<bool>(false),
+ /*is_child_account=*/absl::optional<bool>(false),
"source=TestSource,mode=0,enable_account_consistency=true,"
"supervised=false,consistency_enabled_by_default=false");
}
@@ -338,7 +353,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGaiaURL) {
// No request when account consistency is disabled.
account_consistency_ = AccountConsistencyMethod::kDisabled;
CheckMirrorHeaderRequest(GURL("https://accounts.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
/*expected_request=*/"");
CheckMirrorCookieRequest(GURL("https://accounts.google.com"), "0123456789",
/*expected_request=*/"");
@@ -347,7 +362,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGaiaURL) {
// No request when Mirror account consistency enabled, but user not signed in
// to Chrome.
CheckMirrorHeaderRequest(GURL("https://accounts.google.com"), /*gaia_id=*/"",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
/*expected_request=*/"");
CheckMirrorCookieRequest(GURL("https://accounts.google.com"), /*gaia_id=*/"",
/*expected_request=*/"");
@@ -356,7 +371,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorRequestGaiaURL) {
// signed in to Chrome.
CheckMirrorHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false");
CheckMirrorCookieRequest(GURL("https://accounts.google.com"), "0123456789",
@@ -370,7 +385,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceRequest) {
// ChromeConnected but no Dice for Docs URLs.
CheckDiceHeaderRequest(
GURL("https://docs.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,id=0123456789,mode=0,enable_account_consistency=false,"
"consistency_enabled_by_default=false",
/*expected_dice_request=*/"");
@@ -381,7 +396,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceRequest) {
ASSERT_FALSE(client_id.empty());
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
/*expected_mirror_request=*/"",
base::StringPrintf(
"version=%s,client_id=%s,device_id=DeviceID,signin_mode=all_accounts,"
@@ -392,7 +407,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceRequest) {
sync_enabled_ = true;
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
/*expected_mirror_request=*/"",
base::StringPrintf("version=%s,client_id=%s,device_id=DeviceID,"
"sync_account_id=0123456789,signin_mode=all_accounts,"
@@ -402,7 +417,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceRequest) {
// No ChromeConnected and no Dice for other URLs.
CheckDiceHeaderRequest(GURL("https://www.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
/*expected_mirror_request=*/"",
/*expected_dice_request=*/"");
}
@@ -416,7 +431,7 @@ TEST_F(SigninHeaderHelperTest, DiceCookiesBlocked) {
ASSERT_FALSE(client_id.empty());
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt, "",
+ /*is_child_account=*/absl::nullopt, "",
base::StringPrintf(
"version=%s,client_id=%s,device_id=DeviceID,signin_mode=all_accounts,"
"signout_mode=show_confirmation",
@@ -428,7 +443,7 @@ TEST_F(SigninHeaderHelperTest, TestNoDiceRequestWhenDisabled) {
account_consistency_ = AccountConsistencyMethod::kMirror;
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,mode=0,enable_account_consistency=true,"
"consistency_enabled_by_default=false",
"");
@@ -443,7 +458,7 @@ TEST_F(SigninHeaderHelperTest, TestDiceEmptyDeviceID) {
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
/*expected_mirror_request=*/"",
base::StringPrintf("version=%s,client_id=%s,signin_mode=all_accounts,"
"signout_mode=show_confirmation",
@@ -458,7 +473,7 @@ TEST_F(SigninHeaderHelperTest, TestSignoutConfirmation) {
CheckDiceHeaderRequest(
GURL("https://accounts.google.com"), "0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
/*expected_mirror_request=*/"",
base::StringPrintf(
"version=%s,client_id=%s,device_id=DeviceID,signin_mode=all_accounts,"
@@ -477,7 +492,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderRequestDriveSignedOut) {
AccountConsistencyMethod::kMirror, AccountConsistencyMethod::kDice}) {
account_consistency_ = account_consistency;
CheckMirrorHeaderRequest(url, /*gaia_id=*/"",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
/*expected_request=*/"");
CheckMirrorCookieRequest(url, /*gaia_id=*/"",
/*expected_request=*/"");
@@ -494,7 +509,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderRequestDriveSignedIn) {
// Request with Gaia ID when Mirror account consistency is enabled and user
// is signed in to Chrome.
CheckMirrorHeaderRequest(url, /*gaia_id=*/"0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,id=0123456789,mode=0,enable_"
"account_consistency=true,"
"consistency_enabled_by_default=false");
@@ -508,7 +523,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderRequestDriveSignedIn) {
// Request with Gaia ID when DICE account consistency is enabled and user is
// opted in to sycn.
CheckMirrorHeaderRequest(url, /*gaia_id=*/"0123456789",
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
"source=TestSource,id=0123456789,mode=0,enable_"
"account_consistency=false,"
"consistency_enabled_by_default=false");
@@ -658,7 +673,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderEligibleRedirectURL) {
RequestAdapterWrapper request_adapter(url, original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), redirect_url, account_id,
- /*is_child_account=*/base::nullopt, account_consistency_,
+ /*is_child_account=*/absl::nullopt, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
EXPECT_TRUE(
@@ -677,7 +692,7 @@ TEST_F(SigninHeaderHelperTest, TestMirrorHeaderNonEligibleRedirectURL) {
RequestAdapterWrapper request_adapter(url, original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), redirect_url, account_id,
- /*is_child_account=*/base::nullopt, account_consistency_,
+ /*is_child_account=*/absl::nullopt, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
EXPECT_FALSE(
@@ -697,7 +712,7 @@ TEST_F(SigninHeaderHelperTest, TestIgnoreMirrorHeaderNonEligibleURLs) {
RequestAdapterWrapper request_adapter(url, original_headers);
AppendOrRemoveMirrorRequestHeader(
request_adapter.adapter(), redirect_url, account_id,
- /*is_child_account=*/base::nullopt, account_consistency_,
+ /*is_child_account=*/absl::nullopt, account_consistency_,
cookie_settings_.get(), PROFILE_MODE_DEFAULT, kTestSource,
false /* force_account_consistency */);
std::string header;
@@ -730,7 +745,7 @@ TEST_F(SigninHeaderHelperTest, TestBuildManageAccountsParams) {
EXPECT_EQ(true, params.is_saml);
EXPECT_EQ(true, params.is_same_tab);
EXPECT_EQ(GURL(kContinueURL), params.continue_url);
-#if defined(OS_ANDROID) || defined(OS_IOS)
+#if defined(OS_ANDROID)
EXPECT_EQ(true, params.show_consistency_promo);
#endif
}
diff --git a/chromium/components/signin/core/browser/signin_internals_util.h b/chromium/components/signin/core/browser/signin_internals_util.h
index dc6a0e240ea..09e80e87532 100644
--- a/chromium/components/signin/core/browser/signin_internals_util.h
+++ b/chromium/components/signin/core/browser/signin_internals_util.h
@@ -11,7 +11,6 @@
#include <memory>
#include <string>
-#include "base/values.h"
namespace signin_internals_util {
diff --git a/chromium/components/signin/internal/identity_manager/BUILD.gn b/chromium/components/signin/internal/identity_manager/BUILD.gn
index 8f54d7a1cc9..171d8a0719b 100644
--- a/chromium/components/signin/internal/identity_manager/BUILD.gn
+++ b/chromium/components/signin/internal/identity_manager/BUILD.gn
@@ -96,6 +96,14 @@ source_set("identity_manager") {
deps += [ "//components/user_manager" ]
} else {
+ if (is_chromeos_lacros) {
+ # TODO(bsazonov): Simplify this after removing profile_oauth2_token_service_delegate_chromeos_legacy.
+ sources += [
+ "profile_oauth2_token_service_delegate_chromeos.cc",
+ "profile_oauth2_token_service_delegate_chromeos.h",
+ ]
+ deps += [ "//components/account_manager_core" ]
+ }
sources += [
"primary_account_policy_manager_impl.cc",
"primary_account_policy_manager_impl.h",
@@ -159,6 +167,7 @@ source_set("unit_tests") {
"//components/signin/public/base:signin_buildflags",
"//components/signin/public/base:test_support",
"//components/signin/public/identity_manager",
+ "//components/signin/public/identity_manager:test_support",
"//components/signin/public/webdata",
"//components/sync_preferences:test_support",
"//components/webdata/common",
@@ -173,8 +182,6 @@ source_set("unit_tests") {
if (is_android) {
sources += [ "profile_oauth2_token_service_delegate_android_unittest.cc" ]
-
- deps += [ "//components/signin/public/identity_manager:test_support" ]
}
if (is_chromeos_ash) {
diff --git a/chromium/components/signin/internal/identity_manager/account_info_util.cc b/chromium/components/signin/internal/identity_manager/account_info_util.cc
index cb77753ba13..7e2d28d222f 100644
--- a/chromium/components/signin/internal/identity_manager/account_info_util.cc
+++ b/chromium/components/signin/internal/identity_manager/account_info_util.cc
@@ -18,22 +18,22 @@ const char kLocaleKey[] = "locale";
const char kPictureUrlKey[] = "picture";
} // namespace
-base::Optional<AccountInfo> AccountInfoFromUserInfo(
+absl::optional<AccountInfo> AccountInfoFromUserInfo(
const base::Value& user_info) {
if (!user_info.is_dict())
- return base::nullopt;
+ return absl::nullopt;
// Both |gaia_id| and |email| are required value in the JSON reply, so
// return empty result if any is missing.
const base::Value* gaia_id_value =
user_info.FindKeyOfType(kGaiaIdKey, base::Value::Type::STRING);
if (!gaia_id_value)
- return base::nullopt;
+ return absl::nullopt;
const base::Value* email_value =
user_info.FindKeyOfType(kEmailKey, base::Value::Type::STRING);
if (!email_value)
- return base::nullopt;
+ return absl::nullopt;
AccountInfo account_info;
account_info.email = email_value->GetString();
diff --git a/chromium/components/signin/internal/identity_manager/account_info_util.h b/chromium/components/signin/internal/identity_manager/account_info_util.h
index 53207e5c483..74330a7bbc3 100644
--- a/chromium/components/signin/internal/identity_manager/account_info_util.h
+++ b/chromium/components/signin/internal/identity_manager/account_info_util.h
@@ -5,13 +5,13 @@
#ifndef COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_ACCOUNT_INFO_UTIL_H_
#define COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_ACCOUNT_INFO_UTIL_H_
-#include "base/optional.h"
#include "base/values.h"
#include "components/signin/public/identity_manager/account_info.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
// Builds an AccountInfo from the JSON data returned by the gaia servers (the
// data should have been converted to base::Value), if possible.
-base::Optional<AccountInfo> AccountInfoFromUserInfo(
+absl::optional<AccountInfo> AccountInfoFromUserInfo(
const base::Value& user_info);
#endif // COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_ACCOUNT_INFO_UTIL_H_
diff --git a/chromium/components/signin/internal/identity_manager/account_info_util_unittest.cc b/chromium/components/signin/internal/identity_manager/account_info_util_unittest.cc
index cc658a06104..a3aa467d47f 100644
--- a/chromium/components/signin/internal/identity_manager/account_info_util_unittest.cc
+++ b/chromium/components/signin/internal/identity_manager/account_info_util_unittest.cc
@@ -49,7 +49,7 @@ using AccountInfoUtilTest = PlatformTest;
// Tests that AccountInfoFromUserInfo returns an AccountInfo with the value
// extracted from the passed base::Value.
TEST_F(AccountInfoUtilTest, FromUserInfo) {
- base::Optional<AccountInfo> maybe_account_info =
+ absl::optional<AccountInfo> maybe_account_info =
AccountInfoFromUserInfo(CreateUserInfoWithValues(
/*email=*/"user@example.com", /*gaia=*/"gaia_id_user_example_com",
/*hosted_domain=*/"example.com", /*full_name=*/"full name",
@@ -71,7 +71,7 @@ TEST_F(AccountInfoUtilTest, FromUserInfo) {
// Tests that AccountInfoFromUserInfo returns an AccountInfo with empty or
// default values if no fields are set in the user_info.
TEST_F(AccountInfoUtilTest, FromUserInfo_EmptyValues) {
- base::Optional<AccountInfo> maybe_account_info =
+ absl::optional<AccountInfo> maybe_account_info =
AccountInfoFromUserInfo(CreateUserInfoWithValues(
/*email=*/"", /*gaia=*/"", /*hosted_domain=*/"", /*full_name=*/"",
/*given_name=*/"", /*locale=*/"", /*picture_url=*/""));
@@ -92,7 +92,7 @@ TEST_F(AccountInfoUtilTest, FromUserInfo_EmptyValues) {
// extracted from the passed base::Value, with default value for |hosted_domain|
// if missing.
TEST_F(AccountInfoUtilTest, FromUserInfo_NoHostedDomain) {
- base::Optional<AccountInfo> maybe_account_info =
+ absl::optional<AccountInfo> maybe_account_info =
AccountInfoFromUserInfo(CreateUserInfoWithValues(
/*email=*/"user@example.com", /*gaia=*/"gaia_id_user_example_com",
/*hosted_domain=*/nullptr, /*full_name=*/"full name",
@@ -109,7 +109,7 @@ TEST_F(AccountInfoUtilTest, FromUserInfo_NoHostedDomain) {
// extracted from the passed base::Value, with default value for |picture_url|
// if missing.
TEST_F(AccountInfoUtilTest, FromUserInfo_NoPictureUrl) {
- base::Optional<AccountInfo> maybe_account_info =
+ absl::optional<AccountInfo> maybe_account_info =
AccountInfoFromUserInfo(CreateUserInfoWithValues(
/*email=*/"user@example.com", /*gaia=*/"gaia_id_user_example_com",
/*hosted_domain=*/"example.com", /*full_name=*/"full name",
@@ -125,7 +125,7 @@ TEST_F(AccountInfoUtilTest, FromUserInfo_NoPictureUrl) {
// Tests that if AccountInfoFromUserInfo fails if the value passed has no
// value for |email|.
TEST_F(AccountInfoUtilTest, FromUserInfo_NoEmail) {
- base::Optional<AccountInfo> maybe_account_info =
+ absl::optional<AccountInfo> maybe_account_info =
AccountInfoFromUserInfo(CreateUserInfoWithValues(
/*email=*/nullptr, /*gaia=*/"gaia_id_user_example_com",
/*hosted_domain=*/"example.com", /*full_name=*/"full name",
@@ -138,7 +138,7 @@ TEST_F(AccountInfoUtilTest, FromUserInfo_NoEmail) {
// Tests that if AccountInfoFromUserInfo fails if the value passed has no
// value for |gaia|.
TEST_F(AccountInfoUtilTest, FromUserInfo_NoGaiaId) {
- base::Optional<AccountInfo> maybe_account_info =
+ absl::optional<AccountInfo> maybe_account_info =
AccountInfoFromUserInfo(CreateUserInfoWithValues(
/*email=*/"user@example.com", /*gaia=*/nullptr,
/*hosted_domain=*/"example.com", /*full_name=*/"full name",
@@ -151,7 +151,7 @@ TEST_F(AccountInfoUtilTest, FromUserInfo_NoGaiaId) {
// Tests that if AccountInfoFromUserInfo fails if the value passed is not a
// dictionary.
TEST_F(AccountInfoUtilTest, FromUserInfo_NotADictionary) {
- base::Optional<AccountInfo> maybe_account_info =
+ absl::optional<AccountInfo> maybe_account_info =
AccountInfoFromUserInfo(base::Value("not a dictionary"));
EXPECT_FALSE(maybe_account_info.has_value());
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 68944ea785b..44a587f233e 100644
--- a/chromium/components/signin/internal/identity_manager/account_tracker_service.cc
+++ b/chromium/components/signin/internal/identity_manager/account_tracker_service.cc
@@ -238,7 +238,7 @@ void AccountTrackerService::SetAccountInfoFromUserInfo(
DCHECK(base::Contains(accounts_, account_id));
AccountInfo& account_info = accounts_[account_id];
- base::Optional<AccountInfo> maybe_account_info =
+ absl::optional<AccountInfo> maybe_account_info =
AccountInfoFromUserInfo(*user_info);
if (maybe_account_info) {
// Should we DCHECK that the account stored in |accounts_| has the same
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 e52e1547813..276f18b3f51 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
@@ -36,7 +36,7 @@
#include "testing/gtest/include/gtest/gtest.h"
#if defined(OS_ANDROID)
-#include "components/signin/internal/identity_manager/child_account_info_fetcher_android.h"
+#include "components/signin/public/identity_manager/identity_test_utils.h"
#endif
namespace {
@@ -177,7 +177,9 @@ class AccountTrackerServiceTest : public testing::Test {
: signin_client_(&pref_service_),
fake_oauth2_token_service_(&pref_service_) {
#if defined(OS_ANDROID)
- ChildAccountInfoFetcherAndroid::InitializeForTests();
+ // Mock AccountManagerFacade in java code for tests that require its
+ // initialization.
+ signin::SetUpMockAccountManagerFacade();
#endif
AccountTrackerService::RegisterPrefs(pref_service_.registry());
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 d03c005f806..8ce9809a78d 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
@@ -116,4 +116,13 @@ void AccountsCookieMutatorImpl::LogOutAllAccounts(
source, std::move(completion_callback));
}
+void AccountsCookieMutatorImpl::RemoveLoggedOutAccountByGaiaId(
+ const std::string& gaia_id) {
+ // Note that RemoveLoggedOutAccountByGaiaId() does NOT internally trigger a
+ // ListAccounts fetch. It could make sense to force a request here, e.g. via
+ // ForceOnCookieChangeProcessing(), but this isn't considered important enough
+ // to justify the risk for overloading the server.
+ gaia_cookie_manager_service_->RemoveLoggedOutAccountByGaiaId(gaia_id);
+}
+
} // 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 cf8dc8e6d5b..d98f0afc47a 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
@@ -69,6 +69,8 @@ class AccountsCookieMutatorImpl : public AccountsCookieMutator {
gaia::GaiaSource source,
LogOutFromCookieCompletedCallback completion_callback) override;
+ void RemoveLoggedOutAccountByGaiaId(const std::string& gaia_id) override;
+
private:
class MultiloginHelperWrapper : public SetAccountsInCookieTask {
public:
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 ab5c2d7499e..f939edfcec3 100644
--- a/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.cc
+++ b/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.cc
@@ -4,7 +4,6 @@
#include "components/signin/internal/identity_manager/accounts_mutator_impl.h"
-#include "base/optional.h"
#include "build/chromeos_buildflags.h"
#include "components/prefs/pref_service.h"
#include "components/signin/internal/identity_manager/account_tracker_service.h"
@@ -15,6 +14,7 @@
#include "components/signin/public/identity_manager/account_info.h"
#include "google_apis/gaia/core_account_id.h"
#include "google_apis/gaia/gaia_constants.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace signin {
@@ -63,8 +63,8 @@ CoreAccountId AccountsMutatorImpl::AddOrUpdateAccount(
void AccountsMutatorImpl::UpdateAccountInfo(
const CoreAccountId& account_id,
- base::Optional<bool> is_child_account,
- base::Optional<bool> is_under_advanced_protection) {
+ absl::optional<bool> is_child_account,
+ absl::optional<bool> is_under_advanced_protection) {
if (is_child_account.has_value()) {
account_tracker_service_->SetIsChildAccount(account_id,
is_child_account.value());
diff --git a/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.h b/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.h
index 742b026de0b..19cc2c096ae 100644
--- a/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.h
+++ b/chromium/components/signin/internal/identity_manager/accounts_mutator_impl.h
@@ -42,8 +42,8 @@ class AccountsMutatorImpl : public AccountsMutator {
signin_metrics::SourceForRefreshTokenOperation source) override;
void UpdateAccountInfo(
const CoreAccountId& account_id,
- base::Optional<bool> is_child_account,
- base::Optional<bool> is_under_advanced_protection) override;
+ absl::optional<bool> is_child_account,
+ absl::optional<bool> is_under_advanced_protection) override;
void RemoveAccount(
const CoreAccountId& account_id,
signin_metrics::SourceForRefreshTokenOperation source) override;
diff --git a/chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.cc b/chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.cc
index e8bad35a5bf..b59fe1cd5e5 100644
--- a/chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.cc
+++ b/chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.cc
@@ -31,11 +31,6 @@ ChildAccountInfoFetcherAndroid::Create(AccountFetcherService* service,
new ChildAccountInfoFetcherAndroid(service, account_info));
}
-void ChildAccountInfoFetcherAndroid::InitializeForTests() {
- signin::Java_ChildAccountInfoFetcher_initializeForTests(
- base::android::AttachCurrentThread());
-}
-
ChildAccountInfoFetcherAndroid::ChildAccountInfoFetcherAndroid(
AccountFetcherService* service,
const CoreAccountInfo& account_info) {
diff --git a/chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.h b/chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.h
index e51b1334922..864e7347945 100644
--- a/chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.h
+++ b/chromium/components/signin/internal/identity_manager/child_account_info_fetcher_android.h
@@ -6,7 +6,6 @@
#define COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_CHILD_ACCOUNT_INFO_FETCHER_ANDROID_H_
#include <jni.h>
-#include <string>
#include "base/android/scoped_java_ref.h"
#include "components/signin/public/identity_manager/account_info.h"
diff --git a/chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.cc b/chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.cc
index 2d732c23a33..f284e6a8ca0 100644
--- a/chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.cc
+++ b/chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.cc
@@ -19,7 +19,7 @@ DeviceAccountsSynchronizerImpl::~DeviceAccountsSynchronizerImpl() = default;
void DeviceAccountsSynchronizerImpl::
ReloadAllAccountsFromSystemWithPrimaryAccount(
- const base::Optional<CoreAccountId>& primary_account_id) {
+ const absl::optional<CoreAccountId>& primary_account_id) {
token_service_delegate_->ReloadAllAccountsFromSystemWithPrimaryAccount(
primary_account_id);
}
diff --git a/chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.h b/chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.h
index 0ee9d2fdd56..e2283bc8dde 100644
--- a/chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.h
+++ b/chromium/components/signin/internal/identity_manager/device_accounts_synchronizer_impl.h
@@ -21,7 +21,7 @@ class DeviceAccountsSynchronizerImpl : public DeviceAccountsSynchronizer {
// DeviceAccountsSynchronizer implementation.
void ReloadAllAccountsFromSystemWithPrimaryAccount(
- const base::Optional<CoreAccountId>& primary_account_id) override;
+ const absl::optional<CoreAccountId>& primary_account_id) override;
#if defined(OS_IOS)
void ReloadAccountFromSystem(const CoreAccountId& account_id) override;
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 773aa6063e7..cb65ddf82c9 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
@@ -14,6 +14,7 @@
#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/json/json_reader.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
@@ -99,6 +100,11 @@ void RecordLogoutRequestState(LogoutRequestState logout_state) {
UMA_HISTOGRAM_ENUMERATION("Signin.GaiaCookieManager.Logout", logout_state);
}
+void RecordRemoveLocalAccountOutcome(
+ GaiaCookieManagerService::RemoveLocalAccountOutcome outcome) {
+ base::UmaHistogramEnumeration("Signin.RemoveLocalAccountOutcome", outcome);
+}
+
} // namespace
GaiaCookieManagerService::GaiaCookieRequest::SetAccountsParams::
@@ -663,6 +669,36 @@ void GaiaCookieManagerService::LogOutAllAccounts(
}
}
+void GaiaCookieManagerService::RemoveLoggedOutAccountByGaiaId(
+ const std::string& gaia_id) {
+ VLOG(1) << "GaiaCookieManagerService::RemoveLoggedOutAccountByGaiaId";
+
+ if (list_accounts_stale_) {
+ RecordRemoveLocalAccountOutcome(RemoveLocalAccountOutcome::kAccountsStale);
+ return;
+ }
+
+ const bool accounts_updated =
+ base::EraseIf(signed_out_accounts_,
+ [&gaia_id](const gaia::ListedAccount& account) {
+ return account.gaia_id == gaia_id;
+ }) != 0;
+
+ if (!accounts_updated) {
+ RecordRemoveLocalAccountOutcome(
+ RemoveLocalAccountOutcome::kSignedOutAccountMissing);
+ return;
+ }
+
+ RecordRemoveLocalAccountOutcome(RemoveLocalAccountOutcome::kSuccess);
+
+ if (gaia_accounts_updated_in_cookie_callback_) {
+ gaia_accounts_updated_in_cookie_callback_.Run(
+ listed_accounts_, signed_out_accounts_,
+ GoogleServiceAuthError(GoogleServiceAuthError::NONE));
+ }
+}
+
void GaiaCookieManagerService::CancelAll() {
VLOG(1) << "GaiaCookieManagerService::CancelAll";
gaia_auth_fetcher_.reset();
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 b1c7391940a..201bc6c0674 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
@@ -8,7 +8,6 @@
#include <map>
#include <memory>
#include <string>
-#include <unordered_map>
#include <utility>
#include <vector>
@@ -69,6 +68,19 @@ class GaiaCookieManagerService
SET_ACCOUNTS
};
+ // The result of processing a request to remove an account (i.e.
+ // Google-Accounts-RemoveLocalAccount). Used as entry for histogram
+ // |Signin.RemoveLocalAccountOutcome|, hence entries should not be renumbered
+ // and numeric values should never be reused. Exposed publicly for testing
+ // purposes.
+ enum class RemoveLocalAccountOutcome {
+ kSuccess = 0,
+ kAccountsStale = 1,
+ // Missing means the account is not listed in |signed_out_accounts_|.
+ kSignedOutAccountMissing = 2,
+ kMaxValue = kSignedOutAccountMissing
+ };
+
typedef base::OnceCallback<void(signin::SetAccountsInCookieResult)>
SetAccountsInCookieCompletedCallback;
typedef base::OnceCallback<void(const CoreAccountId&,
@@ -271,6 +283,11 @@ class GaiaCookieManagerService
void LogOutAllAccounts(gaia::GaiaSource source,
LogOutFromCookieCompletedCallback callback);
+ // Indicates that an account previously listed via ListAccounts should now
+ // be removed. Does not trigger a ListAccounts request and does not change the
+ // staleness of the account information.
+ void RemoveLoggedOutAccountByGaiaId(const std::string& gaia_id);
+
// Call observers when setting accounts in cookie completes.
void SignalSetAccountsComplete(signin::SetAccountsInCookieResult result);
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 bbe4939cd8c..3326598ac54 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
@@ -98,6 +98,11 @@ MATCHER_P(ListedAccountEquals, expected, "") {
return AreAccountListsEqual(expected, arg);
}
+// Custom matcher for ListedAccount.
+MATCHER_P(ListedAccountMatchesGaiaId, gaia_id, "") {
+ return arg.gaia_id == std::string(gaia_id);
+}
+
class InstrumentedGaiaCookieManagerService : public GaiaCookieManagerService {
public:
InstrumentedGaiaCookieManagerService(ProfileOAuth2TokenService* token_service,
@@ -248,6 +253,7 @@ class GaiaCookieManagerServiceTest : public testing::Test {
} // namespace
using ::testing::_;
+using ::testing::ElementsAre;
TEST_F(GaiaCookieManagerServiceTest, Success) {
InstrumentedGaiaCookieManagerService helper(token_service(), signin_client());
@@ -1097,3 +1103,147 @@ TEST_F(GaiaCookieManagerServiceTest, UbertokenSuccessFetchesExternalCCOnce) {
EXPECT_CALL(helper, StartFetchingMergeSession());
SimulateUbertokenSuccess(&helper, "token3");
}
+
+TEST_F(GaiaCookieManagerServiceTest, RemoveLoggedOutAccountByGaiaId) {
+ const std::string kTestGaiaId1 = "8";
+ const std::string kTestGaiaId2 = "9";
+
+ ::testing::NiceMock<InstrumentedGaiaCookieManagerService> helper(
+ token_service(), signin_client());
+ ::testing::NiceMock<MockObserver> observer(&helper);
+
+ std::vector<gaia::ListedAccount> signed_in_accounts;
+ std::vector<gaia::ListedAccount> signed_out_accounts;
+ ASSERT_FALSE(helper.ListAccounts(&signed_in_accounts, &signed_out_accounts));
+
+ // Simulate two signed out accounts being listed.
+ SimulateListAccountsSuccess(
+ &helper,
+ base::StringPrintf(
+ "[\"f\","
+ "[[\"a\", 0, \"n\", \"a@d.com\", \"p\", 0, 0, 0, 0, 1, \"%s\","
+ "null,null,null,1],"
+ "[\"b\", 0, \"n\", \"b@d.com\", \"p\", 0, 0, 0, 0, 1, \"%s\","
+ "null,null,null,1]]]",
+ kTestGaiaId1.c_str(), kTestGaiaId2.c_str()));
+
+ ASSERT_TRUE(helper.ListAccounts(&signed_in_accounts, &signed_out_accounts));
+ ASSERT_THAT(signed_out_accounts,
+ ElementsAre(ListedAccountMatchesGaiaId(kTestGaiaId1),
+ ListedAccountMatchesGaiaId(kTestGaiaId2)));
+
+ // The removal should notify observers, with one account removed.
+ EXPECT_CALL(observer,
+ OnGaiaAccountsInCookieUpdated(
+ _, /*signed_out_accounts=*/
+ ElementsAre(ListedAccountMatchesGaiaId(kTestGaiaId2)), _));
+ EXPECT_CALL(helper, StartFetchingListAccounts()).Times(0);
+ base::HistogramTester histograms;
+ helper.RemoveLoggedOutAccountByGaiaId(kTestGaiaId1);
+
+ // Verify that ListAccounts wasn't triggered.
+ EXPECT_FALSE(helper.is_running());
+ EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&helper));
+
+ ASSERT_TRUE(helper.ListAccounts(&signed_in_accounts, &signed_out_accounts));
+ EXPECT_THAT(signed_out_accounts,
+ ElementsAre(ListedAccountMatchesGaiaId(kTestGaiaId2)));
+
+ histograms.ExpectUniqueSample(
+ "Signin.RemoveLocalAccountOutcome",
+ GaiaCookieManagerService::RemoveLocalAccountOutcome::kSuccess, 1);
+}
+
+TEST_F(GaiaCookieManagerServiceTest,
+ RemoveLoggedOutAccountByGaiaIdWhileAccountsStale) {
+ const std::string kTestGaiaId1 = "8";
+
+ ::testing::NiceMock<InstrumentedGaiaCookieManagerService> helper(
+ token_service(), signin_client());
+ ::testing::NiceMock<MockObserver> observer(&helper);
+
+ std::vector<gaia::ListedAccount> signed_in_accounts;
+ std::vector<gaia::ListedAccount> signed_out_accounts;
+ ASSERT_FALSE(helper.ListAccounts(&signed_in_accounts, &signed_out_accounts));
+
+ // Simulate one signed out account being listed.
+ SimulateListAccountsSuccess(
+ &helper,
+ base::StringPrintf(
+ "[\"f\","
+ "[[\"a\", 0, \"n\", \"a@d.com\", \"p\", 0, 0, 0, 0, 1, \"%s\","
+ "null,null,null,1]]]",
+ kTestGaiaId1.c_str()));
+
+ // Change list account state to be stale, which will trigger list accounts
+ // request.
+ helper.ForceOnCookieChangeProcessing();
+
+ ASSERT_FALSE(helper.ListAccounts(&signed_in_accounts, &signed_out_accounts));
+ ASSERT_THAT(signed_out_accounts,
+ ElementsAre(ListedAccountMatchesGaiaId(kTestGaiaId1)));
+
+ // The removal should be ignored because the account list is stale.
+ EXPECT_CALL(observer, OnGaiaAccountsInCookieUpdated(_, _, _)).Times(0);
+ EXPECT_CALL(helper, StartFetchingListAccounts()).Times(0);
+ base::HistogramTester histograms;
+ helper.RemoveLoggedOutAccountByGaiaId(kTestGaiaId1);
+
+ // Verify that ListAccounts wasn't triggered again.
+ EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&helper));
+
+ ASSERT_FALSE(helper.ListAccounts(&signed_in_accounts, &signed_out_accounts));
+ EXPECT_THAT(signed_out_accounts,
+ ElementsAre(ListedAccountMatchesGaiaId(kTestGaiaId1)));
+
+ histograms.ExpectUniqueSample(
+ "Signin.RemoveLocalAccountOutcome",
+ GaiaCookieManagerService::RemoveLocalAccountOutcome::kAccountsStale, 1);
+}
+
+TEST_F(GaiaCookieManagerServiceTest,
+ RemoveLoggedOutAccountByGaiaIdForMissingAccount) {
+ const std::string kTestGaiaId1 = "8";
+ const std::string kNonListedAccount = "9";
+
+ ::testing::NiceMock<InstrumentedGaiaCookieManagerService> helper(
+ token_service(), signin_client());
+ ::testing::NiceMock<MockObserver> observer(&helper);
+
+ std::vector<gaia::ListedAccount> signed_in_accounts;
+ std::vector<gaia::ListedAccount> signed_out_accounts;
+ ASSERT_FALSE(helper.ListAccounts(&signed_in_accounts, &signed_out_accounts));
+
+ // Simulate one signed out account being listed.
+ SimulateListAccountsSuccess(
+ &helper,
+ base::StringPrintf(
+ "[\"f\","
+ "[[\"a\", 0, \"n\", \"a@d.com\", \"p\", 0, 0, 0, 0, 1, \"%s\","
+ "null,null,null,1]]]",
+ kTestGaiaId1.c_str()));
+
+ ASSERT_TRUE(helper.ListAccounts(&signed_in_accounts, &signed_out_accounts));
+ ASSERT_THAT(signed_out_accounts,
+ ElementsAre(ListedAccountMatchesGaiaId(kTestGaiaId1)));
+
+ // The removal should be ignored because the Gaia ID is not listed/known.
+ EXPECT_CALL(observer, OnGaiaAccountsInCookieUpdated(_, _, _)).Times(0);
+ EXPECT_CALL(helper, StartFetchingListAccounts()).Times(0);
+ base::HistogramTester histograms;
+ helper.RemoveLoggedOutAccountByGaiaId(kNonListedAccount);
+
+ // Verify that ListAccounts wasn't triggered.
+ EXPECT_FALSE(helper.is_running());
+ EXPECT_TRUE(testing::Mock::VerifyAndClearExpectations(&helper));
+
+ ASSERT_TRUE(helper.ListAccounts(&signed_in_accounts, &signed_out_accounts));
+ EXPECT_THAT(signed_out_accounts,
+ ElementsAre(ListedAccountMatchesGaiaId(kTestGaiaId1)));
+
+ histograms.ExpectUniqueSample(
+ "Signin.RemoveLocalAccountOutcome",
+ GaiaCookieManagerService::RemoveLocalAccountOutcome::
+ kSignedOutAccountMissing,
+ 1);
+}
diff --git a/chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc b/chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
index 26d866036d9..82a6d6698bb 100644
--- a/chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
+++ b/chromium/components/signin/internal/identity_manager/mutable_profile_oauth2_token_service_delegate.cc
@@ -50,30 +50,6 @@ enum class LoadTokenFromDBStatus {
NUM_LOAD_TOKEN_FROM_DB_STATUS
};
-// Used to record events related to token revocation requests in histograms.
-// Do not change existing values, new values can only be added at the end.
-enum class TokenRevocationRequestProgress {
- // The request was created.
- kRequestCreated = 0,
- // The request was sent over the network.
- kRequestStarted = 1,
- // The network request completed with a failure.
- kRequestFailed = 2,
- // The network request completed with a success.
- kRequestSucceeded = 3,
-
- kMaxValue = kRequestSucceeded
-};
-
-// Adds a sample to the TokenRevocationRequestProgress histogram. Encapsuled in
-// a function to reduce executable size, because histogram macros may generate a
-// lot of code.
-void RecordRefreshTokenRevocationRequestEvent(
- TokenRevocationRequestProgress event) {
- UMA_HISTOGRAM_ENUMERATION("Signin.RefreshTokenRevocationRequestProgress",
- event);
-}
-
std::string ApplyAccountIdPrefix(const std::string& account_id) {
return kAccountIdPrefix + account_id;
}
@@ -166,8 +142,6 @@ MutableProfileOAuth2TokenServiceDelegate::RevokeServerRefreshToken::
token_service_delegate_->GetURLLoaderFactory()),
refresh_token_(refresh_token),
attempt_(attempt) {
- RecordRefreshTokenRevocationRequestEvent(
- TokenRevocationRequestProgress::kRequestCreated);
client->DelayNetworkCall(
base::BindRepeating(&MutableProfileOAuth2TokenServiceDelegate::
RevokeServerRefreshToken::Start,
@@ -176,8 +150,6 @@ MutableProfileOAuth2TokenServiceDelegate::RevokeServerRefreshToken::
void MutableProfileOAuth2TokenServiceDelegate::RevokeServerRefreshToken::
Start() {
- RecordRefreshTokenRevocationRequestEvent(
- TokenRevocationRequestProgress::kRequestStarted);
fetcher_.StartRevokeOAuth2Token(refresh_token_);
}
@@ -207,18 +179,11 @@ bool MutableProfileOAuth2TokenServiceDelegate::RevokeServerRefreshToken::
void MutableProfileOAuth2TokenServiceDelegate::RevokeServerRefreshToken::
OnOAuth2RevokeTokenCompleted(
GaiaAuthConsumer::TokenRevocationStatus status) {
- UMA_HISTOGRAM_ENUMERATION("Signin.RefreshTokenRevocationStatus", status);
if (ShouldRetry(status)) {
token_service_delegate_->server_revokes_.push_back(
std::make_unique<RevokeServerRefreshToken>(
token_service_delegate_, token_service_delegate_->client_,
refresh_token_, attempt_ + 1));
- } else {
- RecordRefreshTokenRevocationRequestEvent(
- (status == GaiaAuthConsumer::TokenRevocationStatus::kSuccess)
- ? TokenRevocationRequestProgress::kRequestSucceeded
- : TokenRevocationRequestProgress::kRequestFailed);
- UMA_HISTOGRAM_ENUMERATION("Signin.RefreshTokenRevocationCompleted", status);
}
// |this| pointer will be deleted when removed from the vector, so don't
// access any members after call to erase().
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 d60787cc73e..f64019b108f 100644
--- a/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.h
+++ b/chromium/components/signin/internal/identity_manager/oauth_multilogin_helper.h
@@ -19,7 +19,6 @@
#include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/gaia_auth_fetcher.h"
#include "net/cookies/cookie_access_result.h"
-#include "services/network/public/mojom/cookie_manager.mojom.h"
class GaiaAuthFetcher;
class GoogleServiceAuthError;
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 332632058a7..14095b440a4 100644
--- a/chromium/components/signin/internal/identity_manager/primary_account_manager.cc
+++ b/chromium/components/signin/internal/identity_manager/primary_account_manager.cc
@@ -56,6 +56,7 @@ void PrimaryAccountManager::RegisterProfilePrefs(PrefRegistrySimple* registry) {
registry->RegisterBooleanPref(prefs::kAutologinEnabled, true);
registry->RegisterListPref(prefs::kReverseAutologinRejectedEmailList);
registry->RegisterBooleanPref(prefs::kSigninAllowed, true);
+ registry->RegisterBooleanPref(prefs::kSigninAllowedByPolicy, true);
registry->RegisterBooleanPref(prefs::kSignedInWithCredentialProvider, false);
}
@@ -353,7 +354,7 @@ void PrimaryAccountManager::OnSignoutDecisionReached(
break;
case RemoveAccountsOption::kKeepAllAccounts:
if (previous_state.consent_level == signin::ConsentLevel::kSignin) {
- // Nothing to update as the primary account is already at kNotRequired
+ // Nothing to update as the primary account is already at kSignin
// consent level. Prefer returning to avoid firing useless
// OnPrimaryAccountChanged() notifications.
return;
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 700d8217dca..a87da779070 100644
--- a/chromium/components/signin/internal/identity_manager/primary_account_manager.h
+++ b/chromium/components/signin/internal/identity_manager/primary_account_manager.h
@@ -19,18 +19,17 @@
#define COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PRIMARY_ACCOUNT_MANAGER_H_
#include <memory>
-#include <string>
#include "base/macros.h"
#include "base/observer_list.h"
#include "base/observer_list_types.h"
-#include "base/optional.h"
#include "build/chromeos_buildflags.h"
#include "components/signin/internal/identity_manager/profile_oauth2_token_service_observer.h"
#include "components/signin/public/base/signin_client.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/primary_account_change_event.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
class AccountTrackerService;
class PrefRegistrySimple;
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 83900c87bc1..b61786ed770 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
@@ -46,40 +46,41 @@ PrimaryAccountMutatorImpl::PrimaryAccountMutatorImpl(
PrimaryAccountMutatorImpl::~PrimaryAccountMutatorImpl() {}
bool PrimaryAccountMutatorImpl::SetPrimaryAccount(
- const CoreAccountId& account_id) {
+ const CoreAccountId& account_id,
+ ConsentLevel consent_level) {
+ DCHECK(!account_id.empty());
AccountInfo account_info = account_tracker_->GetAccountInfo(account_id);
-
-#if !BUILDFLAG(IS_CHROMEOS_ASH)
- if (!pref_service_->GetBoolean(prefs::kSigninAllowed))
+ if (account_info.IsEmpty())
return false;
- if (primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSync))
- return false;
+ DCHECK_EQ(account_info.account_id, account_id);
+ DCHECK(!account_info.email.empty());
+ DCHECK(!account_info.gaia.empty());
- if (account_info.account_id != account_id || account_info.email.empty())
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
+ if (!pref_service_->GetBoolean(prefs::kSigninAllowed))
return false;
-
- // TODO(crbug.com/889899): should check that the account email is allowed.
#endif
- primary_account_manager_->SetSyncPrimaryAccountInfo(account_info);
- return true;
-}
-
-void PrimaryAccountMutatorImpl::SetUnconsentedPrimaryAccount(
- const CoreAccountId& account_id) {
+ switch (consent_level) {
+ case ConsentLevel::kSync:
+#if !BUILDFLAG(IS_CHROMEOS_ASH)
+ if (primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSync))
+ return false;
+#endif
+ primary_account_manager_->SetSyncPrimaryAccountInfo(account_info);
+ return true;
+ case ConsentLevel::kSignin:
#if BUILDFLAG(IS_CHROMEOS_ASH)
- // On Chrome OS the UPA can only be set once and never removed or changed.
- DCHECK(!account_id.empty());
- DCHECK(!primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSignin));
+ // On Chrome OS the UPA can only be set once and never removed or changed.
+ DCHECK(
+ !primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSignin));
#endif
- AccountInfo account_info;
- if (!account_id.empty()) {
- account_info = account_tracker_->GetAccountInfo(account_id);
- DCHECK(!account_info.IsEmpty());
+ DCHECK(!primary_account_manager_->HasPrimaryAccount(ConsentLevel::kSync));
+ primary_account_manager_->SetUnconsentedPrimaryAccountInfo(account_info);
+ return true;
}
-
- primary_account_manager_->SetUnconsentedPrimaryAccountInfo(account_info);
+ return false;
}
#if !BUILDFLAG(IS_CHROMEOS_ASH)
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 99b74257624..0fe82594a61 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
@@ -5,8 +5,6 @@
#ifndef COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PRIMARY_ACCOUNT_MUTATOR_IMPL_H_
#define COMPONENTS_SIGNIN_INTERNAL_IDENTITY_MANAGER_PRIMARY_ACCOUNT_MUTATOR_IMPL_H_
-#include <string>
-
#include "build/chromeos_buildflags.h"
#include "components/signin/public/base/account_consistency_method.h"
#include "components/signin/public/identity_manager/primary_account_mutator.h"
@@ -31,8 +29,8 @@ class PrimaryAccountMutatorImpl : public PrimaryAccountMutator {
~PrimaryAccountMutatorImpl() override;
// PrimaryAccountMutator implementation.
- bool SetPrimaryAccount(const CoreAccountId& account_id) override;
- void SetUnconsentedPrimaryAccount(const CoreAccountId& account_id) override;
+ bool SetPrimaryAccount(const CoreAccountId& account_id,
+ ConsentLevel consent_level) override;
void RevokeSyncConsent(signin_metrics::ProfileSignout source_metric,
signin_metrics::SignoutDelete delete_metric) override;
#if !BUILDFLAG(IS_CHROMEOS_ASH)
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 2757404a0d7..5e9d4c37529 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
@@ -31,6 +31,10 @@
#include "components/user_manager/user_manager.h"
#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+#include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.h"
+#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
+
#if defined(OS_IOS)
#include "components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h"
#include "components/signin/public/identity_manager/ios/device_accounts_provider.h"
@@ -74,6 +78,19 @@ std::unique_ptr<ProfileOAuth2TokenServiceDelegate> CreateCrOsOAuthDelegate(
is_regular_profile);
}
#elif BUILDFLAG(ENABLE_DICE_SUPPORT)
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+std::unique_ptr<ProfileOAuth2TokenServiceDelegate> CreateCrOsOAuthDelegate(
+ AccountTrackerService* account_tracker_service,
+ network::NetworkConnectionTracker* network_connection_tracker,
+ account_manager::AccountManagerFacade* account_manager_facade,
+ bool is_regular_profile) {
+ return std::make_unique<signin::ProfileOAuth2TokenServiceDelegateChromeOS>(
+ account_tracker_service, network_connection_tracker,
+ account_manager_facade, is_regular_profile);
+}
+#endif // BUILDFLAG(IS_CHROMEOS_LACROS)
+
std::unique_ptr<MutableProfileOAuth2TokenServiceDelegate>
CreateMutableProfileOAuthDelegate(
AccountTrackerService* account_tracker_service,
@@ -111,9 +128,11 @@ CreateOAuth2TokenServiceDelegate(
SigninClient* signin_client,
#if BUILDFLAG(IS_CHROMEOS_ASH)
ash::AccountManager* account_manager,
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
account_manager::AccountManagerFacade* account_manager_facade,
bool is_regular_profile,
-#endif
+#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
#if !defined(OS_ANDROID)
bool delete_signin_cookies_on_exit,
scoped_refptr<TokenWebData> token_web_data,
@@ -136,9 +155,24 @@ CreateOAuth2TokenServiceDelegate(
return CreateCrOsOAuthDelegate(account_tracker_service,
network_connection_tracker, account_manager,
account_manager_facade, is_regular_profile);
+#elif BUILDFLAG(IS_CHROMEOS_LACROS)
+ // For the time being, Mirror is enabled only in the first / "Main" Profile in
+ // Lacros.
+ if (account_consistency == signin::AccountConsistencyMethod::kMirror) {
+ return CreateCrOsOAuthDelegate(account_tracker_service,
+ network_connection_tracker,
+ account_manager_facade, is_regular_profile);
+ } else {
+ // TODO(crbug.com/1198490): Remove this when we don't need DICE and
+ // `MutableProfileOAuth2TokenServiceDelegate` on Lacros anymore.
+ return CreateMutableProfileOAuthDelegate(
+ account_tracker_service, account_consistency,
+ delete_signin_cookies_on_exit, token_web_data, signin_client,
+ network_connection_tracker);
+ }
#elif BUILDFLAG(ENABLE_DICE_SUPPORT)
// Fall back to |MutableProfileOAuth2TokenServiceDelegate| on all platforms
- // other than Android, iOS, and Chrome OS.
+ // other than Android, iOS, and Chrome OS (Ash and Lacros).
return CreateMutableProfileOAuthDelegate(
account_tracker_service, account_consistency,
delete_signin_cookies_on_exit, token_web_data, signin_client,
@@ -161,9 +195,11 @@ std::unique_ptr<ProfileOAuth2TokenService> BuildProfileOAuth2TokenService(
signin::AccountConsistencyMethod account_consistency,
#if BUILDFLAG(IS_CHROMEOS_ASH)
ash::AccountManager* account_manager,
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
account_manager::AccountManagerFacade* account_manager_facade,
bool is_regular_profile,
-#endif
+#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
#if !defined(OS_ANDROID)
bool delete_signin_cookies_on_exit,
scoped_refptr<TokenWebData> token_web_data,
@@ -190,8 +226,11 @@ std::unique_ptr<ProfileOAuth2TokenService> BuildProfileOAuth2TokenService(
CreateOAuth2TokenServiceDelegate(
account_tracker_service, account_consistency, signin_client,
#if BUILDFLAG(IS_CHROMEOS_ASH)
- account_manager, account_manager_facade, is_regular_profile,
-#endif
+ account_manager,
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+ account_manager_facade, is_regular_profile,
+#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
#if !defined(OS_ANDROID)
delete_signin_cookies_on_exit, token_web_data,
#endif
diff --git a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.h b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.h
index 1e7659c9f54..baaaa27fa04 100644
--- a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.h
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_builder.h
@@ -43,11 +43,13 @@ class TokenWebData;
namespace ash {
class AccountManager;
}
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
namespace account_manager {
class AccountManagerFacade;
}
-#endif
+#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
std::unique_ptr<ProfileOAuth2TokenService> BuildProfileOAuth2TokenService(
PrefService* pref_service,
@@ -56,9 +58,11 @@ std::unique_ptr<ProfileOAuth2TokenService> BuildProfileOAuth2TokenService(
signin::AccountConsistencyMethod account_consistency,
#if BUILDFLAG(IS_CHROMEOS_ASH)
ash::AccountManager* account_manager,
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
account_manager::AccountManagerFacade* account_manager_facade,
bool is_regular_profile,
-#endif
+#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
#if !defined(OS_ANDROID)
bool delete_signin_cookies_on_exit,
scoped_refptr<TokenWebData> token_web_data,
diff --git a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
index 999e6461529..9e3156a4167 100644
--- a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate.h
@@ -19,6 +19,7 @@
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_access_token_manager.h"
#include "net/base/backoff_entry.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#if defined(OS_ANDROID)
#include "base/android/jni_android.h"
@@ -129,7 +130,7 @@ class ProfileOAuth2TokenServiceDelegate {
#if defined(OS_IOS) || defined(OS_ANDROID)
// Triggers platform specific implementation to reload accounts from system.
virtual void ReloadAllAccountsFromSystemWithPrimaryAccount(
- const base::Optional<CoreAccountId>& primary_account_id) {}
+ const absl::optional<CoreAccountId>& primary_account_id) {}
#endif
#if defined(OS_IOS)
diff --git a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
index c7872b8b7ae..0de4283023b 100644
--- a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.cc
@@ -310,7 +310,7 @@ void ProfileOAuth2TokenServiceDelegateAndroid::OnAccessTokenInvalidated(
void ProfileOAuth2TokenServiceDelegateAndroid::
ReloadAllAccountsFromSystemWithPrimaryAccount(
- const base::Optional<CoreAccountId>& primary_account_id) {
+ const absl::optional<CoreAccountId>& primary_account_id) {
JNIEnv* env = AttachCurrentThread();
ScopedJavaLocalRef<jstring> j_account_id =
@@ -326,7 +326,7 @@ void ProfileOAuth2TokenServiceDelegateAndroid::
ReloadAllAccountsWithPrimaryAccountAfterSeeding(
JNIEnv* env,
const base::android::JavaParamRef<jstring>& account_id) {
- base::Optional<CoreAccountId> core_account_id;
+ absl::optional<CoreAccountId> core_account_id;
if (account_id) {
core_account_id =
CoreAccountId::FromString(ConvertJavaStringToUTF8(env, account_id));
@@ -335,7 +335,7 @@ void ProfileOAuth2TokenServiceDelegateAndroid::
}
void ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList(
- const base::Optional<CoreAccountId>& signed_in_account_id,
+ const absl::optional<CoreAccountId>& signed_in_account_id,
const std::vector<CoreAccountId>& prev_ids,
const std::vector<CoreAccountId>& curr_ids) {
DVLOG(1) << "ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList:"
@@ -388,7 +388,7 @@ void ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList(
}
bool ProfileOAuth2TokenServiceDelegateAndroid::UpdateAccountList(
- const base::Optional<CoreAccountId>& signed_in_id,
+ const absl::optional<CoreAccountId>& signed_in_id,
const std::vector<CoreAccountId>& prev_ids,
const std::vector<CoreAccountId>& curr_ids,
std::vector<CoreAccountId>* refreshed_ids,
diff --git a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h
index 95196ec1410..46ed5cdd374 100644
--- a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_android.h
@@ -51,7 +51,7 @@ class ProfileOAuth2TokenServiceDelegateAndroid
void LoadCredentials(const CoreAccountId& primary_account_id) override;
void ReloadAllAccountsFromSystemWithPrimaryAccount(
- const base::Optional<CoreAccountId>& primary_account_id) override;
+ const absl::optional<CoreAccountId>& primary_account_id) override;
// Resumes the reload of accounts once the account seeding is complete.
// TODO(crbug.com/934688) Once ProfileOAuth2TokenServiceDelegate.java is
@@ -65,7 +65,7 @@ class ProfileOAuth2TokenServiceDelegateAndroid
// NOTE: TokenAvailable notifications will be sent for all accounts, even if
// they were already known. See https://crbug.com/939470 for details.
void UpdateAccountList(
- const base::Optional<CoreAccountId>& signed_in_account_id,
+ const absl::optional<CoreAccountId>& signed_in_account_id,
const std::vector<CoreAccountId>& prev_ids,
const std::vector<CoreAccountId>& curr_ids);
@@ -100,7 +100,7 @@ class ProfileOAuth2TokenServiceDelegateAndroid
// Return whether accounts are valid and we have access to all the tokens in
// |curr_ids|.
- bool UpdateAccountList(const base::Optional<CoreAccountId>& signed_in_id,
+ bool UpdateAccountList(const absl::optional<CoreAccountId>& signed_in_id,
const std::vector<CoreAccountId>& prev_ids,
const std::vector<CoreAccountId>& curr_ids,
std::vector<CoreAccountId>* refreshed_ids,
diff --git a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.cc b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.cc
index 7c773db3497..eff34b2c6e5 100644
--- a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.cc
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_chromeos.cc
@@ -11,6 +11,8 @@
#include "base/bind.h"
#include "base/containers/contains.h"
#include "base/logging.h"
+#include "build/build_config.h"
+#include "build/chromeos_buildflags.h"
#include "components/signin/internal/identity_manager/account_tracker_service.h"
#include "google_apis/gaia/oauth2_access_token_fetcher_immediate_error.h"
#include "net/base/backoff_entry.h"
@@ -98,6 +100,7 @@ class PersistentErrorsHelper : public base::RefCounted<PersistentErrorsHelper> {
// No accounts to get error status for, run callback immediately.
std::move(callback).Run(
std::map<account_manager::AccountKey, GoogleServiceAuthError>());
+ return;
}
// The ownership of this object is shared between callbacks passed to
@@ -318,9 +321,21 @@ void ProfileOAuth2TokenServiceDelegateChromeOS::LoadCredentials(
void ProfileOAuth2TokenServiceDelegateChromeOS::UpdateCredentials(
const CoreAccountId& account_id,
const std::string& refresh_token) {
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+ NOTREACHED()
+ << "If you're seeing this error in a browser_test, consider "
+ "disabling the test while we set up the testing "
+ "infrastructure to talk to Ash in a browser_test. Also, please add a "
+ "comment / CL ref. to crbug.com/1197201 if you disable your test.";
+ // TODO(sinhak): We need a way to write accounts to Account Manager in
+ // browser_tests and lacros_chrome_browsertests. For browser_tests, the
+ // solution may be to build Account Manager in Lacros. For
+ // lacros_chrome_browsertests, we will need to talk to EngProd.
+#else
// UpdateCredentials should not be called on Chrome OS. Credentials should be
// updated through Chrome OS Account Manager.
NOTREACHED();
+#endif
}
scoped_refptr<network::SharedURLLoaderFactory>
@@ -502,12 +517,12 @@ void ProfileOAuth2TokenServiceDelegateChromeOS::OnAccountRemoved(
void ProfileOAuth2TokenServiceDelegateChromeOS::RevokeCredentials(
const CoreAccountId& account_id) {
- // Signing out of Chrome is not possible on Chrome OS.
+ // Signing out of Chrome is not possible on Chrome OS Ash / Lacros.
NOTREACHED();
}
void ProfileOAuth2TokenServiceDelegateChromeOS::RevokeAllCredentials() {
- // Signing out of Chrome is not possible on Chrome OS.
+ // Signing out of Chrome is not possible on Chrome OS Ash / Lacros.
NOTREACHED();
}
diff --git a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h
index 3cac71d9c1f..ef414ca0ee3 100644
--- a/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h
+++ b/chromium/components/signin/internal/identity_manager/profile_oauth2_token_service_delegate_ios.h
@@ -54,7 +54,7 @@ class ProfileOAuth2TokenServiceIOSDelegate
void RevokeAllCredentials() override;
void ReloadAllAccountsFromSystemWithPrimaryAccount(
- const base::Optional<CoreAccountId>& primary_account_id) override;
+ const absl::optional<CoreAccountId>& primary_account_id) override;
void ReloadAccountFromSystem(const CoreAccountId& account_id) override;
// Adds |account_id| to |accounts_| if it does not exist or udpates
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 62c473e0b2c..cde6ddfd83a 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
@@ -294,7 +294,7 @@ void ProfileOAuth2TokenServiceIOSDelegate::RevokeAllCredentials() {
void ProfileOAuth2TokenServiceIOSDelegate::
ReloadAllAccountsFromSystemWithPrimaryAccount(
- const base::Optional<CoreAccountId>& primary_account_id) {
+ const absl::optional<CoreAccountId>& primary_account_id) {
ReloadCredentials(primary_account_id.value_or(CoreAccountId()));
}
diff --git a/chromium/components/signin/ios/DIR_METADATA b/chromium/components/signin/ios/DIR_METADATA
deleted file mode 100644
index 5fad6891646..00000000000
--- a/chromium/components/signin/ios/DIR_METADATA
+++ /dev/null
@@ -1,3 +0,0 @@
-monorail {
- component: "Services>SignIn"
-}
diff --git a/chromium/components/signin/ios/browser/account_consistency_service.h b/chromium/components/signin/ios/browser/account_consistency_service.h
index ca895d52b10..7220a445097 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service.h
+++ b/chromium/components/signin/ios/browser/account_consistency_service.h
@@ -7,7 +7,6 @@
#include <map>
#include <set>
-#include <string>
#include "base/callback.h"
#include "base/macros.h"
@@ -52,14 +51,6 @@ class AccountConsistencyService : public KeyedService,
// Removes the handler associated with |web_state|.
void RemoveWebStateHandler(web::WebState* web_state);
- // Checks for the presence of Gaia cookies and if they have been deleted
- // notifies the AccountReconcilor (the class responsible for rebuilding Gaia
- // cookies if needed). Calls callback if Gaia cookies were restored.
- //
- // Applies a one hour time restriction in between updates to avoid too many
- // |GetAllCookies| calls on the cookie manager.
- void SetGaiaCookiesIfDeleted(base::OnceClosure cookies_restored_callback);
-
// Notifies the AccountReconcilor that Gaia cookies have been deleted. Calls
// callback once the Gaia cookies have been restored and returns YES on
// success. Note that in order to avoid redirect loops this method applies a
@@ -100,16 +91,6 @@ class AccountConsistencyService : public KeyedService,
void OnDeleteCookiesFinished(base::OnceClosure callback,
uint32_t num_cookies_deleted);
- // Triggers a Gaia cookie update on the Google domain. Calls
- // |cookies_restored_callback| if the Gaia cookies were restored.
- void TriggerGaiaCookieChangeIfDeleted(
- base::OnceClosure cookies_restored_callback,
- const net::CookieAccessResultList& cookie_list,
- const net::CookieAccessResultList& excluded_cookies);
-
- // Clears all pending cookie requests and cached domains.
- void ResetInternalState();
-
// IdentityManager::Observer implementation.
void OnPrimaryAccountChanged(
const signin::PrimaryAccountChangeEvent& event) override;
@@ -134,7 +115,6 @@ class AccountConsistencyService : public KeyedService,
int64_t active_cookie_manager_requests_for_testing_;
// Last time Gaia cookie was updated for the Google domain.
- base::Time last_gaia_cookie_verification_time_;
base::Time last_gaia_cookie_update_time_;
// List of callbacks to be called following GAIA cookie restoration.
diff --git a/chromium/components/signin/ios/browser/account_consistency_service.mm b/chromium/components/signin/ios/browser/account_consistency_service.mm
index 5ff4951ab1d..0e46b18de4c 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service.mm
+++ b/chromium/components/signin/ios/browser/account_consistency_service.mm
@@ -136,14 +136,10 @@ class AccountConsistencyService::AccountConsistencyHandler
base::OnceCallback<void(PolicyDecision)> callback) override;
void WebStateDestroyed() override;
- // Marks that GAIA cookies have been restored.
- void MarkGaiaCookiesRestored();
-
// Loads |url| in the current tab.
void NavigateToURL(GURL url);
bool show_consistency_promo_ = false;
- bool gaia_cookies_restored_ = false;
AccountConsistencyService* account_consistency_service_; // Weak.
AccountReconcilor* account_reconcilor_; // Weak.
signin::IdentityManager* identity_manager_;
@@ -199,38 +195,36 @@ void AccountConsistencyService::AccountConsistencyHandler::ShouldAllowResponse(
GURL url = net::GURLWithNSURL(http_response.URL);
// User is showing intent to navigate to a Google-owned domain. Set GAIA and
- // CHROME_CONNECTED cookies if the user is signed in or if they are not signed
- // in and navigating to a GAIA sign-on (this is filtered in
+ // CHROME_CONNECTED cookies if the user is signed in (this is filtered in
// ChromeConnectedHelper).
if (signin::IsUrlEligibleForMirrorCookie(url)) {
account_consistency_service_->SetChromeConnectedCookieWithUrls(
{url, GURL(kGoogleUrl)});
}
- // Chrome monitors GAIA cookies when navigating to Google associated domains
- // to ensure that signed-in users remain signed-in to their Google services on
- // the web. This includes redirects to accounts.google.com.
- if (google_util::IsGoogleAssociatedDomainUrl(url)) {
- // TODO(crbug.com/1131027): Disable GAIA cookie restore on Google URLs that
- // may display cookie consent in the content area that conflict with the
- // sign-in notification. This will be removed once we perform cookie
- // restoration before sending a navigation request.
- if (!(google_util::IsGoogleHomePageUrl(url) ||
- google_util::IsGoogleSearchUrl(url))) {
- // Reset boolean that tracks displaying the sign-in notification infobar.
- // This ensures that only the most recent navigation will trigger an
- // infobar.
- gaia_cookies_restored_ = false;
- account_consistency_service_->SetGaiaCookiesIfDeleted(
- base::BindOnce(&AccountConsistencyHandler::MarkGaiaCookiesRestored,
- weak_ptr_factory_.GetWeakPtr()));
- }
- }
+ // Reset boolean that tracks displaying the sign-in consistency promo. This
+ // ensures that the promo is cancelled once navigation has started and the
+ // WKWebView is cancelling previous navigations.
+ show_consistency_promo_ = false;
if (!gaia::IsGaiaSignonRealm(url.GetOrigin())) {
std::move(callback).Run(PolicyDecision::Allow());
return;
}
+
+ // If the user has been prompted to enter their credentials on a Gaia sign-on
+ // page show the account consistency promo.
+ NSString* x_autologin_header = [[http_response allHeaderFields]
+ objectForKey:[NSString stringWithUTF8String:signin::kAutoLoginHeader]];
+ if (signin::IsMICEWebSignInEnabled() && x_autologin_header) {
+ show_consistency_promo_ = true;
+ // Allows the URL response to load before showing the consistency promo.
+ // The promo should always be displayed in the foreground of Gaia
+ // sign-on.
+ std::move(callback).Run(PolicyDecision::Allow());
+ return;
+ }
+
NSString* manage_accounts_header = [[http_response allHeaderFields]
objectForKey:
[NSString stringWithUTF8String:signin::kChromeManageAccountsHeader]];
@@ -243,10 +237,6 @@ void AccountConsistencyService::AccountConsistencyHandler::ShouldAllowResponse(
base::SysNSStringToUTF8(manage_accounts_header));
account_reconcilor_->OnReceivedManageAccountsResponse(params.service_type);
- // Reset boolean that tracks displaying the sign-in consistency promo. This
- // ensures that the promo is cancelled once navigation has started and the
- // WKWebView is cancelling previous navigations.
- show_consistency_promo_ = false;
switch (params.service_type) {
case signin::GAIA_SERVICE_TYPE_INCOGNITO: {
@@ -278,16 +268,7 @@ void AccountConsistencyService::AccountConsistencyHandler::ShouldAllowResponse(
}
}
}
- if (params.show_consistency_promo) {
- show_consistency_promo_ = true;
- // Allows the URL response to load before showing the consistency promo.
- // The promo should always be displayed in the foreground of Gaia
- // sign-on.
- std::move(callback).Run(PolicyDecision::Allow());
- return;
- } else {
- [delegate_ onAddAccount];
- }
+ [delegate_ onAddAccount];
break;
case signin::GAIA_SERVICE_TYPE_SIGNOUT:
case signin::GAIA_SERVICE_TYPE_DEFAULT:
@@ -308,11 +289,6 @@ void AccountConsistencyService::AccountConsistencyHandler::ShouldAllowResponse(
std::move(callback).Run(PolicyDecision::Cancel());
}
-void AccountConsistencyService::AccountConsistencyHandler::
- MarkGaiaCookiesRestored() {
- gaia_cookies_restored_ = true;
-}
-
void AccountConsistencyService::AccountConsistencyHandler::NavigateToURL(
GURL url) {
web_state_->OpenURL(web::WebState::OpenURLParams(
@@ -334,26 +310,9 @@ void AccountConsistencyService::AccountConsistencyHandler::PageLoaded(
return;
}
- // Displays the sign-in notification infobar if GAIA cookies have been
- // restored. This occurs once the URL has been loaded to avoid a race
- // condition in which the infobar is dismissed prior to the page load.
- if (gaia_cookies_restored_) {
- [delegate_ onRestoreGaiaCookies];
- LogIOSGaiaCookiesState(
- GaiaCookieStateOnSignedInNavigation::kGaiaCookieRestoredOnShowInfobar);
- gaia_cookies_restored_ = false;
- }
-
if (show_consistency_promo_ && gaia::IsGaiaSignonRealm(url.GetOrigin())) {
- [delegate_ onShowConsistencyPromo];
+ [delegate_ onShowConsistencyPromo:url];
show_consistency_promo_ = false;
-
- // Chrome uses the CHROME_CONNECTED cookie to determine whether the
- // eligibility promo should be shown. Once it is shown we should remove the
- // cookie, since it should otherwise not be used unless the user is signed
- // in.
- account_consistency_service_->RemoveAllChromeConnectedCookies(
- base::OnceClosure());
}
}
@@ -423,55 +382,6 @@ void AccountConsistencyService::RemoveWebStateHandler(
web_state->RemoveObserver(handler.get());
}
-void AccountConsistencyService::SetGaiaCookiesIfDeleted(
- base::OnceClosure cookies_restored_callback) {
- // We currently enforce a time threshold to update the Gaia cookie
- // for signed-in users to prevent calling the expensive method
- // |GetAllCookies| in the cookie manager.
- if (base::Time::Now() - last_gaia_cookie_verification_time_ <
- GetDelayThresholdToUpdateGaiaCookie() ||
- !identity_manager_->HasPrimaryAccount(signin::ConsentLevel::kSignin)) {
- return;
- }
- network::mojom::CookieManager* cookie_manager =
- browser_state_->GetCookieManager();
- cookie_manager->GetCookieList(
- GaiaUrls::GetInstance()->secure_google_url(),
- net::CookieOptions::MakeAllInclusive(),
- base::BindOnce(
- &AccountConsistencyService::TriggerGaiaCookieChangeIfDeleted,
- base::Unretained(this), std::move(cookies_restored_callback)));
- last_gaia_cookie_verification_time_ = base::Time::Now();
-}
-
-void AccountConsistencyService::TriggerGaiaCookieChangeIfDeleted(
- base::OnceClosure cookies_restored_callback,
- const net::CookieAccessResultList& cookie_list,
- const net::CookieAccessResultList& unused_excluded_cookies) {
- for (const auto& cookie : cookie_list) {
- if (cookie.cookie.Name() == GaiaConstants::kGaiaSigninCookieName) {
- LogIOSGaiaCookiesState(
- GaiaCookieStateOnSignedInNavigation::kGaiaCookiePresentOnNavigation);
- return;
- }
- }
-
- // The SAPISID cookie may have been deleted previous to this update due to
- // ITP restrictions marking Google domains as potential trackers.
- LogIOSGaiaCookiesState(
- GaiaCookieStateOnSignedInNavigation::
- kGaiaCookieAbsentOnGoogleAssociatedDomainNavigation);
-
- if (!base::FeatureList::IsEnabled(signin::kRestoreGaiaCookiesIfDeleted)) {
- return;
- }
-
- // Re-generate cookie to ensure that the user is properly signed in.
- identity_manager_->GetAccountsCookieMutator()->ForceTriggerOnCookieChange();
- gaia_cookies_restored_callbacks_.push_back(
- std::move(cookies_restored_callback));
-}
-
void AccountConsistencyService::RemoveAllChromeConnectedCookies(
base::OnceClosure callback) {
DCHECK(!browser_state_->IsOffTheRecord());
@@ -488,7 +398,6 @@ void AccountConsistencyService::RemoveAllChromeConnectedCookies(
std::move(filter),
base::BindOnce(&AccountConsistencyService::OnDeleteCookiesFinished,
base::Unretained(this), std::move(callback)));
- last_gaia_cookie_verification_time_ = base::Time();
}
void AccountConsistencyService::OnDeleteCookiesFinished(
@@ -518,7 +427,7 @@ void AccountConsistencyService::SetChromeConnectedCookieWithUrl(
const std::string domain = GetDomainFromUrl(url);
std::string cookie_value = signin::BuildMirrorRequestCookieIfPossible(
url,
- identity_manager_->GetPrimaryAccountInfo(signin::ConsentLevel::kSync)
+ identity_manager_->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
.gaia,
signin::AccountConsistencyMethod::kMirror, cookie_settings_.get(),
signin::PROFILE_MODE_DEFAULT);
@@ -572,10 +481,6 @@ void AccountConsistencyService::AddChromeConnectedCookies() {
}
void AccountConsistencyService::OnBrowsingDataRemoved() {
- // CHROME_CONNECTED cookies have been removed, update internal state
- // accordingly.
- last_gaia_cookie_verification_time_ = base::Time();
-
// SAPISID cookie has been removed, notify the GCMS.
// TODO(https://crbug.com/930582) : Remove the need to expose this method
// or move it to the network::CookieManager.
diff --git a/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm b/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
index 6c1f3807ffe..f87374e3423 100644
--- a/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
+++ b/chromium/components/signin/ios/browser/account_consistency_service_unittest.mm
@@ -195,7 +195,8 @@ class AccountConsistencyServiceTest : public PlatformTest {
// Identity APIs.
void SignIn() {
signin::MakePrimaryAccountAvailable(identity_test_env_->identity_manager(),
- kFakeEmail);
+ kFakeEmail,
+ signin::ConsentLevel::kSync);
WaitUntilAllCookieRequestsAreApplied();
}
@@ -225,9 +226,8 @@ class AccountConsistencyServiceTest : public PlatformTest {
// Verifies the time that the Gaia cookie was last updated for google.com.
void CheckGaiaCookieWithUpdateTime(base::Time time) {
- EXPECT_EQ(
- time,
- account_consistency_service_->last_gaia_cookie_verification_time_);
+ EXPECT_EQ(time,
+ account_consistency_service_->last_gaia_cookie_update_time_);
}
// Navigation APIs.
@@ -280,7 +280,7 @@ class AccountConsistencyServiceTest : public PlatformTest {
network::mojom::CookieDeletionFilterPtr filter =
network::mojom::CookieDeletionFilter::New();
filter->including_domains =
- base::Optional<std::vector<std::string>>({kGoogleDomain});
+ absl::optional<std::vector<std::string>>({kGoogleDomain});
cookie_manager->DeleteCookies(std::move(filter),
base::OnceCallback<void(uint)>());
}
@@ -456,25 +456,25 @@ TEST_F(AccountConsistencyServiceTest, ChromeManageAccountsDefault) {
}
// Tests that the ManageAccountsDelegate is notified when a navigation on Gaia
-// signon realm returns with a X-Chrome-Manage-Accounts header with show
-// consistency promo and ADDSESSION action.
-TEST_F(AccountConsistencyServiceTest,
- ChromeManageAccountsShowConsistencyPromo) {
+// signon realm returns with a X-Auto-Login header.
+TEST_F(AccountConsistencyServiceTest, ChromeShowConsistencyPromo) {
+ base::test::ScopedFeatureList consistency_feature_list;
+ consistency_feature_list.InitAndEnableFeature(
+ signin::kMobileIdentityConsistency);
+ base::test::ScopedFeatureList websignin_feature_list;
+ websignin_feature_list.InitAndEnableFeature(signin::kMICEWebSignIn);
+
id delegate =
[OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
- [[delegate expect] onShowConsistencyPromo];
+ [[[delegate expect] ignoringNonObjectArgs] onShowConsistencyPromo:GURL()];
- NSDictionary* headers = [NSDictionary
- dictionaryWithObject:@"action=ADDSESSION,show_consistency_promo=true"
- forKey:@"X-Chrome-Manage-Accounts"];
+ NSDictionary* headers = [NSDictionary dictionaryWithObject:@"args=unused"
+ forKey:@"X-Auto-Login"];
NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
statusCode:200
HTTPVersion:@"HTTP/1.1"
headerFields:headers];
- EXPECT_CALL(*account_reconcilor_, OnReceivedManageAccountsResponse(
- signin::GAIA_SERVICE_TYPE_ADDSESSION))
- .Times(1);
SimulateNavigateToURL(response, delegate);
@@ -483,22 +483,20 @@ TEST_F(AccountConsistencyServiceTest,
// Tests that the consistency promo is not displayed when a page fails to load.
TEST_F(AccountConsistencyServiceTest,
- ChromeManageAccountsNotShowConsistencyPromoOnPageLoadFailure) {
+ ChromeNotShowConsistencyPromoOnPageLoadFailure) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(signin::kMobileIdentityConsistency);
id delegate =
[OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
- [[delegate reject] onShowConsistencyPromo];
+ [[[delegate reject] ignoringNonObjectArgs] onShowConsistencyPromo:GURL()];
- NSDictionary* headers = [NSDictionary
- dictionaryWithObject:@"action=ADDSESSION,show_consistency_promo=true"
- forKey:@"X-Chrome-Manage-Accounts"];
+ NSDictionary* headers = [NSDictionary dictionaryWithObject:@"args=unused"
+ forKey:@"X-Auto-Login"];
NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
statusCode:200
HTTPVersion:@"HTTP/1.1"
headerFields:headers];
- EXPECT_CALL(*account_reconcilor_, OnReceivedManageAccountsResponse(
- signin::GAIA_SERVICE_TYPE_ADDSESSION))
- .Times(1);
SimulateNavigateToURLWithPageLoadFailure(response, delegate);
@@ -508,19 +506,20 @@ TEST_F(AccountConsistencyServiceTest,
// Tests that the consistency promo is not displayed when a page fails to load
// and user chooses another action.
TEST_F(AccountConsistencyServiceTest,
- ChromeManageAccountsNotShowConsistencyPromoOnPageLoadFailureRedirect) {
+ ChromeNotShowConsistencyPromoOnPageLoadFailureRedirect) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(signin::kMobileIdentityConsistency);
+
id delegate =
[OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
[[delegate expect] onAddAccount];
- [[delegate reject] onShowConsistencyPromo];
+ [[[delegate reject] ignoringNonObjectArgs] onShowConsistencyPromo:GURL()];
EXPECT_CALL(*account_reconcilor_, OnReceivedManageAccountsResponse(
- signin::GAIA_SERVICE_TYPE_ADDSESSION))
- .Times(2);
+ signin::GAIA_SERVICE_TYPE_ADDSESSION));
- NSDictionary* headers = [NSDictionary
- dictionaryWithObject:@"action=ADDSESSION,show_consistency_promo=true"
- forKey:@"X-Chrome-Manage-Accounts"];
+ NSDictionary* headers = [NSDictionary dictionaryWithObject:@"args=unused"
+ forKey:@"X-Auto-Login"];
NSHTTPURLResponse* responseSignin = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
statusCode:200
@@ -543,28 +542,6 @@ TEST_F(AccountConsistencyServiceTest,
EXPECT_OCMOCK_VERIFY(delegate);
}
-// Tests that the consistency promo is not displayed when a non GAIA URL is
-// committed.
-TEST_F(AccountConsistencyServiceTest,
- ChromeManageAccountsNotShowConsistencyPromoOnNonGaiaURL) {
- id delegate =
- [OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
- [[delegate reject] onShowConsistencyPromo];
-
- NSDictionary* headers = [NSDictionary
- dictionaryWithObject:@"action=ADDSESSION,show_consistency_promo=true"
- forKey:@"X-Chrome-Manage-Accounts"];
- NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
- initWithURL:[NSURL URLWithString:@"https://youtube.com//"]
- statusCode:200
- HTTPVersion:@"HTTP/1.1"
- headerFields:headers];
-
- SimulateNavigateToURL(response, delegate);
-
- EXPECT_OCMOCK_VERIFY(delegate);
-}
-
// Tests that the ManageAccountsDelegate is notified when a navigation on Gaia
// signon realm returns with a X-Chrome-Manage-Accounts header with ADDSESSION
// action.
@@ -673,74 +650,6 @@ TEST_F(AccountConsistencyServiceTest, SetChromeConnectedCookie) {
CheckDomainHasChromeConnectedCookie(kYoutubeDomain);
}
-// Tests that the GAIA cookie update time is not updated before the scheduled
-// interval.
-TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateNotUpdateTime) {
- SignIn();
-
- // HTTP response URL is eligible for Mirror (the test does not use google.com
- // since the CHROME_CONNECTED cookie is generated for it by default.
- NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
- initWithURL:[NSURL URLWithString:@"https://youtube.com"]
- statusCode:200
- HTTPVersion:@"HTTP/1.1"
- headerFields:@{}];
-
- SimulateNavigateToURL(response, nil);
-
- // Advance clock, but stay within the one-hour Gaia update time.
- base::TimeDelta oneMinuteDelta = base::TimeDelta::FromMinutes(1);
- task_environment_.FastForwardBy(oneMinuteDelta);
- SimulateNavigateToURL(response, nil);
-
- CheckGaiaCookieWithUpdateTime(base::Time::Now() - oneMinuteDelta);
-}
-
-// Tests that the GAIA cookie update time is updated at the scheduled interval.
-TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateAtUpdateTime) {
- SignIn();
-
- // HTTP response URL is eligible for Mirror (the test does not use google.com
- // since the CHROME_CONNECTED cookie is generated for it by default.
- NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
- initWithURL:[NSURL URLWithString:@"https://youtube.com"]
- statusCode:200
- HTTPVersion:@"HTTP/1.1"
- headerFields:@{}];
-
- SimulateNavigateToURL(response, nil);
-
- // Advance clock past one-hour Gaia update time.
- task_environment_.FastForwardBy(base::TimeDelta::FromHours(2));
- SimulateNavigateToURL(response, nil);
-
- CheckGaiaCookieWithUpdateTime(base::Time::Now());
-}
-
-// Ensures that the presence or absence of GAIA cookies is logged even if the
-// |kRestoreGAIACookiesIfDeleted| experiment is disabled.
-TEST_F(AccountConsistencyServiceTest, GAIACookieStatusLoggedProperly) {
- // HTTP response URL is eligible for Mirror (the test does not use google.com
- // since the CHROME_CONNECTED cookie is generated for it by default.
- NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
- initWithURL:[NSURL URLWithString:@"https://youtube.com"]
- statusCode:200
- HTTPVersion:@"HTTP/1.1"
- headerFields:@{}];
-
- base::HistogramTester histogram_tester;
- histogram_tester.ExpectTotalCount(kGAIACookieOnNavigationHistogram, 0);
-
- SimulateNavigateToURL(response, nil);
- base::RunLoop().RunUntilIdle();
- histogram_tester.ExpectTotalCount(kGAIACookieOnNavigationHistogram, 0);
-
- SignIn();
- SimulateNavigateToURL(response, nil);
- base::RunLoop().RunUntilIdle();
- histogram_tester.ExpectTotalCount(kGAIACookieOnNavigationHistogram, 1);
-}
-
// Tests that navigating to accounts.google.com without a GAIA cookie is logged
// by the navigation histogram.
TEST_F(AccountConsistencyServiceTest, GAIACookieMissingOnSignin) {
@@ -817,7 +726,7 @@ TEST_F(AccountConsistencyServiceTest, SetChromeConnectedCookiesAfterDelete) {
// is signed out and navigating to google.com for |kMobileIdentityConsistency|
// experiment.
TEST_F(AccountConsistencyServiceTest,
- SetMiceChromeConnectedCookiesSignedOutGoogleVisitor) {
+ SetChromeConnectedCookiesSignedOutGoogleVisitor) {
base::test::ScopedFeatureList feature_list;
feature_list.InitAndEnableFeature(signin::kMobileIdentityConsistency);
id delegate =
@@ -840,21 +749,21 @@ TEST_F(AccountConsistencyServiceTest,
EXPECT_OCMOCK_VERIFY(delegate);
}
-// Ensures that CHROME_CONNECTED cookies are only set on GAIA urls when the user
-// is signed out and taps sign-in button for |kMobileIdentityConsistency|
-// experiment. These cookies are immediately removed after the sign-in promo is
-// shown.
+// Ensures that CHROME_CONNECTED cookies are not set when the user is signed out
+// after the sign-in promo is shown.
TEST_F(AccountConsistencyServiceTest,
- SetMiceChromeConnectedCookiesSignedOutGaiaVisitor) {
- base::test::ScopedFeatureList feature_list;
- feature_list.InitAndEnableFeature(signin::kMobileIdentityConsistency);
+ SetChromeConnectedCookiesSignedOutGaiaVisitor) {
+ base::test::ScopedFeatureList consistency_feature_list;
+ consistency_feature_list.InitAndEnableFeature(
+ signin::kMobileIdentityConsistency);
+ base::test::ScopedFeatureList websignin_feature_list;
+ websignin_feature_list.InitAndEnableFeature(signin::kMICEWebSignIn);
id delegate =
[OCMockObject mockForProtocol:@protocol(ManageAccountsDelegate)];
- [[delegate expect] onShowConsistencyPromo];
+ [[[delegate expect] ignoringNonObjectArgs] onShowConsistencyPromo:GURL()];
- NSDictionary* headers = [NSDictionary
- dictionaryWithObject:@"action=ADDSESSION,show_consistency_promo=true"
- forKey:@"X-Chrome-Manage-Accounts"];
+ NSDictionary* headers = [NSDictionary dictionaryWithObject:@"args=unused"
+ forKey:@"X-Auto-Login"];
NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
statusCode:200
@@ -865,11 +774,61 @@ TEST_F(AccountConsistencyServiceTest,
EXPECT_TRUE(web_state_.ShouldAllowResponse(response,
/* for_main_frame = */ true));
- CheckDomainHasChromeConnectedCookie("accounts.google.com");
-
web_state_.SetCurrentURL(net::GURLWithNSURL(response.URL));
web_state_.OnPageLoaded(web::PageLoadCompletionStatus::SUCCESS);
CheckNoChromeConnectedCookies();
EXPECT_OCMOCK_VERIFY(delegate);
}
+
+TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateBeforeDelay) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(signin::kRestoreGaiaCookiesOnUserAction);
+
+ SignIn();
+
+ NSDictionary* headers =
+ [NSDictionary dictionaryWithObject:@"action=ADDSESSION"
+ forKey:@"X-Chrome-Manage-Accounts"];
+ NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
+ initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
+ statusCode:200
+ HTTPVersion:@"HTTP/1.1"
+ headerFields:headers];
+
+ SimulateNavigateToURL(response, nil);
+
+ // Advance clock, but stay within the one-hour Gaia update time.
+ base::TimeDelta oneMinuteDelta = base::TimeDelta::FromMinutes(1);
+ task_environment_.FastForwardBy(oneMinuteDelta);
+ SimulateNavigateToURLWithInterruption(response, nil);
+
+ // Does not process the second Gaia restore event.
+ CheckGaiaCookieWithUpdateTime(base::Time::Now() - oneMinuteDelta);
+}
+
+TEST_F(AccountConsistencyServiceTest, SetGaiaCookieUpdateAfterDelay) {
+ base::test::ScopedFeatureList feature_list;
+ feature_list.InitAndEnableFeature(signin::kRestoreGaiaCookiesOnUserAction);
+
+ SignIn();
+
+ NSDictionary* headers =
+ [NSDictionary dictionaryWithObject:@"action=ADDSESSION"
+ forKey:@"X-Chrome-Manage-Accounts"];
+ NSHTTPURLResponse* response = [[NSHTTPURLResponse alloc]
+ initWithURL:[NSURL URLWithString:@"https://accounts.google.com/"]
+ statusCode:200
+ HTTPVersion:@"HTTP/1.1"
+ headerFields:headers];
+
+ SimulateNavigateToURL(response, nil);
+
+ // Advance clock past the one-hour Gaia update time.
+ base::TimeDelta twoHourDelta = base::TimeDelta::FromHours(2);
+ task_environment_.FastForwardBy(twoHourDelta);
+ SimulateNavigateToURL(response, nil);
+
+ // Will process the second Gaia restore event, since it is past the delay.
+ CheckGaiaCookieWithUpdateTime(base::Time::Now());
+}
diff --git a/chromium/components/signin/ios/browser/features.cc b/chromium/components/signin/ios/browser/features.cc
index 8d2e2601f9a..a6e86425ff8 100644
--- a/chromium/components/signin/ios/browser/features.cc
+++ b/chromium/components/signin/ios/browser/features.cc
@@ -16,9 +16,6 @@ bool ForceStartupSigninPromo() {
return base::FeatureList::IsEnabled(kForceStartupSigninPromo);
}
-const base::Feature kRestoreGaiaCookiesIfDeleted{
- "RestoreGAIACookiesIfDeleted", base::FEATURE_DISABLED_BY_DEFAULT};
-
const base::Feature kRestoreGaiaCookiesOnUserAction{
"RestoreGAIACookiesOnUserAction", base::FEATURE_DISABLED_BY_DEFAULT};
diff --git a/chromium/components/signin/ios/browser/features.h b/chromium/components/signin/ios/browser/features.h
index 89efdcecc00..3ee40d81779 100644
--- a/chromium/components/signin/ios/browser/features.h
+++ b/chromium/components/signin/ios/browser/features.h
@@ -18,9 +18,6 @@ extern const base::Feature kSimplifySignOutIOS;
// Returns true if the startup sign-in promo should be displayed at boot.
bool ForceStartupSigninPromo();
-// Feature controlling whether to restore GAIA cookies if they are deleted.
-extern const base::Feature kRestoreGaiaCookiesIfDeleted;
-
// Feature controlling whether to restore GAIA cookies when the user explicitly
// requests to sign in to a Google service.
extern const base::Feature kRestoreGaiaCookiesOnUserAction;
diff --git a/chromium/components/signin/ios/browser/manage_accounts_delegate.h b/chromium/components/signin/ios/browser/manage_accounts_delegate.h
index 763d93944cc..637b30f492c 100644
--- a/chromium/components/signin/ios/browser/manage_accounts_delegate.h
+++ b/chromium/components/signin/ios/browser/manage_accounts_delegate.h
@@ -22,7 +22,9 @@ class GURL;
// Called when the user taps a sign-in or add account button in a Google web
// property with signin::kMobileIdentityConsistency enabled.
-- (void)onShowConsistencyPromo;
+// |url| is the continuation URL received from the server. If it is valid,
+// then this delegate should navigate to |url|.
+- (void)onShowConsistencyPromo:(const GURL&)url;
// Called when the user taps on go incognito button in a Google web property.
// |url| is the continuation URL received from the server. If it is valid,
diff --git a/chromium/components/signin/public/android/BUILD.gn b/chromium/components/signin/public/android/BUILD.gn
index 06f18bf999e..f25e8537171 100644
--- a/chromium/components/signin/public/android/BUILD.gn
+++ b/chromium/components/signin/public/android/BUILD.gn
@@ -5,9 +5,11 @@ android_library("java") {
"$google_play_services_package:google_play_services_auth_base_java",
"$google_play_services_package:google_play_services_base_java",
"//base:base_java",
+ "//components/externalauth/android:java",
"//net/android:net_java",
"//third_party/android_deps:android_support_v4_java",
"//third_party/android_deps:chromium_play_services_availability_java",
+ "//third_party/android_deps:guava_android_java",
"//third_party/androidx:androidx_annotation_annotation_java",
]
@@ -19,23 +21,17 @@ android_library("java") {
sources = [
"java/src/org/chromium/components/signin/AccessTokenData.java",
"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/AccountManagerFacadeImpl.java",
"java/src/org/chromium/components/signin/AccountManagerFacadeProvider.java",
- "java/src/org/chromium/components/signin/AccountManagerResult.java",
"java/src/org/chromium/components/signin/AccountRenameChecker.java",
- "java/src/org/chromium/components/signin/AccountTrackerService.java",
+ "java/src/org/chromium/components/signin/AccountRestrictionPatternReceiver.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/ConnectionRetry.java",
- "java/src/org/chromium/components/signin/GmsAvailabilityException.java",
- "java/src/org/chromium/components/signin/GmsJustUpdatedException.java",
- "java/src/org/chromium/components/signin/MutableObservableValue.java",
- "java/src/org/chromium/components/signin/ObservableValue.java",
"java/src/org/chromium/components/signin/PatternMatcher.java",
"java/src/org/chromium/components/signin/ProfileDataSource.java",
"java/src/org/chromium/components/signin/SystemAccountManagerDelegate.java",
@@ -44,6 +40,7 @@ android_library("java") {
"java/src/org/chromium/components/signin/base/CoreAccountInfo.java",
"java/src/org/chromium/components/signin/base/GoogleServiceAuthError.java",
"java/src/org/chromium/components/signin/identitymanager/AccountInfoService.java",
+ "java/src/org/chromium/components/signin/identitymanager/AccountTrackerService.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/PrimaryAccountChangeEvent.java",
@@ -57,12 +54,12 @@ generate_jni("jni_headers") {
namespace = "signin"
sources = [
"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/base/AccountInfo.java",
"java/src/org/chromium/components/signin/base/CoreAccountId.java",
"java/src/org/chromium/components/signin/base/CoreAccountInfo.java",
"java/src/org/chromium/components/signin/base/GoogleServiceAuthError.java",
+ "java/src/org/chromium/components/signin/identitymanager/AccountTrackerService.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/PrimaryAccountChangeEvent.java",
@@ -83,6 +80,7 @@ android_library("signin_java_test_support") {
":test_support_jni_headers",
"//base:base_java",
"//base:jni_java",
+ "//third_party/android_deps:guava_android_java",
"//third_party/androidx:androidx_annotation_annotation_java",
"//third_party/mockito:mockito_java",
]
@@ -129,10 +127,9 @@ java_library("junit") {
sources = [
"junit/src/org/chromium/components/signin/AccountManagerFacadeImplTest.java",
"junit/src/org/chromium/components/signin/AccountRenameCheckerTest.java",
- "junit/src/org/chromium/components/signin/AccountTrackerServiceTest.java",
- "junit/src/org/chromium/components/signin/ObservableValueTest.java",
"junit/src/org/chromium/components/signin/PatternMatcherTest.java",
"junit/src/org/chromium/components/signin/identitymanager/AccountInfoServiceTest.java",
+ "junit/src/org/chromium/components/signin/identitymanager/AccountTrackerServiceTest.java",
]
deps = [
":java",
@@ -141,8 +138,13 @@ java_library("junit") {
"//base:base_java",
"//base:base_java_test_support",
"//base:base_junit_test_support",
+ "//components/externalauth/android:google_delegate_public_impl_java",
+ "//components/externalauth/android:java",
"//testing/android/junit:junit_test_support",
+ "//third_party/android_deps:guava_android_java",
"//third_party/android_deps:robolectric_all_java",
+ "//third_party/androidx:androidx_annotation_annotation_java",
+ "//third_party/androidx:androidx_test_rules_java",
"//third_party/junit",
"//third_party/mockito:mockito_java",
]
diff --git a/chromium/components/signin/public/android/DEPS b/chromium/components/signin/public/android/DEPS
index b8ac3035f71..944f0130c2e 100644
--- a/chromium/components/signin/public/android/DEPS
+++ b/chromium/components/signin/public/android/DEPS
@@ -1,3 +1,4 @@
include_rules = [
+ "+components/externalauth/android/java/src/org/chromium/components/externalauth/ExternalAuthUtils.java",
"+content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestThreadUtils.java",
]
diff --git a/chromium/components/signin/public/android/DIR_METADATA b/chromium/components/signin/public/android/DIR_METADATA
deleted file mode 100644
index 4735e25f37d..00000000000
--- a/chromium/components/signin/public/android/DIR_METADATA
+++ /dev/null
@@ -1,5 +0,0 @@
-monorail {
- component: "Services>SignIn"
-}
-
-team_email: "chrome-signin@chromium.org"
diff --git a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountManagerFacadeImplTest.java b/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountManagerFacadeImplTest.java
index 2da2805f72a..07343569a1d 100644
--- a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountManagerFacadeImplTest.java
+++ b/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountManagerFacadeImplTest.java
@@ -4,18 +4,21 @@
package org.chromium.components.signin;
-import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import static org.robolectric.Shadows.shadowOf;
+import android.Manifest;
import android.accounts.Account;
+import android.accounts.AccountManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.UserManager;
+import androidx.test.rule.GrantPermissionRule;
+
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@@ -24,87 +27,95 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
+import org.mockito.quality.Strictness;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
+import org.robolectric.shadows.ShadowAccountManager;
+import org.robolectric.shadows.ShadowUserManager;
+import org.chromium.base.ThreadUtils;
import org.chromium.base.metrics.UmaRecorder;
import org.chromium.base.metrics.UmaRecorderHolder;
import org.chromium.base.task.test.CustomShadowAsyncTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
-import org.chromium.base.test.util.CallbackHelper;
+import org.chromium.components.externalauth.ExternalAuthUtils;
import org.chromium.components.signin.AccountManagerFacade.ChildAccountStatusListener;
import org.chromium.components.signin.test.util.AccountHolder;
import org.chromium.components.signin.test.util.FakeAccountManagerDelegate;
-import org.chromium.testing.local.CustomShadowUserManager;
import java.util.List;
-import java.util.concurrent.TimeoutException;
/**
* Robolectric tests for {@link AccountManagerFacade}. See also {@link AccountManagerFacadeTest}.
*/
@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE,
- shadows = {CustomShadowAsyncTask.class, CustomShadowUserManager.class})
+@Config(shadows = {CustomShadowAsyncTask.class, ShadowUserManager.class,
+ ShadowAccountManager.class})
public class AccountManagerFacadeImplTest {
private static final String TEST_TOKEN_SCOPE = "test-token-scope";
- private CustomShadowUserManager mShadowUserManager;
- private FakeAccountManagerDelegate mDelegate;
- private AccountManagerFacade mFacade;
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
@Rule
- public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ public final GrantPermissionRule mGrantPermissionRule =
+ GrantPermissionRule.grant(Manifest.permission.GET_ACCOUNTS);
@Mock
private UmaRecorder mUmaRecorderMock;
+ @Mock
+ ExternalAuthUtils mExternalAuthUtilsMock;
+
+ @Mock
+ private AccountsChangeObserver mObserverMock;
+
+ @Mock
+ private ChildAccountStatusListener mChildAccountStatusListenerMock;
+
+ private final Context mContext = RuntimeEnvironment.application;
+ private ShadowUserManager mShadowUserManager;
+ private ShadowAccountManager mShadowAccountManager;
+ private FakeAccountManagerDelegate mDelegate;
+ private AccountManagerFacade mFacade;
+
+ // Prefer to use the facade with the real system delegate instead of the fake delegate
+ // to test the facade more thoroughly
+ private AccountManagerFacade mFacadeWithSystemDelegate;
+
@Before
public void setUp() {
UmaRecorderHolder.setNonNativeDelegate(mUmaRecorderMock);
- Context context = RuntimeEnvironment.application;
- UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
- mShadowUserManager = (CustomShadowUserManager) shadowOf(userManager);
+ when(mExternalAuthUtilsMock.canUseGooglePlayServices()).thenReturn(true);
+ ExternalAuthUtils.setInstanceForTesting(mExternalAuthUtilsMock);
+
+ mShadowUserManager =
+ shadowOf((UserManager) mContext.getSystemService(Context.USER_SERVICE));
+ mShadowAccountManager = shadowOf(AccountManager.get(mContext));
+ ThreadUtils.setThreadAssertsDisabledForTesting(true);
mDelegate = new FakeAccountManagerDelegate();
mFacade = new AccountManagerFacadeImpl(mDelegate);
- }
- private void setAccountRestrictionPatterns(String... patterns) {
- Bundle restrictions = new Bundle();
- restrictions.putStringArray(
- AccountManagerFacadeImpl.ACCOUNT_RESTRICTION_PATTERNS_KEY, patterns);
- mShadowUserManager.setApplicationRestrictions(
- RuntimeEnvironment.application.getPackageName(), restrictions);
- RuntimeEnvironment.application.sendBroadcast(
- new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED));
- }
-
- private void clearAccountRestrictionPatterns() {
- mShadowUserManager.setApplicationRestrictions(
- RuntimeEnvironment.application.getPackageName(), new Bundle());
- RuntimeEnvironment.application.sendBroadcast(
- new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED));
+ mFacadeWithSystemDelegate =
+ new AccountManagerFacadeImpl(new SystemAccountManagerDelegate());
}
@Test
- public void testRegisterObserversCalledInConstructor() {
- FakeAccountManagerDelegate delegate = spy(new FakeAccountManagerDelegate());
- verify(delegate, never()).registerObservers();
- AccountManagerFacade accountManagerFacade = new AccountManagerFacadeImpl(delegate);
- verify(delegate).registerObservers();
+ public void testAccountsChangerObservationInitialization() {
+ mFacadeWithSystemDelegate.addObserver(mObserverMock);
+ verify(mObserverMock, never()).onAccountsChanged();
+
+ mContext.sendBroadcast(new Intent(AccountManager.LOGIN_ACCOUNTS_CHANGED_ACTION));
+
+ verify(mObserverMock).onAccountsChanged();
}
@Test
public void testCountOfAccountLoggedAfterAccountsFetched() {
addTestAccount("test@gmail.com");
+
AccountManagerFacade facade = new AccountManagerFacadeImpl(mDelegate);
- CallbackHelper callbackHelper = new CallbackHelper();
- facade.runAfterCacheIsPopulated(() -> callbackHelper.notifyCalled());
- try {
- callbackHelper.waitForFirst();
- } catch (TimeoutException e) {
- throw new RuntimeException("Timed out waiting for callback", e);
- }
+
verify(mUmaRecorderMock)
.recordLinearHistogram("Signin.AndroidNumberOfDeviceAccounts", 1, 1, 50, 51);
}
@@ -112,7 +123,7 @@ public class AccountManagerFacadeImplTest {
@Test
public void testCanonicalAccount() {
addTestAccount("test@gmail.com");
- List<Account> accounts = mFacade.tryGetGoogleAccounts();
+ List<Account> accounts = mFacade.getGoogleAccounts().get();
Assert.assertNotNull(AccountUtils.findAccountByName(accounts, "test@gmail.com"));
Assert.assertNotNull(AccountUtils.findAccountByName(accounts, "Test@gmail.com"));
@@ -125,7 +136,7 @@ public class AccountManagerFacadeImplTest {
@Test
public void testNonCanonicalAccount() {
addTestAccount("test.me@gmail.com");
- List<Account> accounts = mFacade.tryGetGoogleAccounts();
+ List<Account> accounts = mFacade.getGoogleAccounts().get();
Assert.assertNotNull(AccountUtils.findAccountByName(accounts, "test.me@gmail.com"));
Assert.assertNotNull(AccountUtils.findAccountByName(accounts, "testme@gmail.com"));
@@ -134,106 +145,152 @@ public class AccountManagerFacadeImplTest {
}
@Test
- public void testGetAccounts() throws AccountManagerDelegateException {
- Assert.assertEquals(List.of(), mFacade.getGoogleAccounts());
+ public void testGetAccounts() {
+ Assert.assertEquals(List.of(), mFacade.getGoogleAccounts().get());
Account account = addTestAccount("test@gmail.com");
- Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts().get());
Account account2 = addTestAccount("test2@gmail.com");
- Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts().get());
Account account3 = addTestAccount("test3@gmail.com");
- Assert.assertEquals(List.of(account, account2, account3), mFacade.getGoogleAccounts());
+ Assert.assertEquals(
+ List.of(account, account2, account3), mFacade.getGoogleAccounts().get());
removeTestAccount(account2);
- Assert.assertEquals(List.of(account, account3), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account, account3), mFacade.getGoogleAccounts().get());
}
@Test
- public void testGetAccountsWithAccountPattern() throws AccountManagerDelegateException {
+ public void testGetAccountsWithAccountPattern() {
setAccountRestrictionPatterns("*@example.com");
Account account = addTestAccount("test@example.com");
- Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts().get());
addTestAccount("test@gmail.com"); // Doesn't match the pattern.
- Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts().get());
Account account2 = addTestAccount("test2@example.com");
- Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts().get());
addTestAccount("test2@gmail.com"); // Doesn't match the pattern.
- Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts().get());
removeTestAccount(account);
- Assert.assertEquals(List.of(account2), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account2), mFacade.getGoogleAccounts().get());
}
@Test
- public void testGetAccountsWithTwoAccountPatterns() throws AccountManagerDelegateException {
+ public void testGetAccountsWithTwoAccountPatterns() {
setAccountRestrictionPatterns("test1@example.com", "test2@gmail.com");
addTestAccount("test@gmail.com"); // Doesn't match the pattern.
addTestAccount("test@example.com"); // Doesn't match the pattern.
- Assert.assertEquals(List.of(), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(), mFacade.getGoogleAccounts().get());
Account account = addTestAccount("test1@example.com");
- Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts().get());
addTestAccount("test2@example.com"); // Doesn't match the pattern.
- Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts().get());
Account account2 = addTestAccount("test2@gmail.com");
- Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts().get());
}
@Test
- public void testGetAccountsWithAccountPatternsChange() throws AccountManagerDelegateException {
- Assert.assertEquals(List.of(), mFacade.getGoogleAccounts());
+ public void testGetAccountsWithAccountPatternsChange() {
+ Assert.assertEquals(List.of(), mFacade.getGoogleAccounts().get());
Account account = addTestAccount("test@gmail.com");
- Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts().get());
Account account2 = addTestAccount("test2@example.com");
- Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts().get());
Account account3 = addTestAccount("test3@gmail.com");
- Assert.assertEquals(List.of(account, account2, account3), mFacade.getGoogleAccounts());
+ Assert.assertEquals(
+ List.of(account, account2, account3), mFacade.getGoogleAccounts().get());
setAccountRestrictionPatterns("test@gmail.com");
- Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts().get());
setAccountRestrictionPatterns("*@example.com", "test3@gmail.com");
- Assert.assertEquals(List.of(account2, account3), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account2, account3), mFacade.getGoogleAccounts().get());
removeTestAccount(account3);
- Assert.assertEquals(List.of(account2), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account2), mFacade.getGoogleAccounts().get());
+ }
+
+ @Test
+ public void testGetAccountsWithAccountPatternsCleared() {
+ final Account account1 = addTestAccount("test1@gmail.com");
+ final Account account2 = addTestAccount("testexample2@example.com");
+ setAccountRestrictionPatterns("*@example.com");
+ Assert.assertEquals(List.of(account2), mFacade.getGoogleAccounts().get());
- clearAccountRestrictionPatterns();
- Assert.assertEquals(List.of(account, account2), mFacade.getGoogleAccounts());
+ mShadowUserManager.setApplicationRestrictions(mContext.getPackageName(), new Bundle());
+ mContext.sendBroadcast(new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED));
+
+ Assert.assertEquals(List.of(account1, account2), mFacade.getGoogleAccounts().get());
}
@Test
- public void testGetAccountsMultipleMatchingPatterns() throws AccountManagerDelegateException {
+ public void testGetAccountsMultipleMatchingPatterns() {
setAccountRestrictionPatterns("*@gmail.com", "test@gmail.com");
Account account = addTestAccount("test@gmail.com"); // Matches both patterns
- Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts());
+ Assert.assertEquals(List.of(account), mFacade.getGoogleAccounts().get());
}
@Test
- public void testCheckChildAccount() {
- Account testAccount = addTestAccount("test@gmail.com");
- Account ucaAccount = addTestAccount(
+ public void testCheckChildAccountForRegularChild() {
+ final Account account = setFeaturesForAccount(
"uca@gmail.com", AccountManagerFacadeImpl.FEATURE_IS_CHILD_ACCOUNT_KEY);
- Account usmAccount = addTestAccount(
+
+ mFacadeWithSystemDelegate.checkChildAccountStatus(account, mChildAccountStatusListenerMock);
+
+ verify(mChildAccountStatusListenerMock).onStatusReady(ChildAccountStatus.REGULAR_CHILD);
+ }
+
+ @Test
+ public void testCheckChildAccountForUSMChild() {
+ final Account account = setFeaturesForAccount(
"usm@gmail.com", AccountManagerFacadeImpl.FEATURE_IS_USM_ACCOUNT_KEY);
- Account bothAccount = addTestAccount("uca_usm@gmail.com",
- AccountManagerFacadeImpl.FEATURE_IS_CHILD_ACCOUNT_KEY,
- AccountManagerFacadeImpl.FEATURE_IS_USM_ACCOUNT_KEY);
-
- assertChildAccountStatus(testAccount, ChildAccountStatus.NOT_CHILD);
- assertChildAccountStatus(ucaAccount, ChildAccountStatus.REGULAR_CHILD);
- assertChildAccountStatus(usmAccount, ChildAccountStatus.USM_CHILD);
- assertChildAccountStatus(bothAccount, ChildAccountStatus.REGULAR_CHILD);
+
+ mFacadeWithSystemDelegate.checkChildAccountStatus(account, mChildAccountStatusListenerMock);
+
+ verify(mChildAccountStatusListenerMock).onStatusReady(ChildAccountStatus.USM_CHILD);
+ }
+
+ @Test
+ public void testCheckChildAccountForRegularUSMChild() {
+ final Account account = setFeaturesForAccount("usm_uca@gmail.com",
+ AccountManagerFacadeImpl.FEATURE_IS_USM_ACCOUNT_KEY,
+ AccountManagerFacadeImpl.FEATURE_IS_CHILD_ACCOUNT_KEY);
+
+ mFacadeWithSystemDelegate.checkChildAccountStatus(account, mChildAccountStatusListenerMock);
+
+ verify(mChildAccountStatusListenerMock).onStatusReady(ChildAccountStatus.REGULAR_CHILD);
+ }
+
+ @Test
+ public void testCheckChildAccountForAdult() {
+ final Account account = setFeaturesForAccount("adult@gmail.com");
+
+ mFacadeWithSystemDelegate.checkChildAccountStatus(account, mChildAccountStatusListenerMock);
+
+ verify(mChildAccountStatusListenerMock).onStatusReady(ChildAccountStatus.NOT_CHILD);
+ }
+
+ @Test
+ public void testGetAccessToken() throws AuthException {
+ final Account account = AccountUtils.createAccountFromName("test@gmail.com");
+ final AccessTokenData originalToken =
+ mFacadeWithSystemDelegate.getAccessToken(account, TEST_TOKEN_SCOPE);
+
+ Assert.assertEquals("The same token should be returned.",
+ mFacadeWithSystemDelegate.getAccessToken(account, TEST_TOKEN_SCOPE).getToken(),
+ originalToken.getToken());
}
@Test
@@ -243,7 +300,9 @@ public class AccountManagerFacadeImplTest {
Assert.assertEquals("The same token should be returned before invalidating the token.",
mFacade.getAccessToken(account, TEST_TOKEN_SCOPE).getToken(),
originalToken.getToken());
+
mFacade.invalidateAccessToken(originalToken.getToken());
+
final AccessTokenData newToken = mFacade.getAccessToken(account, TEST_TOKEN_SCOPE);
Assert.assertNotEquals(
"A different token should be returned since the original token is invalidated.",
@@ -255,22 +314,26 @@ public class AccountManagerFacadeImplTest {
AccountManagerFacadeProvider.getInstance();
}
- private Account addTestAccount(String accountEmail, String... features) {
- AccountHolder holder = AccountHolder.builder(accountEmail)
- .addFeatures(features)
- .build();
+ private Account setFeaturesForAccount(String email, String... features) {
+ final Account account = AccountUtils.createAccountFromName(email);
+ mShadowAccountManager.setFeatures(account, features);
+ return account;
+ }
+
+ private void setAccountRestrictionPatterns(String... patterns) {
+ Bundle restrictions = new Bundle();
+ restrictions.putStringArray("RestrictAccountsToPatterns", patterns);
+ mShadowUserManager.setApplicationRestrictions(mContext.getPackageName(), restrictions);
+ mContext.sendBroadcast(new Intent(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED));
+ }
+
+ private Account addTestAccount(String accountEmail) {
+ final AccountHolder holder = AccountHolder.createFromEmail(accountEmail);
mDelegate.addAccount(holder);
- Assert.assertFalse(((AccountManagerFacadeImpl) mFacade).isUpdatePending().get());
return holder.getAccount();
}
private void removeTestAccount(Account account) {
- mDelegate.removeAccount(AccountHolder.builder(account).build());
- }
-
- private void assertChildAccountStatus(Account account, @ChildAccountStatus.Status int status) {
- ChildAccountStatusListener listenerMock = mock(ChildAccountStatusListener.class);
- mFacade.checkChildAccountStatus(account, listenerMock);
- verify(listenerMock).onStatusReady(status);
+ mDelegate.removeAccount(AccountHolder.createFromAccount(account));
}
}
diff --git a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountRenameCheckerTest.java b/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountRenameCheckerTest.java
index 52d9c158509..af336538277 100644
--- a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountRenameCheckerTest.java
+++ b/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountRenameCheckerTest.java
@@ -7,6 +7,8 @@ package org.chromium.components.signin;
import android.accounts.Account;
import android.content.Context;
+import androidx.annotation.Nullable;
+
import com.google.android.gms.auth.AccountChangeEvent;
import com.google.android.gms.auth.GoogleAuthUtil;
@@ -18,6 +20,7 @@ import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
+import org.chromium.base.task.test.CustomShadowAsyncTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
import java.util.ArrayList;
@@ -25,31 +28,35 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.concurrent.atomic.AtomicReference;
/**
* JUnit tests of the class {@link AccountRenameChecker}.
*/
@RunWith(BaseRobolectricTestRunner.class)
-@Config(shadows = {AccountRenameCheckerTest.ShadowGoogleAuthUtil.class})
+@Config(shadows = {AccountRenameCheckerTest.ShadowGoogleAuthUtil.class,
+ CustomShadowAsyncTask.class})
public class AccountRenameCheckerTest {
@Implements(GoogleAuthUtil.class)
static final class ShadowGoogleAuthUtil {
- private static final Map<String, String> sEvents = new HashMap<>();
+ private static final Map<String, List<AccountChangeEvent>> sEvents = new HashMap<>();
@Implementation
public static List<AccountChangeEvent> getAccountChangeEvents(
Context context, int eventIndex, String accountEmail) {
- if (sEvents.containsKey(accountEmail)) {
- final AccountChangeEvent event = new AccountChangeEvent(0L, accountEmail,
- GoogleAuthUtil.CHANGE_TYPE_ACCOUNT_RENAMED_TO, 0,
- sEvents.get(accountEmail));
- return List.of(event);
- }
- return Collections.emptyList();
+ return sEvents.getOrDefault(accountEmail, Collections.emptyList());
}
static void insertRenameEvent(String from, String to) {
- sEvents.put(from, to);
+ addEvent(from,
+ new AccountChangeEvent(
+ 0L, from, GoogleAuthUtil.CHANGE_TYPE_ACCOUNT_RENAMED_TO, 0, to));
+ }
+
+ static void addEvent(String email, AccountChangeEvent event) {
+ final List<AccountChangeEvent> events = sEvents.getOrDefault(email, new ArrayList<>());
+ events.add(event);
+ sEvents.put(email, events);
}
static void clearAllEvents() {
@@ -57,7 +64,7 @@ public class AccountRenameCheckerTest {
}
}
- private final AccountRenameChecker mChecker = new AccountRenameChecker();
+ private final AccountRenameChecker mChecker = AccountRenameChecker.get();
@After
public void tearDown() {
@@ -68,21 +75,30 @@ public class AccountRenameCheckerTest {
public void newNameIsValidWhenTheRenamedAccountIsPresent() {
ShadowGoogleAuthUtil.insertRenameEvent("A", "B");
- Assert.assertEquals("B", mChecker.getNewNameOfRenamedAccount("A", getAccounts("B")));
+ Assert.assertEquals("B", getNewNameOfRenamedAccount("A", List.of("B")));
+ }
+
+ @Test
+ public void newNameIsValidWhenOldAccountIsRemovedAndThenRenamed() {
+ ShadowGoogleAuthUtil.addEvent("A",
+ new AccountChangeEvent(0L, "A", GoogleAuthUtil.CHANGE_TYPE_ACCOUNT_REMOVED, 0, ""));
+ ShadowGoogleAuthUtil.insertRenameEvent("A", "B");
+
+ Assert.assertEquals("B", getNewNameOfRenamedAccount("A", List.of("B")));
}
@Test
public void newNameIsNullWhenTheOldAccountIsNotRenamed() {
ShadowGoogleAuthUtil.insertRenameEvent("B", "C");
- Assert.assertNull(mChecker.getNewNameOfRenamedAccount("A", getAccounts("D")));
+ Assert.assertNull(getNewNameOfRenamedAccount("A", List.of("D")));
}
@Test
public void newNameIsNullWhenTheRenamedAccountIsNotPresent() {
ShadowGoogleAuthUtil.insertRenameEvent("B", "C");
- Assert.assertNull(mChecker.getNewNameOfRenamedAccount("B", getAccounts("D")));
+ Assert.assertNull(getNewNameOfRenamedAccount("B", List.of("D")));
}
@Test
@@ -90,7 +106,7 @@ public class AccountRenameCheckerTest {
ShadowGoogleAuthUtil.insertRenameEvent("A", "B");
ShadowGoogleAuthUtil.insertRenameEvent("B", "C");
- Assert.assertEquals("C", mChecker.getNewNameOfRenamedAccount("A", getAccounts("C")));
+ Assert.assertEquals("C", getNewNameOfRenamedAccount("A", List.of("C")));
}
@Test
@@ -102,7 +118,7 @@ public class AccountRenameCheckerTest {
ShadowGoogleAuthUtil.insertRenameEvent("B", "C");
ShadowGoogleAuthUtil.insertRenameEvent("C", "D");
- Assert.assertEquals("D", mChecker.getNewNameOfRenamedAccount("A", getAccounts("D")));
+ Assert.assertEquals("D", getNewNameOfRenamedAccount("A", List.of("D")));
}
@Test
@@ -115,14 +131,18 @@ public class AccountRenameCheckerTest {
ShadowGoogleAuthUtil.insertRenameEvent("C", "D");
ShadowGoogleAuthUtil.insertRenameEvent("D", "A"); // Looped.
- Assert.assertEquals("D", mChecker.getNewNameOfRenamedAccount("A", getAccounts("D", "X")));
+ Assert.assertEquals("D", getNewNameOfRenamedAccount("A", List.of("D", "X")));
}
- private List<Account> getAccounts(String... names) {
+ private @Nullable String getNewNameOfRenamedAccount(
+ String oldAccountEmail, List<String> accountEmails) {
final List<Account> accounts = new ArrayList<>();
- for (String name : names) {
- accounts.add(AccountUtils.createAccountFromName(name));
+ for (String email : accountEmails) {
+ accounts.add(AccountUtils.createAccountFromName(email));
}
- return accounts;
+ final AtomicReference<String> newAccountName = new AtomicReference<>();
+ mChecker.getNewNameOfRenamedAccountAsync(oldAccountEmail, accounts)
+ .then(newAccountName::set);
+ return newAccountName.get();
}
}
diff --git a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/ObservableValueTest.java b/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/ObservableValueTest.java
deleted file mode 100644
index ab684c86961..00000000000
--- a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/ObservableValueTest.java
+++ /dev/null
@@ -1,109 +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 static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyZeroInteractions;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.robolectric.annotation.Config;
-
-import org.chromium.base.test.BaseRobolectricTestRunner;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-/**
- * Robolectric tests for {@link ObservableValue}.
- */
-@RunWith(BaseRobolectricTestRunner.class)
-@Config(manifest = Config.NONE)
-public class ObservableValueTest {
- @Test
- public void testNullAllowed() {
- MutableObservableValue<Integer> value = new MutableObservableValue<>(null);
- // Using null as a value should be allowed.
- assertNull(value.get());
- }
-
- @Test
- public void testAddObserverNoCallsToOnValueChanged() {
- MutableObservableValue<Integer> value = new MutableObservableValue<>(0);
- ObservableValue.Observer observer = mock(ObservableValue.Observer.class);
- value.addObserver(observer);
- verifyZeroInteractions(observer);
- }
-
- @Test
- public void testObserverIsNotifiedOnSet() {
- MutableObservableValue<Integer> value = new MutableObservableValue<>(0);
- ObservableValue.Observer observer = mock(ObservableValue.Observer.class);
- value.addObserver(observer);
-
- value.set(1);
- assertEquals(1, (int) value.get());
- verify(observer, times(1)).onValueChanged();
- }
-
- @Test
- public void testObserverIsNotNotifiedOnSetWithTheSameValue() {
- MutableObservableValue<Integer> value = new MutableObservableValue<>(123);
- ObservableValue.Observer observer = mock(ObservableValue.Observer.class);
- value.addObserver(observer);
-
- // Manually allocate the new value to make sure it's a different object and not a reference
- // to the same object from Java integer pool.
- @SuppressWarnings("UnnecessaryBoxing")
- Integer newValue = new Integer(123);
-
- value.set(newValue);
- assertEquals(123, (int) value.get());
- verifyZeroInteractions(observer);
- }
-
- @Test
- public void testObserverIsNotNotifiedAfterRemoval() {
- MutableObservableValue<Integer> value = new MutableObservableValue<>(0);
- ObservableValue.Observer observer = mock(ObservableValue.Observer.class);
- value.addObserver(observer);
-
- value.removeObserver(observer);
- value.set(321);
- assertEquals(321, (int) value.get());
- verifyZeroInteractions(observer);
- }
-
- @Test
- public void testGetReturnsUpdatedValueFromObserver() {
- MutableObservableValue<Integer> value = new MutableObservableValue<>(0);
- AtomicInteger valueHolder = new AtomicInteger(0);
- value.addObserver(() -> valueHolder.set(value.get()));
-
- value.set(123);
- assertEquals(123, valueHolder.get());
- }
-
- @Test
- public void testCanModifyObserverListFromOnValueChanged() {
- MutableObservableValue<Integer> value = new MutableObservableValue<>(0);
- AtomicInteger callCounter = new AtomicInteger(0);
- ObservableValue.Observer observer = new ObservableValue.Observer() {
- @Override
- public void onValueChanged() {
- callCounter.incrementAndGet();
- value.removeObserver(this);
- }
- };
- value.addObserver(observer);
- value.set(234);
- assertEquals("Observer should be invoked once", 1, callCounter.get());
- value.set(345);
- assertEquals("Observer should've been removed after the first call", 1, callCounter.get());
- }
-}
diff --git a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/identitymanager/AccountInfoServiceTest.java b/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/identitymanager/AccountInfoServiceTest.java
index c3a3a692757..88e7a54aa87 100644
--- a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/identitymanager/AccountInfoServiceTest.java
+++ b/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/identitymanager/AccountInfoServiceTest.java
@@ -37,6 +37,9 @@ public class AccountInfoServiceTest {
private IdentityManager mIdentityManagerMock;
@Mock
+ private AccountTrackerService mAccountTrackerServiceMock;
+
+ @Mock
private AccountInfoService.Observer mObserverMock;
private final AccountInfo mAccountInfoWithAvatar =
@@ -47,7 +50,7 @@ public class AccountInfoServiceTest {
@Before
public void setUp() {
- AccountInfoService.init(mIdentityManagerMock);
+ AccountInfoService.init(mIdentityManagerMock, mAccountTrackerServiceMock);
mService = AccountInfoService.get();
}
diff --git a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountTrackerServiceTest.java b/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/identitymanager/AccountTrackerServiceTest.java
index e8fcb271e69..14597aad2e8 100644
--- a/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/AccountTrackerServiceTest.java
+++ b/chromium/components/signin/public/android/junit/src/org/chromium/components/signin/identitymanager/AccountTrackerServiceTest.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;
+package org.chromium.components.signin.identitymanager;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -38,6 +38,8 @@ import org.chromium.base.Callback;
import org.chromium.base.task.test.CustomShadowAsyncTask;
import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.base.test.util.JniMocker;
+import org.chromium.components.signin.AccountManagerFacadeProvider;
+import org.chromium.components.signin.AccountUtils;
import org.chromium.components.signin.base.CoreAccountInfo;
import org.chromium.components.signin.test.util.FakeAccountManagerFacade;
@@ -98,16 +100,6 @@ public class AccountTrackerServiceTest {
}
@Test
- public void testSeedAccountsWithoutGooglePlayServices() {
- when(mFakeAccountManagerFacade.isGooglePlayServicesAvailable()).thenReturn(false);
-
- mService.seedAccountsIfNeeded(mRunnableMock);
-
- verify(mFakeAccountManagerFacade, never()).tryGetGoogleAccounts(any());
- verify(mRunnableMock, never()).run();
- }
-
- @Test
public void testSeedAccountsIfNeededBeforeAccountsAreSeeded() {
mService.seedAccountsIfNeeded(mRunnableMock);
@@ -227,7 +219,7 @@ public class AccountTrackerServiceTest {
final AtomicInteger invocationCount = new AtomicInteger(0);
doAnswer(AdditionalAnswers.answerVoid((VoidAnswer1<Callback<List<Account>>>) argument0 -> {
if (invocationCount.incrementAndGet() < expectedNumberOfInvocations) {
- argument0.onResult(mFakeAccountManagerFacade.tryGetGoogleAccounts());
+ argument0.onResult(mFakeAccountManagerFacade.getGoogleAccounts().get());
}
}))
.when(mFakeAccountManagerFacade)
diff --git a/chromium/components/signin/public/base/account_consistency_method.cc b/chromium/components/signin/public/base/account_consistency_method.cc
index 9898ec09bed..1e706d0d992 100644
--- a/chromium/components/signin/public/base/account_consistency_method.cc
+++ b/chromium/components/signin/public/base/account_consistency_method.cc
@@ -19,17 +19,29 @@ const base::Feature kMobileIdentityConsistencyVar{
// Feature flag for FRE related changes as part of MICE.
const base::Feature kMobileIdentityConsistencyFRE{
"MobileIdentityConsistencyFRE", base::FEATURE_DISABLED_BY_DEFAULT};
+const base::Feature kMobileIdentityConsistencyPromos{
+ "MobileIdentityConsistencyPromos", base::FEATURE_DISABLED_BY_DEFAULT};
#endif
#if defined(OS_IOS)
const base::Feature kMobileIdentityConsistency{
"MobileIdentityConsistency", base::FEATURE_DISABLED_BY_DEFAULT};
-#endif
+
+const base::Feature kMICEWebSignIn{"MICEWebSignInEnabled",
+ base::FEATURE_DISABLED_BY_DEFAULT};
+#endif // defined(OS_IOS)
#if defined(OS_ANDROID) || defined(OS_IOS)
bool IsMobileIdentityConsistencyEnabled() {
return base::FeatureList::IsEnabled(kMobileIdentityConsistency);
}
-#endif
+#endif // defined(OS_ANDROID) || defined(OS_IOS)
+
+#if defined(OS_IOS)
+bool IsMICEWebSignInEnabled() {
+ return IsMobileIdentityConsistencyEnabled() &&
+ base::FeatureList::IsEnabled(kMICEWebSignIn);
+}
+#endif // defined(OS_IOS)
} // 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 b0779772fb5..e4a6ea6ee40 100644
--- a/chromium/components/signin/public/base/account_consistency_method.h
+++ b/chromium/components/signin/public/base/account_consistency_method.h
@@ -27,7 +27,19 @@ bool IsMobileIdentityConsistencyEnabled();
// Feature flag for FRE related changes as part of MICE.
extern const base::Feature kMobileIdentityConsistencyFRE;
-#endif
+
+// Feature flag for promo-related changes of `kMobileIdentityConsistency`.
+extern const base::Feature kMobileIdentityConsistencyPromos;
+#endif // defined(OS_ANDROID) || defined(OS_IOS)
+
+#if defined(OS_IOS)
+// Feature flag for promo-related changes of `kMobileIdentityConsistency`.
+extern const base::Feature kMICEWebSignIn;
+
+// Returns true if the flags |kMICEWebSignInEnabled| and
+// |kMobileIdentityConsistency| are enabled for the platform.
+bool IsMICEWebSignInEnabled();
+#endif // defined(OS_IOS)
enum class AccountConsistencyMethod : int {
// No account consistency.
diff --git a/chromium/components/signin/public/base/multilogin_parameters.cc b/chromium/components/signin/public/base/multilogin_parameters.cc
index ce5878cf683..19ec7b85267 100644
--- a/chromium/components/signin/public/base/multilogin_parameters.cc
+++ b/chromium/components/signin/public/base/multilogin_parameters.cc
@@ -6,8 +6,7 @@
namespace signin {
-MultiloginParameters::MultiloginParameters()
- : mode(gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER) {}
+MultiloginParameters::MultiloginParameters() = default;
MultiloginParameters::MultiloginParameters(
const gaia::MultiloginMode mode,
diff --git a/chromium/components/signin/public/base/multilogin_parameters.h b/chromium/components/signin/public/base/multilogin_parameters.h
index efb672e3e0b..4859c7c6749 100644
--- a/chromium/components/signin/public/base/multilogin_parameters.h
+++ b/chromium/components/signin/public/base/multilogin_parameters.h
@@ -5,7 +5,6 @@
#ifndef COMPONENTS_SIGNIN_PUBLIC_BASE_MULTILOGIN_PARAMETERS_H_
#define COMPONENTS_SIGNIN_PUBLIC_BASE_MULTILOGIN_PARAMETERS_H_
-#include <string>
#include <vector>
#include "google_apis/gaia/core_account_id.h"
@@ -26,7 +25,12 @@ struct MultiloginParameters {
return mode == other.mode && accounts_to_send == other.accounts_to_send;
}
- gaia::MultiloginMode mode;
+ bool operator!=(const MultiloginParameters& other) const {
+ return !(*this == other);
+ }
+
+ gaia::MultiloginMode mode =
+ gaia::MultiloginMode::MULTILOGIN_UPDATE_COOKIE_ACCOUNTS_ORDER;
std::vector<CoreAccountId> accounts_to_send;
};
} // namespace signin
diff --git a/chromium/components/signin/public/base/signin_client.h b/chromium/components/signin/public/base/signin_client.h
index 2f917a15cab..48b496d10a4 100644
--- a/chromium/components/signin/public/base/signin_client.h
+++ b/chromium/components/signin/public/base/signin_client.h
@@ -9,7 +9,6 @@
#include "base/callback.h"
#include "base/callback_list.h"
-#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/keyed_service/core/keyed_service.h"
@@ -19,8 +18,8 @@
#include "url/gurl.h"
#if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "base/optional.h"
#include "components/account_manager_core/account.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#endif
class PrefService;
@@ -100,7 +99,7 @@ class SigninClient : public KeyedService {
virtual bool IsNonEnterpriseUser(const std::string& username);
#if BUILDFLAG(IS_CHROMEOS_LACROS)
- virtual base::Optional<account_manager::Account>
+ virtual absl::optional<account_manager::Account>
GetInitialPrimaryAccount() = 0;
#endif
};
diff --git a/chromium/components/signin/public/base/signin_metrics.cc b/chromium/components/signin/public/base/signin_metrics.cc
index 9f4b9c7853a..40e268f9be6 100644
--- a/chromium/components/signin/public/base/signin_metrics.cc
+++ b/chromium/components/signin/public/base/signin_metrics.cc
@@ -43,10 +43,6 @@ void RecordSigninUserActionForAccessPoint(AccessPoint access_point) {
base::RecordAction(
base::UserMetricsAction("Signin_Signin_FromExtensions"));
break;
- case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
- base::RecordAction(
- base::UserMetricsAction("Signin_Signin_FromAppsPageLink"));
- break;
case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
base::RecordAction(
base::UserMetricsAction("Signin_Signin_FromBookmarkBubble"));
@@ -198,7 +194,6 @@ void RecordSigninWithDefaultUserActionForAccessPoint(
case AccessPoint::ACCESS_POINT_MENU:
case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
case AccessPoint::ACCESS_POINT_EXTENSIONS:
- case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
case AccessPoint::ACCESS_POINT_USER_MANAGER:
case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
@@ -278,7 +273,6 @@ void RecordSigninNotDefaultUserActionForAccessPoint(
case AccessPoint::ACCESS_POINT_MENU:
case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
case AccessPoint::ACCESS_POINT_EXTENSIONS:
- case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
case AccessPoint::ACCESS_POINT_USER_MANAGER:
case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
@@ -362,7 +356,6 @@ void RecordSigninNewAccountNoExistingAccountUserActionForAccessPoint(
case AccessPoint::ACCESS_POINT_MENU:
case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
case AccessPoint::ACCESS_POINT_EXTENSIONS:
- case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
case AccessPoint::ACCESS_POINT_USER_MANAGER:
case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
@@ -449,7 +442,6 @@ void RecordSigninNewAccountExistingAccountUserActionForAccessPoint(
case AccessPoint::ACCESS_POINT_MENU:
case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
case AccessPoint::ACCESS_POINT_EXTENSIONS:
- case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
case AccessPoint::ACCESS_POINT_USER_MANAGER:
case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
@@ -825,10 +817,6 @@ void RecordSigninImpressionUserActionForAccessPoint(AccessPoint access_point) {
base::RecordAction(base::UserMetricsAction(
"Signin_Impression_FromExtensionInstallBubble"));
break;
- case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
- base::RecordAction(
- base::UserMetricsAction("Signin_Impression_FromAppsPageLink"));
- break;
case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
base::RecordAction(
base::UserMetricsAction("Signin_Impression_FromBookmarkBubble"));
@@ -1025,7 +1013,6 @@ void RecordSigninImpressionWithAccountUserActionForAccessPoint(
case AccessPoint::ACCESS_POINT_MENU:
case AccessPoint::ACCESS_POINT_SUPERVISED_USER:
case AccessPoint::ACCESS_POINT_EXTENSIONS:
- case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
case AccessPoint::ACCESS_POINT_USER_MANAGER:
case AccessPoint::ACCESS_POINT_DEVICES_PAGE:
case AccessPoint::ACCESS_POINT_CLOUD_PRINT:
diff --git a/chromium/components/signin/public/base/signin_metrics.h b/chromium/components/signin/public/base/signin_metrics.h
index b9e4d70c593..f4cf883cb24 100644
--- a/chromium/components/signin/public/base/signin_metrics.h
+++ b/chromium/components/signin/public/base/signin_metrics.h
@@ -148,7 +148,7 @@ enum class AccessPoint : int {
ACCESS_POINT_SUPERVISED_USER = 4,
ACCESS_POINT_EXTENSION_INSTALL_BUBBLE = 5,
ACCESS_POINT_EXTENSIONS = 6,
- ACCESS_POINT_APPS_PAGE_LINK = 7,
+ // ACCESS_POINT_APPS_PAGE_LINK = 7, no longer used.
ACCESS_POINT_BOOKMARK_BUBBLE = 8,
ACCESS_POINT_BOOKMARK_MANAGER = 9,
ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN = 10,
@@ -222,52 +222,51 @@ enum class AccountConsistencyPromoAction : int {
// Promo is not shown as there are no accounts on device.
SUPPRESSED_NO_ACCOUNTS = 0,
// User has dismissed the promo by tapping back button.
- DISMISSED_BACK,
+ DISMISSED_BACK = 1,
// User has tapped |Add account to device| from expanded account list.
- ADD_ACCOUNT_STARTED,
- // User tapped the button from the expanded account list to open the incognito
- // interstitial
- // then confirmed opening the page in the incognito tab by tapping |Continue|
- // in the incognito
- // interstitial.
- STARTED_INCOGNITO_SESSION,
+ ADD_ACCOUNT_STARTED = 2,
+
+ // Deprecated 05/2021, since the Incognito option has been removed from
+ // account picker bottomsheet.
+ // STARTED_INCOGNITO_SESSION = 3,
+
// User has selected the default account and signed in with it
- SIGNED_IN_WITH_DEFAULT_ACCOUNT,
+ SIGNED_IN_WITH_DEFAULT_ACCOUNT = 4,
// User has selected one of the non default accounts and signed in with it.
- SIGNED_IN_WITH_NON_DEFAULT_ACCOUNT,
+ SIGNED_IN_WITH_NON_DEFAULT_ACCOUNT = 5,
// The promo was shown to user.
- SHOWN,
+ SHOWN = 6,
// Promo is not shown due to sign-in being disallowed either by an enterprise
// policy
// or by |Allow Chrome sign-in| toggle.
- SUPPRESSED_SIGNIN_NOT_ALLOWED,
+ SUPPRESSED_SIGNIN_NOT_ALLOWED = 7,
// User has added an account and signed in with this account.
// When this metric is recorded, we won't record
// SIGNED_IN_WITH_DEFAULT_ACCOUNT or
// SIGNED_IN_WITH_NON_DEFAULT_ACCOUNT.
- SIGNED_IN_WITH_ADDED_ACCOUNT,
+ SIGNED_IN_WITH_ADDED_ACCOUNT = 8,
// User has dismissed the promo by tapping on the scrim above the bottom
// sheet.
- DISMISSED_SCRIM,
+ DISMISSED_SCRIM = 9,
// User has dismissed the promo by swiping down the bottom sheet.
- DISMISSED_SWIPE_DOWN,
+ DISMISSED_SWIPE_DOWN = 10,
// User has dismissed the promo by other means.
- DISMISSED_OTHER,
+ DISMISSED_OTHER = 11,
// The auth error screen was shown to the user.
- AUTH_ERROR_SHOWN,
+ AUTH_ERROR_SHOWN = 12,
// The generic error screen was shown to the user.
- GENERIC_ERROR_SHOWN,
+ GENERIC_ERROR_SHOWN = 13,
// User has dismissed the promo by tapping on the dismissal button in the
// bottom sheet.
- DISMISSED_BUTTON,
+ DISMISSED_BUTTON = 14,
// User has completed the account addition flow triggered from the bottom
// sheet.
- ADD_ACCOUNT_COMPLETED,
+ ADD_ACCOUNT_COMPLETED = 15,
// The bottom sheet was suppressed as the user hit consecutive active
// dismissal limit.
- SUPPRESSED_CONSECUTIVE_DISMISSALS,
+ SUPPRESSED_CONSECUTIVE_DISMISSALS = 16,
- MAX,
+ MAX = 17,
};
// This class is used to record web sign-in events within 2 minutes after
diff --git a/chromium/components/signin/public/base/signin_metrics_unittest.cc b/chromium/components/signin/public/base/signin_metrics_unittest.cc
index bda46e4f579..540566d8d54 100644
--- a/chromium/components/signin/public/base/signin_metrics_unittest.cc
+++ b/chromium/components/signin/public/base/signin_metrics_unittest.cc
@@ -23,7 +23,6 @@ const AccessPoint kAccessPointsThatSupportUserAction[] = {
AccessPoint::ACCESS_POINT_SUPERVISED_USER,
AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE,
AccessPoint::ACCESS_POINT_EXTENSIONS,
- AccessPoint::ACCESS_POINT_APPS_PAGE_LINK,
AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE,
AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER,
AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN,
@@ -50,7 +49,6 @@ const AccessPoint kAccessPointsThatSupportImpression[] = {
AccessPoint::ACCESS_POINT_MENU,
AccessPoint::ACCESS_POINT_SETTINGS,
AccessPoint::ACCESS_POINT_EXTENSION_INSTALL_BUBBLE,
- AccessPoint::ACCESS_POINT_APPS_PAGE_LINK,
AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE,
AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER,
AccessPoint::ACCESS_POINT_AVATAR_BUBBLE_SIGN_IN,
@@ -97,8 +95,6 @@ class SigninMetricsTest : public ::testing::Test {
return "ExtensionInstallBubble";
case AccessPoint::ACCESS_POINT_EXTENSIONS:
return "Extensions";
- case AccessPoint::ACCESS_POINT_APPS_PAGE_LINK:
- return "AppsPageLink";
case AccessPoint::ACCESS_POINT_BOOKMARK_BUBBLE:
return "BookmarkBubble";
case AccessPoint::ACCESS_POINT_BOOKMARK_MANAGER:
diff --git a/chromium/components/signin/public/base/signin_pref_names.cc b/chromium/components/signin/public/base/signin_pref_names.cc
index bba71b0bc08..1803fb0eb3a 100644
--- a/chromium/components/signin/public/base/signin_pref_names.cc
+++ b/chromium/components/signin/public/base/signin_pref_names.cc
@@ -85,6 +85,10 @@ const char kSignedInWithCredentialProvider[] =
// Boolean which stores if the user is allowed to signin to chrome.
const char kSigninAllowed[] = "signin.allowed";
+// Boolean which stores if the user is allowed to signin to chrome with the
+// current applied policies.
+const char kSigninAllowedByPolicy[] = "signin.allowed_by_policy";
+
// True if the token service has been prepared for Dice migration.
const char kTokenServiceDiceCompatible[] = "token_service.dice_compatible";
diff --git a/chromium/components/signin/public/base/signin_pref_names.h b/chromium/components/signin/public/base/signin_pref_names.h
index 3230e8533db..8d49c5b4c57 100644
--- a/chromium/components/signin/public/base/signin_pref_names.h
+++ b/chromium/components/signin/public/base/signin_pref_names.h
@@ -27,6 +27,7 @@ extern const char kGoogleServicesUsernamePattern[];
extern const char kReverseAutologinRejectedEmailList[];
extern const char kSignedInWithCredentialProvider[];
extern const char kSigninAllowed[];
+extern const char kSigninAllowedByPolicy[];
extern const char kTokenServiceDiceCompatible[];
extern const char kGaiaCookieLastListAccountsData[];
diff --git a/chromium/components/signin/public/base/signin_switches.cc b/chromium/components/signin/public/base/signin_switches.cc
index 8243123737b..58f66e6b66e 100644
--- a/chromium/components/signin/public/base/signin_switches.cc
+++ b/chromium/components/signin/public/base/signin_switches.cc
@@ -4,6 +4,7 @@
#include "components/signin/public/base/signin_switches.h"
+#include "base/feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
@@ -29,13 +30,16 @@ const base::Feature kForceAccountIdMigration{"ForceAccountIdMigration",
// Menagerie API.
const base::Feature kDeprecateMenagerieAPI{"DeprecateMenagerieAPI",
base::FEATURE_DISABLED_BY_DEFAULT};
+// This feature flag is used to wipe device data on child account signin.
+const base::Feature kWipeDataOnChildAccountSignin{
+ "WipeDataOnChildAccountSignin", base::FEATURE_DISABLED_BY_DEFAULT};
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
const base::Feature kUseAccountManagerFacade{"kUseAccountManagerFacade",
base::FEATURE_ENABLED_BY_DEFAULT};
-#elif BUILDFLAG(IS_CHROMEOS_LACROS)
-const base::Feature kUseAccountManagerFacade{"kUseAccountManagerFacade",
- base::FEATURE_DISABLED_BY_DEFAULT};
#endif
+
+const base::Feature kMinorModeSupport{"MinorModeSupport",
+ 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 fa46dd79e23..9a634b37dbc 100644
--- a/chromium/components/signin/public/base/signin_switches.h
+++ b/chromium/components/signin/public/base/signin_switches.h
@@ -31,12 +31,17 @@ extern const base::Feature kForceAccountIdMigration;
// This feature flag is for the deprecating of the Android profile data
// Menagerie API.
extern const base::Feature kDeprecateMenagerieAPI;
+// This feature flag is used to wipe device data on child account signin.
+extern const base::Feature kWipeDataOnChildAccountSignin;
#endif // defined(OS_ANDROID)
-#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+#if BUILDFLAG(IS_CHROMEOS_ASH)
// Killswitch for PO2TS migration to AccountManagerFacade.
extern const base::Feature kUseAccountManagerFacade;
#endif
+
+// Support for the minor mode.
+extern const base::Feature kMinorModeSupport;
} // namespace switches
#endif // COMPONENTS_SIGNIN_PUBLIC_BASE_SIGNIN_SWITCHES_H_
diff --git a/chromium/components/signin/public/base/test_signin_client.cc b/chromium/components/signin/public/base/test_signin_client.cc
index 767a7aa6bd8..871b1bd2501 100644
--- a/chromium/components/signin/public/base/test_signin_client.cc
+++ b/chromium/components/signin/public/base/test_signin_client.cc
@@ -14,8 +14,8 @@
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "base/optional.h"
#include "components/account_manager_core/account.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#endif
TestSigninClient::TestSigninClient(
@@ -122,14 +122,14 @@ bool TestSigninClient::IsNonEnterpriseUser(const std::string& email) {
}
#if BUILDFLAG(IS_CHROMEOS_LACROS)
-base::Optional<account_manager::Account>
+absl::optional<account_manager::Account>
TestSigninClient::GetInitialPrimaryAccount() {
return initial_primary_account_;
}
void TestSigninClient::SetInitialPrimaryAccountForTests(
const account_manager::Account& account) {
- initial_primary_account_ = base::make_optional(account);
+ initial_primary_account_ = absl::make_optional(account);
}
#endif
diff --git a/chromium/components/signin/public/base/test_signin_client.h b/chromium/components/signin/public/base/test_signin_client.h
index 7c2b09f37dc..a8bd37e7788 100644
--- a/chromium/components/signin/public/base/test_signin_client.h
+++ b/chromium/components/signin/public/base/test_signin_client.h
@@ -21,8 +21,8 @@
#include "services/network/test/test_url_loader_factory.h"
#if BUILDFLAG(IS_CHROMEOS_LACROS)
-#include "base/optional.h"
#include "components/account_manager_core/account.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#endif
class PrefService;
@@ -96,7 +96,7 @@ class TestSigninClient : public SigninClient {
void SetDiceMigrationCompleted() override;
bool IsNonEnterpriseUser(const std::string& email) override;
#if BUILDFLAG(IS_CHROMEOS_LACROS)
- base::Optional<account_manager::Account> GetInitialPrimaryAccount() override;
+ absl::optional<account_manager::Account> GetInitialPrimaryAccount() override;
#endif
#if BUILDFLAG(IS_CHROMEOS_LACROS)
@@ -119,7 +119,7 @@ class TestSigninClient : public SigninClient {
std::vector<base::OnceClosure> delayed_network_calls_;
#if BUILDFLAG(IS_CHROMEOS_LACROS)
- base::Optional<account_manager::Account> initial_primary_account_;
+ absl::optional<account_manager::Account> initial_primary_account_;
#endif
DISALLOW_COPY_AND_ASSIGN(TestSigninClient);
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 54ddaf3a6af..0e6161b5236 100644
--- a/chromium/components/signin/public/identity_manager/access_token_fetcher.cc
+++ b/chromium/components/signin/public/identity_manager/access_token_fetcher.cc
@@ -8,6 +8,7 @@
#include "base/check_op.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "components/signin/public/identity_manager/access_token_constants.h"
#include "components/signin/public/identity_manager/access_token_info.h"
#include "google_apis/gaia/gaia_constants.h"
diff --git a/chromium/components/signin/public/identity_manager/account_info.h b/chromium/components/signin/public/identity_manager/account_info.h
index dbffa5e86ff..739f77ceab3 100644
--- a/chromium/components/signin/public/identity_manager/account_info.h
+++ b/chromium/components/signin/public/identity_manager/account_info.h
@@ -7,9 +7,9 @@
#include <string>
-#include "base/optional.h"
#include "build/build_config.h"
#include "google_apis/gaia/core_account_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/gfx/image/image.h"
#if defined(OS_ANDROID)
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 200fd2a1f69..81df07c1fd8 100644
--- a/chromium/components/signin/public/identity_manager/accounts_cookie_mutator.h
+++ b/chromium/components/signin/public/identity_manager/accounts_cookie_mutator.h
@@ -132,6 +132,10 @@ class AccountsCookieMutator {
gaia::GaiaSource source,
LogOutFromCookieCompletedCallback completion_callback) = 0;
+ // Indicates that an account previously listed via ListAccounts should now
+ // be removed.
+ virtual void RemoveLoggedOutAccountByGaiaId(const std::string& gaia_id) = 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 77a4839d460..3ab7cb41a99 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
@@ -9,6 +9,7 @@
#include "base/bind.h"
#include "base/run_loop.h"
+#include "base/strings/stringprintf.h"
#include "base/test/bind.h"
#include "base/test/gtest_util.h"
#include "base/test/task_environment.h"
diff --git a/chromium/components/signin/public/identity_manager/accounts_mutator.h b/chromium/components/signin/public/identity_manager/accounts_mutator.h
index ab675b1712d..b2c34f4e908 100644
--- a/chromium/components/signin/public/identity_manager/accounts_mutator.h
+++ b/chromium/components/signin/public/identity_manager/accounts_mutator.h
@@ -8,9 +8,9 @@
#include <string>
#include "base/macros.h"
-#include "base/optional.h"
#include "build/chromeos_buildflags.h"
#include "components/signin/public/base/signin_buildflags.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace signin_metrics {
enum class SourceForRefreshTokenOperation;
@@ -39,8 +39,8 @@ class AccountsMutator {
// Updates the information about account identified by |account_id|.
virtual void UpdateAccountInfo(
const CoreAccountId& account_id,
- base::Optional<bool> is_child_account,
- base::Optional<bool> is_under_advanced_protection) = 0;
+ absl::optional<bool> is_child_account,
+ absl::optional<bool> is_under_advanced_protection) = 0;
// Removes the account given by |account_id|. Also revokes the token
// server-side if needed.
diff --git a/chromium/components/signin/public/identity_manager/accounts_mutator_unittest.cc b/chromium/components/signin/public/identity_manager/accounts_mutator_unittest.cc
index fef09d7213b..0daef5ace2b 100644
--- a/chromium/components/signin/public/identity_manager/accounts_mutator_unittest.cc
+++ b/chromium/components/signin/public/identity_manager/accounts_mutator_unittest.cc
@@ -5,7 +5,6 @@
#include "components/signin/internal/identity_manager/accounts_mutator_impl.h"
#include "base/bind.h"
-#include "base/optional.h"
#include "base/test/gtest_util.h"
#include "base/test/task_environment.h"
#include "build/chromeos_buildflags.h"
@@ -18,6 +17,7 @@
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace {
@@ -157,7 +157,7 @@ TEST_F(AccountsMutatorTest, UpdateAccountInfo) {
accounts_mutator()->UpdateAccountInfo(
account_id,
/*is_child_account=*/true,
- /*is_under_advanced_protection=*/base::nullopt);
+ /*is_under_advanced_protection=*/absl::nullopt);
AccountInfo updated_account_info_1 =
identity_manager()
->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId(
@@ -175,7 +175,7 @@ TEST_F(AccountsMutatorTest, UpdateAccountInfo) {
original_account_info.is_under_advanced_protection);
accounts_mutator()->UpdateAccountInfo(account_id,
- /*is_child_account=*/base::nullopt,
+ /*is_child_account=*/absl::nullopt,
/*is_under_advanced_protection=*/true);
AccountInfo updated_account_info_2 =
identity_manager()
@@ -334,8 +334,8 @@ TEST_F(AccountsMutatorTest,
// Set up the primary account.
std::string primary_account_email("primary.account@example.com");
- AccountInfo primary_account_info =
- MakePrimaryAccountAvailable(identity_manager(), primary_account_email);
+ AccountInfo primary_account_info = MakePrimaryAccountAvailable(
+ identity_manager(), primary_account_email, signin::ConsentLevel::kSync);
// Now try invalidating the primary account, and check that it gets updated.
base::RunLoop run_loop;
@@ -372,8 +372,8 @@ TEST_F(
// Set up the primary account.
std::string primary_account_email("primary.account@example.com");
- AccountInfo primary_account_info =
- MakePrimaryAccountAvailable(identity_manager(), primary_account_email);
+ AccountInfo primary_account_info = MakePrimaryAccountAvailable(
+ identity_manager(), primary_account_email, signin::ConsentLevel::kSync);
// Next, add a secondary account.
base::RunLoop run_loop;
diff --git a/chromium/components/signin/public/identity_manager/device_accounts_synchronizer.h b/chromium/components/signin/public/identity_manager/device_accounts_synchronizer.h
index 3c441ae850f..20c2e3a551f 100644
--- a/chromium/components/signin/public/identity_manager/device_accounts_synchronizer.h
+++ b/chromium/components/signin/public/identity_manager/device_accounts_synchronizer.h
@@ -5,9 +5,9 @@
#ifndef COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_DEVICE_ACCOUNTS_SYNCHRONIZER_H_
#define COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_DEVICE_ACCOUNTS_SYNCHRONIZER_H_
-#include "base/optional.h"
#include "build/build_config.h"
#include "google_apis/gaia/core_account_id.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
namespace signin {
@@ -22,7 +22,7 @@ class DeviceAccountsSynchronizer {
// accounts will be visible in IdentityManager::GetAccountsWithRefreshTokens()
// with any persistent errors cleared after this method is called.
virtual void ReloadAllAccountsFromSystemWithPrimaryAccount(
- const base::Optional<CoreAccountId>& primary_account_id) = 0;
+ const absl::optional<CoreAccountId>& primary_account_id) = 0;
#if defined(OS_IOS)
// Reloads the information of the device-level account with |account_id|. The
diff --git a/chromium/components/signin/public/identity_manager/identity_manager.cc b/chromium/components/signin/public/identity_manager/identity_manager.cc
index 16c774d763c..2c6f6372c02 100644
--- a/chromium/components/signin/public/identity_manager/identity_manager.cc
+++ b/chromium/components/signin/public/identity_manager/identity_manager.cc
@@ -7,7 +7,6 @@
#include <string>
#include "base/bind.h"
-#include "base/optional.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "components/signin/internal/identity_manager/account_fetcher_service.h"
@@ -23,6 +22,7 @@
#include "components/signin/public/identity_manager/diagnostics_provider.h"
#include "components/signin/public/identity_manager/primary_account_mutator.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "third_party/abseil-cpp/absl/types/optional.h"
#if defined(OS_ANDROID)
#include "base/android/jni_string.h"
@@ -60,12 +60,13 @@ void SetPrimaryAccount(IdentityManager* identity_manager,
const CoreAccountId account_id = account_tracker_service->SeedAccountInfo(
/*gaia=*/device_account.key.id, device_account.raw_email);
// TODO(https://crbug.com/1194983): Figure out how split sync settings will
- // work here.
- identity_manager->GetPrimaryAccountMutator()->SetUnconsentedPrimaryAccount(
- account_id);
+ // work here. For now, we will mimic Ash's behaviour of having sync turned on
+ // by default.
+ identity_manager->GetPrimaryAccountMutator()->SetPrimaryAccount(
+ account_id, ConsentLevel::kSync);
- CHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kSignin));
- CHECK_EQ(identity_manager->GetPrimaryAccountInfo(ConsentLevel::kSignin).gaia,
+ CHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
+ CHECK_EQ(identity_manager->GetPrimaryAccountInfo(ConsentLevel::kSync).gaia,
device_account.key.id);
}
#endif
@@ -136,7 +137,7 @@ IdentityManager::IdentityManager(IdentityManager::InitParameters&& parameters)
// Profile / KeyedServices - but with the availability of IdentityManager. We
// don't have such a place in Lacros - which guarantees that the Primary
// Account will be available on startup - just like Ash.
- base::Optional<account_manager::Account> initial_account =
+ absl::optional<account_manager::Account> initial_account =
signin_client_->GetInitialPrimaryAccount();
if (initial_account.has_value()) {
SetPrimaryAccount(this, account_tracker_service_.get(), signin_client_,
@@ -178,7 +179,7 @@ void IdentityManager::RemoveObserver(Observer* observer) {
observer_list_.RemoveObserver(observer);
}
-// TODO(862619) change return type to base::Optional<CoreAccountInfo>
+// TODO(862619) change return type to absl::optional<CoreAccountInfo>
CoreAccountInfo IdentityManager::GetPrimaryAccountInfo(
ConsentLevel consent) const {
return primary_account_manager_->GetPrimaryAccountInfo(consent);
@@ -297,7 +298,16 @@ GoogleServiceAuthError IdentityManager::GetErrorStateOfRefreshTokenForAccount(
return token_service_->GetAuthError(account_id);
}
-base::Optional<AccountInfo>
+absl::optional<AccountInfo> IdentityManager::FindExtendedAccountInfoByAccountId(
+ const CoreAccountId& account_id) const {
+ AccountInfo account_info =
+ account_tracker_service_->GetAccountInfo(account_id);
+ if (account_info.IsEmpty())
+ return absl::nullopt;
+ return account_info;
+}
+
+absl::optional<AccountInfo>
IdentityManager::FindExtendedAccountInfoForAccountWithRefreshToken(
const CoreAccountInfo& account_info) const {
AccountInfo extended_account_info =
@@ -307,12 +317,12 @@ IdentityManager::FindExtendedAccountInfoForAccountWithRefreshToken(
// case of failure, the AccountInfo will be unpopulated, thus we should not
// be able to find a valid refresh token.
if (!HasAccountWithRefreshToken(extended_account_info.account_id))
- return base::nullopt;
+ return absl::nullopt;
return GetAccountInfoForAccountWithRefreshToken(account_info.account_id);
}
-base::Optional<AccountInfo>
+absl::optional<AccountInfo>
IdentityManager::FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId(
const CoreAccountId& account_id) const {
AccountInfo account_info =
@@ -322,12 +332,12 @@ IdentityManager::FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId(
// case of failure, the AccountInfo will be unpopulated, thus we should not
// be able to find a valid refresh token.
if (!HasAccountWithRefreshToken(account_info.account_id))
- return base::nullopt;
+ return absl::nullopt;
return GetAccountInfoForAccountWithRefreshToken(account_info.account_id);
}
-base::Optional<AccountInfo> IdentityManager::
+absl::optional<AccountInfo> IdentityManager::
FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
const std::string& email_address) const {
AccountInfo account_info =
@@ -337,12 +347,12 @@ base::Optional<AccountInfo> IdentityManager::
// case of failure, the AccountInfo will be unpopulated, thus we should not
// be able to find a valid refresh token.
if (!HasAccountWithRefreshToken(account_info.account_id))
- return base::nullopt;
+ return absl::nullopt;
return GetAccountInfoForAccountWithRefreshToken(account_info.account_id);
}
-base::Optional<AccountInfo>
+absl::optional<AccountInfo>
IdentityManager::FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId(
const std::string& gaia_id) const {
AccountInfo account_info =
@@ -352,7 +362,7 @@ IdentityManager::FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId(
// case of failure, the AccountInfo will be unpopulated, thus we should not
// be able to find a valid refresh token.
if (!HasAccountWithRefreshToken(account_info.account_id))
- return base::nullopt;
+ return absl::nullopt;
return GetAccountInfoForAccountWithRefreshToken(account_info.account_id);
}
diff --git a/chromium/components/signin/public/identity_manager/identity_manager.h b/chromium/components/signin/public/identity_manager/identity_manager.h
index ce7d2a4cc23..20c54fca5ca 100644
--- a/chromium/components/signin/public/identity_manager/identity_manager.h
+++ b/chromium/components/signin/public/identity_manager/identity_manager.h
@@ -251,17 +251,23 @@ class IdentityManager : public KeyedService,
GoogleServiceAuthError GetErrorStateOfRefreshTokenForAccount(
const CoreAccountId& account_id) const;
+ // Returns extended information for account identified by |account_id|.
+ // The information will be returned if the information is available regardless
+ // of whether the refresh token is available for the account.
+ absl::optional<AccountInfo> FindExtendedAccountInfoByAccountId(
+ const CoreAccountId& account_id) const;
+
// Returns extended information for account identified by |account_info|.
// The information will be returned if the information is available and
// refresh token is available for account.
- base::Optional<AccountInfo> FindExtendedAccountInfoForAccountWithRefreshToken(
+ absl::optional<AccountInfo> FindExtendedAccountInfoForAccountWithRefreshToken(
const CoreAccountInfo& account_info) const;
// Looks up and returns information for account with given |account_id|. If
// the account cannot be found, return an empty optional. This is equivalent
// to searching on the vector returned by GetAccountsWithRefreshTokens() but
// without allocating memory for the vector.
- base::Optional<AccountInfo>
+ absl::optional<AccountInfo>
FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId(
const CoreAccountId& account_id) const;
@@ -269,7 +275,7 @@ class IdentityManager : public KeyedService,
// the account cannot be found, return an empty optional. This is equivalent
// to searching on the vector returned by GetAccountsWithRefreshTokens() but
// without allocating memory for the vector.
- base::Optional<AccountInfo>
+ absl::optional<AccountInfo>
FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
const std::string& email_address) const;
@@ -277,7 +283,7 @@ class IdentityManager : public KeyedService,
// account cannot be found, return an empty optional. This is equivalent to
// searching on the vector returned by GetAccountsWithRefreshTokens() but
// without allocating memory for the vector.
- base::Optional<AccountInfo>
+ absl::optional<AccountInfo>
FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId(
const std::string& gaia_id) const;
@@ -486,10 +492,8 @@ class IdentityManager : public KeyedService,
private:
// 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);
+ const std::string& email,
+ ConsentLevel consent_level);
friend void SetRefreshTokenForPrimaryAccount(
IdentityManager* identity_manager,
const std::string& token_value);
@@ -499,7 +503,8 @@ class IdentityManager : public KeyedService,
IdentityManager* identity_manager);
friend AccountInfo MakePrimaryAccountAvailable(
IdentityManager* identity_manager,
- const std::string& email);
+ const std::string& email,
+ ConsentLevel consent_level);
friend void RevokeSyncConsent(IdentityManager* identity_manager);
friend void ClearPrimaryAccount(IdentityManager* identity_manager);
friend AccountInfo MakeAccountAvailable(IdentityManager* 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 cff722fb004..18eef228dd3 100644
--- a/chromium/components/signin/public/identity_manager/identity_manager_builder.cc
+++ b/chromium/components/signin/public/identity_manager/identity_manager_builder.cc
@@ -115,9 +115,11 @@ IdentityManager::InitParameters BuildIdentityManagerInitParameters(
params->pref_service, account_tracker_service.get(),
params->network_connection_tracker, params->account_consistency,
#if BUILDFLAG(IS_CHROMEOS_ASH)
- params->account_manager, params->account_manager_facade,
- params->is_regular_profile,
-#endif
+ params->account_manager,
+#endif // BUILDFLAG(IS_CHROMEOS_ASH)
+#if BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
+ params->account_manager_facade, params->is_regular_profile,
+#endif // BUILDFLAG(IS_CHROMEOS_ASH) || BUILDFLAG(IS_CHROMEOS_LACROS)
#if !defined(OS_ANDROID)
params->delete_signin_cookies_on_exit, params->token_web_data,
#endif
diff --git a/chromium/components/signin/public/identity_manager/identity_manager_builder.h b/chromium/components/signin/public/identity_manager/identity_manager_builder.h
index dfd07ac8789..26818a57ebf 100644
--- a/chromium/components/signin/public/identity_manager/identity_manager_builder.h
+++ b/chromium/components/signin/public/identity_manager/identity_manager_builder.h
@@ -51,6 +51,12 @@ class AccountManagerFacade;
}
#endif
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+namespace account_manager {
+class AccountManagerFacade;
+}
+#endif
+
namespace signin {
enum class AccountConsistencyMethod;
@@ -58,25 +64,31 @@ struct IdentityManagerBuildParams {
IdentityManagerBuildParams();
~IdentityManagerBuildParams();
- AccountConsistencyMethod account_consistency;
+ AccountConsistencyMethod account_consistency =
+ AccountConsistencyMethod::kDisabled;
std::unique_ptr<AccountTrackerService> account_tracker_service;
std::unique_ptr<image_fetcher::ImageDecoder> image_decoder;
- PrefService* local_state;
+ PrefService* local_state = nullptr;
network::NetworkConnectionTracker* network_connection_tracker;
- PrefService* pref_service;
+ PrefService* pref_service = nullptr;
base::FilePath profile_path;
- SigninClient* signin_client;
+ SigninClient* signin_client = nullptr;
std::unique_ptr<ProfileOAuth2TokenService> token_service;
#if !defined(OS_ANDROID)
- bool delete_signin_cookies_on_exit;
+ bool delete_signin_cookies_on_exit = false;
scoped_refptr<TokenWebData> token_web_data;
#endif
#if BUILDFLAG(IS_CHROMEOS_ASH)
- ash::AccountManager* account_manager;
- account_manager::AccountManagerFacade* account_manager_facade;
- bool is_regular_profile;
+ ash::AccountManager* account_manager = nullptr;
+ account_manager::AccountManagerFacade* account_manager_facade = nullptr;
+ bool is_regular_profile = false;
+#endif
+
+#if BUILDFLAG(IS_CHROMEOS_LACROS)
+ account_manager::AccountManagerFacade* account_manager_facade = nullptr;
+ bool is_regular_profile = false;
#endif
#if defined(OS_IOS)
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 bdf6ef105fb..9206820d912 100644
--- a/chromium/components/signin/public/identity_manager/identity_manager_unittest.cc
+++ b/chromium/components/signin/public/identity_manager/identity_manager_unittest.cc
@@ -562,7 +562,7 @@ TEST_F(IdentityManagerTest, PrimaryAccountInfoAtStartup) {
TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSignin) {
ClearPrimaryAccount(identity_manager());
- SetPrimaryAccount(identity_manager(), kTestEmail);
+ SetPrimaryAccount(identity_manager(), kTestEmail, ConsentLevel::kSync);
auto event = identity_manager_observer()->GetPrimaryAccountChangedEvent();
EXPECT_EQ(PrimaryAccountChangeEvent::Type::kSet,
event.GetEventTypeFor(ConsentLevel::kSync));
@@ -598,7 +598,7 @@ TEST_F(IdentityManagerTest, PrimaryAccountInfoAfterSigninAndSignout) {
ClearPrimaryAccount(identity_manager());
// First ensure that the user is signed in from the POV of the
// IdentityManager.
- SetPrimaryAccount(identity_manager(), kTestEmail);
+ SetPrimaryAccount(identity_manager(), kTestEmail, ConsentLevel::kSync);
// Sign the user out and check that the IdentityManager responds
// appropriately.
@@ -642,7 +642,7 @@ TEST_F(IdentityManagerTest,
ClearPrimaryAccount(identity_manager());
// First ensure that the user is signed in from the POV of the
// IdentityManager.
- SetPrimaryAccount(identity_manager(), kTestEmail);
+ SetPrimaryAccount(identity_manager(), kTestEmail, ConsentLevel::kSync);
identity_manager()->account_fetcher_service_->EnableAccountRemovalForTest();
// Revoke the primary's account credentials from the token service and
@@ -1259,8 +1259,7 @@ TEST_F(IdentityManagerTest, RemoveAccessTokenFromCache) {
identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId,
kTestEmail);
identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount(
- primary_account_id());
-
+ primary_account_id(), ConsentLevel::kSync);
SetRefreshTokenForAccount(identity_manager(), primary_account_id(),
"refresh_token");
@@ -1303,7 +1302,7 @@ TEST_F(IdentityManagerTest,
identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId,
kTestEmail);
identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount(
- primary_account_id());
+ primary_account_id(), ConsentLevel::kSync);
SetRefreshTokenForAccount(identity_manager(), primary_account_id(),
"refresh_token");
@@ -1396,7 +1395,7 @@ TEST_F(IdentityManagerTest, ObserveAccessTokenFetch) {
identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId,
kTestEmail);
identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount(
- primary_account_id());
+ primary_account_id(), ConsentLevel::kSync);
SetRefreshTokenForAccount(identity_manager(), primary_account_id(),
"refresh_token");
@@ -1454,7 +1453,7 @@ TEST_F(IdentityManagerTest,
identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId,
kTestEmail);
identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount(
- primary_account_id());
+ primary_account_id(), ConsentLevel::kSync);
SetRefreshTokenForAccount(identity_manager(), primary_account_id(),
"refresh_token");
token_service()->set_auto_post_fetch_response_on_message_loop(true);
@@ -2146,7 +2145,7 @@ TEST_F(IdentityManagerTest,
identity_manager()->GetAccountTrackerService()->SeedAccountInfo(kTestGaiaId,
kTestEmail);
identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount(
- primary_account_id());
+ primary_account_id(), ConsentLevel::kSync);
SetRefreshTokenForAccount(identity_manager(), primary_account_id(),
"refresh_token");
@@ -2157,6 +2156,26 @@ TEST_F(IdentityManagerTest,
identity_manager_observer()->BatchChangeRecords().at(0).at(0));
}
+// Checks that FindExtendedAccountInfoByAccountId() returns information about
+// the account if the account is found or nullopt if there are no accounts with
+// requested |account_id|.
+TEST_F(IdentityManagerTest, FindExtendedAccountInfoByAccountId) {
+ auto account_id =
+ identity_manager()->PickAccountIdForAccount(kTestGaiaId, kTestEmail);
+
+ absl::optional<AccountInfo> maybe_account_info;
+ maybe_account_info = identity_manager()->FindExtendedAccountInfoByAccountId(
+ CoreAccountId("dummy_value"));
+ EXPECT_FALSE(maybe_account_info.has_value());
+
+ maybe_account_info =
+ identity_manager()->FindExtendedAccountInfoByAccountId(account_id);
+ EXPECT_TRUE(maybe_account_info.has_value());
+ EXPECT_EQ(account_id, maybe_account_info.value().account_id);
+ EXPECT_EQ(kTestEmail, maybe_account_info.value().email);
+ EXPECT_EQ(kTestGaiaId, maybe_account_info.value().gaia);
+}
+
// Checks that FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId()
// returns information about the account if the account is found or nullopt if
// there are no accounts with requested |account_id|.
@@ -2167,7 +2186,7 @@ TEST_F(IdentityManagerTest,
const AccountInfo foo_account_info =
MakeAccountAvailable(identity_manager(), "foo@bar.com");
- base::Optional<AccountInfo> maybe_account_info;
+ absl::optional<AccountInfo> maybe_account_info;
maybe_account_info =
identity_manager()
->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId(
@@ -2194,7 +2213,7 @@ TEST_F(IdentityManagerTest,
const AccountInfo foo_account_info =
MakeAccountAvailable(identity_manager(), "foo@bar.com");
- base::Optional<AccountInfo> maybe_account_info;
+ absl::optional<AccountInfo> maybe_account_info;
maybe_account_info =
identity_manager()
->FindExtendedAccountInfoForAccountWithRefreshTokenByEmailAddress(
@@ -2221,7 +2240,7 @@ TEST_F(IdentityManagerTest,
const AccountInfo foo_account_info =
MakeAccountAvailable(identity_manager(), "foo@bar.com");
- base::Optional<AccountInfo> maybe_account_info;
+ absl::optional<AccountInfo> maybe_account_info;
maybe_account_info =
identity_manager()
->FindExtendedAccountInfoForAccountWithRefreshTokenByGaiaId(
@@ -2375,7 +2394,7 @@ TEST_F(IdentityManagerTest, FindExtendedAccountInfoForAccountWithRefreshToken) {
// FindExtendedAccountInfoForAccountWithRefreshToken() returns extended
// account information if the account is known and has valid refresh token.
- const base::Optional<AccountInfo> extended_account_info =
+ const absl::optional<AccountInfo> extended_account_info =
identity_manager()->FindExtendedAccountInfoForAccountWithRefreshToken(
account_info);
@@ -2388,9 +2407,9 @@ TEST_F(IdentityManagerTest, FindExtendedAccountInfoForAccountWithRefreshToken) {
#if defined(OS_ANDROID)
TEST_F(IdentityManagerTest, ForceRefreshOfExtendedAccountInfo) {
// The flow of this test results in an interaction with
- // ChildAccountInfoFetcherAndroid, which requires initialization in order to
- // avoid a crash.
- ChildAccountInfoFetcherAndroid::InitializeForTests();
+ // ChildAccountInfoFetcherAndroid, which requires initialization of
+ // AccountManagerFacade in java code to avoid a crash.
+ SetUpMockAccountManagerFacade();
identity_manager()->GetAccountFetcherService()->OnNetworkInitialized();
AccountInfo account_info =
diff --git a/chromium/components/signin/public/identity_manager/identity_mutator.cc b/chromium/components/signin/public/identity_manager/identity_mutator.cc
index fe5b5bac5c9..094e4406a8f 100644
--- a/chromium/components/signin/public/identity_manager/identity_mutator.cc
+++ b/chromium/components/signin/public/identity_manager/identity_mutator.cc
@@ -29,20 +29,10 @@ bool JniIdentityMutator::SetPrimaryAccount(
PrimaryAccountMutator* primary_account_mutator =
identity_mutator_->GetPrimaryAccountMutator();
DCHECK(primary_account_mutator);
- // TODO(https://crbug.com/1046746): Refactor PrimaryAccountMutator API and
- // pass ConsentLevel directly there.
- switch (static_cast<ConsentLevel>(j_consent_level)) {
- case ConsentLevel::kSync:
- return primary_account_mutator->SetPrimaryAccount(
- ConvertFromJavaCoreAccountId(env, primary_account_id));
- case ConsentLevel::kSignin:
- primary_account_mutator->SetUnconsentedPrimaryAccount(
- ConvertFromJavaCoreAccountId(env, primary_account_id));
- return true;
- default:
- NOTREACHED() << "Unknown consent level: " << j_consent_level;
- return false;
- }
+
+ return primary_account_mutator->SetPrimaryAccount(
+ ConvertFromJavaCoreAccountId(env, primary_account_id),
+ static_cast<ConsentLevel>(j_consent_level));
}
bool JniIdentityMutator::ClearPrimaryAccount(JNIEnv* env,
@@ -62,7 +52,7 @@ void JniIdentityMutator::ReloadAllAccountsFromSystemWithPrimaryAccount(
DeviceAccountsSynchronizer* device_accounts_synchronizer =
identity_mutator_->GetDeviceAccountsSynchronizer();
DCHECK(device_accounts_synchronizer);
- base::Optional<CoreAccountId> primary_account_id;
+ absl::optional<CoreAccountId> primary_account_id;
if (j_primary_account_id) {
primary_account_id =
ConvertFromJavaCoreAccountId(env, j_primary_account_id);
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 d5bd7fee328..72280aa9e8a 100644
--- a/chromium/components/signin/public/identity_manager/identity_test_environment.cc
+++ b/chromium/components/signin/public/identity_manager/identity_test_environment.cc
@@ -376,12 +376,14 @@ void IdentityTestEnvironment::WaitForRefreshTokensLoaded() {
CoreAccountInfo IdentityTestEnvironment::SetPrimaryAccount(
const std::string& email) {
- return signin::SetPrimaryAccount(identity_manager(), email);
+ return signin::SetPrimaryAccount(identity_manager(), email,
+ signin::ConsentLevel::kSync);
}
CoreAccountInfo IdentityTestEnvironment::SetUnconsentedPrimaryAccount(
const std::string& email) {
- return signin::SetUnconsentedPrimaryAccount(identity_manager(), email);
+ return signin::SetPrimaryAccount(identity_manager(), email,
+ signin::ConsentLevel::kSignin);
}
void IdentityTestEnvironment::SetRefreshTokenForPrimaryAccount() {
@@ -398,7 +400,8 @@ void IdentityTestEnvironment::RemoveRefreshTokenForPrimaryAccount() {
AccountInfo IdentityTestEnvironment::MakePrimaryAccountAvailable(
const std::string& email) {
- return signin::MakePrimaryAccountAvailable(identity_manager(), email);
+ return signin::MakePrimaryAccountAvailable(identity_manager(), email,
+ signin::ConsentLevel::kSync);
}
AccountInfo IdentityTestEnvironment::MakeUnconsentedPrimaryAccountAvailable(
@@ -408,8 +411,8 @@ AccountInfo IdentityTestEnvironment::MakeUnconsentedPrimaryAccountAvailable(
// 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);
+ identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount(
+ account_info.account_id, signin::ConsentLevel::kSignin);
#elif defined(OS_IOS)
// iOS only support the primary account.
AccountInfo account_info = MakePrimaryAccountAvailable(email);
@@ -421,9 +424,8 @@ AccountInfo IdentityTestEnvironment::MakeUnconsentedPrimaryAccountAvailable(
// Tests that don't use the |SigninManager| needs the unconsented primary
// account to be set manually.
if (!identity_manager()->HasPrimaryAccount(ConsentLevel::kSignin)) {
- identity_manager()
- ->GetPrimaryAccountMutator()
- ->SetUnconsentedPrimaryAccount(account_info.account_id);
+ identity_manager()->GetPrimaryAccountMutator()->SetPrimaryAccount(
+ account_info.account_id, signin::ConsentLevel::kSignin);
}
#endif
DCHECK(identity_manager()->HasPrimaryAccount(ConsentLevel::kSignin));
@@ -491,7 +493,7 @@ void IdentityTestEnvironment::
const std::string& token,
const base::Time& expiration,
const std::string& id_token) {
- WaitForAccessTokenRequestIfNecessary(base::nullopt);
+ WaitForAccessTokenRequestIfNecessary(absl::nullopt);
fake_token_service()->IssueTokenForAllPendingRequests(
TokenResponseBuilder()
.WithAccessToken(token)
@@ -521,7 +523,7 @@ void IdentityTestEnvironment::
const base::Time& expiration,
const std::string& id_token,
const ScopeSet& scopes) {
- WaitForAccessTokenRequestIfNecessary(base::nullopt);
+ WaitForAccessTokenRequestIfNecessary(absl::nullopt);
fake_token_service()->IssueTokenForScope(scopes,
TokenResponseBuilder()
.WithAccessToken(token)
@@ -533,7 +535,7 @@ void IdentityTestEnvironment::
void IdentityTestEnvironment::
WaitForAccessTokenRequestIfNecessaryAndRespondWithError(
const GoogleServiceAuthError& error) {
- WaitForAccessTokenRequestIfNecessary(base::nullopt);
+ WaitForAccessTokenRequestIfNecessary(absl::nullopt);
fake_token_service()->IssueErrorForAllPendingRequests(error);
}
@@ -611,7 +613,7 @@ void IdentityTestEnvironment::HandleOnAccessTokenRequested(
}
void IdentityTestEnvironment::WaitForAccessTokenRequestIfNecessary(
- base::Optional<CoreAccountId> account_id) {
+ absl::optional<CoreAccountId> account_id) {
// Handle HandleOnAccessTokenRequested getting called before
// WaitForAccessTokenRequestIfNecessary.
if (account_id) {
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 48054519d75..5db0d967ae9 100644
--- a/chromium/components/signin/public/identity_manager/identity_test_environment.h
+++ b/chromium/components/signin/public/identity_manager/identity_test_environment.h
@@ -10,7 +10,6 @@
#include <vector>
#include "base/callback.h"
-#include "base/optional.h"
#include "base/scoped_observation.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
@@ -19,6 +18,7 @@
#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"
+#include "third_party/abseil-cpp/absl/types/optional.h"
class FakeProfileOAuth2TokenService;
class IdentityTestEnvironmentProfileAdaptor;
@@ -346,7 +346,7 @@ class IdentityTestEnvironment : public IdentityManager::DiagnosticsObserver,
kPending,
kAvailable,
} state;
- base::Optional<CoreAccountId> account_id;
+ absl::optional<CoreAccountId> account_id;
base::OnceClosure on_available;
};
@@ -421,7 +421,7 @@ class IdentityTestEnvironment : public IdentityManager::DiagnosticsObserver,
// Otherwise and runs a nested runloop until a matching access token request
// is observed.
void WaitForAccessTokenRequestIfNecessary(
- base::Optional<CoreAccountId> account_id);
+ absl::optional<CoreAccountId> account_id);
// Returns the FakeProfileOAuth2TokenService owned by IdentityManager.
FakeProfileOAuth2TokenService* fake_token_service();
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 5562e06d554..81c68a3fcca 100644
--- a/chromium/components/signin/public/identity_manager/identity_test_utils.cc
+++ b/chromium/components/signin/public/identity_manager/identity_test_utils.cc
@@ -16,7 +16,6 @@
#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/primary_account_mutator.h"
#include "components/signin/public/identity_manager/test_identity_manager_observer.h"
@@ -132,26 +131,9 @@ void WaitForRefreshTokensLoaded(IdentityManager* identity_manager) {
}
CoreAccountInfo SetPrimaryAccount(IdentityManager* identity_manager,
- const std::string& email) {
- DCHECK(!identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
- PrimaryAccountManager* primary_account_manager =
- identity_manager->GetPrimaryAccountManager();
- DCHECK(!primary_account_manager->HasPrimaryAccount(ConsentLevel::kSync));
-
- AccountInfo account_info =
- EnsureAccountExists(identity_manager->GetAccountTrackerService(), email);
- DCHECK(!account_info.gaia.empty());
-
- primary_account_manager->SetSyncPrimaryAccountInfo(account_info);
-
- DCHECK(primary_account_manager->HasPrimaryAccount(ConsentLevel::kSync));
- DCHECK(identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
- return identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSync);
-}
-
-CoreAccountInfo SetUnconsentedPrimaryAccount(IdentityManager* identity_manager,
- const std::string& email) {
- DCHECK(!identity_manager->HasPrimaryAccount(ConsentLevel::kSignin));
+ const std::string& email,
+ ConsentLevel consent_level) {
+ DCHECK(!identity_manager->HasPrimaryAccount(consent_level));
AccountInfo account_info =
EnsureAccountExists(identity_manager->GetAccountTrackerService(), email);
@@ -159,48 +141,54 @@ CoreAccountInfo SetUnconsentedPrimaryAccount(IdentityManager* identity_manager,
PrimaryAccountManager* primary_account_manager =
identity_manager->GetPrimaryAccountManager();
- primary_account_manager->SetUnconsentedPrimaryAccountInfo(account_info);
-
- DCHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kSignin));
- DCHECK_EQ(
- account_info.gaia,
- identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
- .gaia);
- return identity_manager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin);
+ switch (consent_level) {
+ case ConsentLevel::kSync:
+ primary_account_manager->SetSyncPrimaryAccountInfo(account_info);
+ break;
+ case ConsentLevel::kSignin:
+ primary_account_manager->SetUnconsentedPrimaryAccountInfo(account_info);
+ }
+
+ DCHECK(identity_manager->HasPrimaryAccount(consent_level));
+ DCHECK_EQ(account_info.gaia,
+ identity_manager->GetPrimaryAccountInfo(consent_level).gaia);
+ return identity_manager->GetPrimaryAccountInfo(consent_level);
}
void SetRefreshTokenForPrimaryAccount(IdentityManager* identity_manager,
const std::string& token_value) {
- DCHECK(identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
+ DCHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
CoreAccountId account_id =
- identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSync);
+ identity_manager->GetPrimaryAccountId(ConsentLevel::kSync);
SetRefreshTokenForAccount(identity_manager, account_id, token_value);
}
void SetInvalidRefreshTokenForPrimaryAccount(
IdentityManager* identity_manager) {
- DCHECK(identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
+ DCHECK(identity_manager->HasPrimaryAccount(ConsentLevel::kSync));
CoreAccountId account_id =
- identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSync);
+ identity_manager->GetPrimaryAccountId(ConsentLevel::kSync);
SetInvalidRefreshTokenForAccount(identity_manager, account_id);
}
void RemoveRefreshTokenForPrimaryAccount(IdentityManager* identity_manager) {
- if (!identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync))
+ if (!identity_manager->HasPrimaryAccount(ConsentLevel::kSync))
return;
CoreAccountId account_id =
- identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSync);
+ identity_manager->GetPrimaryAccountId(ConsentLevel::kSync);
RemoveRefreshTokenForAccount(identity_manager, account_id);
}
AccountInfo MakePrimaryAccountAvailable(IdentityManager* identity_manager,
- const std::string& email) {
- CoreAccountInfo account_info = SetPrimaryAccount(identity_manager, email);
+ const std::string& email,
+ ConsentLevel consent_level) {
+ CoreAccountInfo account_info =
+ SetPrimaryAccount(identity_manager, email, consent_level);
SetRefreshTokenForPrimaryAccount(identity_manager);
- base::Optional<AccountInfo> primary_account_info =
+ absl::optional<AccountInfo> primary_account_info =
identity_manager
->FindExtendedAccountInfoForAccountWithRefreshTokenByAccountId(
account_info.account_id);
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 619d83be4f0..40dc2edc7e6 100644
--- a/chromium/components/signin/public/identity_manager/identity_test_utils.h
+++ b/chromium/components/signin/public/identity_manager/identity_test_utils.h
@@ -10,6 +10,7 @@
#include "base/bind.h"
#include "build/build_config.h"
#include "components/signin/public/identity_manager/account_info.h"
+#include "components/signin/public/identity_manager/consent_level.h"
namespace network {
class TestURLLoaderFactory;
@@ -39,18 +40,15 @@ class IdentityManager;
void WaitForRefreshTokensLoaded(IdentityManager* identity_manager);
// Sets the primary account (which must not already be set) to the given email
-// address, generating a GAIA ID that corresponds uniquely to that email
-// address. On non-ChromeOS, results in the firing of the IdentityManager and
-// PrimaryAccountManager callbacks for signin success. Blocks until the primary
-// account is set. Returns the CoreAccountInfo of the newly-set account.
+// address with corresponding consent level, generating a GAIA ID that
+// corresponds uniquely to that email address. On non-ChromeOS, results in the
+// firing of the IdentityManager and PrimaryAccountManager callbacks for signin
+// success. Blocks until the primary account is set. Returns the CoreAccountInfo
+// of the newly-set account.
// NOTE: See disclaimer at top of file re: direct usage.
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);
+ const std::string& email,
+ ConsentLevel consent_level);
// 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
@@ -78,7 +76,8 @@ void RemoveRefreshTokenForPrimaryAccount(IdentityManager* identity_manager);
// newly-available account.
// NOTE: See disclaimer at top of file re: direct usage.
AccountInfo MakePrimaryAccountAvailable(IdentityManager* identity_manager,
- const std::string& email);
+ const std::string& email,
+ ConsentLevel consent_level);
// Revokes sync consent from the primary account: the primary account is left
// at ConsentLevel::kSignin.
diff --git a/chromium/components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h b/chromium/components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h
index 975eccf41a5..3af5f868746 100644
--- a/chromium/components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h
+++ b/chromium/components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h
@@ -6,7 +6,6 @@
#define COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_OBJC_IDENTITY_MANAGER_OBSERVER_BRIDGE_H_
#import <Foundation/Foundation.h>
-#include <vector>
#include "components/signin/public/identity_manager/identity_manager.h"
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 0675918925b..f05f22c7a9a 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
@@ -166,7 +166,7 @@ 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
+ // Returns the primary account ID. If consent is |kSignin| this may be
// the "unconsented" primary account ID.
CoreAccountId GetAccountId() const;
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 9695b5993b8..604daa2ab88 100644
--- a/chromium/components/signin/public/identity_manager/primary_account_mutator.h
+++ b/chromium/components/signin/public/identity_manager/primary_account_mutator.h
@@ -5,8 +5,6 @@
#ifndef COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_PRIMARY_ACCOUNT_MUTATOR_H_
#define COMPONENTS_SIGNIN_PUBLIC_IDENTITY_MANAGER_PRIMARY_ACCOUNT_MUTATOR_H_
-#include <string>
-
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
@@ -18,6 +16,7 @@ enum class SignoutDelete;
struct CoreAccountId;
namespace signin {
+enum class ConsentLevel;
// PrimaryAccountMutator is the interface to set and clear the primary account
// (see IdentityManager for more information).
@@ -40,6 +39,7 @@ class PrimaryAccountMutator {
PrimaryAccountMutator const& operator=(const PrimaryAccountMutator& other) =
delete;
+ // For ConsentLevel::kSync -
// Marks the account with |account_id| as the primary account, and returns
// whether the operation succeeded or not. To succeed, this requires that:
// - the account is known by the IdentityManager.
@@ -49,14 +49,14 @@ class PrimaryAccountMutator {
// - there is not already a primary account set.
// TODO(https://crbug.com/983124): Investigate adding all the extra
// requirements on ChromeOS as well.
- virtual bool SetPrimaryAccount(const CoreAccountId& account_id) = 0;
-
+ //
+ // For ConsentLevel::kSignin -
// 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;
+ // of "unconsented". Returns whether the operation succeeded or not.
+ virtual bool SetPrimaryAccount(const CoreAccountId& account_id,
+ ConsentLevel consent_level) = 0;
// Revokes sync consent from the primary account. We distinguish the following
// cases:
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 d77e1876dc3..68288e3474b 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
@@ -127,8 +127,8 @@ void RunRevokeConsentTest(
identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
AccountInfo account_info =
environment.MakeAccountAvailable(kPrimaryAccountEmail);
- EXPECT_TRUE(
- primary_account_mutator->SetPrimaryAccount(account_info.account_id));
+ EXPECT_TRUE(primary_account_mutator->SetPrimaryAccount(
+ account_info.account_id, signin::ConsentLevel::kSync));
EXPECT_TRUE(identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
EXPECT_TRUE(identity_manager->HasPrimaryAccountWithRefreshToken(
signin::ConsentLevel::kSync));
@@ -265,8 +265,8 @@ TEST_F(PrimaryAccountMutatorTest, SetPrimaryAccount) {
EXPECT_FALSE(environment.identity_manager()->HasPrimaryAccount(
signin::ConsentLevel::kSync));
- EXPECT_TRUE(
- primary_account_mutator->SetPrimaryAccount(account_info.account_id));
+ EXPECT_TRUE(primary_account_mutator->SetPrimaryAccount(
+ account_info.account_id, signin::ConsentLevel::kSync));
EXPECT_TRUE(identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
EXPECT_EQ(identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSync),
@@ -297,7 +297,7 @@ TEST_F(PrimaryAccountMutatorTest, SetPrimaryAccount_NoAccount) {
EXPECT_FALSE(
identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
EXPECT_FALSE(primary_account_mutator->SetPrimaryAccount(
- CoreAccountId(kUnknownAccountId)));
+ CoreAccountId(kUnknownAccountId), signin::ConsentLevel::kSync));
}
// Checks that setting the primary account fails if the account is unknown.
@@ -320,7 +320,7 @@ TEST_F(PrimaryAccountMutatorTest, SetPrimaryAccount_UnknownAccount) {
EXPECT_FALSE(
identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
EXPECT_FALSE(primary_account_mutator->SetPrimaryAccount(
- CoreAccountId(kUnknownAccountId)));
+ CoreAccountId(kUnknownAccountId), signin::ConsentLevel::kSync));
}
// Checks that trying to set the primary account fails when there is already a
@@ -346,11 +346,11 @@ TEST_F(PrimaryAccountMutatorTest, SetPrimaryAccount_AlreadyHasPrimaryAccount) {
EXPECT_FALSE(
identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
EXPECT_TRUE(primary_account_mutator->SetPrimaryAccount(
- primary_account_info.account_id));
+ primary_account_info.account_id, signin::ConsentLevel::kSync));
EXPECT_TRUE(identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
EXPECT_FALSE(primary_account_mutator->SetPrimaryAccount(
- another_account_info.account_id));
+ another_account_info.account_id, signin::ConsentLevel::kSync));
EXPECT_EQ(identity_manager->GetPrimaryAccountId(signin::ConsentLevel::kSync),
primary_account_info.account_id);
@@ -384,7 +384,7 @@ TEST_F(PrimaryAccountMutatorTest,
EXPECT_FALSE(
identity_manager->HasPrimaryAccount(signin::ConsentLevel::kSync));
EXPECT_FALSE(primary_account_mutator->SetPrimaryAccount(
- primary_account_info.account_id));
+ primary_account_info.account_id, signin::ConsentLevel::kSync));
}
// End of tests of preconditions not being satisfied causing the setting of
diff --git a/chromium/components/signin/public/webdata/token_web_data.cc b/chromium/components/signin/public/webdata/token_web_data.cc
index 9d6077da0ab..a213d159f7c 100644
--- a/chromium/components/signin/public/webdata/token_web_data.cc
+++ b/chromium/components/signin/public/webdata/token_web_data.cc
@@ -13,7 +13,7 @@
#include "components/signin/public/webdata/token_service_table.h"
#include "components/webdata/common/web_database_service.h"
-using base::Bind;
+using base::BindOnce;
using base::Time;
class TokenWebDataBackend
@@ -78,27 +78,28 @@ TokenWebData::TokenWebData(
void TokenWebData::SetTokenForService(const std::string& service,
const std::string& token) {
- wdbs_->ScheduleDBTask(
- FROM_HERE, Bind(&TokenWebDataBackend::SetTokenForService, token_backend_,
- service, token));
+ wdbs_->ScheduleDBTask(FROM_HERE,
+ BindOnce(&TokenWebDataBackend::SetTokenForService,
+ token_backend_, service, token));
}
void TokenWebData::RemoveAllTokens() {
wdbs_->ScheduleDBTask(
- FROM_HERE, Bind(&TokenWebDataBackend::RemoveAllTokens, token_backend_));
+ FROM_HERE,
+ BindOnce(&TokenWebDataBackend::RemoveAllTokens, token_backend_));
}
void TokenWebData::RemoveTokenForService(const std::string& service) {
wdbs_->ScheduleDBTask(FROM_HERE,
- Bind(&TokenWebDataBackend::RemoveTokenForService,
- token_backend_, service));
+ BindOnce(&TokenWebDataBackend::RemoveTokenForService,
+ token_backend_, service));
}
// Null on failure. Success is WDResult<std::string>
WebDataServiceBase::Handle TokenWebData::GetAllTokens(
WebDataServiceConsumer* consumer) {
return wdbs_->ScheduleDBTaskWithResult(
- FROM_HERE, Bind(&TokenWebDataBackend::GetAllTokens, token_backend_),
+ FROM_HERE, BindOnce(&TokenWebDataBackend::GetAllTokens, token_backend_),
consumer);
}
diff --git a/chromium/components/signin/public/webdata/token_web_data.h b/chromium/components/signin/public/webdata/token_web_data.h
index 680b904ed7c..fdefff11e66 100644
--- a/chromium/components/signin/public/webdata/token_web_data.h
+++ b/chromium/components/signin/public/webdata/token_web_data.h
@@ -13,8 +13,6 @@
#include <string>
#include <vector>
-#include "base/callback_forward.h"
-#include "base/files/file_path.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"