| Index: chrome/browser/sync/glue/device_info_sync_service.cc
|
| diff --git a/chrome/browser/sync/glue/device_info_sync_service.cc b/chrome/browser/sync/glue/device_info_sync_service.cc
|
| index 17fd8edf7381882eff4e513dd6fb7ca74c615373..fe7ccc1bfeff053149df22bfa7189a858257cbf0 100644
|
| --- a/chrome/browser/sync/glue/device_info_sync_service.cc
|
| +++ b/chrome/browser/sync/glue/device_info_sync_service.cc
|
| @@ -8,6 +8,7 @@
|
| #include "chrome/browser/sync/glue/local_device_info_provider.h"
|
| #include "sync/api/sync_change.h"
|
| #include "sync/protocol/sync.pb.h"
|
| +#include "sync/util/time.h"
|
|
|
| namespace browser_sync {
|
|
|
| @@ -22,7 +23,8 @@ using syncer::SyncMergeResult;
|
|
|
| DeviceInfoSyncService::DeviceInfoSyncService(
|
| LocalDeviceInfoProvider* local_device_info_provider)
|
| - : local_device_info_provider_(local_device_info_provider) {
|
| + : local_device_backup_time_(-1),
|
| + local_device_info_provider_(local_device_info_provider) {
|
| DCHECK(local_device_info_provider);
|
| }
|
|
|
| @@ -43,51 +45,70 @@ SyncMergeResult DeviceInfoSyncService::MergeDataAndStartSyncing(
|
| sync_processor_ = sync_processor.Pass();
|
| error_handler_ = error_handler.Pass();
|
|
|
| + // Initialization should be completed before this type is enabled
|
| + // and local device info must be available.
|
| + const DeviceInfo* local_device_info =
|
| + local_device_info_provider_->GetLocalDeviceInfo();
|
| + DCHECK(local_device_info != NULL);
|
| +
|
| + // Indicates whether a local device has been added or updated.
|
| + // |change_type| defaults to ADD and might be changed to
|
| + // UPDATE to INVALID down below if the initial data contains
|
| + // data matching the local device ID.
|
| + SyncChange::SyncChangeType change_type = SyncChange::ACTION_ADD;
|
| + size_t num_items_new = 0;
|
| + size_t num_items_updated = 0;
|
| +
|
| // Iterate over all initial sync data and copy it to the cache.
|
| for (SyncDataList::const_iterator iter = initial_sync_data.begin();
|
| iter != initial_sync_data.end();
|
| ++iter) {
|
| DCHECK_EQ(syncer::DEVICE_INFO, iter->GetDataType());
|
| - StoreSyncData(iter->GetSpecifics().device_info().cache_guid(), *iter);
|
| - }
|
|
|
| - size_t num_items_new = initial_sync_data.size();
|
| - size_t num_items_updated = 0;
|
| - // Indicates whether a local device has been added or updated.
|
| - SyncChange::SyncChangeType change_type = SyncChange::ACTION_INVALID;
|
| -
|
| - // Initialization should be completed before this type is enabled
|
| - // and local device info must be available.
|
| - const DeviceInfo* local_device_info =
|
| - local_device_info_provider_->GetLocalDeviceInfo();
|
| - DCHECK(local_device_info != NULL);
|
| - // Before storing the local device info check if the data with
|
| - // the same guid has already been synced. This attempts to retrieve
|
| - // DeviceInfo from the cached data initialized above.
|
| - scoped_ptr<DeviceInfo> synced_local_device_info =
|
| - GetDeviceInfo(local_device_info->guid());
|
| -
|
| - if (synced_local_device_info.get()) {
|
| - // Local device info has been synced and exists in the cache.
|
| - // |num_items_new| and |num_items_updated| need to be updated to
|
| - // reflect that.
|
| - num_items_new--;
|
| - // Overwrite the synced device info with the local data only if
|
| - // it is different.
|
| - if (!synced_local_device_info->Equals(*local_device_info)) {
|
| - num_items_updated++;
|
| - change_type = SyncChange::ACTION_UPDATE;
|
| + const std::string& id = iter->GetSpecifics().device_info().cache_guid();
|
| +
|
| + if (id == local_device_info->guid()) {
|
| + // |initial_sync_data| contains data matching the local device.
|
| + scoped_ptr<DeviceInfo> synced_local_device_info =
|
| + make_scoped_ptr(CreateDeviceInfo(*iter));
|
| +
|
| + // Retrieve local device backup timestamp value from the sync data.
|
| + bool has_synced_backup_time =
|
| + iter->GetSpecifics().device_info().has_backup_timestamp();
|
| + int64 synced_backup_time =
|
| + has_synced_backup_time
|
| + ? iter->GetSpecifics().device_info().backup_timestamp()
|
| + : -1;
|
| +
|
| + // Overwrite |local_device_backup_time_| with this value if it
|
| + // hasn't been set yet.
|
| + if (!has_local_device_backup_time() && has_synced_backup_time) {
|
| + set_local_device_backup_time(synced_backup_time);
|
| + }
|
| +
|
| + // Store the synced device info for the local device only
|
| + // it is the same as the local info. Otherwise store the local
|
| + // device info and issue a change further below after finishing
|
| + // processing the |initial_sync_data|.
|
| + if (synced_local_device_info->Equals(*local_device_info) &&
|
| + synced_backup_time == local_device_backup_time()) {
|
| + change_type = SyncChange::ACTION_INVALID;
|
| + } else {
|
| + num_items_updated++;
|
| + change_type = SyncChange::ACTION_UPDATE;
|
| + continue;
|
| + }
|
| + } else {
|
| + // A new device that doesn't match the local device.
|
| + num_items_new++;
|
| }
|
| - } else {
|
| - // Local device info doesn't yet exist in the cache and
|
| - // will be added further below.
|
| - // |num_items_new| and |num_items_updated| are already correct.
|
| - change_type = SyncChange::ACTION_ADD;
|
| +
|
| + StoreSyncData(id, *iter);
|
| }
|
|
|
| syncer::SyncMergeResult result(type);
|
|
|
| - // Update SyncData from device info if it is new or different than
|
| + // Add SyncData for the local device if it is new or different than
|
| // the synced one, and also add it to the |change_list|.
|
| if (change_type != SyncChange::ACTION_INVALID) {
|
| SyncData local_data = CreateLocalData(local_device_info);
|
| @@ -114,6 +135,7 @@ void DeviceInfoSyncService::StopSyncing(syncer::ModelType type) {
|
| all_data_.clear();
|
| sync_processor_.reset();
|
| error_handler_.reset();
|
| + clear_local_device_backup_time();
|
| }
|
|
|
| SyncDataList DeviceInfoSyncService::GetAllSyncData(
|
| @@ -208,6 +230,56 @@ void DeviceInfoSyncService::NotifyObservers() {
|
| FOR_EACH_OBSERVER(Observer, observers_, OnDeviceInfoChange());
|
| }
|
|
|
| +void DeviceInfoSyncService::UpdateLocalDeviceBackupTime(
|
| + base::Time backup_time) {
|
| + set_local_device_backup_time(syncer::TimeToProtoTime(backup_time));
|
| +
|
| + if (sync_processor_.get()) {
|
| + // Local device info must be available in advance
|
| + DCHECK(local_device_info_provider_->GetLocalDeviceInfo());
|
| + const std::string& local_id =
|
| + local_device_info_provider_->GetLocalDeviceInfo()->guid();
|
| +
|
| + SyncDataMap::iterator iter = all_data_.find(local_id);
|
| + DCHECK(iter != all_data_.end());
|
| +
|
| + syncer::SyncData& data = iter->second;
|
| + if (UpdateBackupTime(&data)) {
|
| + // Local device backup time has changed.
|
| + // Push changes to the server via the |sync_processor_|.
|
| + SyncChangeList change_list;
|
| + change_list.push_back(SyncChange(
|
| + FROM_HERE, syncer::SyncChange::ACTION_UPDATE, data));
|
| + sync_processor_->ProcessSyncChanges(FROM_HERE, change_list);
|
| + }
|
| + }
|
| +}
|
| +
|
| +bool DeviceInfoSyncService::UpdateBackupTime(syncer::SyncData* sync_data) {
|
| + DCHECK(has_local_device_backup_time());
|
| + DCHECK(sync_data->GetSpecifics().has_device_info());
|
| + const sync_pb::DeviceInfoSpecifics& source_specifics =
|
| + sync_data->GetSpecifics().device_info();
|
| +
|
| + if (!source_specifics.has_backup_timestamp() ||
|
| + source_specifics.backup_timestamp() != local_device_backup_time()) {
|
| + sync_pb::EntitySpecifics entity(sync_data->GetSpecifics());
|
| + entity.mutable_device_info()->set_backup_timestamp(
|
| + local_device_backup_time());
|
| + *sync_data = CreateLocalData(entity);
|
| +
|
| + return true;
|
| + }
|
| +
|
| + return false;
|
| +}
|
| +
|
| +base::Time DeviceInfoSyncService::GetLocalDeviceBackupTime() const {
|
| + return has_local_device_backup_time()
|
| + ? syncer::ProtoTimeToTime(local_device_backup_time())
|
| + : base::Time();
|
| +}
|
| +
|
| SyncData DeviceInfoSyncService::CreateLocalData(const DeviceInfo* info) {
|
| sync_pb::EntitySpecifics entity;
|
| sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info();
|
| @@ -219,11 +291,22 @@ SyncData DeviceInfoSyncService::CreateLocalData(const DeviceInfo* info) {
|
| specifics.set_device_type(info->device_type());
|
| specifics.set_signin_scoped_device_id(info->signin_scoped_device_id());
|
|
|
| + if (has_local_device_backup_time()) {
|
| + specifics.set_backup_timestamp(local_device_backup_time());
|
| + }
|
| +
|
| + return CreateLocalData(entity);
|
| +}
|
| +
|
| +SyncData DeviceInfoSyncService::CreateLocalData(
|
| + const sync_pb::EntitySpecifics& entity) {
|
| + const sync_pb::DeviceInfoSpecifics& specifics = entity.device_info();
|
| +
|
| std::string local_device_tag =
|
| - base::StringPrintf("DeviceInfo_%s", info->guid().c_str());
|
| + base::StringPrintf("DeviceInfo_%s", specifics.cache_guid().c_str());
|
|
|
| return SyncData::CreateLocalData(
|
| - local_device_tag, info->client_name(), entity);
|
| + local_device_tag, specifics.client_name(), entity);
|
| }
|
|
|
| DeviceInfo* DeviceInfoSyncService::CreateDeviceInfo(
|
|
|