Commit da4c5442 authored by David Roger's avatar David Roger Committed by Commit Bot

[signin] Split Dice and Mirror specific logic out of AccountReconcilor

This CL creates a AccountReconcilorDelegate class, with two subclasses
specialized for Mirror and Dice respectively.

Bug: 777774
Cq-Include-Trybots: master.tryserver.chromium.mac:ios-simulator-cronet;master.tryserver.chromium.mac:ios-simulator-full-configs
Change-Id: I4bdb4ecee7d4f12e910a2704a09802c383bca9bb
Reviewed-on: https://chromium-review.googlesource.com/766368
Commit-Queue: David Roger <droger@chromium.org>
Reviewed-by: default avatarMihai Sardarescu <msarda@chromium.org>
Cr-Commit-Position: refs/heads/master@{#517347}
parent d081f57b
......@@ -4,12 +4,24 @@
#include "chrome/browser/signin/account_reconcilor_factory.h"
#include <utility>
#include "base/logging.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/chrome_signin_client_factory.h"
#include "chrome/browser/signin/gaia_cookie_manager_service_factory.h"
#include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
#include "chrome/browser/signin/signin_manager_factory.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
#include "components/signin/core/browser/mirror_account_reconcilor_delegate.h"
#include "components/signin/core/browser/profile_management_switches.h"
#include "components/signin/core/browser/signin_features.h"
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
#include "components/signin/core/browser/dice_account_reconcilor_delegate.h"
#endif
AccountReconcilorFactory::AccountReconcilorFactory()
: BrowserContextKeyedServiceFactory(
......@@ -43,12 +55,41 @@ KeyedService* AccountReconcilorFactory::BuildServiceInstanceFor(
SigninManagerFactory::GetForProfile(profile),
ChromeSigninClientFactory::GetForProfile(profile),
GaiaCookieManagerServiceFactory::GetForProfile(profile),
profile->IsNewProfile());
CreateAccountReconcilorDelegate(profile));
reconcilor->Initialize(true /* start_reconcile_if_tokens_available */);
return reconcilor;
}
void AccountReconcilorFactory::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
AccountReconcilor::RegisterProfilePrefs(registry);
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
signin::DiceAccountReconcilorDelegate::RegisterProfilePrefs(registry);
#endif
}
// static
std::unique_ptr<signin::AccountReconcilorDelegate>
AccountReconcilorFactory::CreateAccountReconcilorDelegate(Profile* profile) {
std::unique_ptr<signin::AccountReconcilorDelegate> delegate;
switch (signin::GetAccountConsistencyMethod()) {
case signin::AccountConsistencyMethod::kMirror:
delegate = std::make_unique<signin::MirrorAccountReconcilorDelegate>(
SigninManagerFactory::GetForProfile(profile));
break;
case signin::AccountConsistencyMethod::kDisabled:
case signin::AccountConsistencyMethod::kDiceFixAuthErrors:
delegate = std::make_unique<signin::AccountReconcilorDelegate>();
break;
case signin::AccountConsistencyMethod::kDicePrepareMigration:
case signin::AccountConsistencyMethod::kDiceMigration:
case signin::AccountConsistencyMethod::kDice:
#if BUILDFLAG(ENABLE_DICE_SUPPORT)
delegate = std::make_unique<signin::DiceAccountReconcilorDelegate>(
profile->GetPrefs(), profile->IsNewProfile());
#else
NOTREACHED();
#endif
break;
}
return delegate;
}
......@@ -5,10 +5,16 @@
#ifndef CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_FACTORY_H_
#define CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_FACTORY_H_
#include <memory>
#include "base/memory/singleton.h"
#include "components/keyed_service/content/browser_context_keyed_service_factory.h"
#include "components/signin/core/browser/account_reconcilor.h"
namespace signin {
class AccountReconcilorDelegate;
}
class AccountReconcilor;
class Profile;
// Singleton that owns all AccountReconcilors and associates them with
......@@ -25,10 +31,15 @@ class AccountReconcilorFactory : public BrowserContextKeyedServiceFactory {
private:
friend struct base::DefaultSingletonTraits<AccountReconcilorFactory>;
friend class DummyAccountReconcilorWithDelegate; // For testing.
AccountReconcilorFactory();
~AccountReconcilorFactory() override;
// Creates the AccountReconcilorDelegate.
static std::unique_ptr<signin::AccountReconcilorDelegate>
CreateAccountReconcilorDelegate(Profile* profile);
// BrowserContextKeyedServiceFactory:
KeyedService* BuildServiceInstanceFor(
content::BrowserContext* profile) const override;
......
......@@ -42,6 +42,8 @@ static_library("browser") {
"account_investigator.h",
"account_reconcilor.cc",
"account_reconcilor.h",
"account_reconcilor_delegate.cc",
"account_reconcilor_delegate.h",
"account_tracker_service.cc",
"account_tracker_service.h",
"child_account_info_fetcher.cc",
......@@ -52,10 +54,14 @@ static_library("browser") {
"child_account_info_fetcher_impl.h",
"chrome_connected_header_helper.cc",
"chrome_connected_header_helper.h",
"dice_account_reconcilor_delegate.cc",
"dice_account_reconcilor_delegate.h",
"dice_header_helper.cc",
"dice_header_helper.h",
"gaia_cookie_manager_service.cc",
"gaia_cookie_manager_service.h",
"mirror_account_reconcilor_delegate.cc",
"mirror_account_reconcilor_delegate.h",
"profile_identity_provider.cc",
"profile_identity_provider.h",
"profile_management_switches.cc",
......@@ -139,6 +145,8 @@ static_library("browser") {
if (!enable_dice_support) {
sources -= [
"dice_account_reconcilor_delegate.cc",
"dice_account_reconcilor_delegate.h",
"dice_header_helper.cc",
"dice_header_helper.h",
]
......@@ -194,6 +202,7 @@ source_set("unit_tests") {
"account_info_unittest.cc",
"account_investigator_unittest.cc",
"account_tracker_service_unittest.cc",
"dice_account_reconcilor_delegate_unittest.cc",
"gaia_cookie_manager_service_unittest.cc",
"profile_management_switches_unittest.cc",
"refresh_token_annotation_request_unittest.cc",
......@@ -222,6 +231,10 @@ source_set("unit_tests") {
"signin_status_metrics_provider_unittest.cc",
]
}
if (!enable_dice_support) {
sources -= [ "dice_account_reconcilor_delegate_unittest.cc" ]
}
}
if (is_android) {
......
......@@ -4,11 +4,8 @@
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_
#include <functional>
#include <memory>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/callback_forward.h"
......@@ -29,18 +26,17 @@
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/oauth2_token_service.h"
namespace signin {
class AccountReconcilorDelegate;
}
class ProfileOAuth2TokenService;
class SigninClient;
namespace user_prefs {
class PrefRegistrySyncable;
}
class AccountReconcilor : public KeyedService,
public content_settings::Observer,
public GaiaCookieManagerService::Observer,
public OAuth2TokenService::Observer,
public SigninManagerBase::Observer {
public OAuth2TokenService::Observer {
public:
// When an instance of this class exists, the account reconcilor is suspended.
// It will automatically restart when all instances of Lock have been
......@@ -78,21 +74,21 @@ class AccountReconcilor : public KeyedService,
virtual void OnUnblockReconcile() {}
};
AccountReconcilor(ProfileOAuth2TokenService* token_service,
SigninManagerBase* signin_manager,
SigninClient* client,
GaiaCookieManagerService* cookie_manager_service,
bool is_new_profile);
AccountReconcilor(
ProfileOAuth2TokenService* token_service,
SigninManagerBase* signin_manager,
SigninClient* client,
GaiaCookieManagerService* cookie_manager_service,
std::unique_ptr<signin::AccountReconcilorDelegate> delegate);
~AccountReconcilor() override;
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Initializes the account reconcilor. Should be called once after
// construction.
void Initialize(bool start_reconcile_if_tokens_available);
// Signal that the status of the new_profile_management flag has changed.
// Pass the new status as an explicit parameter since disabling the flag
// doesn't remove it from the CommandLine::ForCurrentProcess().
void OnNewProfileManagementFlagChanged(bool new_flag_status);
// Enables and disables the reconciliation.
void EnableReconcile();
void DisableReconcile(bool logout_all_gaia_accounts);
// Signal that an X-Chrome-Manage-Accounts was received from GAIA. Pass the
// ServiceType specified by GAIA in the 204 response.
......@@ -161,7 +157,6 @@ class AccountReconcilor : public KeyedService,
AddAccountToCookieCompletedWithBogusAccount);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, NoLoopWithBadPrimary);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, WontMergeAccountsWithError);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorMigrationTest, MigrateAtCreation);
bool IsRegisteredWithTokenService() const {
return registered_with_token_service_;
......@@ -177,13 +172,6 @@ class AccountReconcilor : public KeyedService,
void RegisterWithContentSettings();
void UnregisterWithContentSettings();
// The reconcilor is enabled if Sync or Dice is enabled.
bool IsEnabled();
// Returns true if account consistency is enforced (Mirror or Dice).
// If this is false, reconcile is done, but its results are discarded and no
// changes to the accounts are made.
bool IsAccountConsistencyEnforced();
// 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 std::string& account_id);
......@@ -199,20 +187,18 @@ class AccountReconcilor : public KeyedService,
// Revokes tokens for all accounts in chrome_accounts_ but primary_account_.
void RevokeAllSecondaryTokens();
void ValidateAccountsFromTokenService();
// Returns the list of valid accounts from the TokenService.
// The primary account is returned in |out_primary_account| if any.
std::vector<std::string> LoadValidAccountsFromTokenService(
std::string* out_primary_account,
bool* out_is_primary_account_valid) const;
// Note internally that this |account_id| is added to the cookie jar.
bool MarkAccountAsAddedToCookie(const std::string& account_id);
// The reconcilor only starts when the token service is ready.
bool IsTokenServiceReady();
// Returns the first account to add in the Gaia cookie.
// If this returns an empty string, the user must be logged out of all
// accounts.
// |gaia_accounts| are the current accounts in the Gaia cookie.
std::string GetFirstGaiaAccountForReconcile(
const std::vector<gaia::ListedAccount>& gaia_accounts) const;
// Overriden from content_settings::Observer.
void OnContentSettingChanged(
const ContentSettingsPattern& primary_pattern,
......@@ -233,12 +219,6 @@ class AccountReconcilor : public KeyedService,
void OnEndBatchChanges() override;
void OnRefreshTokensLoaded() override;
// Overriden from SigninManagerBase::Observer.
void GoogleSigninSucceeded(const std::string& account_id,
const std::string& username) override;
void GoogleSignedOut(const std::string& account_id,
const std::string& username) override;
// Lock related methods.
void IncrementLockCount();
void DecrementLockCount();
......@@ -246,11 +226,7 @@ class AccountReconcilor : public KeyedService,
void UnblockReconcile();
bool IsReconcileBlocked() const;
// Dice migration methods:
// Returns true if migration can happen on the next startup.
bool IsReadyForDiceMigration(bool is_new_profile);
// Schedules migration to happen at next startup.
static void SetDiceMigrationOnStartup(PrefService* prefs, bool migrate);
std::unique_ptr<signin::AccountReconcilorDelegate> delegate_;
// The ProfileOAuth2TokenService associated with this reconcilor.
ProfileOAuth2TokenService* token_service_;
......@@ -289,8 +265,6 @@ class AccountReconcilor : public KeyedService,
std::vector<std::string> chrome_accounts_;
std::vector<std::string> add_to_cookie_;
bool chrome_accounts_changed_;
// Last known "first account". Used when cookies are lost as a best guess.
std::string last_known_first_account_;
// Used for the Lock.
// StartReconcile() is blocked while this is > 0.
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/account_reconcilor_delegate.h"
namespace signin {
bool AccountReconcilorDelegate::IsReconcileEnabled() const {
return false;
}
bool AccountReconcilorDelegate::IsAccountConsistencyEnforced() const {
return false;
}
bool AccountReconcilorDelegate::ShouldAbortReconcileIfPrimaryHasError() const {
return false;
}
std::string AccountReconcilorDelegate::GetFirstGaiaAccountForReconcile(
const std::vector<std::string>& chrome_accounts,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const std::string& primary_account,
bool first_execution) const {
return std::string();
}
} // namespace signin
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_DELEGATE_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_DELEGATE_H_
#include <string>
#include <vector>
#include "google_apis/gaia/gaia_auth_util.h"
class AccountReconcilor;
namespace signin {
// Base class for AccountReconcilorDelegate.
class AccountReconcilorDelegate {
public:
virtual ~AccountReconcilorDelegate() {}
// Returns true if the reconcilor should reconcile the profile. Defaults to
// false.
virtual bool IsReconcileEnabled() const;
// Returns true if account consistency is enforced (Mirror or Dice).
// If this is false, reconcile is done, but its results are discarded and no
// changes to the accounts are made. Defaults to false.
virtual bool IsAccountConsistencyEnforced() const;
// Returns true if Reconcile should be aborted when the primary account is in
// error state. Defaults to false.
virtual bool ShouldAbortReconcileIfPrimaryHasError() const;
// Returns the first account to add in the Gaia cookie.
// If this returns an empty string, the user must be logged out of all
// accounts.
virtual std::string GetFirstGaiaAccountForReconcile(
const std::vector<std::string>& chrome_accounts,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const std::string& primary_account,
bool first_execution) const;
// Called when reconcile is finished.
virtual void OnReconcileFinished(const std::string& first_account,
bool reconcile_is_noop) {}
void set_reconcilor(AccountReconcilor* reconcilor) {
reconcilor_ = reconcilor;
}
AccountReconcilor* reconcilor() { return reconcilor_; }
private:
AccountReconcilor* reconcilor_;
};
} // namespace signin
#endif // COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_DELEGATE_H_
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/dice_account_reconcilor_delegate.h"
#include <vector>
#include "base/logging.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "components/signin/core/browser/profile_management_switches.h"
namespace signin {
namespace {
// Preference indicating that the Dice migration should happen at the next
// Chrome startup.
const char kDiceMigrationOnStartupPref[] =
"signin.AccountReconcilor.kDiceMigrationOnStartup";
const char kDiceMigrationStatusHistogram[] = "Signin.DiceMigrationStatus";
// Used for UMA histogram kDiceMigrationStatusHistogram.
// Do not remove or re-order values.
enum class DiceMigrationStatus {
kEnabled,
kDisabledReadyForMigration,
kDisabledNotReadyForMigration,
// This is the last value. New values should be inserted above.
kDiceMigrationStatusCount
};
} // namespace
DiceAccountReconcilorDelegate::DiceAccountReconcilorDelegate(
PrefService* user_prefs,
bool is_new_profile)
: user_prefs_(user_prefs) {
DCHECK(user_prefs_);
bool is_ready_for_dice = IsReadyForDiceMigration(is_new_profile);
if (is_ready_for_dice && IsDiceMigrationEnabled()) {
if (!IsDiceEnabledForProfile(user_prefs_))
VLOG(1) << "Profile is migrating to Dice";
MigrateProfileToDice(user_prefs_);
DCHECK(IsDiceEnabledForProfile(user_prefs_));
}
UMA_HISTOGRAM_ENUMERATION(
kDiceMigrationStatusHistogram,
IsDiceEnabledForProfile(user_prefs_)
? DiceMigrationStatus::kEnabled
: (is_ready_for_dice
? DiceMigrationStatus::kDisabledReadyForMigration
: DiceMigrationStatus::kDisabledNotReadyForMigration),
DiceMigrationStatus::kDiceMigrationStatusCount);
}
// static
void DiceAccountReconcilorDelegate::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(kDiceMigrationOnStartupPref, false);
}
// static
void DiceAccountReconcilorDelegate::SetDiceMigrationOnStartup(
PrefService* prefs,
bool migrate) {
VLOG(1) << "Dice migration on next startup: " << migrate;
prefs->SetBoolean(kDiceMigrationOnStartupPref, migrate);
}
bool DiceAccountReconcilorDelegate::IsReadyForDiceMigration(
bool is_new_profile) {
return is_new_profile || user_prefs_->GetBoolean(kDiceMigrationOnStartupPref);
}
bool DiceAccountReconcilorDelegate::IsReconcileEnabled() const {
return IsDicePrepareMigrationEnabled();
}
bool DiceAccountReconcilorDelegate::IsAccountConsistencyEnforced() const {
return IsDiceEnabledForProfile(user_prefs_);
}
// - On first execution, the candidates are examined in this order:
// 1. The primary account
// 2. The current first Gaia account
// 3. The last known first Gaia account
// 4. The first account in the token service
// - On subsequent executions, the order is:
// 1. The current first Gaia account
// 2. The primary account
// 3. The last known first Gaia account
// 4. The first account in the token service
std::string DiceAccountReconcilorDelegate::GetFirstGaiaAccountForReconcile(
const std::vector<std::string>& chrome_accounts,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const std::string& primary_account,
bool first_execution) const {
if (chrome_accounts.empty())
return std::string(); // No Chrome account, log out.
bool valid_primary_account =
!primary_account.empty() &&
base::ContainsValue(chrome_accounts, primary_account);
if (gaia_accounts.empty()) {
if (valid_primary_account)
return primary_account;
// Try the last known account. This happens when the cookies are cleared
// while Sync is disabled.
if (base::ContainsValue(chrome_accounts, last_known_first_account_))
return last_known_first_account_;
// As a last resort, use the first Chrome account.
return chrome_accounts[0];
}
const std::string& first_gaia_account = gaia_accounts[0].id;
bool first_gaia_account_is_valid =
gaia_accounts[0].valid &&
base::ContainsValue(chrome_accounts, first_gaia_account);
if (!first_gaia_account_is_valid && (primary_account == first_gaia_account)) {
// The primary account is also the first Gaia account, and is invalid.
// Logout everything.
return std::string();
}
if (first_execution) {
// On first execution, try the primary account, and then the first Gaia
// account.
if (valid_primary_account)
return primary_account;
if (first_gaia_account_is_valid)
return first_gaia_account;
// As a last resort, use the first Chrome account.
return chrome_accounts[0];
}
// While Chrome is running, try the first Gaia account, and then the
// primary account.
if (first_gaia_account_is_valid)
return first_gaia_account;
if (valid_primary_account)
return primary_account;
// Changing the first Gaia account while Chrome is running would be
// confusing for the user. Logout everything.
return std::string();
}
void DiceAccountReconcilorDelegate::OnReconcileFinished(
const std::string& first_account,
bool reconcile_is_noop) {
last_known_first_account_ = first_account;
// Migration happens on startup if the last reconcile was a no-op.
if (IsDicePrepareMigrationEnabled())
SetDiceMigrationOnStartup(user_prefs_, reconcile_is_noop);
}
} // namespace signin
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SIGNIN_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"
namespace user_prefs {
class PrefRegistrySyncable;
}
class PrefService;
namespace signin {
// AccountReconcilorDelegate specialized for Dice.
class DiceAccountReconcilorDelegate : public AccountReconcilorDelegate {
public:
DiceAccountReconcilorDelegate(PrefService* user_prefs, bool is_new_profile);
~DiceAccountReconcilorDelegate() override {}
static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
// Dice migration methods, public for testing:
// Schedules migration to happen at next startup.
static void SetDiceMigrationOnStartup(PrefService* prefs, bool migrate);
// Returns true if migration can happen on the next startup.
bool IsReadyForDiceMigration(bool is_new_profile);
// AccountReconcilorDelegate:
bool IsReconcileEnabled() const override;
bool IsAccountConsistencyEnforced() const override;
std::string GetFirstGaiaAccountForReconcile(
const std::vector<std::string>& chrome_accounts,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const std::string& primary_account,
bool first_execution) const override;
void OnReconcileFinished(const std::string& first_account,
bool reconcile_is_noop) override;
private:
PrefService* user_prefs_;
// Last known "first account". Used when cookies are lost as a best guess.
std::string last_known_first_account_;
DISALLOW_COPY_AND_ASSIGN(DiceAccountReconcilorDelegate);
};
} // namespace signin
#endif // COMPONENTS_SIGNIN_CORE_BROWSER_DICE_ACCOUNT_RECONCILOR_DELEGATE_H_
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/dice_account_reconcilor_delegate.h"
#include "components/signin/core/browser/profile_management_switches.h"
#include "components/signin/core/browser/scoped_account_consistency.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gtest/include/gtest/gtest.h"
// Checks that Dice migration happens when the reconcilor is created.
TEST(DiceAccountReconcilorDelegateTest, MigrateAtCreation) {
sync_preferences::TestingPrefServiceSyncable pref_service;
signin::DiceAccountReconcilorDelegate::RegisterProfilePrefs(
pref_service.registry());
signin::RegisterAccountConsistencyProfilePrefs(pref_service.registry());
{
// Migration does not happen if SetDiceMigrationOnStartup() is not called.
signin::ScopedAccountConsistencyDiceMigration scoped_dice_migration;
EXPECT_FALSE(signin::IsDiceEnabledForProfile(&pref_service));
signin::DiceAccountReconcilorDelegate delegate(&pref_service, false);
EXPECT_FALSE(delegate.IsReadyForDiceMigration(false /* is_new_profile */));
EXPECT_FALSE(signin::IsDiceEnabledForProfile(&pref_service));
}
signin::DiceAccountReconcilorDelegate::SetDiceMigrationOnStartup(
&pref_service, true);
{
// Migration does not happen if Dice is not enabled.
signin::ScopedAccountConsistencyDiceFixAuthErrors scoped_dice_fix_errors;
EXPECT_FALSE(signin::IsDiceEnabledForProfile(&pref_service));
signin::DiceAccountReconcilorDelegate delegate(&pref_service, false);
EXPECT_TRUE(delegate.IsReadyForDiceMigration(false /* is_new_profile */));
EXPECT_FALSE(signin::IsDiceEnabledForProfile(&pref_service));
}
{
// Migration happens.
signin::ScopedAccountConsistencyDiceMigration scoped_dice_migration;
EXPECT_FALSE(signin::IsDiceEnabledForProfile(&pref_service));
signin::DiceAccountReconcilorDelegate delegate(&pref_service, false);
EXPECT_TRUE(delegate.IsReadyForDiceMigration(false /* is_new_profile */));
EXPECT_TRUE(signin::IsDiceEnabledForProfile(&pref_service));
}
}
// Checks that new profiles are migrated at creation.
TEST(DiceAccountReconcilorDelegateTest, NewProfile) {
signin::ScopedAccountConsistencyDiceMigration scoped_dice_migration;
sync_preferences::TestingPrefServiceSyncable pref_service;
signin::DiceAccountReconcilorDelegate::RegisterProfilePrefs(
pref_service.registry());
signin::RegisterAccountConsistencyProfilePrefs(pref_service.registry());
EXPECT_FALSE(signin::IsDiceEnabledForProfile(&pref_service));
signin::DiceAccountReconcilorDelegate delegate(&pref_service, true);
EXPECT_TRUE(signin::IsDiceEnabledForProfile(&pref_service));
}
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/signin/core/browser/mirror_account_reconcilor_delegate.h"
#include "base/logging.h"
#include "components/signin/core/browser/account_reconcilor.h"
namespace signin {
MirrorAccountReconcilorDelegate::MirrorAccountReconcilorDelegate(
SigninManagerBase* signin_manager)
: signin_manager_(signin_manager) {
DCHECK(signin_manager_);
signin_manager_->AddObserver(this);
}
MirrorAccountReconcilorDelegate::~MirrorAccountReconcilorDelegate() {
signin_manager_->RemoveObserver(this);
}
bool MirrorAccountReconcilorDelegate::IsReconcileEnabled() const {
return signin_manager_->IsAuthenticated();
}
bool MirrorAccountReconcilorDelegate::IsAccountConsistencyEnforced() const {
return true;
}
bool MirrorAccountReconcilorDelegate::ShouldAbortReconcileIfPrimaryHasError()
const {
return true;
}
std::string MirrorAccountReconcilorDelegate::GetFirstGaiaAccountForReconcile(
const std::vector<std::string>& chrome_accounts,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const std::string& primary_account,
bool first_execution) const {
// Mirror only uses the primary account, and it is never empty.
DCHECK(!primary_account.empty());
DCHECK(base::ContainsValue(chrome_accounts, primary_account));
return primary_account;
}
void MirrorAccountReconcilorDelegate::GoogleSigninSucceeded(
const std::string& account_id,
const std::string& username) {
reconcilor()->EnableReconcile();
}
void MirrorAccountReconcilorDelegate::GoogleSignedOut(
const std::string& account_id,
const std::string& username) {
reconcilor()->DisableReconcile(true /* logout_all_gaia_accounts */);
}
} // namespace signin
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_MIRROR_ACCOUNT_RECONCILOR_DELEGATE_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_MIRROR_ACCOUNT_RECONCILOR_DELEGATE_H_
#include "base/macros.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
#include "components/signin/core/browser/signin_manager_base.h"
namespace signin {
// AccountReconcilorDelegate specialized for Mirror.
class MirrorAccountReconcilorDelegate : public AccountReconcilorDelegate,
public SigninManagerBase::Observer {
public:
MirrorAccountReconcilorDelegate(SigninManagerBase* signin_manager);
~MirrorAccountReconcilorDelegate() override;
private:
// AccountReconcilorDelegate:
bool IsReconcileEnabled() const override;
bool IsAccountConsistencyEnforced() const override;
bool ShouldAbortReconcileIfPrimaryHasError() const override;
std::string GetFirstGaiaAccountForReconcile(
const std::vector<std::string>& chrome_accounts,
const std::vector<gaia::ListedAccount>& gaia_accounts,
const std::string& primary_account,
bool first_execution) const override;
// SigninManagerBase::Observer:
void GoogleSigninSucceeded(const std::string& account_id,
const std::string& username) override;
void GoogleSignedOut(const std::string& account_id,
const std::string& username) override;
SigninManagerBase* signin_manager_;
DISALLOW_COPY_AND_ASSIGN(MirrorAccountReconcilorDelegate);
};
} // namespace signin
#endif // COMPONENTS_SIGNIN_CORE_BROWSER_MIRROR_ACCOUNT_RECONCILOR_DELEGATE_H_
......@@ -8,8 +8,11 @@
#include <memory>
#include "base/memory/ptr_util.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/values.h"
#include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/core/browser/account_reconcilor_delegate.h"
#include "components/signin/core/browser/account_tracker_service.h"
#include "components/signin/core/browser/fake_signin_manager.h"
#include "components/signin/core/browser/gaia_cookie_manager_service.h"
......@@ -78,7 +81,12 @@ class FakeAccountConsistencyService : public AccountConsistencyService {
class MockAccountReconcilor : public AccountReconcilor {
public:
MockAccountReconcilor(SigninClient* client)
: AccountReconcilor(nullptr, nullptr, client, nullptr, false) {}
: AccountReconcilor(
nullptr,
nullptr,
client,
nullptr,
std::make_unique<signin::AccountReconcilorDelegate>()) {}
MOCK_METHOD1(OnReceivedManageAccountsResponse, void(signin::GAIAServiceType));
};
......@@ -150,7 +158,7 @@ class AccountConsistencyServiceTest : public PlatformTest {
cookie_settings_ =
new content_settings::CookieSettings(settings_map_.get(), &prefs_, "");
account_reconcilor_ =
base::MakeUnique<MockAccountReconcilor>(signin_client_.get());
std::make_unique<MockAccountReconcilor>(signin_client_.get());
ResetAccountConsistencyService();
}
......
......@@ -4,11 +4,12 @@
#include "ios/chrome/browser/signin/account_reconcilor_factory.h"
#include <utility>
#include <memory>
#include "base/memory/singleton.h"
#include "components/keyed_service/ios/browser_state_dependency_manager.h"
#include "components/signin/core/browser/account_reconcilor.h"
#include "components/signin/core/browser/mirror_account_reconcilor_delegate.h"
#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
#include "ios/chrome/browser/signin/gaia_cookie_manager_service_factory.h"
#include "ios/chrome/browser/signin/oauth2_token_service_factory.h"
......@@ -45,12 +46,15 @@ std::unique_ptr<KeyedService> AccountReconcilorFactory::BuildServiceInstanceFor(
web::BrowserState* context) const {
ios::ChromeBrowserState* chrome_browser_state =
ios::ChromeBrowserState::FromBrowserState(context);
SigninManager* signin_manager =
SigninManagerFactory::GetForBrowserState(chrome_browser_state);
std::unique_ptr<AccountReconcilor> reconcilor(new AccountReconcilor(
OAuth2TokenServiceFactory::GetForBrowserState(chrome_browser_state),
SigninManagerFactory::GetForBrowserState(chrome_browser_state),
signin_manager,
SigninClientFactory::GetForBrowserState(chrome_browser_state),
GaiaCookieManagerServiceFactory::GetForBrowserState(chrome_browser_state),
false /* is_new_profile */));
std::make_unique<signin::MirrorAccountReconcilorDelegate>(
signin_manager)));
reconcilor->Initialize(true /* start_reconcile_if_tokens_available */);
return reconcilor;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment