Commit 22f80fd2 authored by Rushan Suleymanov's avatar Rushan Suleymanov Committed by Commit Bot

[Sync] Introduce the flag indicating that there are no other clients

Clients will send the flag which will indicate that the client is not
aware of any other clients. This is useful to prevent trying to send
invalidations from the server.

The single client flag is calculated based on known device infos.
Devices which don't have recent enough updates are considered
non-active.

Bug: 1145942
Change-Id: Ia24cb880e361b65796ea8c516ef38c1bfed58b12
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2533775
Commit-Queue: Rushan Suleymanov <rushans@google.com>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#826891}
parent db1ae079
......@@ -27,6 +27,7 @@ namespace {
using testing::ElementsAre;
using testing::IsSupersetOf;
using testing::UnorderedElementsAre;
MATCHER_P(HasCacheGuid, expected_cache_guid, "") {
return arg.specifics().device_info().cache_guid() == expected_cache_guid;
......@@ -168,4 +169,35 @@ IN_PROC_BROWSER_TEST_F(SingleClientDeviceInfoSyncTest,
HasCacheGuid(CacheGuidForSuffix(2))}));
}
IN_PROC_BROWSER_TEST_F(SingleClientDeviceInfoSyncTest,
ShouldSetTheOnlyClientFlag) {
ASSERT_TRUE(SetupSync());
ASSERT_TRUE(
ServerDeviceInfoMatchChecker(
GetFakeServer(), ElementsAre(HasCacheGuid(GetLocalCacheGuid())))
.Wait());
sync_pb::ClientToServerMessage message;
GetFakeServer()->GetLastCommitMessage(&message);
EXPECT_TRUE(message.commit().config_params().single_client());
}
IN_PROC_BROWSER_TEST_F(SingleClientDeviceInfoSyncTest,
ShouldNotProvideTheOnlyClientFlag) {
InjectDeviceInfoEntityToServer(/*suffix=*/1);
ASSERT_TRUE(SetupSync());
ASSERT_TRUE(ServerDeviceInfoMatchChecker(
GetFakeServer(),
UnorderedElementsAre(HasCacheGuid(GetLocalCacheGuid()),
HasCacheGuid(CacheGuidForSuffix(1))))
.Wait());
sync_pb::ClientToServerMessage message;
GetFakeServer()->GetLastCommitMessage(&message);
EXPECT_FALSE(message.commit().config_params().single_client());
}
} // namespace
......@@ -67,6 +67,7 @@ test("components_unittests") {
"//components/blocklist/opt_out_blocklist/sql:unit_tests",
"//components/bookmarks/browser:unit_tests",
"//components/bookmarks/managed:unit_tests",
"//components/browser_sync:unit_tests",
"//components/browsing_data/core:unit_tests",
"//components/captive_portal/core:unit_tests",
"//components/cbor:unit_tests",
......
......@@ -6,6 +6,8 @@ import("//build/config/features.gni")
static_library("browser_sync") {
sources = [
"active_devices_provider_impl.cc",
"active_devices_provider_impl.h",
"browser_sync_client.h",
"browser_sync_switches.cc",
"browser_sync_switches.h",
......@@ -43,7 +45,7 @@ static_library("browser_sync") {
source_set("unit_tests") {
testonly = true
sources = []
sources = [ "active_devices_provider_impl_unittest.cc" ]
deps = [
":browser_sync",
......@@ -60,6 +62,7 @@ source_set("unit_tests") {
"//components/sync:test_support",
"//components/sync_bookmarks",
"//components/sync_device_info",
"//components/sync_device_info:test_support",
"//components/version_info",
"//components/version_info:generate_version_info",
"//components/webdata/common",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <memory>
#include <utility>
#include <vector>
#include "base/feature_list.h"
#include "base/metrics/field_trial_params.h"
#include "components/browser_sync/active_devices_provider_impl.h"
namespace browser_sync {
// Enables filtering out inactive devices which haven't sent DeviceInfo update
// recently (depending on the device's pulse_interval and an additional margin).
const base::Feature kSyncFilterOutInactiveDevicesForSingleClient{
"SyncFilterOutInactiveDevicesForSingleClient",
base::FEATURE_ENABLED_BY_DEFAULT};
// An additional threshold to consider devices as active. It extends device's
// pulse interval to mitigate possible latency after DeviceInfo commit.
const base::FeatureParam<base::TimeDelta> kSyncActiveDeviceMargin{
&kSyncFilterOutInactiveDevicesForSingleClient, "SyncActiveDeviceMargin",
base::TimeDelta::FromMinutes(30)};
ActiveDevicesProviderImpl::ActiveDevicesProviderImpl(
syncer::DeviceInfoTracker* device_info_tracker,
base::Clock* clock)
: device_info_tracker_(device_info_tracker), clock_(clock) {
DCHECK(device_info_tracker_);
device_info_tracker_->AddObserver(this);
}
ActiveDevicesProviderImpl::~ActiveDevicesProviderImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(callback_.is_null());
device_info_tracker_->RemoveObserver(this);
}
size_t ActiveDevicesProviderImpl::CountActiveDevicesIfAvailable() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
std::vector<std::unique_ptr<syncer::DeviceInfo>> all_devices =
device_info_tracker_->GetAllDeviceInfo();
if (!base::FeatureList::IsEnabled(
kSyncFilterOutInactiveDevicesForSingleClient)) {
return all_devices.size();
}
size_t active_devices = 0;
for (const auto& device : all_devices) {
const base::Time expected_expiration_time =
device->last_updated_timestamp() + device->pulse_interval() +
kSyncActiveDeviceMargin.Get();
// If the device's expiration time hasn't been reached, then it is
// considered active device.
if (expected_expiration_time > clock_->Now()) {
active_devices++;
}
}
return active_devices;
}
void ActiveDevicesProviderImpl::SetActiveDevicesChangedCallback(
ActiveDevicesChangedCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// The |callback_| must not be replaced with another non-null |callback|.
DCHECK(callback_.is_null() || callback.is_null());
callback_ = std::move(callback);
}
void ActiveDevicesProviderImpl::OnDeviceInfoChange() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (callback_) {
callback_.Run();
}
}
} // namespace browser_sync
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_BROWSER_SYNC_ACTIVE_DEVICES_PROVIDER_IMPL_H_
#define COMPONENTS_BROWSER_SYNC_ACTIVE_DEVICES_PROVIDER_IMPL_H_
#include "base/sequence_checker.h"
#include "base/time/default_clock.h"
#include "components/sync/driver/active_devices_provider.h"
#include "components/sync_device_info/device_info_tracker.h"
namespace browser_sync {
class ActiveDevicesProviderImpl : public syncer::ActiveDevicesProvider,
public syncer::DeviceInfoTracker::Observer {
public:
ActiveDevicesProviderImpl(syncer::DeviceInfoTracker* device_info_tracker,
base::Clock* clock);
ActiveDevicesProviderImpl(const ActiveDevicesProviderImpl&) = delete;
ActiveDevicesProviderImpl& operator=(const ActiveDevicesProviderImpl&) =
delete;
~ActiveDevicesProviderImpl() override;
// syncer::ActiveDevicesProvider implementation.
size_t CountActiveDevicesIfAvailable() override;
void SetActiveDevicesChangedCallback(
ActiveDevicesChangedCallback callback) override;
// syncer::DeviceInfoTracker::Observer implementation.
void OnDeviceInfoChange() override;
private:
syncer::DeviceInfoTracker* const device_info_tracker_;
const base::Clock* const clock_;
ActiveDevicesChangedCallback callback_;
SEQUENCE_CHECKER(sequence_checker_);
};
} // namespace browser_sync
#endif // COMPONENTS_BROWSER_SYNC_ACTIVE_DEVICES_PROVIDER_IMPL_H_
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/browser_sync/active_devices_provider_impl.h"
#include <memory>
#include <string>
#include <vector>
#include "base/guid.h"
#include "base/test/mock_callback.h"
#include "base/test/simple_test_clock.h"
#include "base/time/time.h"
#include "components/sync_device_info/device_info_util.h"
#include "components/sync_device_info/fake_device_info_tracker.h"
#include "testing/gtest/include/gtest/gtest.h"
using syncer::DeviceInfo;
using syncer::FakeDeviceInfoTracker;
namespace browser_sync {
namespace {
constexpr int kPulseIntervalMinutes = 60;
std::unique_ptr<DeviceInfo> CreateFakeDeviceInfo(
const std::string& name,
base::Time last_updated_timestamp) {
return std::make_unique<syncer::DeviceInfo>(
base::GenerateGUID(), name, "chrome_version", "user_agent",
sync_pb::SyncEnums::TYPE_UNSET, "device_id", "manufacturer_name",
"model_name", last_updated_timestamp,
base::TimeDelta::FromMinutes(kPulseIntervalMinutes),
/*send_tab_to_self_receiving_enabled=*/false,
/*sharing_info=*/base::nullopt,
/*fcm_registration_token=*/std::string(),
/*interested_data_types=*/syncer::ModelTypeSet());
}
class ActiveDevicesProviderImplTest : public testing::Test {
public:
ActiveDevicesProviderImplTest()
: active_devices_provider_(&fake_device_info_tracker_, &clock_) {}
~ActiveDevicesProviderImplTest() override = default;
void AddDevice(const std::string& name, base::Time last_updated_timestamp) {
device_list_.push_back(CreateFakeDeviceInfo(name, last_updated_timestamp));
fake_device_info_tracker_.Add(device_list_.back().get());
}
protected:
std::vector<std::unique_ptr<DeviceInfo>> device_list_;
FakeDeviceInfoTracker fake_device_info_tracker_;
base::SimpleTestClock clock_;
ActiveDevicesProviderImpl active_devices_provider_;
};
TEST_F(ActiveDevicesProviderImplTest, ShouldFilterInactiveDevices) {
AddDevice("device_recent", clock_.Now() - base::TimeDelta::FromMinutes(1));
// Should be considered as active device due to margin even though the device
// is outside the pulse interval.
AddDevice(
"device_pulse_interval",
clock_.Now() - base::TimeDelta::FromMinutes(kPulseIntervalMinutes + 1));
// Very old device.
AddDevice("device_inactive", clock_.Now() - base::TimeDelta::FromDays(100));
EXPECT_EQ(2u, active_devices_provider_.CountActiveDevicesIfAvailable());
}
TEST_F(ActiveDevicesProviderImplTest, ShouldReturnZeroDevices) {
EXPECT_EQ(0u, active_devices_provider_.CountActiveDevicesIfAvailable());
}
TEST_F(ActiveDevicesProviderImplTest, ShouldInvokeCallback) {
base::MockCallback<
syncer::ActiveDevicesProvider::ActiveDevicesChangedCallback>
callback;
active_devices_provider_.SetActiveDevicesChangedCallback(callback.Get());
EXPECT_CALL(callback, Run());
active_devices_provider_.OnDeviceInfoChange();
active_devices_provider_.SetActiveDevicesChangedCallback(
base::RepeatingClosure());
}
} // namespace
} // namespace browser_sync
......@@ -20,6 +20,7 @@
#include "components/autofill/core/browser/webdata/autofill_wallet_offer_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/browser_sync/active_devices_provider_impl.h"
#include "components/browser_sync/browser_sync_client.h"
#include "components/history/core/browser/sync/history_delete_directives_model_type_controller.h"
#include "components/history/core/browser/sync/typed_url_model_type_controller.h"
......@@ -417,8 +418,11 @@ ProfileSyncComponentsFactoryImpl::CreateSyncEngine(
syncer::SyncInvalidationsService* sync_invalidation_service,
const base::WeakPtr<syncer::SyncPrefs>& sync_prefs) {
return std::make_unique<syncer::SyncEngineImpl>(
name, invalidator, sync_invalidation_service, sync_prefs,
sync_client_->GetModelTypeStoreService()->GetSyncDataPath(),
name, invalidator, sync_invalidation_service,
std::make_unique<browser_sync::ActiveDevicesProviderImpl>(
sync_client_->GetDeviceInfoSyncService()->GetDeviceInfoTracker(),
base::DefaultClock::GetInstance()),
sync_prefs, sync_client_->GetModelTypeStoreService()->GetSyncDataPath(),
engines_and_directory_deletion_thread_);
}
......
......@@ -7,6 +7,7 @@ import("//tools/grit/grit_rule.gni")
static_library("driver") {
sources = [
"active_devices_provider.h",
"backend_migrator.cc",
"backend_migrator.h",
"configure_context.h",
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_SYNC_DRIVER_ACTIVE_DEVICES_PROVIDER_H_
#define COMPONENTS_SYNC_DRIVER_ACTIVE_DEVICES_PROVIDER_H_
#include "base/callback.h"
namespace syncer {
// An interface helping to get the number of active devices. Devices are
// considered active if there are DeviceInfo entries that are (typically) less
// than one day old (with a little margin around half an hour).
class ActiveDevicesProvider {
public:
using ActiveDevicesChangedCallback = base::RepeatingClosure;
virtual ~ActiveDevicesProvider() = default;
// Returns number of active devices or 0 if number of active devices is not
// known yet (e.g. data types are not configured).
virtual size_t CountActiveDevicesIfAvailable() = 0;
// The |callback| will be called on each change in device infos. It might be
// called multiple times with the same number of active devices. The
// |callback| must be cleared before this object is destroyed.
virtual void SetActiveDevicesChangedCallback(
ActiveDevicesChangedCallback callback) = 0;
};
} // namespace syncer
#endif // COMPONENTS_SYNC_DRIVER_ACTIVE_DEVICES_PROVIDER_H_
......@@ -526,6 +526,14 @@ void SyncEngineBackend::DoOnInvalidationReceived(const std::string& payload) {
}
}
void SyncEngineBackend::DoOnActiveDevicesChanged(size_t active_devices) {
// If |active_devices| is 0, then current client doesn't know if there are any
// other devices. It's safer to consider that there are some other active
// devices.
const bool single_client = active_devices == 1;
sync_manager_->UpdateSingleClientStatus(single_client);
}
void SyncEngineBackend::GetNigoriNodeForDebugging(AllNodesCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
nigori_controller_->GetAllNodes(std::move(callback));
......
......@@ -153,6 +153,10 @@ class SyncEngineBackend : public base::RefCountedThreadSafe<SyncEngineBackend>,
bool HasUnsyncedItemsForTest() const;
// Called on each device infos change and might be called more than once with
// the same |active_devices|.
void DoOnActiveDevicesChanged(size_t active_devices);
private:
friend class base::RefCountedThreadSafe<SyncEngineBackend>;
......
......@@ -19,6 +19,7 @@
#include "components/sync/base/bind_to_task_runner.h"
#include "components/sync/base/invalidation_helper.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/driver/active_devices_provider.h"
#include "components/sync/driver/glue/sync_engine_backend.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/engine/data_type_activation_response.h"
......@@ -27,7 +28,6 @@
#include "components/sync/engine/events/protocol_event.h"
#include "components/sync/engine/net/http_bridge.h"
#include "components/sync/engine/sync_engine_host.h"
#include "components/sync/engine/sync_manager_factory.h"
#include "components/sync/engine/sync_string_conversions.h"
#include "components/sync/invalidations/fcm_handler.h"
#include "components/sync/invalidations/switches.h"
......@@ -39,6 +39,7 @@ SyncEngineImpl::SyncEngineImpl(
const std::string& name,
invalidation::InvalidationService* invalidator,
SyncInvalidationsService* sync_invalidations_service,
std::unique_ptr<ActiveDevicesProvider> active_devices_provider,
const base::WeakPtr<SyncPrefs>& sync_prefs,
const base::FilePath& sync_data_folder,
scoped_refptr<base::SequencedTaskRunner> sync_task_runner)
......@@ -48,10 +49,11 @@ SyncEngineImpl::SyncEngineImpl(
invalidator_(invalidator),
sync_invalidations_service_(sync_invalidations_service),
#if defined(OS_ANDROID)
sessions_invalidation_enabled_(false) {
sessions_invalidation_enabled_(false),
#else
sessions_invalidation_enabled_(true) {
sessions_invalidation_enabled_(true),
#endif
active_devices_provider_(std::move(active_devices_provider)) {
backend_ = base::MakeRefCounted<SyncEngineBackend>(
name_, sync_data_folder, weak_ptr_factory_.GetWeakPtr());
}
......@@ -187,6 +189,9 @@ void SyncEngineImpl::Shutdown(ShutdownReason reason) {
last_enabled_types_.Clear();
invalidation_handler_registered_ = false;
active_devices_provider_->SetActiveDevicesChangedCallback(
base::RepeatingClosure());
model_type_connector_.reset();
// Shut down and destroy SyncManager.
......@@ -297,6 +302,12 @@ void SyncEngineImpl::HandleInitializationSuccessOnFrontendLoop(
sync_invalidations_service_->AddListener(this);
}
active_devices_provider_->SetActiveDevicesChangedCallback(base::BindRepeating(
&SyncEngineImpl::OnActiveDevicesChanged, weak_ptr_factory_.GetWeakPtr()));
// Initialize active devices count.
OnActiveDevicesChanged();
host_->OnEngineInitialized(initial_types, js_backend, debug_info_listener,
birthday, bag_of_chips, /*success=*/true);
}
......@@ -446,4 +457,13 @@ void SyncEngineImpl::SendInterestedTopicsToInvalidator() {
DCHECK(success);
}
void SyncEngineImpl::OnActiveDevicesChanged() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
sync_task_runner_->PostTask(
FROM_HERE,
base::BindOnce(
&SyncEngineBackend::DoOnActiveDevicesChanged, backend_,
active_devices_provider_->CountActiveDevicesIfAvailable()));
}
} // namespace syncer
......@@ -40,6 +40,7 @@ class InvalidationService;
namespace syncer {
class ActiveDevicesProvider;
class DataTypeDebugInfoListener;
class JsBackend;
class ModelTypeConnector;
......@@ -59,6 +60,7 @@ class SyncEngineImpl : public SyncEngine,
SyncEngineImpl(const std::string& name,
invalidation::InvalidationService* invalidator,
SyncInvalidationsService* sync_invalidations_service,
std::unique_ptr<ActiveDevicesProvider> active_devices_provider,
const base::WeakPtr<SyncPrefs>& sync_prefs,
const base::FilePath& sync_data_folder,
scoped_refptr<base::SequencedTaskRunner> sync_task_runner);
......@@ -168,6 +170,10 @@ class SyncEngineImpl : public SyncEngine,
void SendInterestedTopicsToInvalidator();
// Called on each device infos change and might be called more than once with
// the same |active_devices|.
void OnActiveDevicesChanged();
// The task runner where all the sync engine operations happen.
scoped_refptr<base::SequencedTaskRunner> sync_task_runner_;
......@@ -205,6 +211,8 @@ class SyncEngineImpl : public SyncEngine,
SyncStatus cached_status_;
std::unique_ptr<ActiveDevicesProvider> active_devices_provider_;
// Checks that we're on the same thread this was constructed on (UI thread).
SEQUENCE_CHECKER(sequence_checker_);
......
......@@ -35,6 +35,7 @@
#include "components/sync/base/invalidation_helper.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/sync_prefs.h"
#include "components/sync/driver/active_devices_provider.h"
#include "components/sync/driver/sync_driver_switches.h"
#include "components/sync/engine/fake_sync_manager.h"
#include "components/sync/engine/net/http_bridge.h"
......@@ -171,6 +172,18 @@ class MockInvalidationService : public invalidation::InvalidationService {
(const override));
};
class MockActiveDevicesProvider : public ActiveDevicesProvider {
public:
MockActiveDevicesProvider() = default;
~MockActiveDevicesProvider() override = default;
MOCK_METHOD(size_t, CountActiveDevicesIfAvailable, (), (override));
MOCK_METHOD(void,
SetActiveDevicesChangedCallback,
(ActiveDevicesProvider::ActiveDevicesChangedCallback),
(override));
};
std::unique_ptr<HttpPostProviderFactory> CreateHttpBridgeFactory() {
return std::make_unique<HttpBridgeFactory>(
/*user_agent=*/"",
......@@ -200,6 +213,7 @@ class SyncEngineImplTest : public testing::Test {
base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
backend_ = std::make_unique<SyncEngineImpl>(
"dummyDebugName", &invalidator_, GetSyncInvalidationsService(),
std::make_unique<NiceMock<MockActiveDevicesProvider>>(),
sync_prefs_->AsWeakPtr(),
temp_dir_.GetPath().Append(base::FilePath(kTestSyncDir)),
sync_task_runner);
......
......@@ -193,4 +193,8 @@ void FakeSyncManager::UpdateInvalidationClientId(const std::string&) {
NOTIMPLEMENTED();
}
void FakeSyncManager::UpdateSingleClientStatus(bool single_client) {
// Do nothing.
}
} // namespace syncer
......@@ -97,6 +97,7 @@ class FakeSyncManager : public SyncManager {
void RefreshTypes(ModelTypeSet types) override;
void OnCookieJarChanged(bool account_mismatch, bool empty_jar) override;
void UpdateInvalidationClientId(const std::string&) override;
void UpdateSingleClientStatus(bool single_client) override;
private:
scoped_refptr<base::SequencedTaskRunner> sync_task_runner_;
......
......@@ -240,6 +240,9 @@ class SyncManager {
// Updates invalidation client id.
virtual void UpdateInvalidationClientId(const std::string& client_id) = 0;
// Notifies SyncManager that there are no other known active devices.
virtual void UpdateSingleClientStatus(bool single_client) = 0;
};
} // namespace syncer
......
......@@ -91,6 +91,7 @@ std::unique_ptr<Commit> Commit::Init(ModelTypeSet enabled_types,
const std::string& cache_guid,
bool cookie_jar_mismatch,
bool cookie_jar_empty,
bool single_client,
CommitProcessor* commit_processor,
ExtensionsActivity* extensions_activity) {
// Gather per-type contributions.
......@@ -123,7 +124,7 @@ std::unique_ptr<Commit> Commit::Init(ModelTypeSet enabled_types,
// Set the client config params.
commit_util::AddClientConfigParamsToMessage(
enabled_types, cookie_jar_mismatch, commit_message);
enabled_types, cookie_jar_mismatch, single_client, commit_message);
// Finally, serialize all our contributions.
for (const auto& contribution : contributions) {
......
......@@ -51,6 +51,7 @@ class Commit {
const std::string& cache_guid,
bool cookie_jar_mismatch,
bool cookie_jar_empty,
bool single_client,
CommitProcessor* commit_processor,
ExtensionsActivity* extensions_activity);
......
......@@ -34,6 +34,7 @@ void AddExtensionsActivityToMessage(
void AddClientConfigParamsToMessage(ModelTypeSet enabled_types,
bool cookie_jar_mismatch,
bool single_client,
sync_pb::CommitMessage* message) {
sync_pb::ClientConfigParams* config_params = message->mutable_config_params();
for (ModelType type : enabled_types) {
......@@ -44,6 +45,7 @@ void AddClientConfigParamsToMessage(ModelTypeSet enabled_types,
}
config_params->set_tabs_datatype_enabled(enabled_types.Has(PROXY_TABS));
config_params->set_cookie_jar_mismatch(cookie_jar_mismatch);
config_params->set_single_client(single_client);
}
} // namespace commit_util
......
......@@ -28,6 +28,7 @@ void AddExtensionsActivityToMessage(
// Fills the config_params field of |message|.
void AddClientConfigParamsToMessage(ModelTypeSet enabled_types,
bool cookie_jar_mismatch,
bool single_client,
sync_pb::CommitMessage* message);
} // namespace commit_util
......
......@@ -31,6 +31,7 @@ SyncCycleContext::SyncCycleContext(
invalidator_client_id_(invalidator_client_id),
cookie_jar_mismatch_(false),
cookie_jar_empty_(false),
single_client_(false),
poll_interval_(poll_interval) {
DCHECK(!poll_interval.is_zero());
std::vector<SyncEngineEventListener*>::const_iterator it;
......
......@@ -116,6 +116,9 @@ class SyncCycleContext {
void set_cookie_jar_empty(bool empty_jar) { cookie_jar_empty_ = empty_jar; }
bool single_client() const { return single_client_; }
void set_single_client(bool single_client) { single_client_ = single_client; }
base::TimeDelta poll_interval() const { return poll_interval_; }
void set_poll_interval(base::TimeDelta interval) {
DCHECK(!interval.is_zero());
......@@ -170,6 +173,9 @@ class SyncCycleContext {
// If there's a cookie jar mismatch, whether the cookie jar was empty or not.
bool cookie_jar_empty_;
// If there are no other known active devices.
bool single_client_;
base::TimeDelta poll_interval_;
DISALLOW_COPY_AND_ASSIGN(SyncCycleContext);
......
......@@ -566,4 +566,8 @@ void SyncManagerImpl::UpdateInvalidationClientId(const std::string& client_id) {
cycle_context_->set_invalidator_client_id(client_id);
}
void SyncManagerImpl::UpdateSingleClientStatus(bool single_client) {
cycle_context_->set_single_client(single_client);
}
} // namespace syncer
......@@ -84,6 +84,7 @@ class SyncManagerImpl
override;
void OnCookieJarChanged(bool account_mismatch, bool empty_jar) override;
void UpdateInvalidationClientId(const std::string& client_id) override;
void UpdateSingleClientStatus(bool single_client) override;
// SyncEncryptionHandler::Observer implementation.
void OnPassphraseRequired(
......
......@@ -150,8 +150,8 @@ SyncerError Syncer::BuildAndPostCommits(const ModelTypeSet& request_types,
cycle->context()->max_commit_batch_size(),
cycle->context()->account_name(), cycle->context()->cache_guid(),
cycle->context()->cookie_jar_mismatch(),
cycle->context()->cookie_jar_empty(), &commit_processor,
cycle->context()->extensions_activity()));
cycle->context()->cookie_jar_empty(), cycle->context()->single_client(),
&commit_processor, cycle->context()->extensions_activity()));
if (!commit) {
break;
}
......
......@@ -272,6 +272,7 @@ VISIT_PROTO_FIELDS(const sync_pb::ClientConfigParams& proto) {
VISIT_REP(enabled_type_ids);
VISIT(tabs_datatype_enabled);
VISIT(cookie_jar_mismatch);
VISIT(single_client);
}
VISIT_PROTO_FIELDS(const sync_pb::ClientStatus& proto) {
......
......@@ -441,6 +441,12 @@ message ClientConfigParams {
// chrome account. If multiple accounts are present in the cookie jar, a
// mismatch implies all of them are different from the chrome account.
optional bool cookie_jar_mismatch = 3;
// Indicates that the client is not aware of any other active clients for the
// user. This flag shows that it is not necessary to send invalidations for
// the committed data. The client is considered active if it's DeviceInfo has
// updated recent enough.
optional bool single_client = 4;
}
message CommitMessage {
......
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