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

Side by Side Diff: components/sync/device_info/device_info_service.cc

Issue 2461723002: [Sync] DeviceInfoService static method and error cleanup. (Closed)
Patch Set: Moved local suffix into a constant. Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 "components/sync/device_info/device_info_service.h" 5 #include "components/sync/device_info/device_info_service.h"
6 6
7 #include <stdint.h>
8
7 #include <algorithm> 9 #include <algorithm>
8 #include <set> 10 #include <set>
9 #include <utility> 11 #include <utility>
10 12
11 #include "base/bind.h" 13 #include "base/bind.h"
12 #include "base/location.h" 14 #include "base/location.h"
13 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
14 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
15 #include "components/sync/base/time.h" 17 #include "components/sync/base/time.h"
16 #include "components/sync/device_info/device_info_util.h" 18 #include "components/sync/device_info/device_info_util.h"
(...skipping 10 matching lines...) Expand all
27 using base::TimeDelta; 29 using base::TimeDelta;
28 using sync_pb::DeviceInfoSpecifics; 30 using sync_pb::DeviceInfoSpecifics;
29 using sync_pb::EntitySpecifics; 31 using sync_pb::EntitySpecifics;
30 using sync_pb::ModelTypeState; 32 using sync_pb::ModelTypeState;
31 33
32 using Record = ModelTypeStore::Record; 34 using Record = ModelTypeStore::Record;
33 using RecordList = ModelTypeStore::RecordList; 35 using RecordList = ModelTypeStore::RecordList;
34 using Result = ModelTypeStore::Result; 36 using Result = ModelTypeStore::Result;
35 using WriteBatch = ModelTypeStore::WriteBatch; 37 using WriteBatch = ModelTypeStore::WriteBatch;
36 38
39 namespace {
40
41 // Find the timestamp for the last time this |device_info| was edited.
42 Time GetLastUpdateTime(const DeviceInfoSpecifics& specifics) {
maxbogue 2016/10/28 20:20:01 I genuinely find it more confusing to see just Tim
skym 2016/10/28 20:46:16 Why? Is there some other 'Time' object you think I
43 if (specifics.has_last_updated_timestamp()) {
44 return ProtoTimeToTime(specifics.last_updated_timestamp());
45 } else {
46 return Time();
47 }
48 }
49
50 // Converts DeviceInfoSpecifics into a freshly allocated DeviceInfo.
51 std::unique_ptr<DeviceInfo> SpecificsToModel(
maxbogue 2016/10/28 20:20:01 Here as well I find Model to be vague. I think Spe
skym 2016/10/28 20:46:16 DeviceInfo describes everything going on here. Dev
52 const DeviceInfoSpecifics& specifics) {
53 return base::MakeUnique<DeviceInfo>(
54 specifics.cache_guid(), specifics.client_name(),
55 specifics.chrome_version(), specifics.sync_user_agent(),
56 specifics.device_type(), specifics.signin_scoped_device_id());
57 }
58
59 // Allocate a EntityData and copies |specifics| into it.
60 std::unique_ptr<EntityData> CopyToEntityData(
61 const DeviceInfoSpecifics& specifics) {
62 auto entity_data = base::MakeUnique<EntityData>();
63 *entity_data->specifics.mutable_device_info() = specifics;
64 entity_data->non_unique_name = specifics.client_name();
65 return entity_data;
66 }
67
68 // Converts DeviceInfo into a freshly allocated DeviceInfoSpecifics. Takes
69 // |last_updated_timestamp| to set because the model object does not contain
70 // this concept.
71 std::unique_ptr<DeviceInfoSpecifics> ModelToSpecifics(
72 const DeviceInfo& info,
73 int64_t last_updated_timestamp) {
74 auto specifics = base::MakeUnique<DeviceInfoSpecifics>();
75 specifics->set_cache_guid(info.guid());
76 specifics->set_client_name(info.client_name());
77 specifics->set_chrome_version(info.chrome_version());
78 specifics->set_sync_user_agent(info.sync_user_agent());
79 specifics->set_device_type(info.device_type());
80 specifics->set_signin_scoped_device_id(info.signin_scoped_device_id());
81 specifics->set_last_updated_timestamp(last_updated_timestamp);
82 return specifics;
83 }
84
85 } // namespace
86
37 DeviceInfoService::DeviceInfoService( 87 DeviceInfoService::DeviceInfoService(
38 LocalDeviceInfoProvider* local_device_info_provider, 88 LocalDeviceInfoProvider* local_device_info_provider,
39 const StoreFactoryFunction& callback, 89 const StoreFactoryFunction& callback,
40 const ChangeProcessorFactory& change_processor_factory) 90 const ChangeProcessorFactory& change_processor_factory)
41 : ModelTypeService(change_processor_factory, DEVICE_INFO), 91 : ModelTypeService(change_processor_factory, DEVICE_INFO),
42 local_device_info_provider_(local_device_info_provider) { 92 local_device_info_provider_(local_device_info_provider) {
43 DCHECK(local_device_info_provider); 93 DCHECK(local_device_info_provider);
44 94
45 // This is not threadsafe, but presuably the provider initializes on the same 95 // This is not threadsafe, but presuably the provider initializes on the same
46 // thread as us so we're okay. 96 // thread as us so we're okay.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 const DeviceInfo* local_info = 133 const DeviceInfo* local_info =
84 local_device_info_provider_->GetLocalDeviceInfo(); 134 local_device_info_provider_->GetLocalDeviceInfo();
85 std::string local_guid = local_info->guid(); 135 std::string local_guid = local_info->guid();
86 std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); 136 std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
87 for (const auto& kv : entity_data_map) { 137 for (const auto& kv : entity_data_map) {
88 const DeviceInfoSpecifics& specifics = 138 const DeviceInfoSpecifics& specifics =
89 kv.second.value().specifics.device_info(); 139 kv.second.value().specifics.device_info();
90 DCHECK_EQ(kv.first, specifics.cache_guid()); 140 DCHECK_EQ(kv.first, specifics.cache_guid());
91 if (specifics.cache_guid() == local_guid) { 141 if (specifics.cache_guid() == local_guid) {
92 // Don't Put local data if it's the same as the remote copy. 142 // Don't Put local data if it's the same as the remote copy.
93 if (local_info->Equals(*CopyToModel(specifics))) { 143 if (local_info->Equals(*SpecificsToModel(specifics))) {
94 local_guids_to_put.erase(local_guid); 144 local_guids_to_put.erase(local_guid);
95 } else { 145 } else {
96 // This device is valid right now and this entry is about to be 146 // This device is valid right now and this entry is about to be
97 // committed, use this as an opportunity to refresh the timestamp. 147 // committed, use this as an opportunity to refresh the timestamp.
98 all_data_[local_guid]->set_last_updated_timestamp( 148 all_data_[local_guid]->set_last_updated_timestamp(
99 TimeToProtoTime(Time::Now())); 149 TimeToProtoTime(Time::Now()));
100 } 150 }
101 } else { 151 } else {
102 // Remote data wins conflicts. 152 // Remote data wins conflicts.
103 local_guids_to_put.erase(specifics.cache_guid()); 153 local_guids_to_put.erase(specifics.cache_guid());
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 bool DeviceInfoService::IsSyncing() const { 258 bool DeviceInfoService::IsSyncing() const {
209 return !all_data_.empty(); 259 return !all_data_.empty();
210 } 260 }
211 261
212 std::unique_ptr<DeviceInfo> DeviceInfoService::GetDeviceInfo( 262 std::unique_ptr<DeviceInfo> DeviceInfoService::GetDeviceInfo(
213 const std::string& client_id) const { 263 const std::string& client_id) const {
214 const ClientIdToSpecifics::const_iterator iter = all_data_.find(client_id); 264 const ClientIdToSpecifics::const_iterator iter = all_data_.find(client_id);
215 if (iter == all_data_.end()) { 265 if (iter == all_data_.end()) {
216 return std::unique_ptr<DeviceInfo>(); 266 return std::unique_ptr<DeviceInfo>();
217 } 267 }
218 return CopyToModel(*iter->second); 268 return SpecificsToModel(*iter->second);
219 } 269 }
220 270
221 std::vector<std::unique_ptr<DeviceInfo>> DeviceInfoService::GetAllDeviceInfo() 271 std::vector<std::unique_ptr<DeviceInfo>> DeviceInfoService::GetAllDeviceInfo()
222 const { 272 const {
223 std::vector<std::unique_ptr<DeviceInfo>> list; 273 std::vector<std::unique_ptr<DeviceInfo>> list;
224 for (ClientIdToSpecifics::const_iterator iter = all_data_.begin(); 274 for (ClientIdToSpecifics::const_iterator iter = all_data_.begin();
225 iter != all_data_.end(); ++iter) { 275 iter != all_data_.end(); ++iter) {
226 list.push_back(CopyToModel(*iter->second)); 276 list.push_back(SpecificsToModel(*iter->second));
227 } 277 }
228 return list; 278 return list;
229 } 279 }
230 280
231 void DeviceInfoService::AddObserver(Observer* observer) { 281 void DeviceInfoService::AddObserver(Observer* observer) {
232 observers_.AddObserver(observer); 282 observers_.AddObserver(observer);
233 } 283 }
234 284
235 void DeviceInfoService::RemoveObserver(Observer* observer) { 285 void DeviceInfoService::RemoveObserver(Observer* observer) {
236 observers_.RemoveObserver(observer); 286 observers_.RemoveObserver(observer);
237 } 287 }
238 288
239 int DeviceInfoService::CountActiveDevices() const { 289 int DeviceInfoService::CountActiveDevices() const {
240 return CountActiveDevices(Time::Now()); 290 return CountActiveDevices(Time::Now());
241 } 291 }
242 292
243 void DeviceInfoService::NotifyObservers() { 293 void DeviceInfoService::NotifyObservers() {
244 for (auto& observer : observers_) 294 for (auto& observer : observers_)
245 observer.OnDeviceInfoChange(); 295 observer.OnDeviceInfoChange();
246 } 296 }
247 297
248 // Static.
249 std::unique_ptr<DeviceInfoSpecifics> DeviceInfoService::CopyToSpecifics(
250 const DeviceInfo& info) {
251 std::unique_ptr<DeviceInfoSpecifics> specifics =
252 base::WrapUnique(new DeviceInfoSpecifics);
253 specifics->set_cache_guid(info.guid());
254 specifics->set_client_name(info.client_name());
255 specifics->set_chrome_version(info.chrome_version());
256 specifics->set_sync_user_agent(info.sync_user_agent());
257 specifics->set_device_type(info.device_type());
258 specifics->set_signin_scoped_device_id(info.signin_scoped_device_id());
259 return specifics;
260 }
261
262 // Static.
263 std::unique_ptr<DeviceInfo> DeviceInfoService::CopyToModel(
264 const DeviceInfoSpecifics& specifics) {
265 return base::MakeUnique<DeviceInfo>(
266 specifics.cache_guid(), specifics.client_name(),
267 specifics.chrome_version(), specifics.sync_user_agent(),
268 specifics.device_type(), specifics.signin_scoped_device_id());
269 }
270
271 // Static.
272 std::unique_ptr<EntityData> DeviceInfoService::CopyToEntityData(
273 const DeviceInfoSpecifics& specifics) {
274 std::unique_ptr<EntityData> entity_data(new EntityData());
275 *entity_data->specifics.mutable_device_info() = specifics;
276 entity_data->non_unique_name = specifics.client_name();
277 return entity_data;
278 }
279
280 void DeviceInfoService::StoreSpecifics( 298 void DeviceInfoService::StoreSpecifics(
281 std::unique_ptr<DeviceInfoSpecifics> specifics, 299 std::unique_ptr<DeviceInfoSpecifics> specifics,
282 WriteBatch* batch) { 300 WriteBatch* batch) {
283 const std::string guid = specifics->cache_guid(); 301 const std::string guid = specifics->cache_guid();
284 DVLOG(1) << "Storing DEVICE_INFO for " << specifics->client_name()
285 << " with ID " << guid;
286 store_->WriteData(batch, guid, specifics->SerializeAsString()); 302 store_->WriteData(batch, guid, specifics->SerializeAsString());
287 all_data_[guid] = std::move(specifics); 303 all_data_[guid] = std::move(specifics);
288 } 304 }
289 305
290 bool DeviceInfoService::DeleteSpecifics(const std::string& guid, 306 bool DeviceInfoService::DeleteSpecifics(const std::string& guid,
291 WriteBatch* batch) { 307 WriteBatch* batch) {
292 ClientIdToSpecifics::const_iterator iter = all_data_.find(guid); 308 ClientIdToSpecifics::const_iterator iter = all_data_.find(guid);
293 if (iter != all_data_.end()) { 309 if (iter != all_data_.end()) {
294 DVLOG(1) << "Deleting DEVICE_INFO for " << iter->second->client_name()
295 << " with ID " << guid;
296 store_->DeleteData(batch, guid); 310 store_->DeleteData(batch, guid);
297 all_data_.erase(iter); 311 all_data_.erase(iter);
298 return true; 312 return true;
299 } else { 313 } else {
300 return false; 314 return false;
301 } 315 }
302 } 316 }
303 317
304 void DeviceInfoService::OnProviderInitialized() { 318 void DeviceInfoService::OnProviderInitialized() {
305 // Now that the provider has initialized, remove the subscription. The service 319 // Now that the provider has initialized, remove the subscription. The service
306 // should only need to give the processor metadata upon initialization. If 320 // should only need to give the processor metadata upon initialization. If
307 // sync is disabled and enabled, our provider will try to retrigger this 321 // sync is disabled and enabled, our provider will try to retrigger this
308 // event, but we do not want to send any more metadata to the processor. 322 // event, but we do not want to send any more metadata to the processor.
309 subscription_.reset(); 323 subscription_.reset();
310 324
311 has_provider_initialized_ = true; 325 has_provider_initialized_ = true;
312 LoadMetadataIfReady(); 326 LoadMetadataIfReady();
313 } 327 }
314 328
315 void DeviceInfoService::OnStoreCreated(Result result, 329 void DeviceInfoService::OnStoreCreated(Result result,
316 std::unique_ptr<ModelTypeStore> store) { 330 std::unique_ptr<ModelTypeStore> store) {
317 if (result == Result::SUCCESS) { 331 if (result == Result::SUCCESS) {
318 std::swap(store_, store); 332 std::swap(store_, store);
319 store_->ReadAllData( 333 store_->ReadAllData(
320 base::Bind(&DeviceInfoService::OnReadAllData, base::AsWeakPtr(this))); 334 base::Bind(&DeviceInfoService::OnReadAllData, base::AsWeakPtr(this)));
321 } else { 335 } else {
322 ReportStartupErrorToSync("ModelTypeStore creation failed."); 336 ReportStartupErrorToSync("ModelTypeStore creation failed.");
323 // TODO(skym, crbug.com/582460): Handle unrecoverable initialization
324 // failure.
325 } 337 }
326 } 338 }
327 339
328 void DeviceInfoService::OnReadAllData(Result result, 340 void DeviceInfoService::OnReadAllData(Result result,
329 std::unique_ptr<RecordList> record_list) { 341 std::unique_ptr<RecordList> record_list) {
330 if (result != Result::SUCCESS) { 342 if (result != Result::SUCCESS) {
331 ReportStartupErrorToSync("Initial load of data failed."); 343 ReportStartupErrorToSync("Initial load of data failed.");
332 // TODO(skym, crbug.com/582460): Handle unrecoverable initialization
333 // failure.
334 return; 344 return;
335 } 345 }
336 346
337 for (const Record& r : *record_list.get()) { 347 for (const Record& r : *record_list.get()) {
338 std::unique_ptr<DeviceInfoSpecifics> specifics = 348 std::unique_ptr<DeviceInfoSpecifics> specifics =
339 base::MakeUnique<DeviceInfoSpecifics>(); 349 base::MakeUnique<DeviceInfoSpecifics>();
340 if (specifics->ParseFromString(r.value)) { 350 if (specifics->ParseFromString(r.value)) {
341 all_data_[specifics->cache_guid()] = std::move(specifics); 351 all_data_[specifics->cache_guid()] = std::move(specifics);
342 } else { 352 } else {
343 ReportStartupErrorToSync("Failed to deserialize specifics."); 353 ReportStartupErrorToSync("Failed to deserialize specifics.");
344 // TODO(skym, crbug.com/582460): Handle unrecoverable initialization
345 // failure.
346 } 354 }
347 } 355 }
348 356
349 has_data_loaded_ = true; 357 has_data_loaded_ = true;
350 LoadMetadataIfReady(); 358 LoadMetadataIfReady();
351 } 359 }
352 360
353 void DeviceInfoService::LoadMetadataIfReady() { 361 void DeviceInfoService::LoadMetadataIfReady() {
354 if (has_data_loaded_ && has_provider_initialized_) { 362 if (has_data_loaded_ && has_provider_initialized_) {
355 store_->ReadAllMetadata(base::Bind(&DeviceInfoService::OnReadAllMetadata, 363 store_->ReadAllMetadata(base::Bind(&DeviceInfoService::OnReadAllMetadata,
356 base::AsWeakPtr(this))); 364 base::AsWeakPtr(this)));
357 } 365 }
358 } 366 }
359 367
360 void DeviceInfoService::OnReadAllMetadata( 368 void DeviceInfoService::OnReadAllMetadata(
361 Result result, 369 Result result,
362 std::unique_ptr<RecordList> metadata_records, 370 std::unique_ptr<RecordList> metadata_records,
363 const std::string& global_metadata) { 371 const std::string& global_metadata) {
364 if (result != Result::SUCCESS) { 372 if (result != Result::SUCCESS) {
365 // Store has encountered some serious error. We should still be able to
366 // continue as a read only service, since if we got this far we must have
367 // loaded all data out succesfully.
368 ReportStartupErrorToSync("Load of metadata completely failed."); 373 ReportStartupErrorToSync("Load of metadata completely failed.");
369 return; 374 return;
370 } 375 }
371 376
372 std::unique_ptr<MetadataBatch> batch(new MetadataBatch()); 377 auto batch = base::MakeUnique<MetadataBatch>();
373 ModelTypeState state; 378 ModelTypeState state;
374 if (state.ParseFromString(global_metadata)) { 379 if (state.ParseFromString(global_metadata)) {
375 batch->SetModelTypeState(state); 380 batch->SetModelTypeState(state);
376 } else { 381 } else {
377 // TODO(skym): How bad is this scenario? We may be able to just give an 382 ReportStartupErrorToSync("Failed to deserialize global metadata.");
378 // empty batch to the processor and we'll treat corrupted data type state 383 return;
379 // as no data type state at all. The question is do we want to add any of
380 // the entity metadata to the batch or completely skip that step? We're
381 // going to have to perform a merge shortly. Does this decision/logic even
382 // belong in this service?
383 change_processor()->OnMetadataLoaded(
384 change_processor()->CreateAndUploadError(
385 FROM_HERE, "Failed to deserialize global metadata."),
386 nullptr);
387 } 384 }
385
388 for (const Record& r : *metadata_records.get()) { 386 for (const Record& r : *metadata_records.get()) {
389 sync_pb::EntityMetadata entity_metadata; 387 sync_pb::EntityMetadata entity_metadata;
390 if (entity_metadata.ParseFromString(r.value)) { 388 if (entity_metadata.ParseFromString(r.value)) {
391 batch->AddMetadata(r.id, entity_metadata); 389 batch->AddMetadata(r.id, entity_metadata);
392 } else { 390 } else {
393 // TODO(skym): This really isn't too bad. We just want to regenerate 391 ReportStartupErrorToSync("Failed to deserialize entity metadata.");
394 // metadata for this particular entity. Unfortunately there isn't a
395 // convenient way to tell the processor to do this.
396 LOG(WARNING) << "Failed to deserialize entity metadata.";
397 } 392 }
398 } 393 }
394
399 change_processor()->OnMetadataLoaded(SyncError(), std::move(batch)); 395 change_processor()->OnMetadataLoaded(SyncError(), std::move(batch));
400 ReconcileLocalAndStored(); 396 ReconcileLocalAndStored();
401 } 397 }
402 398
403 void DeviceInfoService::OnCommit(Result result) { 399 void DeviceInfoService::OnCommit(Result result) {
404 if (result != Result::SUCCESS) { 400 if (result != Result::SUCCESS) {
405 LOG(WARNING) << "Failed a write to store."; 401 change_processor()->CreateAndUploadError(FROM_HERE,
402 "Failed a write to store.");
406 } 403 }
407 } 404 }
408 405
409 void DeviceInfoService::ReconcileLocalAndStored() { 406 void DeviceInfoService::ReconcileLocalAndStored() {
410 // On initial syncing we will have a change processor here, but it will not be 407 // On initial syncing we will have a change processor here, but it will not be
411 // tracking changes. We need to persist a copy of our local device info to 408 // tracking changes. We need to persist a copy of our local device info to
412 // disk, but the Put call to the processor will be ignored. That should be 409 // disk, but the Put call to the processor will be ignored. That should be
413 // fine however, as the discrepancy will be picked up later in merge. We don't 410 // fine however, as the discrepancy will be picked up later in merge. We don't
414 // bother trying to track this case and act intelligently because simply not 411 // bother trying to track this case and act intelligently because simply not
415 // much of a benefit in doing so. 412 // much of a benefit in doing so.
416 DCHECK(has_provider_initialized_); 413 DCHECK(has_provider_initialized_);
417 414
418 const DeviceInfo* current_info = 415 const DeviceInfo* current_info =
419 local_device_info_provider_->GetLocalDeviceInfo(); 416 local_device_info_provider_->GetLocalDeviceInfo();
420 auto iter = all_data_.find(current_info->guid()); 417 auto iter = all_data_.find(current_info->guid());
421 418
422 // Convert to DeviceInfo for Equals function. 419 // Convert to DeviceInfo for Equals function.
423 if (iter != all_data_.end() && 420 if (iter != all_data_.end() &&
424 current_info->Equals(*CopyToModel(*iter->second))) { 421 current_info->Equals(*SpecificsToModel(*iter->second))) {
425 const TimeDelta pulse_delay(DeviceInfoUtil::CalculatePulseDelay( 422 const TimeDelta pulse_delay(DeviceInfoUtil::CalculatePulseDelay(
426 GetLastUpdateTime(*iter->second), Time::Now())); 423 GetLastUpdateTime(*iter->second), Time::Now()));
427 if (!pulse_delay.is_zero()) { 424 if (!pulse_delay.is_zero()) {
428 pulse_timer_.Start(FROM_HERE, pulse_delay, 425 pulse_timer_.Start(FROM_HERE, pulse_delay,
429 base::Bind(&DeviceInfoService::SendLocalData, 426 base::Bind(&DeviceInfoService::SendLocalData,
430 base::Unretained(this))); 427 base::Unretained(this)));
431 return; 428 return;
432 } 429 }
433 } 430 }
434 SendLocalData(); 431 SendLocalData();
435 } 432 }
436 433
437 void DeviceInfoService::SendLocalData() { 434 void DeviceInfoService::SendLocalData() {
438 DCHECK(has_provider_initialized_); 435 DCHECK(has_provider_initialized_);
439 436
440 // It is possible that the provider no longer has data for us, such as when 437 // It is possible that the provider no longer has data for us, such as when
441 // the user signs out. No-op this pulse, but keep the timer going in case sync 438 // the user signs out. No-op this pulse, but keep the timer going in case sync
442 // is enabled later. 439 // is enabled later.
443 if (local_device_info_provider_->GetLocalDeviceInfo() != nullptr) { 440 if (local_device_info_provider_->GetLocalDeviceInfo() != nullptr) {
444 std::unique_ptr<DeviceInfoSpecifics> specifics = 441 std::unique_ptr<DeviceInfoSpecifics> specifics =
445 CopyToSpecifics(*local_device_info_provider_->GetLocalDeviceInfo()); 442 ModelToSpecifics(*local_device_info_provider_->GetLocalDeviceInfo(),
446 specifics->set_last_updated_timestamp(TimeToProtoTime(Time::Now())); 443 TimeToProtoTime(Time::Now()));
447
448 std::unique_ptr<MetadataChangeList> metadata_change_list = 444 std::unique_ptr<MetadataChangeList> metadata_change_list =
449 CreateMetadataChangeList(); 445 CreateMetadataChangeList();
450 if (change_processor()->IsTrackingMetadata()) { 446 if (change_processor()->IsTrackingMetadata()) {
451 change_processor()->Put(specifics->cache_guid(), 447 change_processor()->Put(specifics->cache_guid(),
452 CopyToEntityData(*specifics), 448 CopyToEntityData(*specifics),
453 metadata_change_list.get()); 449 metadata_change_list.get());
454 } 450 }
455 451
456 std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch(); 452 std::unique_ptr<WriteBatch> batch = store_->CreateWriteBatch();
457 StoreSpecifics(std::move(specifics), batch.get()); 453 StoreSpecifics(std::move(specifics), batch.get());
(...skipping 27 matching lines...) Expand all
485 }); 481 });
486 } 482 }
487 483
488 void DeviceInfoService::ReportStartupErrorToSync(const std::string& msg) { 484 void DeviceInfoService::ReportStartupErrorToSync(const std::string& msg) {
489 // TODO(skym): Shouldn't need to log this here, reporting should always log. 485 // TODO(skym): Shouldn't need to log this here, reporting should always log.
490 LOG(WARNING) << msg; 486 LOG(WARNING) << msg;
491 change_processor()->OnMetadataLoaded( 487 change_processor()->OnMetadataLoaded(
492 change_processor()->CreateAndUploadError(FROM_HERE, msg), nullptr); 488 change_processor()->CreateAndUploadError(FROM_HERE, msg), nullptr);
493 } 489 }
494 490
495 // static
496 Time DeviceInfoService::GetLastUpdateTime(
497 const DeviceInfoSpecifics& specifics) {
498 if (specifics.has_last_updated_timestamp()) {
499 return ProtoTimeToTime(specifics.last_updated_timestamp());
500 } else {
501 return Time();
502 }
503 }
504
505 } // namespace syncer 491 } // namespace syncer
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698