OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/sync/glue/device_info_sync_service.h" | 5 #include "chrome/browser/sync/glue/device_info_sync_service.h" |
6 | 6 |
7 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
8 #include "chrome/browser/sync/glue/local_device_info_provider.h" | 8 #include "chrome/browser/sync/glue/local_device_info_provider.h" |
9 #include "sync/api/sync_change.h" | 9 #include "sync/api/sync_change.h" |
10 #include "sync/protocol/sync.pb.h" | 10 #include "sync/protocol/sync.pb.h" |
11 #include "sync/util/time.h" | |
11 | 12 |
12 namespace browser_sync { | 13 namespace browser_sync { |
13 | 14 |
14 using syncer::ModelType; | 15 using syncer::ModelType; |
15 using syncer::SyncChange; | 16 using syncer::SyncChange; |
16 using syncer::SyncChangeList; | 17 using syncer::SyncChangeList; |
17 using syncer::SyncChangeProcessor; | 18 using syncer::SyncChangeProcessor; |
18 using syncer::SyncData; | 19 using syncer::SyncData; |
19 using syncer::SyncDataList; | 20 using syncer::SyncDataList; |
20 using syncer::SyncErrorFactory; | 21 using syncer::SyncErrorFactory; |
21 using syncer::SyncMergeResult; | 22 using syncer::SyncMergeResult; |
22 | 23 |
23 DeviceInfoSyncService::DeviceInfoSyncService( | 24 DeviceInfoSyncService::DeviceInfoSyncService( |
24 LocalDeviceInfoProvider* local_device_info_provider) | 25 LocalDeviceInfoProvider* local_device_info_provider) |
25 : local_device_info_provider_(local_device_info_provider) { | 26 : local_device_backup_time_(-1), |
27 local_device_info_provider_(local_device_info_provider) { | |
26 DCHECK(local_device_info_provider); | 28 DCHECK(local_device_info_provider); |
27 } | 29 } |
28 | 30 |
29 DeviceInfoSyncService::~DeviceInfoSyncService() { | 31 DeviceInfoSyncService::~DeviceInfoSyncService() { |
30 } | 32 } |
31 | 33 |
32 SyncMergeResult DeviceInfoSyncService::MergeDataAndStartSyncing( | 34 SyncMergeResult DeviceInfoSyncService::MergeDataAndStartSyncing( |
33 ModelType type, | 35 ModelType type, |
34 const SyncDataList& initial_sync_data, | 36 const SyncDataList& initial_sync_data, |
35 scoped_ptr<SyncChangeProcessor> sync_processor, | 37 scoped_ptr<SyncChangeProcessor> sync_processor, |
36 scoped_ptr<SyncErrorFactory> error_handler) { | 38 scoped_ptr<SyncErrorFactory> error_handler) { |
37 DCHECK(sync_processor.get()); | 39 DCHECK(sync_processor.get()); |
38 DCHECK(error_handler.get()); | 40 DCHECK(error_handler.get()); |
39 DCHECK_EQ(type, syncer::DEVICE_INFO); | 41 DCHECK_EQ(type, syncer::DEVICE_INFO); |
40 | 42 |
41 DCHECK(all_data_.empty()); | 43 DCHECK(all_data_.empty()); |
42 | 44 |
43 sync_processor_ = sync_processor.Pass(); | 45 sync_processor_ = sync_processor.Pass(); |
44 error_handler_ = error_handler.Pass(); | 46 error_handler_ = error_handler.Pass(); |
45 | 47 |
48 // Initialization should be completed before this type is enabled | |
49 // and local device info must be available. | |
50 const DeviceInfo* local_device_info = | |
51 local_device_info_provider_->GetLocalDeviceInfo(); | |
52 DCHECK(local_device_info != NULL); | |
53 | |
54 // Indicates whether a local device has been added or updated. | |
55 // |change_type| defaults to ADD and might be changed to | |
56 // UPDATE to INVALID down below if the initial data contains | |
57 // data matching the local device ID. | |
58 SyncChange::SyncChangeType change_type = SyncChange::ACTION_ADD; | |
59 size_t num_items_new = 0; | |
60 size_t num_items_updated = 0; | |
61 | |
46 // Iterate over all initial sync data and copy it to the cache. | 62 // Iterate over all initial sync data and copy it to the cache. |
47 for (SyncDataList::const_iterator iter = initial_sync_data.begin(); | 63 for (SyncDataList::const_iterator iter = initial_sync_data.begin(); |
48 iter != initial_sync_data.end(); | 64 iter != initial_sync_data.end(); |
49 ++iter) { | 65 ++iter) { |
50 DCHECK_EQ(syncer::DEVICE_INFO, iter->GetDataType()); | 66 DCHECK_EQ(syncer::DEVICE_INFO, iter->GetDataType()); |
51 StoreSyncData(iter->GetSpecifics().device_info().cache_guid(), *iter); | |
52 } | |
53 | 67 |
54 size_t num_items_new = initial_sync_data.size(); | 68 const std::string& id = iter->GetSpecifics().device_info().cache_guid(); |
55 size_t num_items_updated = 0; | |
56 // Indicates whether a local device has been added or updated. | |
57 SyncChange::SyncChangeType change_type = SyncChange::ACTION_INVALID; | |
58 | 69 |
59 // Initialization should be completed before this type is enabled | 70 if (id == local_device_info->guid()) { |
60 // and local device info must be available. | 71 // |initial_sync_data| contains data matching the local device. |
61 const DeviceInfo* local_device_info = | 72 scoped_ptr<DeviceInfo> synced_local_device_info = |
62 local_device_info_provider_->GetLocalDeviceInfo(); | 73 make_scoped_ptr(CreateDeviceInfo(*iter)); |
63 DCHECK(local_device_info != NULL); | |
64 // Before storing the local device info check if the data with | |
65 // the same guid has already been synced. This attempts to retrieve | |
66 // DeviceInfo from the cached data initialized above. | |
67 scoped_ptr<DeviceInfo> synced_local_device_info = | |
68 GetDeviceInfo(local_device_info->guid()); | |
69 | 74 |
70 if (synced_local_device_info.get()) { | 75 // Retrieve local device backup timestamp value from the sync data. |
71 // Local device info has been synced and exists in the cache. | 76 bool has_synced_backup_time = |
72 // |num_items_new| and |num_items_updated| need to be updated to | 77 iter->GetSpecifics().device_info().has_backup_timestamp(); |
73 // reflect that. | 78 int64 synced_backup_time = |
74 num_items_new--; | 79 has_synced_backup_time |
75 // Overwrite the synced device info with the local data only if | 80 ? iter->GetSpecifics().device_info().backup_timestamp() |
76 // it is different. | 81 : -1; |
77 if (!synced_local_device_info->Equals(*local_device_info)) { | 82 |
78 num_items_updated++; | 83 // Overwrite |local_device_backup_time_| with this value if it |
79 change_type = SyncChange::ACTION_UPDATE; | 84 // hasn't been set yet. |
85 if (!has_local_device_backup_time() && has_synced_backup_time) { | |
86 set_local_device_backup_time(synced_backup_time); | |
87 } | |
88 | |
89 // Store the synced device info for the local device only | |
90 // it is the same as the local info. Otherwise store the local | |
91 // device info and issue a change further below after finishing | |
92 // processing the |initial_sync_data|. | |
93 if (synced_local_device_info->Equals(*local_device_info) && | |
94 synced_backup_time == local_device_backup_time()) { | |
95 change_type = SyncChange::ACTION_INVALID; | |
96 } else { | |
97 num_items_updated++; | |
98 change_type = SyncChange::ACTION_UPDATE; | |
99 continue; | |
100 } | |
101 } else { | |
102 // A new device that doesn't match the local device. | |
103 num_items_new++; | |
80 } | 104 } |
81 } else { | 105 |
82 // Local device info doesn't yet exist in the cache and | 106 StoreSyncData(id, *iter); |
83 // will be added further below. | |
84 // |num_items_new| and |num_items_updated| are already correct. | |
85 change_type = SyncChange::ACTION_ADD; | |
86 } | 107 } |
87 | 108 |
88 syncer::SyncMergeResult result(type); | 109 syncer::SyncMergeResult result(type); |
89 | 110 |
90 // Update SyncData from device info if it is new or different than | 111 // Add SyncData for the local deviceif it is new or different than |
pavely
2014/09/17 23:05:32
deviceif => device if
| |
91 // the synced one, and also add it to the |change_list|. | 112 // the synced one, and also add it to the |change_list|. |
92 if (change_type != SyncChange::ACTION_INVALID) { | 113 if (change_type != SyncChange::ACTION_INVALID) { |
93 SyncData local_data = CreateLocalData(local_device_info); | 114 SyncData local_data = CreateLocalData(local_device_info); |
94 StoreSyncData(local_device_info->guid(), local_data); | 115 StoreSyncData(local_device_info->guid(), local_data); |
95 | 116 |
96 SyncChangeList change_list; | 117 SyncChangeList change_list; |
97 change_list.push_back(SyncChange(FROM_HERE, change_type, local_data)); | 118 change_list.push_back(SyncChange(FROM_HERE, change_type, local_data)); |
98 result.set_error( | 119 result.set_error( |
99 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list)); | 120 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list)); |
100 } | 121 } |
101 | 122 |
102 result.set_num_items_before_association(1); | 123 result.set_num_items_before_association(1); |
103 result.set_num_items_after_association(all_data_.size()); | 124 result.set_num_items_after_association(all_data_.size()); |
104 result.set_num_items_added(num_items_new); | 125 result.set_num_items_added(num_items_new); |
105 result.set_num_items_modified(num_items_updated); | 126 result.set_num_items_modified(num_items_updated); |
106 result.set_num_items_deleted(0); | 127 result.set_num_items_deleted(0); |
107 | 128 |
108 NotifyObservers(); | 129 NotifyObservers(); |
109 | 130 |
110 return result; | 131 return result; |
111 } | 132 } |
112 | 133 |
113 void DeviceInfoSyncService::StopSyncing(syncer::ModelType type) { | 134 void DeviceInfoSyncService::StopSyncing(syncer::ModelType type) { |
114 all_data_.clear(); | 135 all_data_.clear(); |
115 sync_processor_.reset(); | 136 sync_processor_.reset(); |
116 error_handler_.reset(); | 137 error_handler_.reset(); |
138 clear_local_device_backup_time(); | |
117 } | 139 } |
118 | 140 |
119 SyncDataList DeviceInfoSyncService::GetAllSyncData( | 141 SyncDataList DeviceInfoSyncService::GetAllSyncData( |
120 syncer::ModelType type) const { | 142 syncer::ModelType type) const { |
121 SyncDataList list; | 143 SyncDataList list; |
122 | 144 |
123 for (SyncDataMap::const_iterator iter = all_data_.begin(); | 145 for (SyncDataMap::const_iterator iter = all_data_.begin(); |
124 iter != all_data_.end(); | 146 iter != all_data_.end(); |
125 ++iter) { | 147 ++iter) { |
126 list.push_back(iter->second); | 148 list.push_back(iter->second); |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
201 } | 223 } |
202 | 224 |
203 void DeviceInfoSyncService::RemoveObserver(Observer* observer) { | 225 void DeviceInfoSyncService::RemoveObserver(Observer* observer) { |
204 observers_.RemoveObserver(observer); | 226 observers_.RemoveObserver(observer); |
205 } | 227 } |
206 | 228 |
207 void DeviceInfoSyncService::NotifyObservers() { | 229 void DeviceInfoSyncService::NotifyObservers() { |
208 FOR_EACH_OBSERVER(Observer, observers_, OnDeviceInfoChange()); | 230 FOR_EACH_OBSERVER(Observer, observers_, OnDeviceInfoChange()); |
209 } | 231 } |
210 | 232 |
233 void DeviceInfoSyncService::UpdateLocalDeviceBackupTime( | |
234 base::Time backup_time) { | |
235 set_local_device_backup_time(syncer::TimeToProtoTime(backup_time)); | |
236 | |
237 if (sync_processor_.get()) { | |
238 // Local device info must be available in advance | |
239 DCHECK(local_device_info_provider_->GetLocalDeviceInfo()); | |
240 const std::string& local_id = | |
241 local_device_info_provider_->GetLocalDeviceInfo()->guid(); | |
242 | |
243 SyncDataMap::iterator iter = all_data_.find(local_id); | |
244 DCHECK(iter != all_data_.end()); | |
245 | |
246 if (UpdateBackupTime(iter->second)) { | |
247 // Local device backup time has changed. | |
248 // Push changes to the server via the |sync_processor_|. | |
249 SyncChangeList change_list; | |
250 change_list.push_back(SyncChange( | |
251 FROM_HERE, syncer::SyncChange::ACTION_UPDATE, iter->second)); | |
252 sync_processor_->ProcessSyncChanges(FROM_HERE, change_list); | |
253 } | |
254 } | |
255 } | |
256 | |
257 bool DeviceInfoSyncService::UpdateBackupTime(syncer::SyncData& sync_data) { | |
pavely
2014/09/17 23:04:38
nit: Pass sync_data as pointer (http://google-styl
| |
258 DCHECK(has_local_device_backup_time()); | |
259 DCHECK(sync_data.GetSpecifics().has_device_info()); | |
260 const sync_pb::DeviceInfoSpecifics& source_specifics = | |
261 sync_data.GetSpecifics().device_info(); | |
262 | |
263 if (!source_specifics.has_backup_timestamp() || | |
264 source_specifics.backup_timestamp() != local_device_backup_time()) { | |
265 sync_pb::EntitySpecifics entity(sync_data.GetSpecifics()); | |
266 entity.mutable_device_info()->set_backup_timestamp( | |
267 local_device_backup_time()); | |
268 sync_data = CreateLocalData(entity); | |
269 | |
270 return true; | |
271 } | |
272 | |
273 return false; | |
274 } | |
275 | |
276 base::Time DeviceInfoSyncService::GetLocalDeviceBackupTime() const { | |
277 return has_local_device_backup_time() | |
278 ? syncer::ProtoTimeToTime(local_device_backup_time()) | |
279 : base::Time(); | |
280 } | |
281 | |
211 SyncData DeviceInfoSyncService::CreateLocalData(const DeviceInfo* info) { | 282 SyncData DeviceInfoSyncService::CreateLocalData(const DeviceInfo* info) { |
212 sync_pb::EntitySpecifics entity; | 283 sync_pb::EntitySpecifics entity; |
213 sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); | 284 sync_pb::DeviceInfoSpecifics& specifics = *entity.mutable_device_info(); |
214 | 285 |
215 specifics.set_cache_guid(info->guid()); | 286 specifics.set_cache_guid(info->guid()); |
216 specifics.set_client_name(info->client_name()); | 287 specifics.set_client_name(info->client_name()); |
217 specifics.set_chrome_version(info->chrome_version()); | 288 specifics.set_chrome_version(info->chrome_version()); |
218 specifics.set_sync_user_agent(info->sync_user_agent()); | 289 specifics.set_sync_user_agent(info->sync_user_agent()); |
219 specifics.set_device_type(info->device_type()); | 290 specifics.set_device_type(info->device_type()); |
220 specifics.set_signin_scoped_device_id(info->signin_scoped_device_id()); | 291 specifics.set_signin_scoped_device_id(info->signin_scoped_device_id()); |
221 | 292 |
293 if (has_local_device_backup_time()) { | |
294 specifics.set_backup_timestamp(local_device_backup_time()); | |
295 } | |
296 | |
297 return CreateLocalData(entity); | |
298 } | |
299 | |
300 SyncData DeviceInfoSyncService::CreateLocalData( | |
301 const sync_pb::EntitySpecifics& entity) { | |
302 const sync_pb::DeviceInfoSpecifics& specifics = entity.device_info(); | |
303 | |
222 std::string local_device_tag = | 304 std::string local_device_tag = |
223 base::StringPrintf("DeviceInfo_%s", info->guid().c_str()); | 305 base::StringPrintf("DeviceInfo_%s", specifics.cache_guid().c_str()); |
224 | 306 |
225 return SyncData::CreateLocalData( | 307 return SyncData::CreateLocalData( |
226 local_device_tag, info->client_name(), entity); | 308 local_device_tag, specifics.client_name(), entity); |
227 } | 309 } |
228 | 310 |
229 DeviceInfo* DeviceInfoSyncService::CreateDeviceInfo( | 311 DeviceInfo* DeviceInfoSyncService::CreateDeviceInfo( |
230 const syncer::SyncData sync_data) { | 312 const syncer::SyncData sync_data) { |
231 const sync_pb::DeviceInfoSpecifics& specifics = | 313 const sync_pb::DeviceInfoSpecifics& specifics = |
232 sync_data.GetSpecifics().device_info(); | 314 sync_data.GetSpecifics().device_info(); |
233 | 315 |
234 return new DeviceInfo(specifics.cache_guid(), | 316 return new DeviceInfo(specifics.cache_guid(), |
235 specifics.client_name(), | 317 specifics.client_name(), |
236 specifics.chrome_version(), | 318 specifics.chrome_version(), |
(...skipping 14 matching lines...) Expand all Loading... | |
251 SyncDataMap::iterator iter = all_data_.find(client_id); | 333 SyncDataMap::iterator iter = all_data_.find(client_id); |
252 if (iter != all_data_.end()) { | 334 if (iter != all_data_.end()) { |
253 DVLOG(1) << "Deleting DEVICE_INFO for " | 335 DVLOG(1) << "Deleting DEVICE_INFO for " |
254 << iter->second.GetSpecifics().device_info().client_name() | 336 << iter->second.GetSpecifics().device_info().client_name() |
255 << " with ID " << client_id; | 337 << " with ID " << client_id; |
256 all_data_.erase(iter); | 338 all_data_.erase(iter); |
257 } | 339 } |
258 } | 340 } |
259 | 341 |
260 } // namespace browser_sync | 342 } // namespace browser_sync |
OLD | NEW |