| 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 "components/autofill/browser/webdata/autofill_table.h" | 10 #include "components/autofill/browser/webdata/autofill_table.h" |
| 11 #include "components/autofill/browser/webdata/autofill_webdata_service.h" | 11 #include "components/autofill/browser/webdata/autofill_webdata_service.h" |
| 12 #include "components/webdata/common/web_database.h" | 12 #include "components/webdata/common/web_database.h" |
| 13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
| 14 #include "net/base/escape.h" | 14 #include "net/base/escape.h" |
| 15 #include "sync/api/sync_error.h" | 15 #include "sync/api/sync_error.h" |
| 16 #include "sync/api/sync_error_factory.h" | 16 #include "sync/api/sync_error_factory.h" |
| 17 #include "sync/protocol/autofill_specifics.pb.h" | 17 #include "sync/protocol/autofill_specifics.pb.h" |
| 18 #include "sync/protocol/sync.pb.h" | 18 #include "sync/protocol/sync.pb.h" |
| 19 | 19 |
| 20 using autofill::AutofillChange; | 20 using autofill::AutofillChange; |
| 21 using autofill::AutofillChangeList; | 21 using autofill::AutofillChangeList; |
| 22 using autofill::AutofillEntry; | 22 using autofill::AutofillEntry; |
| 23 using autofill::AutofillKey; | 23 using autofill::AutofillKey; |
| 24 using autofill::AutofillTable; | 24 using autofill::AutofillTable; |
| 25 using autofill::AutofillWebDataService; | 25 using autofill::AutofillWebDataService; |
| 26 using autofill::AutofillWebDataBackend; |
| 26 using content::BrowserThread; | 27 using content::BrowserThread; |
| 27 | 28 |
| 28 namespace { | 29 namespace { |
| 29 | 30 |
| 30 const char kAutofillEntryNamespaceTag[] = "autofill_entry|"; | 31 const char kAutofillEntryNamespaceTag[] = "autofill_entry|"; |
| 31 | 32 |
| 32 // Merges timestamps from the |autofill| entry and |timestamps|. Returns | 33 // Merges timestamps from the |autofill| entry and |timestamps|. Returns |
| 33 // true if they were different, false if they were the same. | 34 // true if they were different, false if they were the same. |
| 34 // All of the timestamp vectors are assummed to be sorted, resulting vector is | 35 // All of the timestamp vectors are assummed to be sorted, resulting vector is |
| 35 // sorted as well. Only two timestamps - the earliest and the latest are stored. | 36 // sorted as well. Only two timestamps - the earliest and the latest are stored. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 85 void* UserDataKey() { | 86 void* UserDataKey() { |
| 86 // Use the address of a static that COMDAT folding won't ever fold | 87 // Use the address of a static that COMDAT folding won't ever fold |
| 87 // with something else. | 88 // with something else. |
| 88 static int user_data_key = 0; | 89 static int user_data_key = 0; |
| 89 return reinterpret_cast<void*>(&user_data_key); | 90 return reinterpret_cast<void*>(&user_data_key); |
| 90 } | 91 } |
| 91 | 92 |
| 92 } // namespace | 93 } // namespace |
| 93 | 94 |
| 94 AutocompleteSyncableService::AutocompleteSyncableService( | 95 AutocompleteSyncableService::AutocompleteSyncableService( |
| 95 AutofillWebDataService* web_data_service) | 96 AutofillWebDataBackend* webdata_backend) |
| 96 : web_data_service_(web_data_service), | 97 : webdata_backend_(webdata_backend), |
| 97 scoped_observer_(this), | 98 scoped_observer_(this), |
| 98 cull_expired_entries_(false) { | 99 cull_expired_entries_(false) { |
| 99 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 100 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 100 DCHECK(web_data_service_); | 101 DCHECK(webdata_backend_); |
| 101 | 102 |
| 102 scoped_observer_.Add(web_data_service_); | 103 scoped_observer_.Add(webdata_backend_); |
| 103 } | 104 } |
| 104 | 105 |
| 105 AutocompleteSyncableService::~AutocompleteSyncableService() { | 106 AutocompleteSyncableService::~AutocompleteSyncableService() { |
| 106 DCHECK(CalledOnValidThread()); | 107 DCHECK(CalledOnValidThread()); |
| 107 } | 108 } |
| 108 | 109 |
| 109 // static | 110 // static |
| 110 void AutocompleteSyncableService::CreateForWebDataService( | 111 void AutocompleteSyncableService::CreateForWebDataServiceAndBackend( |
| 111 AutofillWebDataService* web_data_service) { | 112 AutofillWebDataService* web_data_service, |
| 113 AutofillWebDataBackend* webdata_backend) { |
| 112 web_data_service->GetDBUserData()->SetUserData( | 114 web_data_service->GetDBUserData()->SetUserData( |
| 113 UserDataKey(), new AutocompleteSyncableService(web_data_service)); | 115 UserDataKey(), new AutocompleteSyncableService(webdata_backend)); |
| 114 } | 116 } |
| 115 | 117 |
| 116 // static | 118 // static |
| 117 AutocompleteSyncableService* AutocompleteSyncableService::FromWebDataService( | 119 AutocompleteSyncableService* AutocompleteSyncableService::FromWebDataService( |
| 118 AutofillWebDataService* web_data_service) { | 120 AutofillWebDataService* web_data_service) { |
| 119 return static_cast<AutocompleteSyncableService*>( | 121 return static_cast<AutocompleteSyncableService*>( |
| 120 web_data_service->GetDBUserData()->GetUserData(UserDataKey())); | 122 web_data_service->GetDBUserData()->GetUserData(UserDataKey())); |
| 121 } | 123 } |
| 122 | 124 |
| 123 AutocompleteSyncableService::AutocompleteSyncableService() | 125 AutocompleteSyncableService::AutocompleteSyncableService() |
| 124 : web_data_service_(NULL), | 126 : webdata_backend_(NULL), |
| 125 scoped_observer_(this), | 127 scoped_observer_(this), |
| 126 cull_expired_entries_(false) { | 128 cull_expired_entries_(false) { |
| 127 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 129 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 128 } | 130 } |
| 129 | 131 |
| 130 void AutocompleteSyncableService::InjectStartSyncFlare( | 132 void AutocompleteSyncableService::InjectStartSyncFlare( |
| 131 const syncer::SyncableService::StartSyncFlare& flare) { | 133 const syncer::SyncableService::StartSyncFlare& flare) { |
| 132 flare_ = flare; | 134 flare_ = flare; |
| 133 } | 135 } |
| 134 | 136 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 172 CreateOrUpdateEntry(*sync_iter, &new_db_entries, &new_synced_entries); | 174 CreateOrUpdateEntry(*sync_iter, &new_db_entries, &new_synced_entries); |
| 173 } | 175 } |
| 174 | 176 |
| 175 if (!SaveChangesToWebData(new_synced_entries)) { | 177 if (!SaveChangesToWebData(new_synced_entries)) { |
| 176 merge_result.set_error(error_handler_->CreateAndUploadError( | 178 merge_result.set_error(error_handler_->CreateAndUploadError( |
| 177 FROM_HERE, | 179 FROM_HERE, |
| 178 "Failed to update webdata.")); | 180 "Failed to update webdata.")); |
| 179 return merge_result; | 181 return merge_result; |
| 180 } | 182 } |
| 181 | 183 |
| 182 AutofillWebDataService::NotifyOfMultipleAutofillChanges(web_data_service_); | 184 webdata_backend_->NotifyOfMultipleAutofillChanges(); |
| 183 | 185 |
| 184 syncer::SyncChangeList new_changes; | 186 syncer::SyncChangeList new_changes; |
| 185 for (AutocompleteEntryMap::iterator i = new_db_entries.begin(); | 187 for (AutocompleteEntryMap::iterator i = new_db_entries.begin(); |
| 186 i != new_db_entries.end(); ++i) { | 188 i != new_db_entries.end(); ++i) { |
| 187 new_changes.push_back( | 189 new_changes.push_back( |
| 188 syncer::SyncChange(FROM_HERE, | 190 syncer::SyncChange(FROM_HERE, |
| 189 i->second.first, | 191 i->second.first, |
| 190 CreateSyncData(*(i->second.second)))); | 192 CreateSyncData(*(i->second.second)))); |
| 191 } | 193 } |
| 192 | 194 |
| 193 if (cull_expired_entries_) { | 195 if (cull_expired_entries_) { |
| 194 // This will schedule a deletion operation on the DB thread, which will | 196 // This will schedule a deletion operation on the DB thread, which will |
| 195 // trigger a notification to propagate the deletion to Sync. | 197 // trigger a notification to propagate the deletion to Sync. |
| 196 web_data_service_->RemoveExpiredFormElements(); | 198 webdata_backend_->RemoveExpiredFormElements(); |
| 197 } | 199 } |
| 198 | 200 |
| 199 merge_result.set_error( | 201 merge_result.set_error( |
| 200 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); | 202 sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); |
| 201 return merge_result; | 203 return merge_result; |
| 202 } | 204 } |
| 203 | 205 |
| 204 void AutocompleteSyncableService::StopSyncing(syncer::ModelType type) { | 206 void AutocompleteSyncableService::StopSyncing(syncer::ModelType type) { |
| 205 DCHECK(CalledOnValidThread()); | 207 DCHECK(CalledOnValidThread()); |
| 206 DCHECK_EQ(syncer::AUTOFILL, type); | 208 DCHECK_EQ(syncer::AUTOFILL, type); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 syncer::SyncChange::ChangeTypeToString(i->change_type())); | 291 syncer::SyncChange::ChangeTypeToString(i->change_type())); |
| 290 } | 292 } |
| 291 } | 293 } |
| 292 | 294 |
| 293 if (!SaveChangesToWebData(new_entries)) { | 295 if (!SaveChangesToWebData(new_entries)) { |
| 294 return error_handler_->CreateAndUploadError( | 296 return error_handler_->CreateAndUploadError( |
| 295 FROM_HERE, | 297 FROM_HERE, |
| 296 "Failed to update webdata."); | 298 "Failed to update webdata."); |
| 297 } | 299 } |
| 298 | 300 |
| 299 AutofillWebDataService::NotifyOfMultipleAutofillChanges(web_data_service_); | 301 webdata_backend_->NotifyOfMultipleAutofillChanges(); |
| 300 | 302 |
| 301 if (cull_expired_entries_) { | 303 if (cull_expired_entries_) { |
| 302 // This will schedule a deletion operation on the DB thread, which will | 304 // This will schedule a deletion operation on the DB thread, which will |
| 303 // trigger a notification to propagate the deletion to Sync. | 305 // trigger a notification to propagate the deletion to Sync. |
| 304 web_data_service_->RemoveExpiredFormElements(); | 306 webdata_backend_->RemoveExpiredFormElements(); |
| 305 } | 307 } |
| 306 | 308 |
| 307 return list_processing_error; | 309 return list_processing_error; |
| 308 } | 310 } |
| 309 | 311 |
| 310 void AutocompleteSyncableService::AutofillEntriesChanged( | 312 void AutocompleteSyncableService::AutofillEntriesChanged( |
| 311 const AutofillChangeList& changes) { | 313 const AutofillChangeList& changes) { |
| 312 // Check if sync is on. If we recieve this notification prior to sync being | 314 // Check if sync is on. If we recieve this notification prior to sync being |
| 313 // started, we'll notify sync to start as soon as it can and later process | 315 // started, we'll notify sync to start as soon as it can and later process |
| 314 // all entries when MergeData..() is called. If we receive this notification | 316 // all entries when MergeData..() is called. If we receive this notification |
| 315 // sync has exited, it will be synced next time Chrome starts. | 317 // sync has exited, it will be synced next time Chrome starts. |
| 316 if (sync_processor_.get()) { | 318 if (sync_processor_.get()) { |
| 317 ActOnChanges(changes); | 319 ActOnChanges(changes); |
| 318 } else if (!flare_.is_null()) { | 320 } else if (!flare_.is_null()) { |
| 319 flare_.Run(syncer::AUTOFILL); | 321 flare_.Run(syncer::AUTOFILL); |
| 320 flare_.Reset(); | 322 flare_.Reset(); |
| 321 } | 323 } |
| 322 } | 324 } |
| 323 | 325 |
| 324 bool AutocompleteSyncableService::LoadAutofillData( | 326 bool AutocompleteSyncableService::LoadAutofillData( |
| 325 std::vector<AutofillEntry>* entries) const { | 327 std::vector<AutofillEntry>* entries) const { |
| 326 return AutofillTable::FromWebDatabase( | 328 return AutofillTable::FromWebDatabase( |
| 327 web_data_service_->GetDatabase())->GetAllAutofillEntries(entries); | 329 webdata_backend_->GetDatabase())->GetAllAutofillEntries(entries); |
| 328 } | 330 } |
| 329 | 331 |
| 330 bool AutocompleteSyncableService::SaveChangesToWebData( | 332 bool AutocompleteSyncableService::SaveChangesToWebData( |
| 331 const std::vector<AutofillEntry>& new_entries) { | 333 const std::vector<AutofillEntry>& new_entries) { |
| 332 DCHECK(CalledOnValidThread()); | 334 DCHECK(CalledOnValidThread()); |
| 333 | 335 |
| 334 if (!new_entries.empty() && | 336 if (!new_entries.empty() && |
| 335 !AutofillTable::FromWebDatabase( | 337 !AutofillTable::FromWebDatabase( |
| 336 web_data_service_->GetDatabase())->UpdateAutofillEntries( | 338 webdata_backend_->GetDatabase())->UpdateAutofillEntries( |
| 337 new_entries)) { | 339 new_entries)) { |
| 338 return false; | 340 return false; |
| 339 } | 341 } |
| 340 return true; | 342 return true; |
| 341 } | 343 } |
| 342 | 344 |
| 343 // Creates or updates an autocomplete entry based on |data|. | 345 // Creates or updates an autocomplete entry based on |data|. |
| 344 void AutocompleteSyncableService::CreateOrUpdateEntry( | 346 void AutocompleteSyncableService::CreateOrUpdateEntry( |
| 345 const syncer::SyncData& data, | 347 const syncer::SyncData& data, |
| 346 AutocompleteEntryMap* loaded_data, | 348 AutocompleteEntryMap* loaded_data, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 400 const std::vector<base::Time>& ts(entry.timestamps()); | 402 const std::vector<base::Time>& ts(entry.timestamps()); |
| 401 for (std::vector<base::Time>::const_iterator timestamp = ts.begin(); | 403 for (std::vector<base::Time>::const_iterator timestamp = ts.begin(); |
| 402 timestamp != ts.end(); ++timestamp) { | 404 timestamp != ts.end(); ++timestamp) { |
| 403 autofill->add_usage_timestamp(timestamp->ToInternalValue()); | 405 autofill->add_usage_timestamp(timestamp->ToInternalValue()); |
| 404 } | 406 } |
| 405 } | 407 } |
| 406 | 408 |
| 407 syncer::SyncError AutocompleteSyncableService::AutofillEntryDelete( | 409 syncer::SyncError AutocompleteSyncableService::AutofillEntryDelete( |
| 408 const sync_pb::AutofillSpecifics& autofill) { | 410 const sync_pb::AutofillSpecifics& autofill) { |
| 409 if (!AutofillTable::FromWebDatabase( | 411 if (!AutofillTable::FromWebDatabase( |
| 410 web_data_service_->GetDatabase())->RemoveFormElement( | 412 webdata_backend_->GetDatabase())->RemoveFormElement( |
| 411 UTF8ToUTF16(autofill.name()), UTF8ToUTF16(autofill.value()))) { | 413 UTF8ToUTF16(autofill.name()), UTF8ToUTF16(autofill.value()))) { |
| 412 return error_handler_->CreateAndUploadError( | 414 return error_handler_->CreateAndUploadError( |
| 413 FROM_HERE, | 415 FROM_HERE, |
| 414 "Could not remove autocomplete entry from WebDatabase."); | 416 "Could not remove autocomplete entry from WebDatabase."); |
| 415 } | 417 } |
| 416 return syncer::SyncError(); | 418 return syncer::SyncError(); |
| 417 } | 419 } |
| 418 | 420 |
| 419 void AutocompleteSyncableService::ActOnChanges( | 421 void AutocompleteSyncableService::ActOnChanges( |
| 420 const AutofillChangeList& changes) { | 422 const AutofillChangeList& changes) { |
| 421 DCHECK(sync_processor_.get()); | 423 DCHECK(sync_processor_.get()); |
| 422 syncer::SyncChangeList new_changes; | 424 syncer::SyncChangeList new_changes; |
| 423 for (AutofillChangeList::const_iterator change = changes.begin(); | 425 for (AutofillChangeList::const_iterator change = changes.begin(); |
| 424 change != changes.end(); ++change) { | 426 change != changes.end(); ++change) { |
| 425 switch (change->type()) { | 427 switch (change->type()) { |
| 426 case AutofillChange::ADD: | 428 case AutofillChange::ADD: |
| 427 case AutofillChange::UPDATE: { | 429 case AutofillChange::UPDATE: { |
| 428 std::vector<base::Time> timestamps; | 430 std::vector<base::Time> timestamps; |
| 429 if (!AutofillTable::FromWebDatabase( | 431 WebDatabase* db = webdata_backend_->GetDatabase(); |
| 430 web_data_service_->GetDatabase())->GetAutofillTimestamps( | 432 if (!AutofillTable::FromWebDatabase(db)->GetAutofillTimestamps( |
| 431 change->key().name(), | 433 change->key().name(), |
| 432 change->key().value(), | 434 change->key().value(), |
| 433 ×tamps)) { | 435 ×tamps)) { |
| 434 NOTREACHED(); | 436 NOTREACHED(); |
| 435 return; | 437 return; |
| 436 } | 438 } |
| 437 AutofillEntry entry(change->key(), timestamps); | 439 AutofillEntry entry(change->key(), timestamps); |
| 438 syncer::SyncChange::SyncChangeType change_type = | 440 syncer::SyncChange::SyncChangeType change_type = |
| 439 (change->type() == AutofillChange::ADD) ? | 441 (change->type() == AutofillChange::ADD) ? |
| 440 syncer::SyncChange::ACTION_ADD : | 442 syncer::SyncChange::ACTION_ADD : |
| 441 syncer::SyncChange::ACTION_UPDATE; | 443 syncer::SyncChange::ACTION_UPDATE; |
| 442 new_changes.push_back(syncer::SyncChange(FROM_HERE, | 444 new_changes.push_back(syncer::SyncChange(FROM_HERE, |
| 443 change_type, | 445 change_type, |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 UTF16ToUTF8(entry.key().value()))); | 483 UTF16ToUTF8(entry.key().value()))); |
| 482 return syncer::SyncData::CreateLocalData(tag, tag, autofill_specifics); | 484 return syncer::SyncData::CreateLocalData(tag, tag, autofill_specifics); |
| 483 } | 485 } |
| 484 | 486 |
| 485 // static | 487 // static |
| 486 std::string AutocompleteSyncableService::KeyToTag(const std::string& name, | 488 std::string AutocompleteSyncableService::KeyToTag(const std::string& name, |
| 487 const std::string& value) { | 489 const std::string& value) { |
| 488 std::string ns(kAutofillEntryNamespaceTag); | 490 std::string ns(kAutofillEntryNamespaceTag); |
| 489 return ns + net::EscapePath(name) + "|" + net::EscapePath(value); | 491 return ns + net::EscapePath(name) + "|" + net::EscapePath(value); |
| 490 } | 492 } |
| OLD | NEW |