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/memory/scoped_ptr.h" 15 #include "base/scoped_observer.h" 16 #include "base/supports_user_data.h" 17 #include "base/threading/non_thread_safe.h" 18 #include "components/autofill/core/browser/webdata/autofill_change.h" 19 #include "components/autofill/core/browser/webdata/autofill_entry.h" 20 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h" 21 #include "components/autofill/core/browser/webdata/autofill_webdata_service.h" 22 #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h" 23 #include "sync/api/sync_change.h" 24 #include "sync/api/sync_data.h" 25 #include "sync/api/sync_error.h" 26 #include "sync/api/syncable_service.h" 27 28 class ProfileSyncServiceAutofillTest; 29 30 namespace syncer { 31 class SyncErrorFactory; 32 } 33 34 namespace sync_pb { 35 class AutofillSpecifics; 36 } 37 38 // The sync implementation for autocomplete. 39 // MergeDataAndStartSyncing() called first, it does cloud->local and 40 // local->cloud syncs. Then for each cloud change we receive 41 // ProcessSyncChanges() and for each local change Observe() is called. 42 class AutocompleteSyncableService 43 : public base::SupportsUserData::Data, 44 public syncer::SyncableService, 45 public autofill::AutofillWebDataServiceObserverOnDBThread, 46 public base::NonThreadSafe { 47 public: 48 virtual ~AutocompleteSyncableService(); 49 50 // Creates a new AutocompleteSyncableService and hangs it off of 51 // |web_data_service|, which takes ownership. 52 static void CreateForWebDataServiceAndBackend( 53 autofill::AutofillWebDataService* web_data_service, 54 autofill::AutofillWebDataBackend* webdata_backend); 55 56 // Retrieves the AutocompleteSyncableService stored on |web_data|. 57 static AutocompleteSyncableService* FromWebDataService( 58 autofill::AutofillWebDataService* web_data_service); 59 60 static syncer::ModelType model_type() { return syncer::AUTOFILL; } 61 62 // syncer::SyncableService implementation. 63 virtual syncer::SyncMergeResult MergeDataAndStartSyncing( 64 syncer::ModelType type, 65 const syncer::SyncDataList& initial_sync_data, 66 scoped_ptr<syncer::SyncChangeProcessor> sync_processor, 67 scoped_ptr<syncer::SyncErrorFactory> error_handler) OVERRIDE; 68 virtual void StopSyncing(syncer::ModelType type) OVERRIDE; 69 virtual syncer::SyncDataList GetAllSyncData( 70 syncer::ModelType type) const OVERRIDE; 71 virtual syncer::SyncError ProcessSyncChanges( 72 const tracked_objects::Location& from_here, 73 const syncer::SyncChangeList& change_list) OVERRIDE; 74 75 // AutofillWebDataServiceObserverOnDBThread implementation. 76 virtual void AutofillEntriesChanged( 77 const autofill::AutofillChangeList& changes) OVERRIDE; 78 79 // Called via sync to tell us if we should cull expired entries when merging 80 // and/or processing sync changes. 81 void UpdateCullSetting(bool cull_expired_entries); 82 bool cull_expired_entries() const { return cull_expired_entries_; } 83 84 // Provides a StartSyncFlare to the SyncableService. See 85 // sync_start_util for more. 86 void InjectStartSyncFlare( 87 const syncer::SyncableService::StartSyncFlare& flare); 88 89 protected: 90 explicit AutocompleteSyncableService( 91 autofill::AutofillWebDataBackend* webdata_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 static std::string KeyToTag(const std::string& name, 148 const std::string& value); 149 150 // For unit-tests. 151 AutocompleteSyncableService(); 152 void set_sync_processor(syncer::SyncChangeProcessor* sync_processor) { 153 sync_processor_.reset(sync_processor); 154 } 155 156 // Lifetime of AutocompleteSyncableService object is shorter than 157 // |autofill_webdata_backend_| passed to it. 158 autofill::AutofillWebDataBackend* webdata_backend_; 159 160 ScopedObserver<autofill::AutofillWebDataBackend, AutocompleteSyncableService> 161 scoped_observer_; 162 163 // We receive ownership of |sync_processor_| in MergeDataAndStartSyncing() and 164 // destroy it in StopSyncing(). 165 scoped_ptr<syncer::SyncChangeProcessor> sync_processor_; 166 167 // We receive ownership of |error_handler_| in MergeDataAndStartSyncing() and 168 // destroy it in StopSyncing(). 169 scoped_ptr<syncer::SyncErrorFactory> error_handler_; 170 171 // Whether we should cull expired autofill entries, can be updated by sync 172 // via UpdateCullingSetting. 173 bool cull_expired_entries_; 174 175 syncer::SyncableService::StartSyncFlare flare_; 176 177 DISALLOW_COPY_AND_ASSIGN(AutocompleteSyncableService); 178 }; 179 180 #endif // CHROME_BROWSER_WEBDATA_AUTOCOMPLETE_SYNCABLE_SERVICE_H_ 181