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 3 // found in the LICENSE file. 4 #ifndef CHROME_BROWSER_WEBDATA_AUTOCOMPLETE_SYNCABLE_SERVICE_H_ 5 #define CHROME_BROWSER_WEBDATA_AUTOCOMPLETE_SYNCABLE_SERVICE_H_ 6 7 #include <map> 8 #include <set> 9 #include <string> 10 #include <utility> 11 #include <vector> 12 13 #include "base/basictypes.h" 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/scoped_observer.h" 17 #include "base/supports_user_data.h" 18 #include "base/threading/non_thread_safe.h" 19 #include "components/autofill/core/browser/webdata/autofill_change.h" 20 #include "components/autofill/core/browser/webdata/autofill_entry.h" 21 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h" 22 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" 23 #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h" 24 #include "sync/api/sync_change.h" 25 #include "sync/api/sync_data.h" 26 #include "sync/api/sync_error.h" 27 #include "sync/api/syncable_service.h" 28 29 class ProfileSyncServiceAutofillTest; 30 31 namespace autofill { 32 class AutofillTable; 33 } 34 35 namespace syncer { 36 class SyncErrorFactory; 37 } 38 39 namespace sync_pb { 40 class AutofillSpecifics; 41 } 42 43 // The sync implementation for autocomplete. 44 // MergeDataAndStartSyncing() called first, it does cloud->local and 45 // local->cloud syncs. Then for each cloud change we receive 46 // ProcessSyncChanges() and for each local change Observe() is called. 47 class AutocompleteSyncableService 48 : public base::SupportsUserData::Data, 49 public syncer::SyncableService, 50 public autofill::AutofillWebDataServiceObserverOnDBThread, 51 public base::NonThreadSafe { 52 public: 53 virtual ~AutocompleteSyncableService(); 54 55 // Creates a new AutocompleteSyncableService and hangs it off of 56 // |web_data_service|, which takes ownership. 57 static void CreateForWebDataServiceAndBackend( 58 autofill::AutofillWebDataService* web_data_service, 59 autofill::AutofillWebDataBackend* web_data_backend); 60 61 // Retrieves the AutocompleteSyncableService stored on |web_data_service|. 62 static AutocompleteSyncableService* FromWebDataService( 63 autofill::AutofillWebDataService* web_data_service); 64 model_type()65 static syncer::ModelType model_type() { return syncer::AUTOFILL; } 66 67 // syncer::SyncableService: 68 virtual syncer::SyncMergeResult MergeDataAndStartSyncing( 69 syncer::ModelType type, 70 const syncer::SyncDataList& initial_sync_data, 71 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, 72 scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE; 73 virtual void StopSyncing(syncer::ModelType type) OVERRIDE; 74 virtual syncer::SyncDataList GetAllSyncData( 75 syncer::ModelType type) const OVERRIDE; 76 virtual syncer::SyncError ProcessSyncChanges( 77 const tracked_objects::Location& from_here, 78 const syncer::SyncChangeList& change_list) OVERRIDE; 79 80 // AutofillWebDataServiceObserverOnDBThread: 81 virtual void AutofillEntriesChanged( 82 const autofill::AutofillChangeList& changes) OVERRIDE; 83 84 // Provides a StartSyncFlare to the SyncableService. See sync_start_util for 85 // more. 86 void InjectStartSyncFlare( 87 const syncer::SyncableService::StartSyncFlare& flare); 88 89 protected: 90 explicit AutocompleteSyncableService( 91 autofill::AutofillWebDataBackend* web_data_backend); 92 93 // Helper to query WebDatabase for the current autocomplete state. 94 // Made virtual for ease of mocking in the unit-test. 95 virtual bool LoadAutofillData( 96 std::vector<autofill::AutofillEntry>* entries) const; 97 98 // Helper to persist any changes that occured during model association to 99 // the WebDatabase. |entries| will be either added or updated. 100 // Made virtual for ease of mocking in the unit-test. 101 virtual bool SaveChangesToWebData( 102 const std::vector<autofill::AutofillEntry>& entries); 103 104 private: 105 friend class ProfileSyncServiceAutofillTest; 106 friend class MockAutocompleteSyncableService; 107 friend class FakeServerUpdater; 108 FRIEND_TEST_ALL_PREFIXES(AutocompleteSyncableServiceTest, 109 MergeDataAndStartSyncing); 110 FRIEND_TEST_ALL_PREFIXES(AutocompleteSyncableServiceTest, GetAllSyncData); 111 FRIEND_TEST_ALL_PREFIXES(AutocompleteSyncableServiceTest, 112 ProcessSyncChanges); 113 FRIEND_TEST_ALL_PREFIXES(AutocompleteSyncableServiceTest, 114 ActOnChange); 115 116 // This is a helper map used only in Merge/Process* functions. The lifetime 117 // of the iterator is longer than the map object. The bool in the pair is used 118 // to indicate if the item needs to be added (true) or updated (false). 119 typedef std::map<autofill::AutofillKey, 120 std::pair<syncer::SyncChange::SyncChangeType, 121 std::vector<autofill::AutofillEntry>::iterator> > 122 AutocompleteEntryMap; 123 124 // Creates or updates an autocomplete entry based on |data|. 125 // |data| - an entry for sync. 126 // |loaded_data| - entries that were loaded from local storage. 127 // |new_entries| - entries that came from the sync. 128 // |ignored_entries| - entries that came from the sync, but too old to be 129 // stored and immediately discarded. 130 void CreateOrUpdateEntry(const syncer::SyncData& data, 131 AutocompleteEntryMap* loaded_data, 132 std::vector<autofill::AutofillEntry>* new_entries); 133 134 // Writes |entry| data into supplied |autofill_specifics|. 135 static void WriteAutofillEntry(const autofill::AutofillEntry& entry, 136 sync_pb::EntitySpecifics* autofill_specifics); 137 138 // Deletes the database entry corresponding to the |autofill| specifics. 139 syncer::SyncError AutofillEntryDelete( 140 const sync_pb::AutofillSpecifics& autofill); 141 142 syncer::SyncData CreateSyncData(const autofill::AutofillEntry& entry) const; 143 144 // Syncs |changes| to the cloud. 145 void ActOnChanges(const autofill::AutofillChangeList& changes); 146 147 // Returns the table associated with the |web_data_backend_|. 148 autofill::AutofillTable* GetAutofillTable() const; 149 150 static std::string KeyToTag(const std::string& name, 151 const std::string& value); 152 153 // For unit-tests. 154 AutocompleteSyncableService(); set_sync_processor(syncer::SyncChangeProcessor * sync_processor)155 void set_sync_processor(syncer::SyncChangeProcessor* sync_processor) { 156 sync_processor_.reset(sync_processor); 157 } 158 159 // The |web_data_backend_| is expected to outlive |this|. 160 autofill::AutofillWebDataBackend* const web_data_backend_; 161 162 ScopedObserver<autofill::AutofillWebDataBackend, AutocompleteSyncableService> 163 scoped_observer_; 164 165 // We receive ownership of |sync_processor_| in MergeDataAndStartSyncing() and 166 // destroy it in StopSyncing(). 167 scoped_ptr<syncer::SyncChangeProcessor> sync_processor_; 168 169 // We receive ownership of |error_handler_| in MergeDataAndStartSyncing() and 170 // destroy it in StopSyncing(). 171 scoped_ptr<syncer::SyncErrorFactory> error_handler_; 172 173 syncer::SyncableService::StartSyncFlare flare_; 174 175 DISALLOW_COPY_AND_ASSIGN(AutocompleteSyncableService); 176 }; 177 178 #endif // CHROME_BROWSER_WEBDATA_AUTOCOMPLETE_SYNCABLE_SERVICE_H_ 179