Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/webdata/autocomplete_syncable_service.h" | 5 #include "chrome/browser/webdata/autocomplete_syncable_service.h" |
| 6 | 6 |
| 7 #include "base/location.h" | 7 #include "base/location.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
| 10 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 bool MergeTimestamps(const sync_pb::AutofillSpecifics& autofill, | 33 bool MergeTimestamps(const sync_pb::AutofillSpecifics& autofill, |
| 34 const std::vector<base::Time>& timestamps, | 34 const std::vector<base::Time>& timestamps, |
| 35 std::vector<base::Time>* new_timestamps) { | 35 std::vector<base::Time>* new_timestamps) { |
| 36 DCHECK(new_timestamps); | 36 DCHECK(new_timestamps); |
| 37 std::set<base::Time> timestamp_union(timestamps.begin(), | 37 std::set<base::Time> timestamp_union(timestamps.begin(), |
| 38 timestamps.end()); | 38 timestamps.end()); |
| 39 | 39 |
| 40 size_t timestamps_count = autofill.usage_timestamp_size(); | 40 size_t timestamps_count = autofill.usage_timestamp_size(); |
| 41 | 41 |
| 42 bool different = timestamps.size() != timestamps_count; | 42 bool different = timestamps.size() != timestamps_count; |
| 43 for (size_t i = 0; i < timestamps_count; ++i) { | 43 for (size_t i = 0; i < timestamps_count; ++i) { |
|
Nicolas Zea
2012/03/21 22:33:03
I'm worried that (if my understanding is correct)
GeorgeY
2012/03/23 21:53:21
Updates will be created only for the entries that
| |
| 44 if (timestamp_union.insert(base::Time::FromInternalValue( | 44 if (timestamp_union.insert(base::Time::FromInternalValue( |
| 45 autofill.usage_timestamp(i))).second) { | 45 autofill.usage_timestamp(i))).second) { |
| 46 different = true; | 46 different = true; |
| 47 } | 47 } |
| 48 } | 48 } |
| 49 | 49 |
| 50 if (different) { | 50 if (different) { |
| 51 new_timestamps->insert(new_timestamps->begin(), | 51 new_timestamps->insert(new_timestamps->begin(), |
| 52 timestamp_union.begin(), | 52 timestamp_union.begin(), |
| 53 timestamp_union.end()); | 53 timestamp_union.end()); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 101 | 101 |
| 102 std::vector<AutofillEntry> new_synced_entries; | 102 std::vector<AutofillEntry> new_synced_entries; |
| 103 // Go through and check for all the entries that sync already knows about. | 103 // Go through and check for all the entries that sync already knows about. |
| 104 // CreateOrUpdateEntry() will remove entries that are same with the synced | 104 // CreateOrUpdateEntry() will remove entries that are same with the synced |
| 105 // ones from |new_db_entries|. | 105 // ones from |new_db_entries|. |
| 106 for (SyncDataList::const_iterator sync_iter = initial_sync_data.begin(); | 106 for (SyncDataList::const_iterator sync_iter = initial_sync_data.begin(); |
| 107 sync_iter != initial_sync_data.end(); ++sync_iter) { | 107 sync_iter != initial_sync_data.end(); ++sync_iter) { |
| 108 CreateOrUpdateEntry(*sync_iter, &new_db_entries, &new_synced_entries); | 108 CreateOrUpdateEntry(*sync_iter, &new_db_entries, &new_synced_entries); |
| 109 } | 109 } |
| 110 | 110 |
| 111 // Check if newly received items need culling. | |
| 112 bool need_to_cull_data = false; | |
| 113 for (size_t i = 0; i < new_synced_entries.size() && !need_to_cull_data; ++i) { | |
| 114 if (new_synced_entries[i].IsExpired()) | |
| 115 need_to_cull_data = true; | |
| 116 } | |
| 117 | |
| 111 if (!SaveChangesToWebData(new_synced_entries)) | 118 if (!SaveChangesToWebData(new_synced_entries)) |
|
Nicolas Zea
2012/03/21 22:33:03
It seems odd to add data to the autofill db if you
GeorgeY
2012/03/23 21:53:21
Change was not as simple :), but I added it - expi
| |
| 112 return SyncError(FROM_HERE, "Failed to update webdata.", model_type()); | 119 return SyncError(FROM_HERE, "Failed to update webdata.", model_type()); |
| 113 | 120 |
| 114 WebDataService::NotifyOfMultipleAutofillChanges(web_data_service_); | 121 WebDataService::NotifyOfMultipleAutofillChanges(web_data_service_); |
| 122 keys_to_ignore_.clear(); | |
| 115 | 123 |
| 116 SyncChangeList new_changes; | 124 SyncChangeList new_changes; |
| 117 for (AutocompleteEntryMap::iterator i = new_db_entries.begin(); | 125 for (AutocompleteEntryMap::iterator i = new_db_entries.begin(); |
| 118 i != new_db_entries.end(); ++i) { | 126 i != new_db_entries.end(); ++i) { |
| 119 new_changes.push_back( | 127 // Sync back only the data that appeared after |
| 120 SyncChange(i->second.first, CreateSyncData(*(i->second.second)))); | 128 // |AutofillEntry::ExpirationTime()|. |
| 129 if (!i->second.second->IsExpired()) { | |
| 130 new_changes.push_back( | |
| 131 SyncChange(i->second.first, CreateSyncData(*(i->second.second)))); | |
| 132 } else { | |
| 133 need_to_cull_data = true; | |
| 134 // Key is not on the server and is too old, it will not ever be synced - | |
| 135 // delete it locally. | |
| 136 if (i->second.first == SyncChange::ACTION_ADD) | |
| 137 keys_to_ignore_.insert(i->first); | |
| 138 } | |
| 139 } | |
| 140 | |
| 141 if (need_to_cull_data) { | |
| 142 // This will schedule deletion operation later on DB thread and we will | |
| 143 // be notified on the results of the deletion and deletes will be synced to | |
| 144 // the sync. | |
| 145 web_data_service_->RemoveExpiredFormElements(); | |
| 121 } | 146 } |
| 122 | 147 |
| 123 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); | 148 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); |
| 124 | 149 |
| 125 return error; | 150 return error; |
| 126 } | 151 } |
| 127 | 152 |
| 128 void AutocompleteSyncableService::StopSyncing(syncable::ModelType type) { | 153 void AutocompleteSyncableService::StopSyncing(syncable::ModelType type) { |
| 129 DCHECK(CalledOnValidThread()); | 154 DCHECK(CalledOnValidThread()); |
| 130 DCHECK_EQ(syncable::AUTOFILL, type); | 155 DCHECK_EQ(syncable::AUTOFILL, type); |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 350 } | 375 } |
| 351 AutofillEntry entry(change->key(), timestamps); | 376 AutofillEntry entry(change->key(), timestamps); |
| 352 SyncChange::SyncChangeType change_type = | 377 SyncChange::SyncChangeType change_type = |
| 353 (change->type() == AutofillChange::ADD) ? | 378 (change->type() == AutofillChange::ADD) ? |
| 354 SyncChange::ACTION_ADD : SyncChange::ACTION_UPDATE; | 379 SyncChange::ACTION_ADD : SyncChange::ACTION_UPDATE; |
| 355 new_changes.push_back(SyncChange(change_type, | 380 new_changes.push_back(SyncChange(change_type, |
| 356 CreateSyncData(entry))); | 381 CreateSyncData(entry))); |
| 357 break; | 382 break; |
| 358 } | 383 } |
| 359 case AutofillChange::REMOVE: { | 384 case AutofillChange::REMOVE: { |
| 360 std::vector<base::Time> timestamps; | 385 if (keys_to_ignore_.find(change->key()) == keys_to_ignore_.end()) { |
| 361 AutofillEntry entry(change->key(), timestamps); | 386 std::vector<base::Time> timestamps; |
| 362 new_changes.push_back(SyncChange(SyncChange::ACTION_DELETE, | 387 AutofillEntry entry(change->key(), timestamps); |
| 363 CreateSyncData(entry))); | 388 new_changes.push_back(SyncChange(SyncChange::ACTION_DELETE, |
| 389 CreateSyncData(entry))); | |
| 390 } | |
| 364 break; | 391 break; |
| 365 } | 392 } |
| 366 default: | 393 default: |
| 367 NOTREACHED(); | 394 NOTREACHED(); |
| 368 break; | 395 break; |
| 369 } | 396 } |
| 370 } | 397 } |
| 371 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); | 398 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); |
| 372 if (error.IsSet()) { | 399 if (error.IsSet()) { |
| 373 DLOG(WARNING) << "[AUTOCOMPLETE SYNC]" | 400 DLOG(WARNING) << "[AUTOCOMPLETE SYNC]" |
| 374 << " Failed processing change:" | 401 << " Failed processing change:" |
| 375 << " Error:" << error.message(); | 402 << " Error:" << error.message(); |
| 376 } | 403 } |
| 404 // |keys_to_ignore_| are only needed for the very first notification. | |
| 405 keys_to_ignore_.clear(); | |
| 377 } | 406 } |
| 378 | 407 |
| 379 SyncData AutocompleteSyncableService::CreateSyncData( | 408 SyncData AutocompleteSyncableService::CreateSyncData( |
| 380 const AutofillEntry& entry) const { | 409 const AutofillEntry& entry) const { |
| 381 sync_pb::EntitySpecifics autofill_specifics; | 410 sync_pb::EntitySpecifics autofill_specifics; |
| 382 WriteAutofillEntry(entry, &autofill_specifics); | 411 WriteAutofillEntry(entry, &autofill_specifics); |
| 383 std::string tag(KeyToTag(UTF16ToUTF8(entry.key().name()), | 412 std::string tag(KeyToTag(UTF16ToUTF8(entry.key().name()), |
| 384 UTF16ToUTF8(entry.key().value()))); | 413 UTF16ToUTF8(entry.key().value()))); |
| 385 return SyncData::CreateLocalData(tag, tag, autofill_specifics); | 414 return SyncData::CreateLocalData(tag, tag, autofill_specifics); |
| 386 } | 415 } |
| 387 | 416 |
| 388 // static | 417 // static |
| 389 std::string AutocompleteSyncableService::KeyToTag(const std::string& name, | 418 std::string AutocompleteSyncableService::KeyToTag(const std::string& name, |
| 390 const std::string& value) { | 419 const std::string& value) { |
| 391 std::string ns(kAutofillEntryNamespaceTag); | 420 std::string ns(kAutofillEntryNamespaceTag); |
| 392 return ns + net::EscapePath(name) + "|" + net::EscapePath(value); | 421 return ns + net::EscapePath(name) + "|" + net::EscapePath(value); |
| 393 } | 422 } |
| OLD | NEW |