Commit d3c720e6 authored by Paula Vidas's avatar Paula Vidas Committed by Commit Bot

[SyncInvalidations] Add interested data types to device info specifics.

This CL adds a field to device info specifics for a list of data types for which the device wants to receive invalidations.
The list will be used by the sync server to send invalidations for only those types.

The data types are obtained from SyncInvalidationsService.

Bug: 1102312
Change-Id: Ia85f2b523d1f9adeef84dc4562d1bd525615e368
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2387113Reviewed-by: default avatarJeffrey Cohen <jeffreycohen@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Reviewed-by: default avatarRushan Suleymanov <rushans@google.com>
Commit-Queue: Paula Vidas <paulavidas@google.com>
Cr-Commit-Position: refs/heads/master@{#804144}
parent fe031a23
......@@ -26,7 +26,8 @@ std::unique_ptr<DeviceInfo> CreateDevice(const std::string& guid,
sync_pb::SyncEnums_DeviceType_TYPE_LINUX, device_id, "manufacturer",
"model", base::Time(), syncer::DeviceInfoUtil::GetPulseInterval(),
/*send_tab_to_self_receiving_enabled=*/true,
/*sharing_info=*/base::nullopt, /*fcm_registration_token=*/std::string());
/*sharing_info=*/base::nullopt, /*fcm_registration_token=*/std::string(),
/*interested_data_types=*/syncer::ModelTypeSet());
}
} // namespace
......
......@@ -37,7 +37,8 @@ std::unique_ptr<DeviceInfo> CreateDevice(const std::string& guid,
"model", base::Time(), syncer::DeviceInfoUtil::GetPulseInterval(),
/*send_tab_to_self_receiving_enabled=*/true,
/*sharing_info=*/base::nullopt,
/*fcm_registration_token=*/std::string());
/*fcm_registration_token=*/std::string(),
/*interested_data_types=*/syncer::ModelTypeSet());
}
} // namespace
......
......@@ -19,5 +19,6 @@ std::unique_ptr<syncer::DeviceInfo> CreateFakeDeviceInfo(
manufacturer_name, model_name, last_updated_timestamp,
syncer::DeviceInfoUtil::GetPulseInterval(),
/*send_tab_to_self_receiving_enabled=*/false, sharing_info,
/*fcm_registration_token=*/std::string());
/*fcm_registration_token=*/std::string(),
/*interested_data_types=*/syncer::ModelTypeSet());
}
......@@ -153,7 +153,8 @@ void SharingBrowserTest::AddDeviceInfo(
original_device.pulse_interval(),
original_device.send_tab_to_self_receiving_enabled(),
original_device.sharing_info(),
original_device.fcm_registration_token());
original_device.fcm_registration_token(),
original_device.interested_data_types());
fake_device_info_tracker_.Add(fake_device.get());
device_infos_.push_back(std::move(fake_device));
}
......
......@@ -78,7 +78,8 @@ std::unique_ptr<syncer::DeviceInfo> CreateDevice(
"model", last_updated_timestamp,
syncer::DeviceInfoUtil::GetPulseInterval(),
send_tab_to_self_receiving_enabled, /*sharing_info=*/base::nullopt,
/*fcm_registration_token=*/std::string());
/*fcm_registration_token=*/std::string(),
/*interested_data_types=*/syncer::ModelTypeSet());
}
sync_pb::ModelTypeState StateWithEncryption(
......
......@@ -41,7 +41,8 @@ static std::unique_ptr<syncer::DeviceInfo> CreateFakeDeviceInfo(
{"sender_id_fcm_token", "sender_id_p256dh", "sender_id_auth_secret"},
std::set<sync_pb::SharingSpecificFields::EnabledFeatures>{
sync_pb::SharingSpecificFields::CLICK_TO_CALL_V2}),
/*fcm_registration_token=*/std::string());
/*fcm_registration_token=*/std::string(),
/*interested_data_types=*/syncer::ModelTypeSet());
}
} // namespace
......
......@@ -148,5 +148,9 @@ message InvalidationSpecificFields {
// FCM registration token of device (using Sync sender ID).
optional string instance_id_token = 1;
// TODO(crbug.com/1082117): add data types list.
// This device wants to receive only invalidations which are related to these
// types. The legitimate values of this field correspond to the protobuf field
// numbers of all EntitySpecifics fields supported by the server (see
// components/sync/protocol/sync.proto).
repeated int32 interested_data_type_ids = 2;
}
......@@ -49,7 +49,8 @@ DeviceInfo::DeviceInfo(const std::string& guid,
base::TimeDelta pulse_interval,
bool send_tab_to_self_receiving_enabled,
const base::Optional<SharingInfo>& sharing_info,
const std::string& fcm_registration_token)
const std::string& fcm_registration_token,
const ModelTypeSet& interested_data_types)
: guid_(guid),
client_name_(client_name),
chrome_version_(chrome_version),
......@@ -62,7 +63,8 @@ DeviceInfo::DeviceInfo(const std::string& guid,
pulse_interval_(pulse_interval),
send_tab_to_self_receiving_enabled_(send_tab_to_self_receiving_enabled),
sharing_info_(sharing_info),
fcm_registration_token_(fcm_registration_token) {}
fcm_registration_token_(fcm_registration_token),
interested_data_types_(interested_data_types) {}
DeviceInfo::~DeviceInfo() {}
......@@ -159,6 +161,10 @@ const std::string& DeviceInfo::fcm_registration_token() const {
return fcm_registration_token_;
}
const ModelTypeSet& DeviceInfo::interested_data_types() const {
return interested_data_types_;
}
bool DeviceInfo::Equals(const DeviceInfo& other) const {
return this->guid() == other.guid() &&
this->client_name() == other.client_name() &&
......@@ -171,7 +177,8 @@ bool DeviceInfo::Equals(const DeviceInfo& other) const {
this->send_tab_to_self_receiving_enabled() ==
other.send_tab_to_self_receiving_enabled() &&
this->sharing_info() == other.sharing_info() &&
this->fcm_registration_token() == other.fcm_registration_token();
this->fcm_registration_token() == other.fcm_registration_token() &&
this->interested_data_types() == other.interested_data_types();
}
std::unique_ptr<base::DictionaryValue> DeviceInfo::ToValue() const {
......@@ -209,4 +216,8 @@ void DeviceInfo::set_fcm_registration_token(const std::string& fcm_token) {
fcm_registration_token_ = fcm_token;
}
void DeviceInfo::set_interested_data_types(const ModelTypeSet& data_types) {
interested_data_types_ = data_types;
}
} // namespace syncer
......@@ -13,6 +13,7 @@
#include "base/macros.h"
#include "base/optional.h"
#include "base/time/time.h"
#include "components/sync/base/model_type.h"
#include "components/sync/protocol/sync.pb.h"
namespace base {
......@@ -74,7 +75,8 @@ class DeviceInfo {
base::TimeDelta pulse_interval,
bool send_tab_to_self_receiving_enabled,
const base::Optional<SharingInfo>& sharing_info,
const std::string& fcm_registration_token);
const std::string& fcm_registration_token,
const ModelTypeSet& interested_data_types);
~DeviceInfo();
// Sync specific unique identifier for the device. Note if a device
......@@ -127,6 +129,9 @@ class DeviceInfo {
// Returns the FCM registration token for sync invalidations.
const std::string& fcm_registration_token() const;
// Returns the data types for which this device receives invalidations.
const ModelTypeSet& interested_data_types() const;
// Gets the OS in string form.
std::string GetOSString() const;
......@@ -150,6 +155,8 @@ class DeviceInfo {
void set_fcm_registration_token(const std::string& fcm_token);
void set_interested_data_types(const ModelTypeSet& data_types);
// Converts the |DeviceInfo| values to a JS friendly DictionaryValue,
// which extension APIs can expose to third party apps.
std::unique_ptr<base::DictionaryValue> ToValue() const;
......@@ -188,6 +195,9 @@ class DeviceInfo {
// An FCM registration token obtained by sync invalidations service.
std::string fcm_registration_token_;
// Data types for which this device receives invalidations.
ModelTypeSet interested_data_types_;
DISALLOW_COPY_AND_ASSIGN(DeviceInfo);
};
......
......@@ -15,6 +15,7 @@
#include "base/bind_helpers.h"
#include "base/location.h"
#include "base/strings/string_util.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/time.h"
#include "components/sync/model/data_type_activation_request.h"
#include "components/sync/model/entity_change.h"
......@@ -87,6 +88,17 @@ base::Optional<DeviceInfo::SharingInfo> SpecificsToSharingInfo(
// Converts DeviceInfoSpecifics into a freshly allocated DeviceInfo.
std::unique_ptr<DeviceInfo> SpecificsToModel(
const DeviceInfoSpecifics& specifics) {
ModelTypeSet data_types;
for (const int field_number :
specifics.invalidation_fields().interested_data_type_ids()) {
ModelType data_type = GetModelTypeFromSpecificsFieldNumber(field_number);
if (!IsRealDataType(data_type)) {
DLOG(WARNING) << "Unknown field number " << field_number;
continue;
}
data_types.Put(data_type);
}
return std::make_unique<DeviceInfo>(
specifics.cache_guid(), specifics.client_name(),
specifics.chrome_version(), specifics.sync_user_agent(),
......@@ -96,7 +108,7 @@ std::unique_ptr<DeviceInfo> SpecificsToModel(
GetPulseIntervalFromSpecifics(specifics),
specifics.feature_fields().send_tab_to_self_receiving_enabled(),
SpecificsToSharingInfo(specifics),
specifics.invalidation_fields().instance_id_token());
specifics.invalidation_fields().instance_id_token(), data_types);
}
// Allocate a EntityData and copies |specifics| into it.
......@@ -151,11 +163,15 @@ std::unique_ptr<DeviceInfoSpecifics> MakeLocalDeviceSpecifics(
}
}
// Set sync invalidations FCM registration token.
// Set sync invalidations FCM registration token and interested data types.
if (!info.fcm_registration_token().empty()) {
specifics->mutable_invalidation_fields()->set_instance_id_token(
info.fcm_registration_token());
}
for (const ModelType data_type : info.interested_data_types()) {
specifics->mutable_invalidation_fields()->add_interested_data_type_ids(
GetSpecificsFieldNumberFromModelType(data_type));
}
return specifics;
}
......
......@@ -16,6 +16,7 @@
#include "base/test/simple_test_clock.h"
#include "base/test/task_environment.h"
#include "components/prefs/testing_pref_service.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/time.h"
#include "components/sync/invalidations/switches.h"
#include "components/sync/model/data_batch.h"
......@@ -40,6 +41,7 @@ using sync_pb::DeviceInfoSpecifics;
using sync_pb::EntitySpecifics;
using sync_pb::ModelTypeState;
using testing::_;
using testing::AllOf;
using testing::IsEmpty;
using testing::Matcher;
using testing::NotNull;
......@@ -93,6 +95,15 @@ MATCHER_P(ModelEqualsSpecifics, expected_specifics, "") {
}
}
ModelTypeSet expected_data_types;
for (const int field_number :
expected_specifics.invalidation_fields().interested_data_type_ids()) {
expected_data_types.Put(GetModelTypeFromSpecificsFieldNumber(field_number));
}
if (expected_data_types != arg.interested_data_types()) {
return false;
}
// Note that we ignore the device name here to avoid having to inject the
// local device's.
return expected_specifics.cache_guid() == arg.guid() &&
......@@ -142,6 +153,15 @@ MATCHER(HasInstanceIdToken, "") {
return true;
}
MATCHER(HasAnyInterestedDataTypes, "") {
const sync_pb::DeviceInfoSpecifics& specifics = arg.device_info();
if (specifics.invalidation_fields().interested_data_type_ids().empty()) {
*result_listener << "which is empty";
return false;
}
return true;
}
std::string CacheGuidForSuffix(int suffix) {
return base::StringPrintf("cache guid %d", suffix);
}
......@@ -219,6 +239,13 @@ std::string SyncInvalidationsInstanceIdTokenForSuffix(int suffix) {
return std::string();
}
ModelTypeSet SyncInvalidationsInterestedDataTypes() {
if (base::FeatureList::IsEnabled(switches::kSubscribeForSyncInvalidations)) {
return ModelTypeSet(BOOKMARKS);
}
return ModelTypeSet();
}
DataTypeActivationRequest TestDataTypeActivationRequest(SyncMode sync_mode) {
DataTypeActivationRequest request;
request.cache_guid = CacheGuidForSuffix(kLocalSuffix);
......@@ -262,6 +289,11 @@ DeviceInfoSpecifics CreateSpecifics(
specifics.mutable_invalidation_fields()->set_instance_id_token(
sync_invalidations_instance_id_token);
}
for (const ModelType type : SyncInvalidationsInterestedDataTypes()) {
specifics.mutable_invalidation_fields()->add_interested_data_type_ids(
GetSpecificsFieldNumberFromModelType(type));
}
return specifics;
}
......@@ -334,7 +366,8 @@ class TestLocalDeviceInfoProvider : public MutableLocalDeviceInfoProvider {
SharingSenderIdP256dhForSuffix(kLocalSuffix),
SharingSenderIdAuthSecretForSuffix(kLocalSuffix)},
sharing_enabled_features),
SyncInvalidationsInstanceIdTokenForSuffix(kLocalSuffix));
SyncInvalidationsInstanceIdTokenForSuffix(kLocalSuffix),
SyncInvalidationsInterestedDataTypes());
}
void Clear() override { local_device_info_.reset(); }
......@@ -1266,7 +1299,11 @@ TEST_F(DeviceInfoSyncBridgeTest, ShouldSendInvalidationFields) {
override_features.InitAndEnableFeature(
switches::kSubscribeForSyncInvalidations);
EXPECT_CALL(*processor(), Put(_, HasSpecifics(HasInstanceIdToken()), _));
EXPECT_CALL(*processor(),
Put(_,
HasSpecifics(
AllOf(HasInstanceIdToken(), HasAnyInterestedDataTypes())),
_));
InitializeAndMergeInitialData(SyncMode::kFull);
}
......
......@@ -20,7 +20,8 @@ std::unique_ptr<syncer::DeviceInfo> CloneDeviceInfo(
device_info.manufacturer_name(), device_info.model_name(),
device_info.last_updated_timestamp(), device_info.pulse_interval(),
device_info.send_tab_to_self_receiving_enabled(),
device_info.sharing_info(), device_info.fcm_registration_token());
device_info.sharing_info(), device_info.fcm_registration_token(),
device_info.interested_data_types());
}
} // namespace
......
......@@ -5,6 +5,7 @@
#include "components/sync_device_info/fake_local_device_info_provider.h"
#include "base/time/time.h"
#include "components/sync/base/model_type.h"
#include "components/sync_device_info/device_info_util.h"
namespace syncer {
......@@ -22,7 +23,8 @@ FakeLocalDeviceInfoProvider::FakeLocalDeviceInfoProvider()
DeviceInfoUtil::GetPulseInterval(),
/*send_tab_to_self_receiving_enabled=*/false,
/*sharing_info=*/base::nullopt,
/*fcm_registration_token=*/std::string()) {}
/*fcm_registration_token=*/std::string(),
/*interested_data_types=*/ModelTypeSet()) {}
FakeLocalDeviceInfoProvider::~FakeLocalDeviceInfoProvider() = default;
......
......@@ -27,6 +27,7 @@ LocalDeviceInfoProviderImpl::LocalDeviceInfoProviderImpl(
DCHECK(sync_client);
if (sync_invalidations_service_) {
sync_invalidations_service_->AddTokenObserver(this);
sync_invalidations_service_->AddSubscribedDataTypesObserver(this);
}
}
......@@ -34,6 +35,7 @@ LocalDeviceInfoProviderImpl::~LocalDeviceInfoProviderImpl() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (sync_invalidations_service_) {
sync_invalidations_service_->RemoveTokenObserver(this);
sync_invalidations_service_->RemoveSubscribedDataTypesObserver(this);
}
}
......@@ -75,6 +77,18 @@ void LocalDeviceInfoProviderImpl::OnFCMRegistrationTokenChanged() {
// TODO(crbug.com/1102336): nudge device info update.
}
void LocalDeviceInfoProviderImpl::OnSubscribedDataTypesChanged() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(
base::FeatureList::IsEnabled(switches::kSubscribeForSyncInvalidations));
DCHECK(sync_invalidations_service_);
if (local_device_info_) {
local_device_info_->set_interested_data_types(
sync_invalidations_service_->GetSubscribedDataTypes());
}
// TODO(crbug.com/1102336): nudge device info update.
}
void LocalDeviceInfoProviderImpl::Initialize(
const std::string& cache_guid,
const std::string& client_name,
......@@ -92,7 +106,8 @@ void LocalDeviceInfoProviderImpl::Initialize(
/*last_updated_timestamp=*/base::Time(),
DeviceInfoUtil::GetPulseInterval(),
sync_client_->GetSendTabToSelfReceivingEnabled(),
sync_client_->GetLocalSharingInfo(), GetFCMRegistrationToken());
sync_client_->GetLocalSharingInfo(), GetFCMRegistrationToken(),
GetInterestedDataTypes());
// Notify observers.
callback_list_.Notify();
......@@ -116,4 +131,11 @@ std::string LocalDeviceInfoProviderImpl::GetFCMRegistrationToken() const {
return std::string();
}
ModelTypeSet LocalDeviceInfoProviderImpl::GetInterestedDataTypes() const {
if (sync_invalidations_service_) {
return sync_invalidations_service_->GetSubscribedDataTypes();
}
return ModelTypeSet();
}
} // namespace syncer
......@@ -12,7 +12,9 @@
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "components/sync/base/model_type.h"
#include "components/sync/invalidations/fcm_registration_token_observer.h"
#include "components/sync/invalidations/subscribed_data_types_observer.h"
#include "components/sync_device_info/device_info.h"
#include "components/sync_device_info/local_device_info_provider.h"
#include "components/version_info/version_info.h"
......@@ -22,12 +24,13 @@ namespace syncer {
class DeviceInfoSyncClient;
class SyncInvalidationsService;
class LocalDeviceInfoProviderImpl
: public MutableLocalDeviceInfoProvider,
public syncer::FCMRegistrationTokenObserver {
class LocalDeviceInfoProviderImpl : public MutableLocalDeviceInfoProvider,
public syncer::FCMRegistrationTokenObserver,
public SubscribedDataTypesObserver {
public:
// |sync_invalidations_service| is used to get an FCM registration token. It
// may be nullptr if sync invalidations are disabled.
// |sync_invalidations_service| is used to get an FCM registration token and
// interested data types. It may be nullptr if sync invalidations are
// disabled.
LocalDeviceInfoProviderImpl(
version_info::Channel channel,
const std::string& version,
......@@ -50,9 +53,14 @@ class LocalDeviceInfoProviderImpl
// syncer::FCMRegistrationTokenObserver implementation.
void OnFCMRegistrationTokenChanged() override;
// SubscribedDataTypesObserver implementation.
void OnSubscribedDataTypesChanged() override;
private:
std::string GetFCMRegistrationToken() const;
ModelTypeSet GetInterestedDataTypes() const;
// The channel (CANARY, DEV, BETA, etc.) of the current client.
const version_info::Channel channel_;
......
......@@ -6,6 +6,7 @@
#include "base/memory/ptr_util.h"
#include "base/test/scoped_feature_list.h"
#include "components/sync/base/model_type.h"
#include "components/sync/base/sync_util.h"
#include "components/sync/invalidations/mock_sync_invalidations_service.h"
#include "components/sync/invalidations/switches.h"
......@@ -90,6 +91,8 @@ class LocalDeviceInfoProviderImplWithSyncInvalidationsTest
switches::kSubscribeForSyncInvalidations);
ON_CALL(mock_sync_invalidations_service_, GetFCMRegistrationToken())
.WillByDefault(ReturnRef(kEmptyToken));
ON_CALL(mock_sync_invalidations_service_, GetSubscribedDataTypes())
.WillByDefault(ReturnRef(kEmptyTypesSet));
}
protected:
......@@ -98,6 +101,7 @@ class LocalDeviceInfoProviderImplWithSyncInvalidationsTest
}
const std::string kEmptyToken;
const ModelTypeSet kEmptyTypesSet;
base::test::ScopedFeatureList override_features_;
NiceMock<MockSyncInvalidationsService> mock_sync_invalidations_service_;
......@@ -210,5 +214,19 @@ TEST_F(LocalDeviceInfoProviderImplWithSyncInvalidationsTest,
kFCMRegistrationToken);
}
TEST_F(LocalDeviceInfoProviderImplWithSyncInvalidationsTest,
ShouldPopulateSubscribedDataTypes) {
InitializeProvider();
ASSERT_THAT(provider_->GetLocalDeviceInfo(), NotNull());
EXPECT_TRUE(provider_->GetLocalDeviceInfo()->interested_data_types().Empty());
const ModelTypeSet kTypes = ModelTypeSet(BOOKMARKS);
EXPECT_CALL(mock_sync_invalidations_service_, GetSubscribedDataTypes())
.WillOnce(ReturnRef(kTypes));
provider_->OnSubscribedDataTypesChanged();
EXPECT_EQ(provider_->GetLocalDeviceInfo()->interested_data_types(), kTypes);
}
} // namespace
} // 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