Commit 4f66fa07 authored by Rushan Suleymanov's avatar Rushan Suleymanov Committed by Commit Bot

[Sync] Add SharingMessageBridge implementation.

Add SharingMessageBridge without wiring it. The bridge does not store any
data on persistent storage.

Bug: 1034930
Change-Id: I0b19a136a2cc8a3e9ec11b7c1bb0f0b629996e52
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2002524Reviewed-by: default avatarAlex Chau <alexchau@chromium.org>
Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Reviewed-by: default avatarvitaliii <vitaliii@chromium.org>
Commit-Queue: Rushan Suleymanov <rushans@google.com>
Cr-Commit-Position: refs/heads/master@{#733594}
parent b5bf3eda
...@@ -1592,6 +1592,9 @@ jumbo_static_library("browser") { ...@@ -1592,6 +1592,9 @@ jumbo_static_library("browser") {
"sharing/sharing_handler_registry.h", "sharing/sharing_handler_registry.h",
"sharing/sharing_handler_registry_impl.cc", "sharing/sharing_handler_registry_impl.cc",
"sharing/sharing_handler_registry_impl.h", "sharing/sharing_handler_registry_impl.h",
"sharing/sharing_message_bridge.h",
"sharing/sharing_message_bridge_impl.cc",
"sharing/sharing_message_bridge_impl.h",
"sharing/sharing_message_handler.h", "sharing/sharing_message_handler.h",
"sharing/sharing_message_sender.cc", "sharing/sharing_message_sender.cc",
"sharing/sharing_message_sender.h", "sharing/sharing_message_sender.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 CHROME_BROWSER_SHARING_SHARING_MESSAGE_BRIDGE_H_
#define CHROME_BROWSER_SHARING_SHARING_MESSAGE_BRIDGE_H_
#include <memory>
#include "components/sync/protocol/sharing_message_specifics.pb.h"
// Class to provide an interface to send sharing messages using Sync.
class SharingMessageBridge {
public:
// TODO(crbug.com/1034930): take callbacks once commit error propagation back
// to the bridge is implemented.
virtual void SendSharingMessage(
std::unique_ptr<sync_pb::SharingMessageSpecifics> specifics) = 0;
virtual ~SharingMessageBridge() = default;
};
#endif // CHROME_BROWSER_SHARING_SHARING_MESSAGE_BRIDGE_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 "chrome/browser/sharing/sharing_message_bridge_impl.h"
#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/mutable_data_batch.h"
#include "components/sync/model_impl/in_memory_metadata_change_list.h"
namespace {
std::unique_ptr<syncer::EntityData> MoveToEntityData(
std::unique_ptr<sync_pb::SharingMessageSpecifics> specifics) {
auto entity_data = std::make_unique<syncer::EntityData>();
entity_data->specifics.set_allocated_sharing_message(specifics.release());
return entity_data;
}
} // namespace
SharingMessageBridgeImpl::SharingMessageBridgeImpl(
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor)
: ModelTypeSyncBridge(std::move(change_processor)) {
// Current data type doesn't have persistent storage so it's ready to sync
// immediately.
this->change_processor()->ModelReadyToSync(
std::make_unique<syncer::MetadataBatch>());
}
SharingMessageBridgeImpl::~SharingMessageBridgeImpl() = default;
void SharingMessageBridgeImpl::SendSharingMessage(
std::unique_ptr<sync_pb::SharingMessageSpecifics> specifics) {
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list =
CreateMetadataChangeList();
std::unique_ptr<syncer::EntityData> entity_data =
MoveToEntityData(std::move(specifics));
const std::string empty_storage_key;
change_processor()->Put(empty_storage_key, std::move(entity_data),
metadata_change_list.get());
}
std::unique_ptr<syncer::MetadataChangeList>
SharingMessageBridgeImpl::CreateMetadataChangeList() {
// The data type intentionally doesn't persist the data on disk, so metadata
// is just ignored.
// TODO(crbug.com/1034930): this metadata changelist stores data in memory, it
// would be better to create DummyMetadataChangeList to ignore any changes at
// all.
return std::make_unique<syncer::InMemoryMetadataChangeList>();
}
base::Optional<syncer::ModelError> SharingMessageBridgeImpl::MergeSyncData(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
DCHECK(entity_data.empty());
DCHECK(change_processor()->IsTrackingMetadata());
return ApplySyncChanges(std::move(metadata_change_list),
std::move(entity_data));
}
base::Optional<syncer::ModelError> SharingMessageBridgeImpl::ApplySyncChanges(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
// This data type is commit only and does not store any data in persistent
// storage. We can ignore any data coming from the server.
return {};
}
void SharingMessageBridgeImpl::GetData(StorageKeyList storage_keys,
DataCallback callback) {
return GetAllDataForDebugging(std::move(callback));
}
void SharingMessageBridgeImpl::GetAllDataForDebugging(DataCallback callback) {
// This data type does not store any data, we can always run the callback
// with empty data.
std::move(callback).Run(std::make_unique<syncer::MutableDataBatch>());
}
std::string SharingMessageBridgeImpl::GetClientTag(
const syncer::EntityData& entity_data) {
return GetStorageKey(entity_data);
}
std::string SharingMessageBridgeImpl::GetStorageKey(
const syncer::EntityData& entity_data) {
NOTREACHED();
return "";
}
// This is commit-only data type without storing any data on persistent storage.
// We do not need keys here.
bool SharingMessageBridgeImpl::SupportsGetClientTag() const {
return false;
}
bool SharingMessageBridgeImpl::SupportsGetStorageKey() const {
return false;
}
// 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 CHROME_BROWSER_SHARING_SHARING_MESSAGE_BRIDGE_IMPL_H_
#define CHROME_BROWSER_SHARING_SHARING_MESSAGE_BRIDGE_IMPL_H_
#include <memory>
#include "chrome/browser/sharing/sharing_message_bridge.h"
#include "components/sync/model/model_type_change_processor.h"
#include "components/sync/model/model_type_sync_bridge.h"
// Class that implements sending sharing messages using Sync. This class
// implements interaction with sync service. Sharing message data type is not
// stored in any persistent storage.
class SharingMessageBridgeImpl : public SharingMessageBridge,
public syncer::ModelTypeSyncBridge {
public:
explicit SharingMessageBridgeImpl(
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor);
~SharingMessageBridgeImpl() override;
SharingMessageBridgeImpl(const SharingMessageBridgeImpl&) = delete;
SharingMessageBridgeImpl& operator=(const SharingMessageBridgeImpl&) = delete;
// SharingMessageBridge implementation.
void SendSharingMessage(
std::unique_ptr<sync_pb::SharingMessageSpecifics> specifics) override;
// ModelTypeSyncBridge implementation.
std::unique_ptr<syncer::MetadataChangeList> CreateMetadataChangeList()
override;
base::Optional<syncer::ModelError> MergeSyncData(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) override;
base::Optional<syncer::ModelError> ApplySyncChanges(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_changes) override;
void GetData(StorageKeyList storage_keys, DataCallback callback) override;
void GetAllDataForDebugging(DataCallback callback) override;
std::string GetClientTag(const syncer::EntityData& entity_data) override;
std::string GetStorageKey(const syncer::EntityData& entity_data) override;
bool SupportsGetClientTag() const override;
bool SupportsGetStorageKey() const override;
};
#endif // CHROME_BROWSER_SHARING_SHARING_MESSAGE_BRIDGE_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 "chrome/browser/sharing/sharing_message_bridge_impl.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "components/sync/model/metadata_batch.h"
#include "components/sync/model/mock_model_type_change_processor.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
using testing::_;
using testing::InvokeWithoutArgs;
using testing::NotNull;
using testing::Return;
using testing::SaveArg;
// Action SaveArgPointeeMove<k>(pointer) saves the value pointed to by the k-th
// (0-based) argument of the mock function by moving it to *pointer.
ACTION_TEMPLATE(SaveArgPointeeMove,
HAS_1_TEMPLATE_PARAMS(int, k),
AND_1_VALUE_PARAMS(pointer)) {
*pointer = std::move(*testing::get<k>(args));
}
class SharingMessageBridgeTest : public testing::Test {
protected:
SharingMessageBridgeTest() {
EXPECT_CALL(*processor(), ModelReadyToSync(NotNull()));
bridge_ = std::make_unique<SharingMessageBridgeImpl>(
mock_processor_.CreateForwardingProcessor());
ON_CALL(*processor(), IsTrackingMetadata()).WillByDefault(Return(true));
}
SharingMessageBridgeImpl* bridge() { return bridge_.get(); }
syncer::MockModelTypeChangeProcessor* processor() { return &mock_processor_; }
std::unique_ptr<sync_pb::SharingMessageSpecifics> CreateSpecifics(
const std::string& payload) const {
auto specifics = std::make_unique<sync_pb::SharingMessageSpecifics>();
specifics->set_payload(payload);
return specifics;
}
private:
base::test::TaskEnvironment task_environment_;
testing::NiceMock<syncer::MockModelTypeChangeProcessor> mock_processor_;
std::unique_ptr<SharingMessageBridgeImpl> bridge_;
};
TEST_F(SharingMessageBridgeTest, ShouldWriteMessagesToProcessor) {
syncer::EntityData entity_data;
EXPECT_CALL(*processor(), Put(_, _, _))
.WillRepeatedly(SaveArgPointeeMove<1>(&entity_data));
bridge()->SendSharingMessage(CreateSpecifics("test_payload"));
EXPECT_TRUE(entity_data.specifics.has_sharing_message());
EXPECT_EQ(entity_data.specifics.sharing_message().payload(), "test_payload");
entity_data.specifics.Clear();
bridge()->SendSharingMessage(CreateSpecifics("another_payload"));
EXPECT_TRUE(entity_data.specifics.has_sharing_message());
EXPECT_EQ(entity_data.specifics.sharing_message().payload(),
"another_payload");
}
TEST_F(SharingMessageBridgeTest, ShouldNotGenerateStorageKey) {
std::string storage_key;
EXPECT_CALL(*processor(), Put(_, _, _)).WillOnce(SaveArg<0>(&storage_key));
bridge()->SendSharingMessage(
std::make_unique<sync_pb::SharingMessageSpecifics>());
EXPECT_TRUE(storage_key.empty());
}
} // namespace
...@@ -3343,6 +3343,7 @@ test("unit_tests") { ...@@ -3343,6 +3343,7 @@ test("unit_tests") {
"../browser/sharing/sharing_fcm_handler_unittest.cc", "../browser/sharing/sharing_fcm_handler_unittest.cc",
"../browser/sharing/sharing_fcm_sender_unittest.cc", "../browser/sharing/sharing_fcm_sender_unittest.cc",
"../browser/sharing/sharing_handler_registry_impl_unittest.cc", "../browser/sharing/sharing_handler_registry_impl_unittest.cc",
"../browser/sharing/sharing_message_bridge_impl_unittest.cc",
"../browser/sharing/sharing_message_sender_unittest.cc", "../browser/sharing/sharing_message_sender_unittest.cc",
"../browser/sharing/sharing_service_unittest.cc", "../browser/sharing/sharing_service_unittest.cc",
"../browser/sharing/sharing_sync_preference_unittest.cc", "../browser/sharing/sharing_sync_preference_unittest.cc",
......
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