Commit 116d07dd authored by Marc Treib's avatar Marc Treib Committed by Commit Bot

Sync StartupController: Replace CanSyncStart by ShouldSyncStart

The new ShouldSyncStart includes the "FirstSetupComplete" check. With
this, StartupController doesn't have any knowledge of Sync setup state
anymore.
As a nice side effect, this allows us to remove SyncPrefs from
StartupController.

Bug: 854978
Change-Id: Ia9fb178cf5a81ada4288f4c33bcc48ced4f631f4
Reviewed-on: https://chromium-review.googlesource.com/1112241
Commit-Queue: Marc Treib <treib@chromium.org>
Reviewed-by: default avatarJan Krcal <jkrcal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#570008}
parent 54c5c178
...@@ -231,10 +231,9 @@ void ProfileSyncService::Initialize() { ...@@ -231,10 +231,9 @@ void ProfileSyncService::Initialize() {
sync_client_->Initialize(); sync_client_->Initialize();
startup_controller_ = std::make_unique<syncer::StartupController>( startup_controller_ = std::make_unique<syncer::StartupController>(
&sync_prefs_,
base::BindRepeating(&ProfileSyncService::GetPreferredDataTypes, base::BindRepeating(&ProfileSyncService::GetPreferredDataTypes,
base::Unretained(this)), base::Unretained(this)),
base::BindRepeating(&ProfileSyncService::CanSyncStart, base::BindRepeating(&ProfileSyncService::ShouldSyncStart,
base::Unretained(this)), base::Unretained(this)),
base::BindRepeating(&ProfileSyncService::StartUpSlowEngineComponents, base::BindRepeating(&ProfileSyncService::StartUpSlowEngineComponents,
base::Unretained(this))); base::Unretained(this)));
...@@ -451,6 +450,13 @@ void ProfileSyncService::CredentialsChanged() { ...@@ -451,6 +450,13 @@ void ProfileSyncService::CredentialsChanged() {
NotifyObservers(); NotifyObservers();
} }
bool ProfileSyncService::ShouldSyncStart(bool bypass_first_setup_check) {
if (!CanSyncStart()) {
return false;
}
return bypass_first_setup_check || IsFirstSetupComplete();
}
void ProfileSyncService::ResetCryptoState() { void ProfileSyncService::ResetCryptoState() {
crypto_ = std::make_unique<syncer::SyncServiceCrypto>( crypto_ = std::make_unique<syncer::SyncServiceCrypto>(
base::BindRepeating(&ProfileSyncService::NotifyObservers, base::BindRepeating(&ProfileSyncService::NotifyObservers,
......
...@@ -510,6 +510,9 @@ class ProfileSyncService : public syncer::SyncService, ...@@ -510,6 +510,9 @@ class ProfileSyncService : public syncer::SyncService,
void AccountStateChanged(); void AccountStateChanged();
void CredentialsChanged(); void CredentialsChanged();
// Callback for StartupController.
bool ShouldSyncStart(bool bypass_first_setup_check);
// Destroys the |crypto_| object and creates a new one with fresh state. // Destroys the |crypto_| object and creates a new one with fresh state.
void ResetCryptoState(); void ResetCryptoState();
......
...@@ -6,13 +6,13 @@ ...@@ -6,13 +6,13 @@
#include <utility> #include <utility>
#include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/location.h" #include "base/location.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/sequenced_task_runner.h" #include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/threading/sequenced_task_runner_handle.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_driver_switches.h"
namespace syncer { namespace syncer {
...@@ -58,13 +58,11 @@ enum DeferredInitTrigger { ...@@ -58,13 +58,11 @@ enum DeferredInitTrigger {
} // namespace } // namespace
StartupController::StartupController( StartupController::StartupController(
const SyncPrefs* sync_prefs,
base::RepeatingCallback<ModelTypeSet()> get_preferred_data_types, base::RepeatingCallback<ModelTypeSet()> get_preferred_data_types,
base::RepeatingCallback<bool()> can_start, base::RepeatingCallback<bool(bool)> should_start,
base::RepeatingClosure start_engine) base::RepeatingClosure start_engine)
: sync_prefs_(sync_prefs), : get_preferred_data_types_callback_(std::move(get_preferred_data_types)),
get_preferred_data_types_callback_(std::move(get_preferred_data_types)), should_start_callback_(std::move(should_start)),
can_start_callback_(std::move(can_start)),
start_engine_callback_(std::move(start_engine)), start_engine_callback_(std::move(start_engine)),
bypass_deferred_startup_(false), bypass_deferred_startup_(false),
weak_factory_(this) {} weak_factory_(this) {}
...@@ -90,8 +88,8 @@ void StartupController::StartUp(StartUpDeferredOption deferred_option) { ...@@ -90,8 +88,8 @@ void StartupController::StartUp(StartUpDeferredOption deferred_option) {
if (first_start) { if (first_start) {
base::SequencedTaskRunnerHandle::Get()->PostDelayedTask( base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
FROM_HERE, FROM_HERE,
base::Bind(&StartupController::OnFallbackStartupTimerExpired, base::BindOnce(&StartupController::OnFallbackStartupTimerExpired,
weak_factory_.GetWeakPtr()), weak_factory_.GetWeakPtr()),
GetDeferredInitDelay()); GetDeferredInitDelay());
} }
return; return;
...@@ -104,7 +102,7 @@ void StartupController::StartUp(StartUpDeferredOption deferred_option) { ...@@ -104,7 +102,7 @@ void StartupController::StartUp(StartUpDeferredOption deferred_option) {
} }
void StartupController::TryStart(bool force_immediate) { void StartupController::TryStart(bool force_immediate) {
if (!can_start_callback_.Run()) { if (!should_start_callback_.Run(force_immediate)) {
return; return;
} }
...@@ -115,11 +113,8 @@ void StartupController::TryStart(bool force_immediate) { ...@@ -115,11 +113,8 @@ void StartupController::TryStart(bool force_immediate) {
// and encryption information to the UI. // and encryption information to the UI.
// Do not start up the sync engine if setup has not completed and isn't // Do not start up the sync engine if setup has not completed and isn't
// in progress, unless told to otherwise. // in progress, unless told to otherwise.
if (force_immediate) { StartUp((force_immediate || bypass_deferred_startup_) ? STARTUP_IMMEDIATE
StartUp(STARTUP_IMMEDIATE); : STARTUP_DEFERRED);
} else if (sync_prefs_->IsFirstSetupComplete()) {
StartUp(bypass_deferred_startup_ ? STARTUP_IMMEDIATE : STARTUP_DEFERRED);
}
} }
void StartupController::RecordTimeDeferred() { void StartupController::RecordTimeDeferred() {
......
...@@ -12,8 +12,6 @@ ...@@ -12,8 +12,6 @@
namespace syncer { namespace syncer {
class SyncPrefs;
// This class is used by ProfileSyncService to manage all logic and state // This class is used by ProfileSyncService to manage all logic and state
// pertaining to initialization of the SyncEngine. // pertaining to initialization of the SyncEngine.
class StartupController { class StartupController {
...@@ -30,16 +28,15 @@ class StartupController { ...@@ -30,16 +28,15 @@ class StartupController {
}; };
StartupController( StartupController(
const SyncPrefs* sync_prefs,
base::RepeatingCallback<ModelTypeSet()> get_preferred_data_types, base::RepeatingCallback<ModelTypeSet()> get_preferred_data_types,
base::RepeatingCallback<bool()> can_start, base::RepeatingCallback<bool(bool force_immediate)> should_start,
base::RepeatingClosure start_engine); base::RepeatingClosure start_engine);
~StartupController(); ~StartupController();
// Starts up sync if it is requested by the user and preconditions are met. // Starts up sync if it is requested by the user and preconditions are met.
// If |force_immediate| is true, this will start sync immediately, bypassing // If |force_immediate| is true, this will start sync immediately, bypassing
// deferred startup and the "first setup complete" check (but *not* the // deferred startup and the "first setup complete" check (but *not* the
// |can_start_callback_| check!). // |should_start_callback_| check!).
void TryStart(bool force_immediate); void TryStart(bool force_immediate);
// Called when a datatype (SyncableService) has a need for sync to start // Called when a datatype (SyncableService) has a need for sync to start
...@@ -66,14 +63,12 @@ class StartupController { ...@@ -66,14 +63,12 @@ class StartupController {
// Records time spent in deferred state with UMA histograms. // Records time spent in deferred state with UMA histograms.
void RecordTimeDeferred(); void RecordTimeDeferred();
const SyncPrefs* sync_prefs_;
const base::RepeatingCallback<ModelTypeSet()> const base::RepeatingCallback<ModelTypeSet()>
get_preferred_data_types_callback_; get_preferred_data_types_callback_;
// A function that can be invoked repeatedly to determine whether sync can be // A function that can be invoked repeatedly to determine whether sync should
// started. |start_engine_| should not be invoked unless this returns true. // be started. |start_engine_| should not be invoked unless this returns true.
const base::RepeatingCallback<bool()> can_start_callback_; const base::RepeatingCallback<bool(bool)> should_start_callback_;
// The callback we invoke when it's time to call expensive // The callback we invoke when it's time to call expensive
// startup routines for the sync engine. // startup routines for the sync engine.
......
...@@ -6,12 +6,11 @@ ...@@ -6,12 +6,11 @@
#include <memory> #include <memory>
#include "base/bind.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/driver/sync_driver_switches.h" #include "components/sync/driver/sync_driver_switches.h"
#include "components/sync_preferences/testing_pref_service_syncable.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
namespace syncer { namespace syncer {
...@@ -19,19 +18,16 @@ namespace syncer { ...@@ -19,19 +18,16 @@ namespace syncer {
class StartupControllerTest : public testing::Test { class StartupControllerTest : public testing::Test {
public: public:
StartupControllerTest() StartupControllerTest()
: preferred_types_(UserTypes()), can_start_(false), started_(false) {} : preferred_types_(UserTypes()), should_start_(false), started_(false) {}
void SetUp() override { void SetUp() override {
base::CommandLine::ForCurrentProcess()->AppendSwitchASCII( base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
switches::kSyncDeferredStartupTimeoutSeconds, "0"); switches::kSyncDeferredStartupTimeoutSeconds, "0");
SyncPrefs::RegisterProfilePrefs(pref_service_.registry());
sync_prefs_ = std::make_unique<SyncPrefs>(&pref_service_);
controller_ = std::make_unique<StartupController>( controller_ = std::make_unique<StartupController>(
sync_prefs_.get(),
base::BindRepeating(&StartupControllerTest::GetPreferredDataTypes, base::BindRepeating(&StartupControllerTest::GetPreferredDataTypes,
base::Unretained(this)), base::Unretained(this)),
base::BindRepeating(&StartupControllerTest::CanStart, base::BindRepeating(&StartupControllerTest::ShouldStart,
base::Unretained(this)), base::Unretained(this)),
base::BindRepeating(&StartupControllerTest::FakeStartBackend, base::BindRepeating(&StartupControllerTest::FakeStartBackend,
base::Unretained(this))); base::Unretained(this)));
...@@ -42,7 +38,7 @@ class StartupControllerTest : public testing::Test { ...@@ -42,7 +38,7 @@ class StartupControllerTest : public testing::Test {
preferred_types_ = types; preferred_types_ = types;
} }
void SetCanStart(bool can_start) { can_start_ = can_start; } void SetShouldStart(bool should_start) { should_start_ = should_start; }
void ExpectStarted() { void ExpectStarted() {
EXPECT_TRUE(started()); EXPECT_TRUE(started());
...@@ -63,44 +59,38 @@ class StartupControllerTest : public testing::Test { ...@@ -63,44 +59,38 @@ class StartupControllerTest : public testing::Test {
bool started() const { return started_; } bool started() const { return started_; }
void clear_started() { started_ = false; } void clear_started() { started_ = false; }
StartupController* controller() { return controller_.get(); } StartupController* controller() { return controller_.get(); }
SyncPrefs* sync_prefs() { return sync_prefs_.get(); }
private: private:
ModelTypeSet GetPreferredDataTypes() { return preferred_types_; } ModelTypeSet GetPreferredDataTypes() { return preferred_types_; }
bool CanStart() { return can_start_; } bool ShouldStart(bool force_immediate) { return should_start_; }
void FakeStartBackend() { started_ = true; } void FakeStartBackend() { started_ = true; }
ModelTypeSet preferred_types_; ModelTypeSet preferred_types_;
bool can_start_; bool should_start_;
bool started_; bool started_;
base::MessageLoop message_loop_; base::MessageLoop message_loop_;
sync_preferences::TestingPrefServiceSyncable pref_service_;
std::unique_ptr<SyncPrefs> sync_prefs_;
std::unique_ptr<StartupController> controller_; std::unique_ptr<StartupController> controller_;
}; };
// Test that sync doesn't start if setup is not in progress or complete. // Test that sync doesn't start if the "should sync start" callback returns
TEST_F(StartupControllerTest, NoSetupComplete) { // false.
TEST_F(StartupControllerTest, ShouldNotStart) {
controller()->TryStart(/*force_immediate=*/false); controller()->TryStart(/*force_immediate=*/false);
ExpectNotStarted(); ExpectNotStarted();
SetCanStart(true); controller()->TryStart(/*force_immediate=*/true);
controller()->TryStart(/*force_immediate=*/false);
ExpectNotStarted(); ExpectNotStarted();
} }
// Test that sync defers if first setup is complete. TEST_F(StartupControllerTest, DefersByDefault) {
TEST_F(StartupControllerTest, DefersAfterFirstSetupComplete) { SetShouldStart(true);
sync_prefs()->SetFirstSetupComplete();
SetCanStart(true);
controller()->TryStart(/*force_immediate=*/false); controller()->TryStart(/*force_immediate=*/false);
ExpectStartDeferred(); ExpectStartDeferred();
} }
// Test that a data type triggering startup starts sync immediately. // Test that a data type triggering startup starts sync immediately.
TEST_F(StartupControllerTest, NoDeferralDataTypeTrigger) { TEST_F(StartupControllerTest, NoDeferralDataTypeTrigger) {
sync_prefs()->SetFirstSetupComplete(); SetShouldStart(true);
SetCanStart(true);
controller()->OnDataTypeRequestsSyncStartup(SESSIONS); controller()->OnDataTypeRequestsSyncStartup(SESSIONS);
ExpectStarted(); ExpectStarted();
} }
...@@ -108,8 +98,7 @@ TEST_F(StartupControllerTest, NoDeferralDataTypeTrigger) { ...@@ -108,8 +98,7 @@ TEST_F(StartupControllerTest, NoDeferralDataTypeTrigger) {
// Test that a data type trigger interrupts the deferral timer and starts // Test that a data type trigger interrupts the deferral timer and starts
// sync immediately. // sync immediately.
TEST_F(StartupControllerTest, DataTypeTriggerInterruptsDeferral) { TEST_F(StartupControllerTest, DataTypeTriggerInterruptsDeferral) {
sync_prefs()->SetFirstSetupComplete(); SetShouldStart(true);
SetCanStart(true);
controller()->TryStart(/*force_immediate=*/false); controller()->TryStart(/*force_immediate=*/false);
ExpectStartDeferred(); ExpectStartDeferred();
...@@ -123,11 +112,10 @@ TEST_F(StartupControllerTest, DataTypeTriggerInterruptsDeferral) { ...@@ -123,11 +112,10 @@ TEST_F(StartupControllerTest, DataTypeTriggerInterruptsDeferral) {
EXPECT_FALSE(started()); EXPECT_FALSE(started());
} }
// Test that the fallback timer starts sync in the event all // Test that the fallback timer starts sync in the event all conditions are met
// conditions are met and no data type requests sync. // and no data type requests sync.
TEST_F(StartupControllerTest, FallbackTimer) { TEST_F(StartupControllerTest, FallbackTimer) {
sync_prefs()->SetFirstSetupComplete(); SetShouldStart(true);
SetCanStart(true);
controller()->TryStart(/*force_immediate=*/false); controller()->TryStart(/*force_immediate=*/false);
ExpectStartDeferred(); ExpectStartDeferred();
...@@ -145,8 +133,7 @@ TEST_F(StartupControllerTest, NoDeferralWithoutSessionsSync) { ...@@ -145,8 +133,7 @@ TEST_F(StartupControllerTest, NoDeferralWithoutSessionsSync) {
types.Remove(SUPERVISED_USER_SETTINGS); types.Remove(SUPERVISED_USER_SETTINGS);
SetPreferredDataTypes(types); SetPreferredDataTypes(types);
sync_prefs()->SetFirstSetupComplete(); SetShouldStart(true);
SetCanStart(true);
controller()->TryStart(/*force_immediate=*/false); controller()->TryStart(/*force_immediate=*/false);
ExpectStarted(); ExpectStarted();
} }
...@@ -160,19 +147,18 @@ TEST_F(StartupControllerTest, FallbackTimerWaits) { ...@@ -160,19 +147,18 @@ TEST_F(StartupControllerTest, FallbackTimerWaits) {
ExpectNotStarted(); ExpectNotStarted();
} }
// Test that sync starts immediately when setup in progress is true. // Test that sync starts immediately when told to do so.
TEST_F(StartupControllerTest, NoDeferralSetupInProgressTrigger) { TEST_F(StartupControllerTest, NoDeferralIfForceImmediate) {
sync_prefs()->SetFirstSetupComplete(); SetShouldStart(true);
SetCanStart(true); ExpectNotStarted();
controller()->TryStart(/*force_immediate=*/true); controller()->TryStart(/*force_immediate=*/true);
ExpectStarted(); ExpectStarted();
} }
// Test that setup in progress being set to true interrupts the deferral timer // Test that setting |force_immediate| interrupts the deferral timer and starts
// and starts sync immediately. // sync immediately.
TEST_F(StartupControllerTest, SetupInProgressTriggerInterruptsDeferral) { TEST_F(StartupControllerTest, ForceImmediateInterruptsDeferral) {
sync_prefs()->SetFirstSetupComplete(); SetShouldStart(true);
SetCanStart(true);
controller()->TryStart(/*force_immediate=*/false); controller()->TryStart(/*force_immediate=*/false);
ExpectStartDeferred(); ExpectStartDeferred();
...@@ -180,13 +166,4 @@ TEST_F(StartupControllerTest, SetupInProgressTriggerInterruptsDeferral) { ...@@ -180,13 +166,4 @@ TEST_F(StartupControllerTest, SetupInProgressTriggerInterruptsDeferral) {
ExpectStarted(); ExpectStarted();
} }
// Test that deferred startup and the FirstSetupComplete check can be bypassed.
TEST_F(StartupControllerTest, BypassDeferredStartupAndSetupCompleteCheck) {
SetCanStart(true);
ASSERT_FALSE(sync_prefs()->IsFirstSetupComplete());
ExpectNotStarted();
controller()->TryStart(/*force_immediate=*/true);
ExpectStarted();
}
} // namespace syncer } // namespace syncer
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