15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/webdata/autocomplete_syncable_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/webdata/autofill_table.h" 11eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "components/autofill/core/browser/webdata/autofill_webdata_service.h" 12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "components/webdata/common/web_database.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/escape.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_error.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/api/sync_error_factory.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/autofill_specifics.pb.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sync/protocol/sync.pb.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using autofill::AutofillChange; 21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using autofill::AutofillChangeList; 22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using autofill::AutofillEntry; 23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using autofill::AutofillKey; 24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using autofill::AutofillTable; 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)using autofill::AutofillWebDataService; 2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)using autofill::AutofillWebDataBackend; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAutofillEntryNamespaceTag[] = "autofill_entry|"; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Merges timestamps from the |sync_timestamps| and the |local_entry|. 34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Returns true if they were different, false if they were the same. If the 35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// timestamps were different, fills |date_created| and |date_last_used| with the 36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// merged timestamps. The |sync_timestamps| vector is assumed to be sorted. 37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool MergeTimestamps( 38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const google::protobuf::RepeatedField<int64_t>& sync_timestamps, 39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const AutofillEntry& local_entry, 40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time* date_created, 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time* date_last_used) { 42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (sync_timestamps.size() == 0) { 43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *date_created = local_entry.date_created(); 44a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *date_last_used = local_entry.date_last_used(); 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 48a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time sync_date_created = 49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time::FromInternalValue(*sync_timestamps.begin()); 50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time sync_date_last_used = 51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time::FromInternalValue(*sync_timestamps.rbegin()); 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (sync_date_created == local_entry.date_created() && 54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) sync_date_last_used == local_entry.date_last_used()) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *date_created = std::min(local_entry.date_created(), sync_date_created); 58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) *date_last_used = std::max(local_entry.date_last_used(), sync_date_last_used); 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return true; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void* UserDataKey() { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Use the address of a static that COMDAT folding won't ever fold 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // with something else. 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static int user_data_key = 0; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return reinterpret_cast<void*>(&user_data_key); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutocompleteSyncableService::AutocompleteSyncableService( 725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) AutofillWebDataBackend* web_data_backend) 735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : web_data_backend_(web_data_backend), 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_observer_(this) { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(web_data_backend_); 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_observer_.Add(web_data_backend_); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutocompleteSyncableService::~AutocompleteSyncableService() { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AutocompleteSyncableService::CreateForWebDataServiceAndBackend( 8790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) AutofillWebDataService* web_data_service, 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) AutofillWebDataBackend* web_data_backend) { 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_data_service->GetDBUserData()->SetUserData( 905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) UserDataKey(), new AutocompleteSyncableService(web_data_backend)); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AutocompleteSyncableService* AutocompleteSyncableService::FromWebDataService( 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AutofillWebDataService* web_data_service) { 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return static_cast<AutocompleteSyncableService*>( 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_data_service->GetDBUserData()->GetUserData(UserDataKey())); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AutocompleteSyncableService::AutocompleteSyncableService() 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) : web_data_backend_(NULL), 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_observer_(this) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AutocompleteSyncableService::InjectStartSyncFlare( 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const syncer::SyncableService::StartSyncFlare& flare) { 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) flare_ = flare; 109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)syncer::SyncMergeResult AutocompleteSyncableService::MergeDataAndStartSyncing( 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::ModelType type, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::SyncDataList& initial_sync_data, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<syncer::SyncChangeProcessor> sync_processor, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<syncer::SyncErrorFactory> error_handler) { 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(!sync_processor_); 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(sync_processor); 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(error_handler); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) syncer::SyncMergeResult merge_result(type); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_handler_ = error_handler.Pass(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<AutofillEntry> entries; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!LoadAutofillData(&entries)) { 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) merge_result.set_error(error_handler_->CreateAndUploadError( 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "Could not load autocomplete data from the WebDatabase.")); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return merge_result; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteEntryMap new_db_entries; 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<AutofillEntry>::iterator it = entries.begin(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != entries.end(); ++it) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_db_entries[it->key()] = 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::make_pair(syncer::SyncChange::ACTION_ADD, it); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_processor_ = sync_processor.Pass(); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<AutofillEntry> new_synced_entries; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Go through and check for all the entries that sync already knows about. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // CreateOrUpdateEntry() will remove entries that are same with the synced 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ones from |new_db_entries|. 1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (syncer::SyncDataList::const_iterator it = initial_sync_data.begin(); 1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != initial_sync_data.end(); ++it) { 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateOrUpdateEntry(*it, &new_db_entries, &new_synced_entries); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SaveChangesToWebData(new_synced_entries)) { 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) merge_result.set_error(error_handler_->CreateAndUploadError( 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "Failed to update webdata.")); 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return merge_result; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChangeList new_changes; 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (AutocompleteEntryMap::iterator it = new_db_entries.begin(); 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it != new_db_entries.end(); ++it) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_changes.push_back( 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange(FROM_HERE, 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) it->second.first, 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CreateSyncData(*(it->second.second)))); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) merge_result.set_error( 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes)); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This will schedule a deletion operation on the DB thread, which will 1695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // trigger a notification to propagate the deletion to Sync. 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // NOTE: This must be called *after* the ProcessSyncChanges call above. 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Otherwise, an item that Sync is not yet aware of might expire, causing a 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Sync error when that item's deletion is propagated to Sync. 1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_data_backend_->RemoveExpiredFormElements(); 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return merge_result; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteSyncableService::StopSyncing(syncer::ModelType type) { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(syncer::AUTOFILL, type); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) sync_processor_.reset(); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_handler_.reset(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncDataList AutocompleteSyncableService::GetAllSyncData( 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::ModelType type) const { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(sync_processor_); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(type, syncer::AUTOFILL); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncDataList current_data; 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<AutofillEntry> entries; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!LoadAutofillData(&entries)) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_data; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<AutofillEntry>::iterator it = entries.begin(); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != entries.end(); ++it) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_data.push_back(CreateSyncData(*it)); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return current_data; 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncError AutocompleteSyncableService::ProcessSyncChanges( 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const tracked_objects::Location& from_here, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::SyncChangeList& change_list) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(sync_processor_); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!sync_processor_) { 213eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError error(FROM_HERE, 214eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::SyncError::DATATYPE_ERROR, 215eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "Models not yet associated.", 216eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch syncer::AUTOFILL); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Data is loaded only if we get new ADD/UPDATE change. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<AutofillEntry> entries; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AutocompleteEntryMap> db_entries; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<AutofillEntry> new_entries; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncError list_processing_error; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (syncer::SyncChangeList::const_iterator i = change_list.begin(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i != change_list.end() && !list_processing_error.IsSet(); ++i) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(i->IsValid()); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (i->change_type()) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case syncer::SyncChange::ACTION_ADD: 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case syncer::SyncChange::ACTION_UPDATE: 2335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!db_entries) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!LoadAutofillData(&entries)) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error_handler_->CreateAndUploadError( 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Could not get the autocomplete data from WebDatabase."); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_entries.reset(new AutocompleteEntryMap); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<AutofillEntry>::iterator it = entries.begin(); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != entries.end(); ++it) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*db_entries)[it->key()] = 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::make_pair(syncer::SyncChange::ACTION_ADD, it); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateOrUpdateEntry(i->sync_data(), db_entries.get(), &new_entries); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case syncer::SyncChange::ACTION_DELETE: { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(i->sync_data().GetSpecifics().has_autofill()) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Autofill specifics data not present on delete!"; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::AutofillSpecifics& autofill = 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i->sync_data().GetSpecifics().autofill(); 2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (autofill.has_value()) 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list_processing_error = AutofillEntryDelete(autofill); 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) else 2575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DVLOG(1) << "Delete for old-style autofill profile being dropped!"; 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case syncer::SyncChange::ACTION_INVALID: 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) NOTREACHED(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error_handler_->CreateAndUploadError( 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ProcessSyncChanges failed on ChangeType " + 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange::ChangeTypeToString(i->change_type())); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SaveChangesToWebData(new_entries)) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error_handler_->CreateAndUploadError( 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Failed to update webdata."); 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // This will schedule a deletion operation on the DB thread, which will 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // trigger a notification to propagate the deletion to Sync. 2785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_data_backend_->RemoveExpiredFormElements(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return list_processing_error; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 283c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void AutocompleteSyncableService::AutofillEntriesChanged( 284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const AutofillChangeList& changes) { 285010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles) // Check if sync is on. If we receive this notification prior to sync being 2865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // started, we'll notify sync to start as soon as it can and later process all 2875f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // entries when MergeDataAndStartSyncing() is called. If we receive this 2885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // notification after sync has exited, it will be synced the next time Chrome 2895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) // starts. 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (sync_processor_) { 291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ActOnChanges(changes); 292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else if (!flare_.is_null()) { 293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) flare_.Run(syncer::AUTOFILL); 294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) flare_.Reset(); 295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutocompleteSyncableService::LoadAutofillData( 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<AutofillEntry>* entries) const { 3005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return GetAutofillTable()->GetAllAutofillEntries(entries); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AutocompleteSyncableService::SaveChangesToWebData( 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<AutofillEntry>& new_entries) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 3065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!GetAutofillTable()->UpdateAutofillEntries(new_entries)) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 3095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) web_data_backend_->NotifyOfMultipleAutofillChanges(); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates or updates an autocomplete entry based on |data|. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteSyncableService::CreateOrUpdateEntry( 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const syncer::SyncData& data, 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteEntryMap* loaded_data, 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<AutofillEntry>* new_entries) { 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::EntitySpecifics& specifics = data.GetSpecifics(); 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const sync_pb::AutofillSpecifics& autofill_specifics(specifics.autofill()); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!autofill_specifics.has_value()) { 3225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DVLOG(1) << "Add/Update for old-style autofill profile being dropped!"; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutofillKey key(autofill_specifics.name().c_str(), 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) autofill_specifics.value().c_str()); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AutocompleteEntryMap::iterator it = loaded_data->find(key); 329a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) const google::protobuf::RepeatedField<int64_t>& timestamps = 330a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) autofill_specifics.usage_timestamp(); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it == loaded_data->end()) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // New entry. 333a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time date_created, date_last_used; 334a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (timestamps.size() > 0) { 335a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) date_created = base::Time::FromInternalValue(*timestamps.begin()); 336a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) date_last_used = base::Time::FromInternalValue(*timestamps.rbegin()); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 338a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) new_entries->push_back(AutofillEntry(key, date_created, date_last_used)); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Entry already present - merge if necessary. 341a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time date_created, date_last_used; 342a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) bool different = MergeTimestamps(timestamps, *it->second.second, 343a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) &date_created, &date_last_used); 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (different) { 345a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AutofillEntry new_entry( 346a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) it->second.second->key(), date_created, date_last_used); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_entries->push_back(new_entry); 348a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // Update the sync db since the timestamps have changed. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(it->second.second) = new_entry; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it->second.first = syncer::SyncChange::ACTION_UPDATE; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loaded_data->erase(it); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteSyncableService::WriteAutofillEntry( 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AutofillEntry& entry, sync_pb::EntitySpecifics* autofill_specifics) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::AutofillSpecifics* autofill = 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) autofill_specifics->mutable_autofill(); 3625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) autofill->set_name(base::UTF16ToUTF8(entry.key().name())); 3635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) autofill->set_value(base::UTF16ToUTF8(entry.key().value())); 364a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) autofill->add_usage_timestamp(entry.date_created().ToInternalValue()); 365a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (entry.date_created() != entry.date_last_used()) 366a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) autofill->add_usage_timestamp(entry.date_last_used().ToInternalValue()); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncError AutocompleteSyncableService::AutofillEntryDelete( 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const sync_pb::AutofillSpecifics& autofill) { 3715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (!GetAutofillTable()->RemoveFormElement( 3725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::UTF8ToUTF16(autofill.name()), 3735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) base::UTF8ToUTF16(autofill.value()))) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return error_handler_->CreateAndUploadError( 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Could not remove autocomplete entry from WebDatabase."); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncer::SyncError(); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AutocompleteSyncableService::ActOnChanges( 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AutofillChangeList& changes) { 3835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(sync_processor_); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChangeList new_changes; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (AutofillChangeList::const_iterator change = changes.begin(); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change != changes.end(); ++change) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (change->type()) { 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AutofillChange::ADD: 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AutofillChange::UPDATE: { 390a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) base::Time date_created, date_last_used; 3915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool success = GetAutofillTable()->GetAutofillTimestamps( 3925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) change->key().name(), change->key().value(), 3935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) &date_created, &date_last_used); 3945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DCHECK(success); 395a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AutofillEntry entry(change->key(), date_created, date_last_used); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange::SyncChangeType change_type = 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (change->type() == AutofillChange::ADD) ? 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange::ACTION_ADD : 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange::ACTION_UPDATE; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_changes.push_back(syncer::SyncChange(FROM_HERE, 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) change_type, 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateSyncData(entry))); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case AutofillChange::REMOVE: { 407a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) AutofillEntry entry(change->key(), base::Time(), base::Time()); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new_changes.push_back( 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange(FROM_HERE, 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncChange::ACTION_DELETE, 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateSyncData(entry))); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) syncer::SyncError error = 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes); 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error.IsSet()) { 4195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) DVLOG(1) << "[AUTOCOMPLETE SYNC] Failed processing change. Error: " 4205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) << error.message(); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)syncer::SyncData AutocompleteSyncableService::CreateSyncData( 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const AutofillEntry& entry) const { 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sync_pb::EntitySpecifics autofill_specifics; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteAutofillEntry(entry, &autofill_specifics); 4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string tag(KeyToTag(base::UTF16ToUTF8(entry.key().name()), 4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::UTF16ToUTF8(entry.key().value()))); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syncer::SyncData::CreateLocalData(tag, tag, autofill_specifics); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)AutofillTable* AutocompleteSyncableService::GetAutofillTable() const { 4345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase()); 4355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)} 4365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::string AutocompleteSyncableService::KeyToTag(const std::string& name, 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& value) { 4405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string prefix(kAutofillEntryNamespaceTag); 4415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return prefix + net::EscapePath(name) + "|" + net::EscapePath(value); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 443