Commit 0e7f03fd authored by Paula Vidas's avatar Paula Vidas Committed by Commit Bot

[SyncInvalidations] Send GetUpdates after interested data types change.

This is to work around race conditions, between one device enabling a
data type (and marking it as "interesting") vs. another device
committing some new data for the type.

Bug: 1126014
Change-Id: I53cb8f8db17d0595a0ee2400fdc33a0299d0e1c9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2403640
Commit-Queue: Paula Vidas <paulavidas@google.com>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Cr-Commit-Position: refs/heads/master@{#807093}
parent b029a29f
...@@ -1466,7 +1466,9 @@ void ProfileSyncService::UpdateDataTypesForInvalidations() { ...@@ -1466,7 +1466,9 @@ void ProfileSyncService::UpdateDataTypesForInvalidations() {
if (!sessions_invalidations_enabled_) { if (!sessions_invalidations_enabled_) {
types.Remove(SESSIONS); types.Remove(SESSIONS);
} }
invalidations_service->SetInterestedDataTypes(types); invalidations_service->SetInterestedDataTypes(
types, base::BindRepeating(&ProfileSyncService::TriggerRefresh,
sync_enabled_weak_factory_.GetWeakPtr()));
} }
SyncCycleSnapshot ProfileSyncService::GetLastCycleSnapshotForDebugging() const { SyncCycleSnapshot ProfileSyncService::GetLastCycleSnapshotForDebugging() const {
......
...@@ -1625,7 +1625,7 @@ TEST_F(ProfileSyncServiceTestWithSubscribeForSyncInvalidations, ...@@ -1625,7 +1625,7 @@ TEST_F(ProfileSyncServiceTestWithSubscribeForSyncInvalidations,
ShouldSendDataTypesToSyncInvalidationsService) { ShouldSendDataTypesToSyncInvalidationsService) {
CreateService(ProfileSyncService::AUTO_START); CreateService(ProfileSyncService::AUTO_START);
SignIn(); SignIn();
EXPECT_CALL(*sync_invalidations_service(), SetInterestedDataTypes(_)); EXPECT_CALL(*sync_invalidations_service(), SetInterestedDataTypes(_, _));
InitializeForFirstSync(); InitializeForFirstSync();
} }
...@@ -1641,10 +1641,10 @@ TEST_F(ProfileSyncServiceTestWithSubscribeForSyncInvalidations, ...@@ -1641,10 +1641,10 @@ TEST_F(ProfileSyncServiceTestWithSubscribeForSyncInvalidations,
InitializeForNthSync(); InitializeForNthSync();
EXPECT_CALL(*sync_invalidations_service(), EXPECT_CALL(*sync_invalidations_service(),
SetInterestedDataTypes(ContainsSessions())); SetInterestedDataTypes(ContainsSessions(), _));
service()->SetInvalidationsForSessionsEnabled(true); service()->SetInvalidationsForSessionsEnabled(true);
EXPECT_CALL(*sync_invalidations_service(), EXPECT_CALL(*sync_invalidations_service(),
SetInterestedDataTypes(Not(ContainsSessions()))); SetInterestedDataTypes(Not(ContainsSessions()), _));
service()->SetInvalidationsForSessionsEnabled(false); service()->SetInvalidationsForSessionsEnabled(false);
} }
......
...@@ -9,9 +9,9 @@ static_library("invalidations") { ...@@ -9,9 +9,9 @@ static_library("invalidations") {
"fcm_handler.cc", "fcm_handler.cc",
"fcm_handler.h", "fcm_handler.h",
"fcm_registration_token_observer.h", "fcm_registration_token_observer.h",
"interested_data_types_handler.h",
"interested_data_types_manager.cc", "interested_data_types_manager.cc",
"interested_data_types_manager.h", "interested_data_types_manager.h",
"interested_data_types_observer.h",
"invalidations_listener.h", "invalidations_listener.h",
"switches.cc", "switches.cc",
"switches.h", "switches.h",
......
...@@ -2,21 +2,22 @@ ...@@ -2,21 +2,22 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_OBSERVER_H_ #ifndef COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_HANDLER_H_
#define COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_OBSERVER_H_ #define COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_HANDLER_H_
#include "base/observer_list.h" #include "base/callback.h"
namespace syncer { namespace syncer {
// An interface to observe changes on data types for which the device wants to // An interface to handle changes on data types for which the device wants to
// receive invalidations. // receive invalidations. Implementations are expected to call the provided
class InterestedDataTypesObserver : public base::CheckedObserver { // callback when the list of data types is sent to the Sync server.
class InterestedDataTypesHandler {
public: public:
// Called on each change of interested data types. // Called on each change of interested data types.
virtual void OnInterestedDataTypesChanged() = 0; virtual void OnInterestedDataTypesChanged(base::OnceClosure callback) = 0;
}; };
} // namespace syncer } // namespace syncer
#endif // COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_OBSERVER_H_ #endif // COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_HANDLER_H_
...@@ -4,22 +4,24 @@ ...@@ -4,22 +4,24 @@
#include "components/sync/invalidations/interested_data_types_manager.h" #include "components/sync/invalidations/interested_data_types_manager.h"
#include "components/sync/invalidations/interested_data_types_observer.h" #include <utility>
#include "base/bind.h"
#include "components/sync/base/model_type.h"
#include "components/sync/invalidations/interested_data_types_handler.h"
namespace syncer { namespace syncer {
InterestedDataTypesManager::InterestedDataTypesManager() = default; InterestedDataTypesManager::InterestedDataTypesManager() = default;
InterestedDataTypesManager::~InterestedDataTypesManager() = default; InterestedDataTypesManager::~InterestedDataTypesManager() {
DCHECK(!interested_data_types_handler_);
void InterestedDataTypesManager::AddInterestedDataTypesObserver(
InterestedDataTypesObserver* observer) {
observers_.AddObserver(observer);
} }
void InterestedDataTypesManager::RemoveInterestedDataTypesObserver( void InterestedDataTypesManager::SetInterestedDataTypesHandler(
InterestedDataTypesObserver* observer) { InterestedDataTypesHandler* handler) {
observers_.RemoveObserver(observer); DCHECK(!interested_data_types_handler_ || !handler);
interested_data_types_handler_ = handler;
} }
const ModelTypeSet& InterestedDataTypesManager::GetInterestedDataTypes() const { const ModelTypeSet& InterestedDataTypesManager::GetInterestedDataTypes() const {
...@@ -27,10 +29,13 @@ const ModelTypeSet& InterestedDataTypesManager::GetInterestedDataTypes() const { ...@@ -27,10 +29,13 @@ const ModelTypeSet& InterestedDataTypesManager::GetInterestedDataTypes() const {
} }
void InterestedDataTypesManager::SetInterestedDataTypes( void InterestedDataTypesManager::SetInterestedDataTypes(
const ModelTypeSet& data_types) { const ModelTypeSet& data_types,
SyncInvalidationsService::InterestedDataTypesAppliedCallback callback) {
ModelTypeSet new_data_types = Difference(data_types, data_types_);
data_types_ = data_types; data_types_ = data_types;
for (InterestedDataTypesObserver& observer : observers_) { if (interested_data_types_handler_) {
observer.OnInterestedDataTypesChanged(); interested_data_types_handler_->OnInterestedDataTypesChanged(
base::BindOnce(std::move(callback), new_data_types));
} }
} }
......
...@@ -5,11 +5,11 @@ ...@@ -5,11 +5,11 @@
#ifndef COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_MANAGER_H_ #ifndef COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_MANAGER_H_
#define COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_MANAGER_H_ #define COMPONENTS_SYNC_INVALIDATIONS_INTERESTED_DATA_TYPES_MANAGER_H_
#include "base/observer_list.h"
#include "components/sync/base/model_type.h" #include "components/sync/base/model_type.h"
#include "components/sync/invalidations/sync_invalidations_service.h"
namespace syncer { namespace syncer {
class InterestedDataTypesObserver; class InterestedDataTypesHandler;
// Manages for which data types are invalidations sent to this device. // Manages for which data types are invalidations sent to this device.
class InterestedDataTypesManager { class InterestedDataTypesManager {
...@@ -20,20 +20,18 @@ class InterestedDataTypesManager { ...@@ -20,20 +20,18 @@ class InterestedDataTypesManager {
InterestedDataTypesManager& operator=(const InterestedDataTypesManager&) = InterestedDataTypesManager& operator=(const InterestedDataTypesManager&) =
delete; delete;
// Add or remove a interested data types change observer. |observer| must not // Set the interested data types change handler. |handler| can be nullptr to
// be nullptr. // unregister any existing handler. There can be at most one handler.
void AddInterestedDataTypesObserver(InterestedDataTypesObserver* observer); void SetInterestedDataTypesHandler(InterestedDataTypesHandler* handler);
void RemoveInterestedDataTypesObserver(InterestedDataTypesObserver* observer);
// Get or set the interested data types. // Get or set the interested data types.
const ModelTypeSet& GetInterestedDataTypes() const; const ModelTypeSet& GetInterestedDataTypes() const;
void SetInterestedDataTypes(const ModelTypeSet& data_types); void SetInterestedDataTypes(
const ModelTypeSet& data_types,
SyncInvalidationsService::InterestedDataTypesAppliedCallback callback);
private: private:
base::ObserverList<InterestedDataTypesObserver, InterestedDataTypesHandler* interested_data_types_handler_ = nullptr;
/*check_empty=*/true,
/*allow_reentrancy=*/false>
observers_;
ModelTypeSet data_types_; ModelTypeSet data_types_;
}; };
......
...@@ -4,16 +4,19 @@ ...@@ -4,16 +4,19 @@
#include "components/sync/invalidations/interested_data_types_manager.h" #include "components/sync/invalidations/interested_data_types_manager.h"
#include "components/sync/invalidations/interested_data_types_observer.h" #include "base/bind_helpers.h"
#include "components/sync/invalidations/interested_data_types_handler.h"
#include "testing/gmock/include/gmock/gmock.h" #include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using testing::_;
namespace syncer { namespace syncer {
namespace { namespace {
class MockDataTypesObserver : public InterestedDataTypesObserver { class MockDataTypesHandler : public InterestedDataTypesHandler {
public: public:
MOCK_METHOD0(OnInterestedDataTypesChanged, void()); MOCK_METHOD1(OnInterestedDataTypesChanged, void(base::OnceClosure callback));
}; };
class InterestedDataTypesManagerTest : public testing::Test { class InterestedDataTypesManagerTest : public testing::Test {
...@@ -22,20 +25,23 @@ class InterestedDataTypesManagerTest : public testing::Test { ...@@ -22,20 +25,23 @@ class InterestedDataTypesManagerTest : public testing::Test {
}; };
TEST_F(InterestedDataTypesManagerTest, ShouldReturnGivenDataTypes) { TEST_F(InterestedDataTypesManagerTest, ShouldReturnGivenDataTypes) {
manager_.SetInterestedDataTypes(ModelTypeSet(BOOKMARKS, PREFERENCES)); manager_.SetInterestedDataTypes(ModelTypeSet(BOOKMARKS, PREFERENCES),
base::DoNothing());
EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES), EXPECT_EQ(ModelTypeSet(BOOKMARKS, PREFERENCES),
manager_.GetInterestedDataTypes()); manager_.GetInterestedDataTypes());
manager_.SetInterestedDataTypes(ModelTypeSet(PREFERENCES, PASSWORDS)); manager_.SetInterestedDataTypes(ModelTypeSet(PREFERENCES, PASSWORDS),
base::DoNothing());
EXPECT_EQ(ModelTypeSet(PREFERENCES, PASSWORDS), EXPECT_EQ(ModelTypeSet(PREFERENCES, PASSWORDS),
manager_.GetInterestedDataTypes()); manager_.GetInterestedDataTypes());
} }
TEST_F(InterestedDataTypesManagerTest, ShouldNotifyOnChange) { TEST_F(InterestedDataTypesManagerTest, ShouldNotifyOnChange) {
testing::NiceMock<MockDataTypesObserver> observer; testing::NiceMock<MockDataTypesHandler> handler;
manager_.AddInterestedDataTypesObserver(&observer); manager_.SetInterestedDataTypesHandler(&handler);
EXPECT_CALL(observer, OnInterestedDataTypesChanged()); EXPECT_CALL(handler, OnInterestedDataTypesChanged(_));
manager_.SetInterestedDataTypes(ModelTypeSet(PASSWORDS, AUTOFILL)); manager_.SetInterestedDataTypes(ModelTypeSet(PASSWORDS, AUTOFILL),
manager_.RemoveInterestedDataTypesObserver(&observer); base::DoNothing());
manager_.SetInterestedDataTypesHandler(nullptr);
} }
} // namespace } // namespace
......
...@@ -28,13 +28,13 @@ class MockSyncInvalidationsService : public SyncInvalidationsService { ...@@ -28,13 +28,13 @@ class MockSyncInvalidationsService : public SyncInvalidationsService {
(FCMRegistrationTokenObserver * observer)); (FCMRegistrationTokenObserver * observer));
MOCK_METHOD(const std::string&, GetFCMRegistrationToken, (), (const)); MOCK_METHOD(const std::string&, GetFCMRegistrationToken, (), (const));
MOCK_METHOD(void, MOCK_METHOD(void,
AddInterestedDataTypesObserver, SetInterestedDataTypesHandler,
(InterestedDataTypesObserver * observer)); (InterestedDataTypesHandler * handler));
MOCK_METHOD(void,
RemoveInterestedDataTypesObserver,
(InterestedDataTypesObserver * observer));
MOCK_METHOD(const ModelTypeSet&, GetInterestedDataTypes, (), (const)); MOCK_METHOD(const ModelTypeSet&, GetInterestedDataTypes, (), (const));
MOCK_METHOD(void, SetInterestedDataTypes, (const ModelTypeSet& data_types)); MOCK_METHOD(void,
SetInterestedDataTypes,
(const ModelTypeSet& data_types,
InterestedDataTypesAppliedCallback callback));
}; };
} // namespace syncer } // namespace syncer
......
...@@ -7,13 +7,14 @@ ...@@ -7,13 +7,14 @@
#include <string> #include <string>
#include "base/callback.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
#include "components/sync/base/model_type.h" #include "components/sync/base/model_type.h"
namespace syncer { namespace syncer {
class FCMRegistrationTokenObserver; class FCMRegistrationTokenObserver;
class InvalidationsListener; class InvalidationsListener;
class InterestedDataTypesObserver; class InterestedDataTypesHandler;
// Service which is used to register with FCM. It is used to obtain an FCM token // Service which is used to register with FCM. It is used to obtain an FCM token
// which is used to send invalidations from the server. The service also // which is used to send invalidations from the server. The service also
...@@ -22,6 +23,11 @@ class InterestedDataTypesObserver; ...@@ -22,6 +23,11 @@ class InterestedDataTypesObserver;
// should be added. // should be added.
class SyncInvalidationsService : public KeyedService { class SyncInvalidationsService : public KeyedService {
public: public:
// Data types which are newly marked as interesting will be passed to the
// callback.
using InterestedDataTypesAppliedCallback =
base::OnceCallback<void(const ModelTypeSet&)>;
// Start or stop listening to invalidations. // Start or stop listening to invalidations.
virtual void SetActive(bool active) = 0; virtual void SetActive(bool active) = 0;
...@@ -39,16 +45,16 @@ class SyncInvalidationsService : public KeyedService { ...@@ -39,16 +45,16 @@ class SyncInvalidationsService : public KeyedService {
// received yet. // received yet.
virtual const std::string& GetFCMRegistrationToken() const = 0; virtual const std::string& GetFCMRegistrationToken() const = 0;
// Add or remove an interested data types change observer. |observer| must not // Set the interested data types change handler. |handler| can be nullptr to
// be nullptr. // unregister any existing handler. There can be at most one handler.
virtual void AddInterestedDataTypesObserver( virtual void SetInterestedDataTypesHandler(
InterestedDataTypesObserver* observer) = 0; InterestedDataTypesHandler* handler) = 0;
virtual void RemoveInterestedDataTypesObserver(
InterestedDataTypesObserver* observer) = 0;
// Get or set for which data types should the device receive invalidations. // Get or set for which data types should the device receive invalidations.
virtual const ModelTypeSet& GetInterestedDataTypes() const = 0; virtual const ModelTypeSet& GetInterestedDataTypes() const = 0;
virtual void SetInterestedDataTypes(const ModelTypeSet& data_types) = 0; virtual void SetInterestedDataTypes(
const ModelTypeSet& data_types,
InterestedDataTypesAppliedCallback callback) = 0;
}; };
} // namespace syncer } // namespace syncer
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "components/sync/invalidations/sync_invalidations_service_impl.h" #include "components/sync/invalidations/sync_invalidations_service_impl.h"
#include <utility>
#include "components/sync/invalidations/fcm_handler.h" #include "components/sync/invalidations/fcm_handler.h"
namespace syncer { namespace syncer {
...@@ -62,14 +64,9 @@ const std::string& SyncInvalidationsServiceImpl::GetFCMRegistrationToken() ...@@ -62,14 +64,9 @@ const std::string& SyncInvalidationsServiceImpl::GetFCMRegistrationToken()
return fcm_handler_->GetFCMRegistrationToken(); return fcm_handler_->GetFCMRegistrationToken();
} }
void SyncInvalidationsServiceImpl::AddInterestedDataTypesObserver( void SyncInvalidationsServiceImpl::SetInterestedDataTypesHandler(
InterestedDataTypesObserver* observer) { InterestedDataTypesHandler* handler) {
data_types_manager_.AddInterestedDataTypesObserver(observer); data_types_manager_.SetInterestedDataTypesHandler(handler);
}
void SyncInvalidationsServiceImpl::RemoveInterestedDataTypesObserver(
InterestedDataTypesObserver* observer) {
data_types_manager_.RemoveInterestedDataTypesObserver(observer);
} }
const ModelTypeSet& SyncInvalidationsServiceImpl::GetInterestedDataTypes() const ModelTypeSet& SyncInvalidationsServiceImpl::GetInterestedDataTypes()
...@@ -78,8 +75,9 @@ const ModelTypeSet& SyncInvalidationsServiceImpl::GetInterestedDataTypes() ...@@ -78,8 +75,9 @@ const ModelTypeSet& SyncInvalidationsServiceImpl::GetInterestedDataTypes()
} }
void SyncInvalidationsServiceImpl::SetInterestedDataTypes( void SyncInvalidationsServiceImpl::SetInterestedDataTypes(
const ModelTypeSet& data_types) { const ModelTypeSet& data_types,
data_types_manager_.SetInterestedDataTypes(data_types); InterestedDataTypesAppliedCallback callback) {
data_types_manager_.SetInterestedDataTypes(data_types, std::move(callback));
} }
void SyncInvalidationsServiceImpl::Shutdown() { void SyncInvalidationsServiceImpl::Shutdown() {
......
...@@ -38,12 +38,12 @@ class SyncInvalidationsServiceImpl : public SyncInvalidationsService { ...@@ -38,12 +38,12 @@ class SyncInvalidationsServiceImpl : public SyncInvalidationsService {
void AddTokenObserver(FCMRegistrationTokenObserver* observer) override; void AddTokenObserver(FCMRegistrationTokenObserver* observer) override;
void RemoveTokenObserver(FCMRegistrationTokenObserver* observer) override; void RemoveTokenObserver(FCMRegistrationTokenObserver* observer) override;
const std::string& GetFCMRegistrationToken() const override; const std::string& GetFCMRegistrationToken() const override;
void AddInterestedDataTypesObserver( void SetInterestedDataTypesHandler(
InterestedDataTypesObserver* observer) override; InterestedDataTypesHandler* handler) override;
void RemoveInterestedDataTypesObserver(
InterestedDataTypesObserver* observer) override;
const ModelTypeSet& GetInterestedDataTypes() const override; const ModelTypeSet& GetInterestedDataTypes() const override;
void SetInterestedDataTypes(const ModelTypeSet& data_types) override; void SetInterestedDataTypes(
const ModelTypeSet& data_types,
InterestedDataTypesAppliedCallback callback) override;
// KeyedService overrides. // KeyedService overrides.
void Shutdown() override; void Shutdown() override;
......
...@@ -225,7 +225,11 @@ LocalDeviceInfoProvider* DeviceInfoSyncBridge::GetLocalDeviceInfoProvider() { ...@@ -225,7 +225,11 @@ LocalDeviceInfoProvider* DeviceInfoSyncBridge::GetLocalDeviceInfoProvider() {
return local_device_info_provider_.get(); return local_device_info_provider_.get();
} }
void DeviceInfoSyncBridge::RefreshLocalDeviceInfo() { void DeviceInfoSyncBridge::RefreshLocalDeviceInfo(base::OnceClosure callback) {
if (!callback.is_null()) {
device_info_synced_callback_list_.push_back(std::move(callback));
}
SendLocalData(); SendLocalData();
} }
...@@ -318,6 +322,15 @@ base::Optional<ModelError> DeviceInfoSyncBridge::ApplySyncChanges( ...@@ -318,6 +322,15 @@ base::Optional<ModelError> DeviceInfoSyncBridge::ApplySyncChanges(
batch->TakeMetadataChangesFrom(std::move(metadata_change_list)); batch->TakeMetadataChangesFrom(std::move(metadata_change_list));
CommitAndNotify(std::move(batch), has_changes); CommitAndNotify(std::move(batch), has_changes);
DCHECK(!local_cache_guid_.empty());
if (!change_processor()->IsEntityUnsynced(local_cache_guid_)) {
for (base::OnceClosure& callback : device_info_synced_callback_list_) {
std::move(callback).Run();
}
device_info_synced_callback_list_.clear();
}
return base::nullopt; return base::nullopt;
} }
......
...@@ -51,8 +51,9 @@ class DeviceInfoSyncBridge : public ModelTypeSyncBridge, ...@@ -51,8 +51,9 @@ class DeviceInfoSyncBridge : public ModelTypeSyncBridge,
// Refresh local copy of device info in memory, and informs sync of the // Refresh local copy of device info in memory, and informs sync of the
// change. Used when the caller knows a property of local device info has // change. Used when the caller knows a property of local device info has
// changed (e.g. SharingInfo), and must be sync-ed to other devices as soon as // changed (e.g. SharingInfo), and must be sync-ed to other devices as soon as
// possible, without waiting for the periodic commits. // possible, without waiting for the periodic commits. |callback| will be
void RefreshLocalDeviceInfo(); // called when device info is synced.
void RefreshLocalDeviceInfo(base::OnceClosure callback);
// ModelTypeSyncBridge implementation. // ModelTypeSyncBridge implementation.
void OnSyncStarting(const DataTypeActivationRequest& request) override; void OnSyncStarting(const DataTypeActivationRequest& request) override;
...@@ -163,6 +164,8 @@ class DeviceInfoSyncBridge : public ModelTypeSyncBridge, ...@@ -163,6 +164,8 @@ class DeviceInfoSyncBridge : public ModelTypeSyncBridge,
// Used to update our local device info once every pulse interval. // Used to update our local device info once every pulse interval.
base::OneShotTimer pulse_timer_; base::OneShotTimer pulse_timer_;
std::vector<base::OnceClosure> device_info_synced_callback_list_;
const std::unique_ptr<DeviceInfoPrefs> device_info_prefs_; const std::unique_ptr<DeviceInfoPrefs> device_info_prefs_;
base::WeakPtrFactory<DeviceInfoSyncBridge> weak_ptr_factory_{this}; base::WeakPtrFactory<DeviceInfoSyncBridge> weak_ptr_factory_{this};
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/run_loop.h" #include "base/run_loop.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/test/bind_test_util.h" #include "base/test/bind_test_util.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h" #include "base/test/scoped_feature_list.h"
#include "base/test/simple_test_clock.h" #include "base/test/simple_test_clock.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
...@@ -502,7 +503,9 @@ class DeviceInfoSyncBridgeTest : public testing::Test, ...@@ -502,7 +503,9 @@ class DeviceInfoSyncBridgeTest : public testing::Test,
void ForcePulse() { bridge()->ForcePulseForTest(); } void ForcePulse() { bridge()->ForcePulseForTest(); }
void RefreshLocalDeviceInfo() { bridge()->RefreshLocalDeviceInfo(); } void RefreshLocalDeviceInfo() {
bridge()->RefreshLocalDeviceInfo(base::OnceClosure());
}
void CommitToStoreAndWait(std::unique_ptr<WriteBatch> batch) { void CommitToStoreAndWait(std::unique_ptr<WriteBatch> batch) {
base::RunLoop loop; base::RunLoop loop;
...@@ -1307,6 +1310,24 @@ TEST_F(DeviceInfoSyncBridgeTest, ShouldSendInvalidationFields) { ...@@ -1307,6 +1310,24 @@ TEST_F(DeviceInfoSyncBridgeTest, ShouldSendInvalidationFields) {
InitializeAndMergeInitialData(SyncMode::kFull); InitializeAndMergeInitialData(SyncMode::kFull);
} }
TEST_F(DeviceInfoSyncBridgeTest, ShouldNotifyWhenDeviceInfoIsSynced) {
InitializeAndMergeInitialData(SyncMode::kFull);
base::MockOnceClosure callback;
bridge()->RefreshLocalDeviceInfo(callback.Get());
std::string guid = local_device()->GetLocalDeviceInfo()->guid();
EXPECT_CALL(*processor(), IsEntityUnsynced(guid)).WillOnce(Return(true));
EXPECT_CALL(callback, Run()).Times(0);
bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(),
EntityChangeList());
EXPECT_CALL(*processor(), IsEntityUnsynced(guid)).WillOnce(Return(false));
EXPECT_CALL(callback, Run());
bridge()->ApplySyncChanges(bridge()->CreateMetadataChangeList(),
EntityChangeList());
}
} // namespace } // namespace
} // namespace syncer } // namespace syncer
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <memory> #include <memory>
#include <string> #include <string>
#include "base/callback.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "components/keyed_service/core/keyed_service.h" #include "components/keyed_service/core/keyed_service.h"
...@@ -37,8 +38,10 @@ class DeviceInfoSyncService : public KeyedService { ...@@ -37,8 +38,10 @@ class DeviceInfoSyncService : public KeyedService {
// Interface to refresh local copy of device info in memory, and informs sync // Interface to refresh local copy of device info in memory, and informs sync
// of the change. Used when the caller knows a property of local device info // of the change. Used when the caller knows a property of local device info
// has changed (e.g. SharingInfo), and must be sync-ed to other devices as // has changed (e.g. SharingInfo), and must be sync-ed to other devices as
// soon as possible, without waiting for the periodic commits. // soon as possible, without waiting for the periodic commits. |callback| will
virtual void RefreshLocalDeviceInfo() = 0; // be called when device info is synced.
virtual void RefreshLocalDeviceInfo(
base::OnceClosure callback = base::OnceClosure()) = 0;
}; };
} // namespace syncer } // namespace syncer
......
...@@ -46,7 +46,7 @@ DeviceInfoSyncServiceImpl::DeviceInfoSyncServiceImpl( ...@@ -46,7 +46,7 @@ DeviceInfoSyncServiceImpl::DeviceInfoSyncServiceImpl(
if (sync_invalidations_service_) { if (sync_invalidations_service_) {
sync_invalidations_service_->AddTokenObserver(this); sync_invalidations_service_->AddTokenObserver(this);
sync_invalidations_service_->AddInterestedDataTypesObserver(this); sync_invalidations_service_->SetInterestedDataTypesHandler(this);
} }
} }
...@@ -66,22 +66,24 @@ DeviceInfoSyncServiceImpl::GetControllerDelegate() { ...@@ -66,22 +66,24 @@ DeviceInfoSyncServiceImpl::GetControllerDelegate() {
return bridge_->change_processor()->GetControllerDelegate(); return bridge_->change_processor()->GetControllerDelegate();
} }
void DeviceInfoSyncServiceImpl::RefreshLocalDeviceInfo() { void DeviceInfoSyncServiceImpl::RefreshLocalDeviceInfo(
bridge_->RefreshLocalDeviceInfo(); base::OnceClosure callback) {
bridge_->RefreshLocalDeviceInfo(std::move(callback));
} }
void DeviceInfoSyncServiceImpl::OnFCMRegistrationTokenChanged() { void DeviceInfoSyncServiceImpl::OnFCMRegistrationTokenChanged() {
RefreshLocalDeviceInfo(); RefreshLocalDeviceInfo();
} }
void DeviceInfoSyncServiceImpl::OnInterestedDataTypesChanged() { void DeviceInfoSyncServiceImpl::OnInterestedDataTypesChanged(
RefreshLocalDeviceInfo(); base::OnceClosure callback) {
RefreshLocalDeviceInfo(std::move(callback));
} }
void DeviceInfoSyncServiceImpl::Shutdown() { void DeviceInfoSyncServiceImpl::Shutdown() {
if (sync_invalidations_service_) { if (sync_invalidations_service_) {
sync_invalidations_service_->RemoveTokenObserver(this); sync_invalidations_service_->RemoveTokenObserver(this);
sync_invalidations_service_->RemoveInterestedDataTypesObserver(this); sync_invalidations_service_->SetInterestedDataTypesHandler(nullptr);
} }
} }
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <string> #include <string>
#include "components/sync/invalidations/fcm_registration_token_observer.h" #include "components/sync/invalidations/fcm_registration_token_observer.h"
#include "components/sync/invalidations/interested_data_types_observer.h" #include "components/sync/invalidations/interested_data_types_handler.h"
#include "components/sync/model/model_type_store.h" #include "components/sync/model/model_type_store.h"
#include "components/sync_device_info/device_info_sync_service.h" #include "components/sync_device_info/device_info_sync_service.h"
...@@ -23,7 +23,7 @@ class SyncInvalidationsService; ...@@ -23,7 +23,7 @@ class SyncInvalidationsService;
class DeviceInfoSyncServiceImpl : public DeviceInfoSyncService, class DeviceInfoSyncServiceImpl : public DeviceInfoSyncService,
public FCMRegistrationTokenObserver, public FCMRegistrationTokenObserver,
public InterestedDataTypesObserver { public InterestedDataTypesHandler {
public: public:
// |local_device_info_provider| must not be null. // |local_device_info_provider| must not be null.
// |device_info_prefs| must not be null. // |device_info_prefs| must not be null.
...@@ -43,13 +43,14 @@ class DeviceInfoSyncServiceImpl : public DeviceInfoSyncService, ...@@ -43,13 +43,14 @@ class DeviceInfoSyncServiceImpl : public DeviceInfoSyncService,
LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() override; LocalDeviceInfoProvider* GetLocalDeviceInfoProvider() override;
DeviceInfoTracker* GetDeviceInfoTracker() override; DeviceInfoTracker* GetDeviceInfoTracker() override;
base::WeakPtr<ModelTypeControllerDelegate> GetControllerDelegate() override; base::WeakPtr<ModelTypeControllerDelegate> GetControllerDelegate() override;
void RefreshLocalDeviceInfo() override; void RefreshLocalDeviceInfo(
base::OnceClosure callback = base::OnceClosure()) override;
// FCMRegistrationTokenObserver implementation. // FCMRegistrationTokenObserver implementation.
void OnFCMRegistrationTokenChanged() override; void OnFCMRegistrationTokenChanged() override;
// InterestedDataTypesObserver implementation. // InterestedDataTypesHandler implementation.
void OnInterestedDataTypesChanged() override; void OnInterestedDataTypesChanged(base::OnceClosure callback) override;
// KeyedService overrides. // KeyedService overrides.
void Shutdown() override; void Shutdown() override;
......
...@@ -25,8 +25,12 @@ FakeDeviceInfoSyncService::GetControllerDelegate() { ...@@ -25,8 +25,12 @@ FakeDeviceInfoSyncService::GetControllerDelegate() {
return fake_model_type_controller_delegate_.GetWeakPtr(); return fake_model_type_controller_delegate_.GetWeakPtr();
} }
void FakeDeviceInfoSyncService::RefreshLocalDeviceInfo() { void FakeDeviceInfoSyncService::RefreshLocalDeviceInfo(
base::OnceClosure callback) {
refresh_local_device_info_count_++; refresh_local_device_info_count_++;
if (!callback.is_null()) {
std::move(callback).Run();
}
} }
int FakeDeviceInfoSyncService::RefreshLocalDeviceInfoCount() { int FakeDeviceInfoSyncService::RefreshLocalDeviceInfoCount() {
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef COMPONENTS_SYNC_DEVICE_INFO_FAKE_DEVICE_INFO_SYNC_SERVICE_H_ #ifndef COMPONENTS_SYNC_DEVICE_INFO_FAKE_DEVICE_INFO_SYNC_SERVICE_H_
#define COMPONENTS_SYNC_DEVICE_INFO_FAKE_DEVICE_INFO_SYNC_SERVICE_H_ #define COMPONENTS_SYNC_DEVICE_INFO_FAKE_DEVICE_INFO_SYNC_SERVICE_H_
#include "base/callback.h"
#include "components/sync/model/fake_model_type_controller_delegate.h" #include "components/sync/model/fake_model_type_controller_delegate.h"
#include "components/sync_device_info/device_info_sync_service.h" #include "components/sync_device_info/device_info_sync_service.h"
#include "components/sync_device_info/fake_device_info_tracker.h" #include "components/sync_device_info/fake_device_info_tracker.h"
...@@ -21,9 +22,9 @@ class FakeDeviceInfoSyncService : public DeviceInfoSyncService { ...@@ -21,9 +22,9 @@ class FakeDeviceInfoSyncService : public DeviceInfoSyncService {
FakeLocalDeviceInfoProvider* GetLocalDeviceInfoProvider() override; FakeLocalDeviceInfoProvider* GetLocalDeviceInfoProvider() override;
FakeDeviceInfoTracker* GetDeviceInfoTracker() override; FakeDeviceInfoTracker* GetDeviceInfoTracker() override;
base::WeakPtr<ModelTypeControllerDelegate> GetControllerDelegate() override; base::WeakPtr<ModelTypeControllerDelegate> GetControllerDelegate() override;
void RefreshLocalDeviceInfo() override; void RefreshLocalDeviceInfo(base::OnceClosure callback) override;
// Returns number of times RefreshLocalDeviceInfo() has neen called. // Returns number of times RefreshLocalDeviceInfo() has been called.
int RefreshLocalDeviceInfoCount(); int RefreshLocalDeviceInfoCount();
private: private:
......
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