| Index: components/sync/user_events/user_event_sync_bridge.cc
|
| diff --git a/components/sync/user_events/user_event_sync_bridge.cc b/components/sync/user_events/user_event_sync_bridge.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..51e058ad5bd374c12cbd831b29963a3eb1d3b1bf
|
| --- /dev/null
|
| +++ b/components/sync/user_events/user_event_sync_bridge.cc
|
| @@ -0,0 +1,214 @@
|
| +// Copyright 2017 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/user_events/user_event_sync_bridge.h"
|
| +
|
| +#include <utility>
|
| +
|
| +#include "base/big_endian.h"
|
| +#include "base/bind.h"
|
| +#include "base/location.h"
|
| +#include "base/logging.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "components/sync/model/entity_change.h"
|
| +#include "components/sync/model/metadata_batch.h"
|
| +#include "components/sync/model/mutable_data_batch.h"
|
| +#include "components/sync/protocol/sync.pb.h"
|
| +
|
| +namespace syncer {
|
| +
|
| +using sync_pb::UserEventSpecifics;
|
| +using sync_pb::ModelTypeState;
|
| +using IdList = ModelTypeStore::IdList;
|
| +using Record = ModelTypeStore::Record;
|
| +using RecordList = ModelTypeStore::RecordList;
|
| +using Result = ModelTypeStore::Result;
|
| +using WriteBatch = ModelTypeStore::WriteBatch;
|
| +
|
| +namespace {
|
| +
|
| +std::string GetStorageKeyFromSpecifics(const UserEventSpecifics& specifics) {
|
| + // Force Big Endian, this means newly created keys are last in sort order,
|
| + // which allows leveldb to append new writes, which it is best at.
|
| + // TODO(skym): Until we force |event_time_usec| to never conflict, this has
|
| + // the potential for errors.
|
| + std::string key(8, 0);
|
| + base::WriteBigEndian(&key[0], specifics.event_time_usec());
|
| + return key;
|
| +}
|
| +
|
| +std::unique_ptr<EntityData> MoveToEntityData(
|
| + std::unique_ptr<UserEventSpecifics> specifics) {
|
| + auto entity_data = base::MakeUnique<EntityData>();
|
| + entity_data->non_unique_name =
|
| + base::Int64ToString(specifics->event_time_usec());
|
| + entity_data->specifics.set_allocated_user_event(specifics.release());
|
| + return entity_data;
|
| +}
|
| +
|
| +std::unique_ptr<EntityData> CopyToEntityData(
|
| + const UserEventSpecifics specifics) {
|
| + auto entity_data = base::MakeUnique<EntityData>();
|
| + entity_data->non_unique_name =
|
| + base::Int64ToString(specifics.event_time_usec());
|
| + *entity_data->specifics.mutable_user_event() = specifics;
|
| + return entity_data;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +UserEventSyncBridge::UserEventSyncBridge(
|
| + const ModelTypeStoreFactory& store_factory,
|
| + const ChangeProcessorFactory& change_processor_factory)
|
| + : ModelTypeSyncBridge(change_processor_factory, USER_EVENTS) {
|
| + store_factory.Run(
|
| + base::Bind(&UserEventSyncBridge::OnStoreCreated, base::AsWeakPtr(this)));
|
| +}
|
| +
|
| +UserEventSyncBridge::~UserEventSyncBridge() {}
|
| +
|
| +std::unique_ptr<MetadataChangeList>
|
| +UserEventSyncBridge::CreateMetadataChangeList() {
|
| + return WriteBatch::CreateMetadataChangeList();
|
| +}
|
| +
|
| +base::Optional<ModelError> UserEventSyncBridge::MergeSyncData(
|
| + std::unique_ptr<MetadataChangeList> metadata_change_list,
|
| + EntityDataMap entity_data_map) {
|
| + NOTREACHED();
|
| + return {};
|
| +}
|
| +
|
| +base::Optional<ModelError> UserEventSyncBridge::ApplySyncChanges(
|
| + std::unique_ptr<MetadataChangeList> metadata_change_list,
|
| + EntityChangeList entity_changes) {
|
| + NOTREACHED();
|
| + return {};
|
| +}
|
| +
|
| +void UserEventSyncBridge::GetData(StorageKeyList storage_keys,
|
| + DataCallback callback) {
|
| + store_->ReadData(storage_keys, base::Bind(&UserEventSyncBridge::OnReadData,
|
| + base::AsWeakPtr(this), callback));
|
| +}
|
| +
|
| +void UserEventSyncBridge::GetAllData(DataCallback callback) {
|
| + store_->ReadAllData(base::Bind(&UserEventSyncBridge::OnReadAllData,
|
| + base::AsWeakPtr(this), callback));
|
| +}
|
| +
|
| +std::string UserEventSyncBridge::GetClientTag(const EntityData& entity_data) {
|
| + return GetStorageKey(entity_data);
|
| +}
|
| +
|
| +std::string UserEventSyncBridge::GetStorageKey(const EntityData& entity_data) {
|
| + return GetStorageKeyFromSpecifics(entity_data.specifics.user_event());
|
| +}
|
| +
|
| +void UserEventSyncBridge::DisableSync() {
|
| + // No data should be retained through sign out.
|
| + store_->ReadAllData(base::Bind(&UserEventSyncBridge::OnReadAllDataToDelete,
|
| + base::AsWeakPtr(this)));
|
| +}
|
| +
|
| +void UserEventSyncBridge::RecordUserEvent(
|
| + std::unique_ptr<UserEventSpecifics> specifics) {
|
| + std::string storage_key = GetStorageKeyFromSpecifics(*specifics);
|
| + std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
|
| + batch->WriteData(storage_key, specifics->SerializeAsString());
|
| + change_processor()->Put(storage_key, MoveToEntityData(std::move(specifics)),
|
| + batch->GetMetadataChangeList());
|
| + store_->CommitWriteBatch(
|
| + std::move(batch),
|
| + base::Bind(&UserEventSyncBridge::OnCommit, base::AsWeakPtr(this)));
|
| +}
|
| +
|
| +void UserEventSyncBridge::OnStoreCreated(
|
| + Result result,
|
| + std::unique_ptr<ModelTypeStore> store) {
|
| + if (result == Result::SUCCESS) {
|
| + std::swap(store_, store);
|
| + store_->ReadAllMetadata(base::Bind(&UserEventSyncBridge::OnReadAllMetadata,
|
| + base::AsWeakPtr(this)));
|
| + } else {
|
| + change_processor()->ReportError(FROM_HERE,
|
| + "ModelTypeStore creation failed.");
|
| + }
|
| +}
|
| +
|
| +void UserEventSyncBridge::OnReadAllMetadata(
|
| + base::Optional<ModelError> error,
|
| + std::unique_ptr<MetadataBatch> metadata_batch) {
|
| + if (error) {
|
| + change_processor()->ReportError(error.value());
|
| + } else {
|
| + if (!metadata_batch->GetModelTypeState().initial_sync_done()) {
|
| + // We have never initialized before, force it to true. We are not going to
|
| + // ever have a GetUpdates because our type is commit only.
|
| + // TODO(skym): Do we need to worry about saving this back ourselves? Or
|
| + // does that get taken care for us?
|
| + ModelTypeState state = metadata_batch->GetModelTypeState();
|
| + state.set_initial_sync_done(true);
|
| + metadata_batch->SetModelTypeState(state);
|
| + }
|
| + change_processor()->ModelReadyToSync(std::move(metadata_batch));
|
| + }
|
| +}
|
| +
|
| +void UserEventSyncBridge::OnCommit(Result result) {
|
| + if (result != Result::SUCCESS) {
|
| + change_processor()->ReportError(FROM_HERE, "Failed writing user events.");
|
| + }
|
| +}
|
| +
|
| +void UserEventSyncBridge::OnReadData(DataCallback callback,
|
| + Result result,
|
| + std::unique_ptr<RecordList> data_records,
|
| + std::unique_ptr<IdList> missing_id_list) {
|
| + OnReadAllData(callback, result, std::move(data_records));
|
| +}
|
| +
|
| +void UserEventSyncBridge::OnReadAllData(
|
| + DataCallback callback,
|
| + Result result,
|
| + std::unique_ptr<RecordList> data_records) {
|
| + if (result != Result::SUCCESS) {
|
| + change_processor()->ReportError(FROM_HERE, "Failed reading user events.");
|
| + return;
|
| + }
|
| +
|
| + auto batch = base::MakeUnique<MutableDataBatch>();
|
| + UserEventSpecifics specifics;
|
| + for (const Record& r : *data_records) {
|
| + if (specifics.ParseFromString(r.value)) {
|
| + DCHECK_EQ(r.id, GetStorageKeyFromSpecifics(specifics));
|
| + batch->Put(r.id, CopyToEntityData(specifics));
|
| + } else {
|
| + change_processor()->ReportError(FROM_HERE,
|
| + "Failed deserializing user events.");
|
| + return;
|
| + }
|
| + }
|
| + callback.Run(std::move(batch));
|
| +}
|
| +
|
| +void UserEventSyncBridge::OnReadAllDataToDelete(
|
| + Result result,
|
| + std::unique_ptr<RecordList> data_records) {
|
| + if (result != Result::SUCCESS) {
|
| + change_processor()->ReportError(FROM_HERE, "Failed reading user events.");
|
| + return;
|
| + }
|
| +
|
| + std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
|
| + for (const Record& r : *data_records) {
|
| + batch->DeleteData(r.id);
|
| + }
|
| + store_->CommitWriteBatch(
|
| + std::move(batch),
|
| + base::Bind(&UserEventSyncBridge::OnCommit, base::AsWeakPtr(this)));
|
| +}
|
| +
|
| +} // namespace syncer
|
|
|