Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Unified Diff: components/sync/device_info/device_info_service.cc

Issue 2460903003: [Sync] Rename DeviceInfoService to DeviceInfoSyncBridge. (Closed)
Patch Set: Updating nullptr to null in comment. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/sync/device_info/device_info_service.cc
diff --git a/components/sync/device_info/device_info_service.cc b/components/sync/device_info/device_info_service.cc
deleted file mode 100644
index b3952bc571ac5e95e47879de24579dda089b927d..0000000000000000000000000000000000000000
--- a/components/sync/device_info/device_info_service.cc
+++ /dev/null
@@ -1,491 +0,0 @@
-// Copyright 2015 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/device_info/device_info_service.h"
-
-#include <stdint.h>
-
-#include <algorithm>
-#include <set>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/location.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_util.h"
-#include "components/sync/base/time.h"
-#include "components/sync/device_info/device_info_util.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/model/sync_error.h"
-#include "components/sync/protocol/model_type_state.pb.h"
-#include "components/sync/protocol/sync.pb.h"
-
-namespace syncer {
-
-using base::Time;
-using base::TimeDelta;
-using sync_pb::DeviceInfoSpecifics;
-using sync_pb::EntitySpecifics;
-using sync_pb::ModelTypeState;
-
-using Record = ModelTypeStore::Record;
-using RecordList = ModelTypeStore::RecordList;
-using Result = ModelTypeStore::Result;
-using WriteBatch = ModelTypeStore::WriteBatch;
-
-namespace {
-
-// Find the timestamp for the last time this |device_info| was edited.
-Time GetLastUpdateTime(const DeviceInfoSpecifics& specifics) {
- if (specifics.has_last_updated_timestamp()) {
- return ProtoTimeToTime(specifics.last_updated_timestamp());
- } else {
- return Time();
- }
-}
-
-// Converts DeviceInfoSpecifics into a freshly allocated DeviceInfo.
-std::unique_ptr<DeviceInfo> SpecificsToModel(
- const DeviceInfoSpecifics& specifics) {
- return base::MakeUnique<DeviceInfo>(
- specifics.cache_guid(), specifics.client_name(),
- specifics.chrome_version(), specifics.sync_user_agent(),
- specifics.device_type(), specifics.signin_scoped_device_id());
-}
-
-// Allocate a EntityData and copies |specifics| into it.
-std::unique_ptr<EntityData> CopyToEntityData(
- const DeviceInfoSpecifics& specifics) {
- auto entity_data = base::MakeUnique<EntityData>();
- *entity_data->specifics.mutable_device_info() = specifics;
- entity_data->non_unique_name = specifics.client_name();
- return entity_data;
-}
-
-// Converts DeviceInfo into a freshly allocated DeviceInfoSpecifics. Takes
-// |last_updated_timestamp| to set because the model object does not contain
-// this concept.
-std::unique_ptr<DeviceInfoSpecifics> ModelToSpecifics(
- const DeviceInfo& info,
- int64_t last_updated_timestamp) {
- auto specifics = base::MakeUnique<DeviceInfoSpecifics>();
- specifics->set_cache_guid(info.guid());
- specifics->set_client_name(info.client_name());
- specifics->set_chrome_version(info.chrome_version());
- specifics->set_sync_user_agent(info.sync_user_agent());
- specifics->set_device_type(info.device_type());
- specifics->set_signin_scoped_device_id(info.signin_scoped_device_id());
- specifics->set_last_updated_timestamp(last_updated_timestamp);
- return specifics;
-}
-
-} // namespace
-
-DeviceInfoService::DeviceInfoService(
- LocalDeviceInfoProvider* local_device_info_provider,
- const StoreFactoryFunction& callback,
- const ChangeProcessorFactory& change_processor_factory)
- : ModelTypeSyncBridge(change_processor_factory, DEVICE_INFO),
- local_device_info_provider_(local_device_info_provider) {
- DCHECK(local_device_info_provider);
-
- // This is not threadsafe, but presuably the provider initializes on the same
- // thread as us so we're okay.
- if (local_device_info_provider->GetLocalDeviceInfo()) {
- OnProviderInitialized();
- } else {
- subscription_ =
- local_device_info_provider->RegisterOnInitializedCallback(base::Bind(
- &DeviceInfoService::OnProviderInitialized, base::Unretained(this)));
- }
-
- callback.Run(
- base::Bind(&DeviceInfoService::OnStoreCreated, base::AsWeakPtr(this)));
-}
-
-DeviceInfoService::~DeviceInfoService() {}
-
-std::unique_ptr<MetadataChangeList>
-DeviceInfoService::CreateMetadataChangeList() {
- return base::MakeUnique<SimpleMetadataChangeList>();
-}
-
-SyncError DeviceInfoService::MergeSyncData(
- std::unique_ptr<MetadataChangeList> metadata_change_list,
- EntityDataMap entity_data_map) {
- DCHECK(has_provider_initialized_);
- DCHECK(change_processor()->IsTrackingMetadata());
-
- // Local data should typically be near empty, with the only possible value
- // corresponding to this device. This is because on signout all device info
- // data is blown away. However, this simplification is being ignored here and
- // a full difference is going to be calculated to explore what other service
- // implementations may look like.
- std::set<std::string> local_guids_to_put;
- for (const auto& kv : all_data_) {
- local_guids_to_put.insert(kv.first);
- }
-
- bool has_changes = false;
- const DeviceInfo* local_info =
- local_device_info_provider_->GetLocalDeviceInfo();
- std::string local_guid = local_info->guid();
- std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
- for (const auto& kv : entity_data_map) {
- const DeviceInfoSpecifics& specifics =
- kv.second.value().specifics.device_info();
- DCHECK_EQ(kv.first, specifics.cache_guid());
- if (specifics.cache_guid() == local_guid) {
- // Don't Put local data if it's the same as the remote copy.
- if (local_info->Equals(*SpecificsToModel(specifics))) {
- local_guids_to_put.erase(local_guid);
- } else {
- // This device is valid right now and this entry is about to be
- // committed, use this as an opportunity to refresh the timestamp.
- all_data_[local_guid]->set_last_updated_timestamp(
- TimeToProtoTime(Time::Now()));
- }
- } else {
- // Remote data wins conflicts.
- local_guids_to_put.erase(specifics.cache_guid());
- has_changes = true;
- StoreSpecifics(base::MakeUnique<DeviceInfoSpecifics>(specifics),
- batch.get());
- }
- }
-
- for (const std::string& guid : local_guids_to_put) {
- change_processor()->Put(guid, CopyToEntityData(*all_data_[guid]),
- metadata_change_list.get());
- }
-
- CommitAndNotify(std::move(batch), std::move(metadata_change_list),
- has_changes);
- return SyncError();
-}
-
-SyncError DeviceInfoService::ApplySyncChanges(
- std::unique_ptr<MetadataChangeList> metadata_change_list,
- EntityChangeList entity_changes) {
- DCHECK(has_provider_initialized_);
-
- std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
- bool has_changes = false;
- for (EntityChange& change : entity_changes) {
- const std::string guid = change.storage_key();
- // Each device is the authoritative source for itself, ignore any remote
- // changes that have our local cache guid.
- if (guid == local_device_info_provider_->GetLocalDeviceInfo()->guid()) {
- continue;
- }
-
- if (change.type() == EntityChange::ACTION_DELETE) {
- has_changes |= DeleteSpecifics(guid, batch.get());
- } else {
- const DeviceInfoSpecifics& specifics =
- change.data().specifics.device_info();
- DCHECK(guid == specifics.cache_guid());
- StoreSpecifics(base::MakeUnique<DeviceInfoSpecifics>(specifics),
- batch.get());
- has_changes = true;
- }
- }
-
- CommitAndNotify(std::move(batch), std::move(metadata_change_list),
- has_changes);
- return SyncError();
-}
-
-void DeviceInfoService::GetData(StorageKeyList storage_keys,
- DataCallback callback) {
- auto batch = base::MakeUnique<MutableDataBatch>();
- for (const auto& key : storage_keys) {
- const auto& iter = all_data_.find(key);
- if (iter != all_data_.end()) {
- DCHECK_EQ(key, iter->second->cache_guid());
- batch->Put(key, CopyToEntityData(*iter->second));
- }
- }
- callback.Run(SyncError(), std::move(batch));
-}
-
-void DeviceInfoService::GetAllData(DataCallback callback) {
- auto batch = base::MakeUnique<MutableDataBatch>();
- for (const auto& kv : all_data_) {
- batch->Put(kv.first, CopyToEntityData(*kv.second));
- }
- callback.Run(SyncError(), std::move(batch));
-}
-
-std::string DeviceInfoService::GetClientTag(const EntityData& entity_data) {
- DCHECK(entity_data.specifics.has_device_info());
- return DeviceInfoUtil::SpecificsToTag(entity_data.specifics.device_info());
-}
-
-std::string DeviceInfoService::GetStorageKey(const EntityData& entity_data) {
- DCHECK(entity_data.specifics.has_device_info());
- return entity_data.specifics.device_info().cache_guid();
-}
-
-void DeviceInfoService::DisableSync() {
- // TODO(skym, crbug.com/659263): Would it be reasonable to pulse_timer_.Stop()
- // or subscription_.reset() here?
-
- // Allow deletion of metadata to happen before the deletion of data below. If
- // we crash after removing metadata but not regular data, then merge can
- // handle pairing everything back up.
- ModelTypeSyncBridge::DisableSync();
-
- // Remove all local data, if sync is being disabled, the user has expressed
- // their desire to not have knowledge about other devices.
- if (!all_data_.empty()) {
- std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
- for (const auto& kv : all_data_) {
- store_->DeleteData(batch.get(), kv.first);
- }
- store_->CommitWriteBatch(
- std::move(batch),
- base::Bind(&DeviceInfoService::OnCommit, base::AsWeakPtr(this)));
-
- all_data_.clear();
- NotifyObservers();
- }
-}
-
-bool DeviceInfoService::IsSyncing() const {
- return !all_data_.empty();
-}
-
-std::unique_ptr<DeviceInfo> DeviceInfoService::GetDeviceInfo(
- const std::string& client_id) const {
- const ClientIdToSpecifics::const_iterator iter = all_data_.find(client_id);
- if (iter == all_data_.end()) {
- return std::unique_ptr<DeviceInfo>();
- }
- return SpecificsToModel(*iter->second);
-}
-
-std::vector<std::unique_ptr<DeviceInfo>> DeviceInfoService::GetAllDeviceInfo()
- const {
- std::vector<std::unique_ptr<DeviceInfo>> list;
- for (ClientIdToSpecifics::const_iterator iter = all_data_.begin();
- iter != all_data_.end(); ++iter) {
- list.push_back(SpecificsToModel(*iter->second));
- }
- return list;
-}
-
-void DeviceInfoService::AddObserver(Observer* observer) {
- observers_.AddObserver(observer);
-}
-
-void DeviceInfoService::RemoveObserver(Observer* observer) {
- observers_.RemoveObserver(observer);
-}
-
-int DeviceInfoService::CountActiveDevices() const {
- return CountActiveDevices(Time::Now());
-}
-
-void DeviceInfoService::NotifyObservers() {
- for (auto& observer : observers_)
- observer.OnDeviceInfoChange();
-}
-
-void DeviceInfoService::StoreSpecifics(
- std::unique_ptr<DeviceInfoSpecifics> specifics,
- WriteBatch* batch) {
- const std::string guid = specifics->cache_guid();
- store_->WriteData(batch, guid, specifics->SerializeAsString());
- all_data_[guid] = std::move(specifics);
-}
-
-bool DeviceInfoService::DeleteSpecifics(const std::string& guid,
- WriteBatch* batch) {
- ClientIdToSpecifics::const_iterator iter = all_data_.find(guid);
- if (iter != all_data_.end()) {
- store_->DeleteData(batch, guid);
- all_data_.erase(iter);
- return true;
- } else {
- return false;
- }
-}
-
-void DeviceInfoService::OnProviderInitialized() {
- // Now that the provider has initialized, remove the subscription. The service
- // should only need to give the processor metadata upon initialization. If
- // sync is disabled and enabled, our provider will try to retrigger this
- // event, but we do not want to send any more metadata to the processor.
- subscription_.reset();
-
- has_provider_initialized_ = true;
- LoadMetadataIfReady();
-}
-
-void DeviceInfoService::OnStoreCreated(Result result,
- std::unique_ptr<ModelTypeStore> store) {
- if (result == Result::SUCCESS) {
- std::swap(store_, store);
- store_->ReadAllData(
- base::Bind(&DeviceInfoService::OnReadAllData, base::AsWeakPtr(this)));
- } else {
- ReportStartupErrorToSync("ModelTypeStore creation failed.");
- }
-}
-
-void DeviceInfoService::OnReadAllData(Result result,
- std::unique_ptr<RecordList> record_list) {
- if (result != Result::SUCCESS) {
- ReportStartupErrorToSync("Initial load of data failed.");
- return;
- }
-
- for (const Record& r : *record_list.get()) {
- std::unique_ptr<DeviceInfoSpecifics> specifics =
- base::MakeUnique<DeviceInfoSpecifics>();
- if (specifics->ParseFromString(r.value)) {
- all_data_[specifics->cache_guid()] = std::move(specifics);
- } else {
- ReportStartupErrorToSync("Failed to deserialize specifics.");
- }
- }
-
- has_data_loaded_ = true;
- LoadMetadataIfReady();
-}
-
-void DeviceInfoService::LoadMetadataIfReady() {
- if (has_data_loaded_ && has_provider_initialized_) {
- store_->ReadAllMetadata(base::Bind(&DeviceInfoService::OnReadAllMetadata,
- base::AsWeakPtr(this)));
- }
-}
-
-void DeviceInfoService::OnReadAllMetadata(
- Result result,
- std::unique_ptr<RecordList> metadata_records,
- const std::string& global_metadata) {
- if (result != Result::SUCCESS) {
- ReportStartupErrorToSync("Load of metadata completely failed.");
- return;
- }
-
- auto batch = base::MakeUnique<MetadataBatch>();
- ModelTypeState state;
- if (state.ParseFromString(global_metadata)) {
- batch->SetModelTypeState(state);
- } else {
- ReportStartupErrorToSync("Failed to deserialize global metadata.");
- return;
- }
-
- for (const Record& r : *metadata_records.get()) {
- sync_pb::EntityMetadata entity_metadata;
- if (entity_metadata.ParseFromString(r.value)) {
- batch->AddMetadata(r.id, entity_metadata);
- } else {
- ReportStartupErrorToSync("Failed to deserialize entity metadata.");
- }
- }
-
- change_processor()->OnMetadataLoaded(SyncError(), std::move(batch));
- ReconcileLocalAndStored();
-}
-
-void DeviceInfoService::OnCommit(Result result) {
- if (result != Result::SUCCESS) {
- change_processor()->CreateAndUploadError(FROM_HERE,
- "Failed a write to store.");
- }
-}
-
-void DeviceInfoService::ReconcileLocalAndStored() {
- // On initial syncing we will have a change processor here, but it will not be
- // tracking changes. We need to persist a copy of our local device info to
- // disk, but the Put call to the processor will be ignored. That should be
- // fine however, as the discrepancy will be picked up later in merge. We don't
- // bother trying to track this case and act intelligently because simply not
- // much of a benefit in doing so.
- DCHECK(has_provider_initialized_);
-
- const DeviceInfo* current_info =
- local_device_info_provider_->GetLocalDeviceInfo();
- auto iter = all_data_.find(current_info->guid());
-
- // Convert to DeviceInfo for Equals function.
- if (iter != all_data_.end() &&
- current_info->Equals(*SpecificsToModel(*iter->second))) {
- const TimeDelta pulse_delay(DeviceInfoUtil::CalculatePulseDelay(
- GetLastUpdateTime(*iter->second), Time::Now()));
- if (!pulse_delay.is_zero()) {
- pulse_timer_.Start(FROM_HERE, pulse_delay,
- base::Bind(&DeviceInfoService::SendLocalData,
- base::Unretained(this)));
- return;
- }
- }
- SendLocalData();
-}
-
-void DeviceInfoService::SendLocalData() {
- DCHECK(has_provider_initialized_);
-
- // It is possible that the provider no longer has data for us, such as when
- // the user signs out. No-op this pulse, but keep the timer going in case sync
- // is enabled later.
- if (local_device_info_provider_->GetLocalDeviceInfo() != nullptr) {
- std::unique_ptr<DeviceInfoSpecifics> specifics =
- ModelToSpecifics(*local_device_info_provider_->GetLocalDeviceInfo(),
- TimeToProtoTime(Time::Now()));
- std::unique_ptr<MetadataChangeList> metadata_change_list =
- CreateMetadataChangeList();
- if (change_processor()->IsTrackingMetadata()) {
- change_processor()->Put(specifics->cache_guid(),
- CopyToEntityData(*specifics),
- metadata_change_list.get());
- }
-
- std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
- StoreSpecifics(std::move(specifics), batch.get());
- CommitAndNotify(std::move(batch), std::move(metadata_change_list), true);
- }
-
- pulse_timer_.Start(
- FROM_HERE, DeviceInfoUtil::kPulseInterval,
- base::Bind(&DeviceInfoService::SendLocalData, base::Unretained(this)));
-}
-
-void DeviceInfoService::CommitAndNotify(
- std::unique_ptr<WriteBatch> batch,
- std::unique_ptr<MetadataChangeList> metadata_change_list,
- bool should_notify) {
- static_cast<SimpleMetadataChangeList*>(metadata_change_list.get())
- ->TransferChanges(store_.get(), batch.get());
- store_->CommitWriteBatch(
- std::move(batch),
- base::Bind(&DeviceInfoService::OnCommit, base::AsWeakPtr(this)));
- if (should_notify) {
- NotifyObservers();
- }
-}
-
-int DeviceInfoService::CountActiveDevices(const Time now) const {
- return std::count_if(all_data_.begin(), all_data_.end(),
- [now](ClientIdToSpecifics::const_reference pair) {
- return DeviceInfoUtil::IsActive(
- GetLastUpdateTime(*pair.second), now);
- });
-}
-
-void DeviceInfoService::ReportStartupErrorToSync(const std::string& msg) {
- // TODO(skym): Shouldn't need to log this here, reporting should always log.
- LOG(WARNING) << msg;
- change_processor()->OnMetadataLoaded(
- change_processor()->CreateAndUploadError(FROM_HERE, msg), nullptr);
-}
-
-} // namespace syncer
« no previous file with comments | « components/sync/device_info/device_info_service.h ('k') | components/sync/device_info/device_info_service_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698