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