| 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 11 matching lines...) Expand all Loading... |
| 22 | 22 |
| 23 using content::BrowserThread; | 23 using content::BrowserThread; |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 const char kAutofillEntryNamespaceTag[] = "autofill_entry|"; | 27 const char kAutofillEntryNamespaceTag[] = "autofill_entry|"; |
| 28 | 28 |
| 29 // Merges timestamps from the |autofill| entry and |timestamps|. Returns | 29 // Merges timestamps from the |autofill| entry and |timestamps|. Returns |
| 30 // true if they were different, false if they were the same. | 30 // true if they were different, false if they were the same. |
| 31 // All of the timestamp vectors are assummed to be sorted, resulting vector is | 31 // All of the timestamp vectors are assummed to be sorted, resulting vector is |
| 32 // sorted as well. | 32 // sorted as well. Only two timestamps - the earliest and the latest are stored. |
| 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(), | |
| 38 timestamps.end()); | |
| 39 | 37 |
| 38 new_timestamps->clear(); |
| 40 size_t timestamps_count = autofill.usage_timestamp_size(); | 39 size_t timestamps_count = autofill.usage_timestamp_size(); |
| 41 | 40 if (timestamps_count == 0 && timestamps.empty()) { |
| 42 bool different = timestamps.size() != timestamps_count; | 41 return false; |
| 43 for (size_t i = 0; i < timestamps_count; ++i) { | 42 } else if (timestamps_count == 0) { |
| 44 if (timestamp_union.insert(base::Time::FromInternalValue( | 43 new_timestamps->insert(new_timestamps->begin(), |
| 45 autofill.usage_timestamp(i))).second) { | 44 timestamps.begin(), |
| 46 different = true; | 45 timestamps.end()); |
| 46 return true; |
| 47 } else if (timestamps.empty()) { |
| 48 new_timestamps->reserve(2); |
| 49 new_timestamps->push_back(base::Time::FromInternalValue( |
| 50 autofill.usage_timestamp(0))); |
| 51 if (timestamps_count > 1) { |
| 52 new_timestamps->push_back(base::Time::FromInternalValue( |
| 53 autofill.usage_timestamp(timestamps_count - 1))); |
| 54 } |
| 55 return true; |
| 56 } else { |
| 57 base::Time sync_time_begin = base::Time::FromInternalValue( |
| 58 autofill.usage_timestamp(0)); |
| 59 base::Time sync_time_end = base::Time::FromInternalValue( |
| 60 autofill.usage_timestamp(timestamps_count - 1)); |
| 61 if (timestamps.front() != sync_time_begin || |
| 62 timestamps.back() != sync_time_end) { |
| 63 new_timestamps->push_back( |
| 64 timestamps.front() < sync_time_begin ? timestamps.front() : |
| 65 sync_time_begin); |
| 66 if (new_timestamps->back() != timestamps.back() || |
| 67 new_timestamps->back() != sync_time_end) { |
| 68 new_timestamps->push_back( |
| 69 timestamps.back() > sync_time_end ? timestamps.back() : |
| 70 sync_time_end); |
| 71 } |
| 72 return true; |
| 73 } else { |
| 74 new_timestamps->insert(new_timestamps->begin(), |
| 75 timestamps.begin(), |
| 76 timestamps.end()); |
| 77 return false; |
| 47 } | 78 } |
| 48 } | 79 } |
| 49 | |
| 50 if (different) { | |
| 51 new_timestamps->insert(new_timestamps->begin(), | |
| 52 timestamp_union.begin(), | |
| 53 timestamp_union.end()); | |
| 54 } | |
| 55 return different; | |
| 56 } | 80 } |
| 57 | 81 |
| 58 } // namespace | 82 } // namespace |
| 59 | 83 |
| 60 AutocompleteSyncableService::AutocompleteSyncableService( | 84 AutocompleteSyncableService::AutocompleteSyncableService( |
| 61 WebDataService* web_data_service) | 85 WebDataService* web_data_service) |
| 62 : web_data_service_(web_data_service) { | 86 : web_data_service_(web_data_service) { |
| 63 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 64 DCHECK(web_data_service_); | 88 DCHECK(web_data_service_); |
| 65 notification_registrar_.Add( | 89 notification_registrar_.Add( |
| (...skipping 28 matching lines...) Expand all Loading... |
| 94 | 118 |
| 95 AutocompleteEntryMap new_db_entries; | 119 AutocompleteEntryMap new_db_entries; |
| 96 for (std::vector<AutofillEntry>::iterator it = entries.begin(); | 120 for (std::vector<AutofillEntry>::iterator it = entries.begin(); |
| 97 it != entries.end(); ++it) { | 121 it != entries.end(); ++it) { |
| 98 new_db_entries[it->key()] = std::make_pair(SyncChange::ACTION_ADD, it); | 122 new_db_entries[it->key()] = std::make_pair(SyncChange::ACTION_ADD, it); |
| 99 } | 123 } |
| 100 | 124 |
| 101 sync_processor_ = sync_processor.Pass(); | 125 sync_processor_ = sync_processor.Pass(); |
| 102 | 126 |
| 103 std::vector<AutofillEntry> new_synced_entries; | 127 std::vector<AutofillEntry> new_synced_entries; |
| 128 std::vector<AutofillEntry> synced_expired_entries; |
| 104 // Go through and check for all the entries that sync already knows about. | 129 // Go through and check for all the entries that sync already knows about. |
| 105 // CreateOrUpdateEntry() will remove entries that are same with the synced | 130 // CreateOrUpdateEntry() will remove entries that are same with the synced |
| 106 // ones from |new_db_entries|. | 131 // ones from |new_db_entries|. |
| 107 for (SyncDataList::const_iterator sync_iter = initial_sync_data.begin(); | 132 for (SyncDataList::const_iterator sync_iter = initial_sync_data.begin(); |
| 108 sync_iter != initial_sync_data.end(); ++sync_iter) { | 133 sync_iter != initial_sync_data.end(); ++sync_iter) { |
| 109 CreateOrUpdateEntry(*sync_iter, &new_db_entries, &new_synced_entries); | 134 CreateOrUpdateEntry(*sync_iter, &new_db_entries, |
| 135 &new_synced_entries, &synced_expired_entries); |
| 110 } | 136 } |
| 111 | 137 |
| 138 // Check if newly received items need culling. |
| 139 bool need_to_cull_data = !synced_expired_entries.empty(); |
| 140 |
| 112 if (!SaveChangesToWebData(new_synced_entries)) | 141 if (!SaveChangesToWebData(new_synced_entries)) |
| 113 return SyncError(FROM_HERE, "Failed to update webdata.", model_type()); | 142 return SyncError(FROM_HERE, "Failed to update webdata.", model_type()); |
| 114 | 143 |
| 115 WebDataService::NotifyOfMultipleAutofillChanges(web_data_service_); | 144 WebDataService::NotifyOfMultipleAutofillChanges(web_data_service_); |
| 145 keys_to_ignore_.clear(); |
| 116 | 146 |
| 117 SyncChangeList new_changes; | 147 SyncChangeList new_changes; |
| 118 for (AutocompleteEntryMap::iterator i = new_db_entries.begin(); | 148 for (AutocompleteEntryMap::iterator i = new_db_entries.begin(); |
| 119 i != new_db_entries.end(); ++i) { | 149 i != new_db_entries.end(); ++i) { |
| 120 new_changes.push_back( | 150 // Sync back only the data that appeared after |
| 121 SyncChange(i->second.first, CreateSyncData(*(i->second.second)))); | 151 // |AutofillEntry::ExpirationTime()|. |
| 152 if (!i->second.second->IsExpired()) { |
| 153 new_changes.push_back( |
| 154 SyncChange(i->second.first, CreateSyncData(*(i->second.second)))); |
| 155 } else { |
| 156 need_to_cull_data = true; |
| 157 // Key is not on the server and is too old, it will not ever be synced - |
| 158 // delete it locally. |
| 159 if (i->second.first == SyncChange::ACTION_ADD) |
| 160 keys_to_ignore_.insert(i->first); |
| 161 } |
| 162 } |
| 163 |
| 164 // Delete only the changes never synced to the db as they are too old. |
| 165 for (size_t i = 0; i < synced_expired_entries.size(); ++i) { |
| 166 // Key is on the server and not local and is too old, we need to notify |
| 167 // sync that it has expired. |
| 168 if (keys_to_ignore_.find(synced_expired_entries[i].key()) == |
| 169 keys_to_ignore_.end()) { |
| 170 new_changes.push_back(SyncChange(SyncChange::ACTION_DELETE, |
| 171 CreateSyncData(synced_expired_entries[i]))); |
| 172 } |
| 173 } |
| 174 |
| 175 if (need_to_cull_data) { |
| 176 // This will schedule deletion operation later on DB thread and we will |
| 177 // be notified on the results of the deletion and deletes will be synced to |
| 178 // the sync. |
| 179 web_data_service_->RemoveExpiredFormElements(); |
| 122 } | 180 } |
| 123 | 181 |
| 124 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); | 182 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); |
| 125 | 183 |
| 126 return error; | 184 return error; |
| 127 } | 185 } |
| 128 | 186 |
| 129 void AutocompleteSyncableService::StopSyncing(syncable::ModelType type) { | 187 void AutocompleteSyncableService::StopSyncing(syncable::ModelType type) { |
| 130 DCHECK(CalledOnValidThread()); | 188 DCHECK(CalledOnValidThread()); |
| 131 DCHECK_EQ(syncable::AUTOFILL, type); | 189 DCHECK_EQ(syncable::AUTOFILL, type); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 162 if (!sync_processor_.get()) { | 220 if (!sync_processor_.get()) { |
| 163 SyncError error(FROM_HERE, "Models not yet associated.", | 221 SyncError error(FROM_HERE, "Models not yet associated.", |
| 164 syncable::AUTOFILL); | 222 syncable::AUTOFILL); |
| 165 return error; | 223 return error; |
| 166 } | 224 } |
| 167 | 225 |
| 168 // Data is loaded only if we get new ADD/UPDATE change. | 226 // Data is loaded only if we get new ADD/UPDATE change. |
| 169 std::vector<AutofillEntry> entries; | 227 std::vector<AutofillEntry> entries; |
| 170 scoped_ptr<AutocompleteEntryMap> db_entries; | 228 scoped_ptr<AutocompleteEntryMap> db_entries; |
| 171 std::vector<AutofillEntry> new_entries; | 229 std::vector<AutofillEntry> new_entries; |
| 230 std::vector<AutofillEntry> ignored_entries; |
| 172 | 231 |
| 173 SyncError list_processing_error; | 232 SyncError list_processing_error; |
| 174 | 233 |
| 175 for (SyncChangeList::const_iterator i = change_list.begin(); | 234 for (SyncChangeList::const_iterator i = change_list.begin(); |
| 176 i != change_list.end() && !list_processing_error.IsSet(); ++i) { | 235 i != change_list.end() && !list_processing_error.IsSet(); ++i) { |
| 177 DCHECK(i->IsValid()); | 236 DCHECK(i->IsValid()); |
| 178 switch (i->change_type()) { | 237 switch (i->change_type()) { |
| 179 case SyncChange::ACTION_ADD: | 238 case SyncChange::ACTION_ADD: |
| 180 case SyncChange::ACTION_UPDATE: | 239 case SyncChange::ACTION_UPDATE: |
| 181 if (!db_entries.get()) { | 240 if (!db_entries.get()) { |
| 182 if (!LoadAutofillData(&entries)) { | 241 if (!LoadAutofillData(&entries)) { |
| 183 return SyncError( | 242 return SyncError( |
| 184 FROM_HERE, | 243 FROM_HERE, |
| 185 "Could not get the autocomplete data from WebDatabase.", | 244 "Could not get the autocomplete data from WebDatabase.", |
| 186 model_type()); | 245 model_type()); |
| 187 } | 246 } |
| 188 db_entries.reset(new AutocompleteEntryMap); | 247 db_entries.reset(new AutocompleteEntryMap); |
| 189 for (std::vector<AutofillEntry>::iterator it = entries.begin(); | 248 for (std::vector<AutofillEntry>::iterator it = entries.begin(); |
| 190 it != entries.end(); ++it) { | 249 it != entries.end(); ++it) { |
| 191 (*db_entries)[it->key()] = | 250 (*db_entries)[it->key()] = |
| 192 std::make_pair(SyncChange::ACTION_ADD, it); | 251 std::make_pair(SyncChange::ACTION_ADD, it); |
| 193 } | 252 } |
| 194 } | 253 } |
| 195 CreateOrUpdateEntry(i->sync_data(), db_entries.get(), &new_entries); | 254 CreateOrUpdateEntry(i->sync_data(), db_entries.get(), |
| 255 &new_entries, &ignored_entries); |
| 196 break; | 256 break; |
| 197 case SyncChange::ACTION_DELETE: { | 257 case SyncChange::ACTION_DELETE: { |
| 198 DCHECK(i->sync_data().GetSpecifics().has_autofill()) | 258 DCHECK(i->sync_data().GetSpecifics().has_autofill()) |
| 199 << "Autofill specifics data not present on delete!"; | 259 << "Autofill specifics data not present on delete!"; |
| 200 const sync_pb::AutofillSpecifics& autofill = | 260 const sync_pb::AutofillSpecifics& autofill = |
| 201 i->sync_data().GetSpecifics().autofill(); | 261 i->sync_data().GetSpecifics().autofill(); |
| 202 if (autofill.has_value()) { | 262 if (autofill.has_value()) { |
| 203 list_processing_error = AutofillEntryDelete(autofill); | 263 list_processing_error = AutofillEntryDelete(autofill); |
| 204 } else { | 264 } else { |
| 205 DLOG(WARNING) | 265 DLOG(WARNING) |
| 206 << "Delete for old-style autofill profile being dropped!"; | 266 << "Delete for old-style autofill profile being dropped!"; |
| 207 } | 267 } |
| 208 } break; | 268 } break; |
| 209 default: | 269 default: |
| 210 NOTREACHED() << "Unexpected sync change state."; | 270 NOTREACHED() << "Unexpected sync change state."; |
| 211 return SyncError(FROM_HERE, "ProcessSyncChanges failed on ChangeType " + | 271 return SyncError(FROM_HERE, "ProcessSyncChanges failed on ChangeType " + |
| 212 SyncChange::ChangeTypeToString(i->change_type()), | 272 SyncChange::ChangeTypeToString(i->change_type()), |
| 213 syncable::AUTOFILL); | 273 syncable::AUTOFILL); |
| 214 } | 274 } |
| 215 } | 275 } |
| 216 | 276 |
| 217 if (!SaveChangesToWebData(new_entries)) | 277 if (!SaveChangesToWebData(new_entries)) |
| 218 return SyncError(FROM_HERE, "Failed to update webdata.", model_type()); | 278 return SyncError(FROM_HERE, "Failed to update webdata.", model_type()); |
| 219 | 279 |
| 280 // Remove already expired data. |
| 281 for (size_t i = 0; i < ignored_entries.size(); ++i) { |
| 282 if (db_entries.get() && |
| 283 db_entries->find(ignored_entries[i].key()) != db_entries->end()) { |
| 284 bool success = web_data_service_->GetDatabase()->GetAutofillTable()-> |
| 285 RemoveFormElement(ignored_entries[i].key().name(), |
| 286 ignored_entries[i].key().value()); |
| 287 DCHECK(success); |
| 288 } |
| 289 } |
| 290 |
| 220 WebDataService::NotifyOfMultipleAutofillChanges(web_data_service_); | 291 WebDataService::NotifyOfMultipleAutofillChanges(web_data_service_); |
| 221 | 292 |
| 222 return list_processing_error; | 293 return list_processing_error; |
| 223 } | 294 } |
| 224 | 295 |
| 225 void AutocompleteSyncableService::Observe(int type, | 296 void AutocompleteSyncableService::Observe(int type, |
| 226 const content::NotificationSource& source, | 297 const content::NotificationSource& source, |
| 227 const content::NotificationDetails& details) { | 298 const content::NotificationDetails& details) { |
| 228 DCHECK_EQ(chrome::NOTIFICATION_AUTOFILL_ENTRIES_CHANGED, type); | 299 DCHECK_EQ(chrome::NOTIFICATION_AUTOFILL_ENTRIES_CHANGED, type); |
| 229 | 300 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 257 GetAutofillTable()->UpdateAutofillEntries(new_entries)) { | 328 GetAutofillTable()->UpdateAutofillEntries(new_entries)) { |
| 258 return false; | 329 return false; |
| 259 } | 330 } |
| 260 return true; | 331 return true; |
| 261 } | 332 } |
| 262 | 333 |
| 263 // Creates or updates an autocomplete entry based on |data|. | 334 // Creates or updates an autocomplete entry based on |data|. |
| 264 void AutocompleteSyncableService::CreateOrUpdateEntry( | 335 void AutocompleteSyncableService::CreateOrUpdateEntry( |
| 265 const SyncData& data, | 336 const SyncData& data, |
| 266 AutocompleteEntryMap* loaded_data, | 337 AutocompleteEntryMap* loaded_data, |
| 267 std::vector<AutofillEntry>* new_entries) { | 338 std::vector<AutofillEntry>* new_entries, |
| 339 std::vector<AutofillEntry>* ignored_entries) { |
| 268 const sync_pb::EntitySpecifics& specifics = data.GetSpecifics(); | 340 const sync_pb::EntitySpecifics& specifics = data.GetSpecifics(); |
| 269 const sync_pb::AutofillSpecifics& autofill_specifics( | 341 const sync_pb::AutofillSpecifics& autofill_specifics( |
| 270 specifics.autofill()); | 342 specifics.autofill()); |
| 271 | 343 |
| 272 if (!autofill_specifics.has_value()) { | 344 if (!autofill_specifics.has_value()) { |
| 273 DLOG(WARNING) | 345 DLOG(WARNING) |
| 274 << "Add/Update for old-style autofill profile being dropped!"; | 346 << "Add/Update for old-style autofill profile being dropped!"; |
| 275 return; | 347 return; |
| 276 } | 348 } |
| 277 | 349 |
| 278 AutofillKey key(autofill_specifics.name().c_str(), | 350 AutofillKey key(autofill_specifics.name().c_str(), |
| 279 autofill_specifics.value().c_str()); | 351 autofill_specifics.value().c_str()); |
| 280 AutocompleteEntryMap::iterator it = loaded_data->find(key); | 352 AutocompleteEntryMap::iterator it = loaded_data->find(key); |
| 281 if (it == loaded_data->end()) { | 353 if (it == loaded_data->end()) { |
| 282 // New entry. | 354 // New entry. |
| 283 std::vector<base::Time> timestamps; | 355 std::vector<base::Time> timestamps; |
| 284 size_t timestamps_count = autofill_specifics.usage_timestamp_size(); | 356 size_t timestamps_count = autofill_specifics.usage_timestamp_size(); |
| 285 timestamps.resize(timestamps_count); | 357 timestamps.reserve(2); |
| 286 for (size_t ts = 0; ts < timestamps_count; ++ts) { | 358 if (timestamps_count) { |
| 287 timestamps[ts] = base::Time::FromInternalValue( | 359 timestamps.push_back(base::Time::FromInternalValue( |
| 288 autofill_specifics.usage_timestamp(ts)); | 360 autofill_specifics.usage_timestamp(0))); |
| 289 } | 361 } |
| 290 new_entries->push_back(AutofillEntry(key, timestamps)); | 362 if (timestamps_count > 1) { |
| 363 timestamps.push_back(base::Time::FromInternalValue( |
| 364 autofill_specifics.usage_timestamp(timestamps_count - 1))); |
| 365 } |
| 366 AutofillEntry new_entry(key, timestamps); |
| 367 if (new_entry.IsExpired()) |
| 368 ignored_entries->push_back(new_entry); |
| 369 else |
| 370 new_entries->push_back(new_entry); |
| 291 } else { | 371 } else { |
| 292 // Entry already present - merge if necessary. | 372 // Entry already present - merge if necessary. |
| 293 std::vector<base::Time> timestamps; | 373 std::vector<base::Time> timestamps; |
| 294 bool different = MergeTimestamps( | 374 bool different = MergeTimestamps( |
| 295 autofill_specifics, it->second.second->timestamps(), ×tamps); | 375 autofill_specifics, it->second.second->timestamps(), ×tamps); |
| 296 if (different) { | 376 if (different) { |
| 297 AutofillEntry new_entry(it->second.second->key(), timestamps); | 377 AutofillEntry new_entry(it->second.second->key(), timestamps); |
| 298 new_entries->push_back(new_entry); | 378 if (new_entry.IsExpired()) { |
| 299 | 379 ignored_entries->push_back(new_entry); |
| 300 // Update the sync db if the list of timestamps have changed. | 380 } else { |
| 301 *(it->second.second) = new_entry; | 381 new_entries->push_back(new_entry); |
| 302 it->second.first = SyncChange::ACTION_UPDATE; | 382 // Update the sync db if the list of timestamps have changed. |
| 383 *(it->second.second) = new_entry; |
| 384 it->second.first = SyncChange::ACTION_UPDATE; |
| 385 } |
| 303 } else { | 386 } else { |
| 304 loaded_data->erase(it); | 387 loaded_data->erase(it); |
| 305 } | 388 } |
| 306 } | 389 } |
| 307 } | 390 } |
| 308 | 391 |
| 309 // static | 392 // static |
| 310 void AutocompleteSyncableService::WriteAutofillEntry( | 393 void AutocompleteSyncableService::WriteAutofillEntry( |
| 311 const AutofillEntry& entry, sync_pb::EntitySpecifics* autofill_specifics) { | 394 const AutofillEntry& entry, sync_pb::EntitySpecifics* autofill_specifics) { |
| 312 sync_pb::AutofillSpecifics* autofill = | 395 sync_pb::AutofillSpecifics* autofill = |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 } | 434 } |
| 352 AutofillEntry entry(change->key(), timestamps); | 435 AutofillEntry entry(change->key(), timestamps); |
| 353 SyncChange::SyncChangeType change_type = | 436 SyncChange::SyncChangeType change_type = |
| 354 (change->type() == AutofillChange::ADD) ? | 437 (change->type() == AutofillChange::ADD) ? |
| 355 SyncChange::ACTION_ADD : SyncChange::ACTION_UPDATE; | 438 SyncChange::ACTION_ADD : SyncChange::ACTION_UPDATE; |
| 356 new_changes.push_back(SyncChange(change_type, | 439 new_changes.push_back(SyncChange(change_type, |
| 357 CreateSyncData(entry))); | 440 CreateSyncData(entry))); |
| 358 break; | 441 break; |
| 359 } | 442 } |
| 360 case AutofillChange::REMOVE: { | 443 case AutofillChange::REMOVE: { |
| 361 std::vector<base::Time> timestamps; | 444 if (keys_to_ignore_.find(change->key()) == keys_to_ignore_.end()) { |
| 362 AutofillEntry entry(change->key(), timestamps); | 445 std::vector<base::Time> timestamps; |
| 363 new_changes.push_back(SyncChange(SyncChange::ACTION_DELETE, | 446 AutofillEntry entry(change->key(), timestamps); |
| 364 CreateSyncData(entry))); | 447 new_changes.push_back(SyncChange(SyncChange::ACTION_DELETE, |
| 448 CreateSyncData(entry))); |
| 449 } |
| 365 break; | 450 break; |
| 366 } | 451 } |
| 367 default: | 452 default: |
| 368 NOTREACHED(); | 453 NOTREACHED(); |
| 369 break; | 454 break; |
| 370 } | 455 } |
| 371 } | 456 } |
| 372 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); | 457 SyncError error = sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); |
| 373 if (error.IsSet()) { | 458 if (error.IsSet()) { |
| 374 DLOG(WARNING) << "[AUTOCOMPLETE SYNC]" | 459 DLOG(WARNING) << "[AUTOCOMPLETE SYNC]" |
| 375 << " Failed processing change:" | 460 << " Failed processing change:" |
| 376 << " Error:" << error.message(); | 461 << " Error:" << error.message(); |
| 377 } | 462 } |
| 463 // |keys_to_ignore_| are only needed for the very first notification. |
| 464 keys_to_ignore_.clear(); |
| 378 } | 465 } |
| 379 | 466 |
| 380 SyncData AutocompleteSyncableService::CreateSyncData( | 467 SyncData AutocompleteSyncableService::CreateSyncData( |
| 381 const AutofillEntry& entry) const { | 468 const AutofillEntry& entry) const { |
| 382 sync_pb::EntitySpecifics autofill_specifics; | 469 sync_pb::EntitySpecifics autofill_specifics; |
| 383 WriteAutofillEntry(entry, &autofill_specifics); | 470 WriteAutofillEntry(entry, &autofill_specifics); |
| 384 std::string tag(KeyToTag(UTF16ToUTF8(entry.key().name()), | 471 std::string tag(KeyToTag(UTF16ToUTF8(entry.key().name()), |
| 385 UTF16ToUTF8(entry.key().value()))); | 472 UTF16ToUTF8(entry.key().value()))); |
| 386 return SyncData::CreateLocalData(tag, tag, autofill_specifics); | 473 return SyncData::CreateLocalData(tag, tag, autofill_specifics); |
| 387 } | 474 } |
| 388 | 475 |
| 389 // static | 476 // static |
| 390 std::string AutocompleteSyncableService::KeyToTag(const std::string& name, | 477 std::string AutocompleteSyncableService::KeyToTag(const std::string& name, |
| 391 const std::string& value) { | 478 const std::string& value) { |
| 392 std::string ns(kAutofillEntryNamespaceTag); | 479 std::string ns(kAutofillEntryNamespaceTag); |
| 393 return ns + net::EscapePath(name) + "|" + net::EscapePath(value); | 480 return ns + net::EscapePath(name) + "|" + net::EscapePath(value); |
| 394 } | 481 } |
| OLD | NEW |