Chromium Code Reviews| 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..a3dfed148df75fe80761fc5347d16714c2327e3d 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 deviceif it is new or different than |
|
pavely
2014/09/17 23:05:32
deviceif => device if
|
| // 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,55 @@ 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()); |
| + |
| + if (UpdateBackupTime(iter->second)) { |
| + // 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, iter->second)); |
| + sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); |
| + } |
| + } |
| +} |
| + |
| +bool DeviceInfoSyncService::UpdateBackupTime(syncer::SyncData& sync_data) { |
|
pavely
2014/09/17 23:04:38
nit: Pass sync_data as pointer (http://google-styl
|
| + 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 +290,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( |