Commit d678d34c authored by Marc Treib's avatar Marc Treib Committed by Commit Bot

Add SyncService::GetUploadToGoogleState

It returns whether uploading data to Google is enabled for a given
ModelType, i.e. whether Sync is active and not in an error state.
There are three possible return values: INITIALIZING (enabled in
principle, but we don't know yet whether we'll encounter e.g. an
auth error), ACTIVE (data is being uploaded to Google), or
NOT_ACTIVE (uploading is either disabled entirely or in a permanent
auth error state).

Change-Id: I86894453bba17cfb6cd94bb3a5c82f915750ea06
Reviewed-on: https://chromium-review.googlesource.com/968821Reviewed-by: default avatarJan Krcal <jkrcal@chromium.org>
Commit-Queue: Marc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#544751}
parent f3237b9d
...@@ -824,6 +824,7 @@ source_set("unit_tests") { ...@@ -824,6 +824,7 @@ source_set("unit_tests") {
"driver/model_type_controller_unittest.cc", "driver/model_type_controller_unittest.cc",
"driver/shared_change_processor_unittest.cc", "driver/shared_change_processor_unittest.cc",
"driver/startup_controller_unittest.cc", "driver/startup_controller_unittest.cc",
"driver/sync_service_utils_unittest.cc",
"driver/sync_stopped_reporter_unittest.cc", "driver/sync_stopped_reporter_unittest.cc",
"driver/sync_util_unittest.cc", "driver/sync_util_unittest.cc",
"engine/cycle/sync_cycle_snapshot_unittest.cc", "engine/cycle/sync_cycle_snapshot_unittest.cc",
......
...@@ -4,8 +4,6 @@ ...@@ -4,8 +4,6 @@
#include "components/sync/driver/sync_service.h" #include "components/sync/driver/sync_service.h"
#include "components/sync/engine/sync_manager.h"
namespace syncer { namespace syncer {
SyncSetupInProgressHandle::SyncSetupInProgressHandle(base::Closure on_destroy) SyncSetupInProgressHandle::SyncSetupInProgressHandle(base::Closure on_destroy)
......
...@@ -126,7 +126,7 @@ class SyncService : public DataTypeEncryptionHandler, public KeyedService { ...@@ -126,7 +126,7 @@ class SyncService : public DataTypeEncryptionHandler, public KeyedService {
// Returns true if sync is fully initialized and active. This implies that // Returns true if sync is fully initialized and active. This implies that
// an initial configuration has successfully completed, although there may // an initial configuration has successfully completed, although there may
// be datatype specific, auth, or other transient errors. To see which // be datatype specific, auth, or other transient errors. To see which
// datetypes are actually syncing, see GetActiveTypes() below. // datatypes are actually syncing, see GetActiveDataTypes() below.
virtual bool IsSyncActive() const = 0; virtual bool IsSyncActive() const = 0;
// Returns true if the local sync backend server has been enabled through a // Returns true if the local sync backend server has been enabled through a
......
...@@ -18,4 +18,21 @@ bool IsTabSyncEnabledAndUnencrypted(SyncService* sync_service, ...@@ -18,4 +18,21 @@ bool IsTabSyncEnabledAndUnencrypted(SyncService* sync_service,
!sync_service->GetEncryptedDataTypes().Has(SESSIONS); !sync_service->GetEncryptedDataTypes().Has(SESSIONS);
} }
UploadState GetUploadToGoogleState(const SyncService* sync_service,
ModelType type) {
// Note: Before configuration is done, GetPreferredDataTypes returns
// "everything" (i.e. the default setting). If a data type is missing there,
// it must be because the user explicitly disabled it.
if (!sync_service->CanSyncStart() || sync_service->IsLocalSyncEnabled() ||
!sync_service->GetPreferredDataTypes().Has(type) ||
sync_service->GetAuthError().IsPersistentError() ||
sync_service->IsUsingSecondaryPassphrase()) {
return UploadState::NOT_ACTIVE;
}
if (!sync_service->IsSyncActive() || !sync_service->ConfigurationDone()) {
return UploadState::INITIALIZING;
}
return UploadState::ACTIVE;
}
} // namespace syncer } // namespace syncer
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#ifndef COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_UTILS_H_ #ifndef COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_UTILS_H_
#define COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_UTILS_H_ #define COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_UTILS_H_
#include "components/sync/base/model_type.h"
class PrefService; class PrefService;
namespace syncer { namespace syncer {
...@@ -16,6 +18,31 @@ class SyncService; ...@@ -16,6 +18,31 @@ class SyncService;
bool IsTabSyncEnabledAndUnencrypted(SyncService* sync_service, bool IsTabSyncEnabledAndUnencrypted(SyncService* sync_service,
PrefService* pref_service); PrefService* pref_service);
// Indicates whether uploading of data to Google is enabled, i.e. the user has
// given consent to upload this data.
enum class UploadState {
// Syncing is enabled in principle, but the sync service is still
// initializing, so e.g. we don't know about any auth errors yet.
INITIALIZING,
// We are not syncing to Google, and the caller should assume that we do not
// have consent to do so. This can have a number of reasons: e.g. sync as a
// whole is disabled, or the given model type is disabled, or we're in
// "local sync" mode, or encryption with a custom passphrase is enabled (in
// which case we're technically still uploading, but Google can't inspect the
// data), or we're in a persistent auth error state. As one special case of an
// auth error, sync may be "paused" because the user signed out of the content
// area.
NOT_ACTIVE,
// We're actively syncing data to Google servers.
ACTIVE
};
// Returns whether |type| is being uploaded to Google. This is useful for
// features that depend on user consent for uploading data (e.g. history) to
// Google.
UploadState GetUploadToGoogleState(const SyncService* sync_service,
ModelType type);
} // namespace syncer } // namespace syncer
#endif // COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_UTILS_H_ #endif // COMPONENTS_SYNC_DRIVER_SYNC_SERVICE_UTILS_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/sync/driver/sync_service_utils.h"
#include "components/sync/base/model_type.h"
#include "components/sync/driver/fake_sync_service.h"
#include "components/sync/driver/sync_service.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace syncer {
class TestSyncService : public FakeSyncService {
public:
TestSyncService() = default;
~TestSyncService() override = default;
void SetSyncAllowed(bool allowed) { sync_allowed_ = allowed; }
void SetSyncActive(bool active) { sync_active_ = active; }
void SetLocalSyncEnabled(bool local) { local_sync_enabled_ = local; }
void SetPreferredDataTypes(const ModelTypeSet& types) {
preferred_data_types_ = types;
}
void SetConfigurationDone(bool done) { configuration_done_ = done; }
void SetCustomPassphraseEnabled(bool enabled) {
custom_passphrase_enabled_ = enabled;
}
// SyncService implementation.
bool IsSyncAllowed() const override { return sync_allowed_; }
bool CanSyncStart() const override { return sync_allowed_; }
bool IsSyncActive() const override { return sync_active_; }
bool IsLocalSyncEnabled() const override { return local_sync_enabled_; }
ModelTypeSet GetPreferredDataTypes() const override {
return preferred_data_types_;
}
ModelTypeSet GetActiveDataTypes() const override {
if (!sync_active_)
return ModelTypeSet();
return preferred_data_types_;
}
ModelTypeSet GetEncryptedDataTypes() const override {
if (!custom_passphrase_enabled_)
return ModelTypeSet(syncer::PASSWORDS);
return preferred_data_types_;
}
bool ConfigurationDone() const override { return configuration_done_; }
bool IsUsingSecondaryPassphrase() const override {
return custom_passphrase_enabled_;
}
private:
bool sync_allowed_ = false;
bool sync_active_ = false;
bool local_sync_enabled_ = false;
ModelTypeSet preferred_data_types_;
bool configuration_done_ = false;
bool custom_passphrase_enabled_ = false;
};
TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfSyncNotAllowed) {
TestSyncService service;
// If sync is not allowed, uploading should never be enabled, even if
// configuration is done and all the data types are enabled.
service.SetSyncAllowed(false);
service.SetConfigurationDone(true);
service.SetPreferredDataTypes(ProtocolTypes());
EXPECT_EQ(UploadState::NOT_ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
// Once sync gets allowed (e.g. policy is updated), uploading should not be
// disabled anymore (though not necessarily active yet).
service.SetSyncAllowed(true);
EXPECT_NE(UploadState::NOT_ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
}
TEST(SyncServiceUtilsTest, UploadToGoogleInitializingUntilConfiguredAndActive) {
TestSyncService service;
service.SetSyncAllowed(true);
service.SetPreferredDataTypes(ProtocolTypes());
// By default, if sync isn't disabled, we should be INITIALIZING.
EXPECT_EQ(UploadState::INITIALIZING,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
// Finished configuration is not enough, still INITIALIZING.
service.SetConfigurationDone(true);
EXPECT_EQ(UploadState::INITIALIZING,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
// Only after sync is both configured and active is upload actually ACTIVE.
service.SetSyncActive(true);
EXPECT_EQ(UploadState::ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
}
TEST(SyncServiceUtilsTest, UploadToGoogleDisabledForModelType) {
TestSyncService service;
service.SetSyncAllowed(true);
service.SetConfigurationDone(true);
service.SetSyncActive(true);
// Sync is enabled only for a specific model type.
service.SetPreferredDataTypes(ModelTypeSet(syncer::BOOKMARKS));
// Sanity check: Upload is ACTIVE for this model type.
ASSERT_EQ(UploadState::ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
// ...but not for other types.
EXPECT_EQ(
UploadState::NOT_ACTIVE,
GetUploadToGoogleState(&service, syncer::HISTORY_DELETE_DIRECTIVES));
EXPECT_EQ(UploadState::NOT_ACTIVE,
GetUploadToGoogleState(&service, syncer::PREFERENCES));
}
TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfLocalSyncEnabled) {
TestSyncService service;
service.SetSyncAllowed(true);
service.SetPreferredDataTypes(ProtocolTypes());
service.SetSyncActive(true);
service.SetConfigurationDone(true);
// If we're in "local sync" mode, uploading should never be enabled, even if
// configuration is done and all the data types are enabled.
service.SetLocalSyncEnabled(true);
EXPECT_EQ(UploadState::NOT_ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
}
TEST(SyncServiceUtilsTest, UploadToGoogleDisabledOnPersistentAuthError) {
TestSyncService service;
service.SetSyncAllowed(true);
service.SetPreferredDataTypes(ProtocolTypes());
service.SetSyncActive(true);
service.SetConfigurationDone(true);
// Sanity check: Upload is active now.
ASSERT_EQ(UploadState::ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
// On a transient error, uploading remains active.
GoogleServiceAuthError transient_error(
GoogleServiceAuthError::CONNECTION_FAILED);
ASSERT_TRUE(transient_error.IsTransientError());
service.set_auth_error(transient_error);
EXPECT_EQ(UploadState::ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
// On a persistent error, uploading is not considered active anymore (even
// though Sync may still be considered active).
GoogleServiceAuthError persistent_error(
GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS);
ASSERT_TRUE(persistent_error.IsPersistentError());
service.set_auth_error(persistent_error);
EXPECT_EQ(UploadState::NOT_ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
// Once the auth error is resolved (e.g. user re-authenticated), uploading is
// active again.
service.set_auth_error(GoogleServiceAuthError(GoogleServiceAuthError::NONE));
EXPECT_EQ(UploadState::ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
}
TEST(SyncServiceUtilsTest, UploadToGoogleDisabledIfCustomPassphraseInUse) {
TestSyncService service;
service.SetSyncAllowed(true);
service.SetPreferredDataTypes(ProtocolTypes());
service.SetSyncActive(true);
service.SetConfigurationDone(true);
// Sanity check: Upload is ACTIVE, even for data types that are always
// encrypted implicitly (PASSWORDS).
ASSERT_EQ(UploadState::ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
ASSERT_EQ(UploadState::ACTIVE,
GetUploadToGoogleState(&service, syncer::PASSWORDS));
// Once a custom passphrase is in use, upload should be considered disabled:
// Even if we're technically still uploading, Google can't inspect the data.
service.SetCustomPassphraseEnabled(true);
EXPECT_EQ(UploadState::NOT_ACTIVE,
GetUploadToGoogleState(&service, syncer::BOOKMARKS));
EXPECT_EQ(UploadState::NOT_ACTIVE,
GetUploadToGoogleState(&service, syncer::PASSWORDS));
}
} // 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