1 // Copyright 2014 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 COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_PROFILE_SYNCABLE_SERVICE_H_
5 #define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_PROFILE_SYNCABLE_SERVICE_H_
7 #if !defined(AUTOFILL_ENABLE_SYNC)
8 #error "This file should be built only when sync is enabled in Autofill"
15 #include "base/basictypes.h"
16 #include "base/gtest_prod_util.h"
17 #include "base/memory/scoped_vector.h"
18 #include "base/scoped_observer.h"
19 #include "base/supports_user_data.h"
20 #include "base/synchronization/lock.h"
21 #include "base/threading/non_thread_safe.h"
22 #include "components/autofill/core/browser/field_types.h"
23 #include "components/autofill/core/browser/webdata/autofill_change.h"
24 #include "components/autofill/core/browser/webdata/autofill_entry.h"
25 #include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
26 #include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
27 #include "sync/api/sync_change.h"
28 #include "sync/api/sync_data.h"
29 #include "sync/api/sync_error.h"
30 #include "sync/api/syncable_service.h"
31 #include "sync/protocol/autofill_specifics.pb.h"
33 class ProfileSyncServiceAutofillTest;
34 class WebDataServiceBase;
38 class AutofillProfile;
40 class AutofillWebDataService;
43 extern const char kAutofillProfileTag[];
45 // The sync implementation for AutofillProfiles.
46 // MergeDataAndStartSyncing() called first, it does cloud->local and
47 // local->cloud syncs. Then for each cloud change we receive
48 // ProcessSyncChanges() and for each local change Observe() is called.
49 class AutofillProfileSyncableService
50 : public base::SupportsUserData::Data,
51 public syncer::SyncableService,
52 public AutofillWebDataServiceObserverOnDBThread,
53 public base::NonThreadSafe {
55 virtual ~AutofillProfileSyncableService();
57 // Creates a new AutofillProfileSyncableService and hangs it off of
58 // |web_data_service|, which takes ownership. This method should only be
59 // called on |web_data_service|'s DB thread.
60 static void CreateForWebDataServiceAndBackend(
61 AutofillWebDataService* web_data_service,
62 AutofillWebDataBackend* webdata_backend,
63 const std::string& app_locale);
65 // Retrieves the AutofillProfileSyncableService stored on |web_data_service|.
66 static AutofillProfileSyncableService* FromWebDataService(
67 AutofillWebDataService* web_data_service);
69 static syncer::ModelType model_type() { return syncer::AUTOFILL_PROFILE; }
71 // syncer::SyncableService implementation.
72 virtual syncer::SyncMergeResult MergeDataAndStartSyncing(
73 syncer::ModelType type,
74 const syncer::SyncDataList& initial_sync_data,
75 scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
76 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) OVERRIDE;
77 virtual void StopSyncing(syncer::ModelType type) OVERRIDE;
78 virtual syncer::SyncDataList GetAllSyncData(
79 syncer::ModelType type) const OVERRIDE;
80 virtual syncer::SyncError ProcessSyncChanges(
81 const tracked_objects::Location& from_here,
82 const syncer::SyncChangeList& change_list) OVERRIDE;
84 // AutofillWebDataServiceObserverOnDBThread implementation.
85 virtual void AutofillProfileChanged(
86 const AutofillProfileChange& change) OVERRIDE;
88 // Provides a StartSyncFlare to the SyncableService. See
89 // sync_start_util for more.
90 void InjectStartSyncFlare(
91 const syncer::SyncableService::StartSyncFlare& flare);
94 AutofillProfileSyncableService(AutofillWebDataBackend* webdata_backend,
95 const std::string& app_locale);
97 // A convenience wrapper of a bunch of state we pass around while
98 // associating models, and send to the WebDatabase for persistence.
99 // We do this so we hold the write lock for only a small period.
100 // When storing the web db we are out of the write lock.
103 // Helper to query WebDatabase for the current autofill state.
104 // Made virtual for ease of mocking in unit tests.
105 // Caller owns returned |profiles|.
106 virtual bool LoadAutofillData(std::vector<AutofillProfile*>* profiles);
108 // Helper to persist any changes that occured during model association to
110 // Made virtual for ease of mocking in unit tests.
111 virtual bool SaveChangesToWebData(const DataBundle& bundle);
114 AutofillProfileSyncableService();
115 void set_sync_processor(syncer::SyncChangeProcessor* sync_processor) {
116 sync_processor_.reset(sync_processor);
119 // Creates syncer::SyncData based on supplied |profile|.
120 // Exposed for unit tests.
121 static syncer::SyncData CreateData(const AutofillProfile& profile);
124 friend class ::ProfileSyncServiceAutofillTest;
125 FRIEND_TEST_ALL_PREFIXES(AutofillProfileSyncableServiceTest,
127 FRIEND_TEST_ALL_PREFIXES(AutofillProfileSyncableServiceTest,
128 UpdateMultivaluedField);
129 FRIEND_TEST_ALL_PREFIXES(AutofillProfileSyncableServiceTest,
132 // The map of the guid to profiles owned by the |profiles_| vector.
133 typedef std::map<std::string, AutofillProfile*> GUIDToProfileMap;
135 // Helper function that overwrites |profile| with data from proto-buffer
137 static bool OverwriteProfileWithServerData(
138 const sync_pb::AutofillProfileSpecifics& specifics,
139 AutofillProfile* profile,
140 const std::string& app_locale);
142 // Writes |profile| data into supplied |profile_specifics|.
143 static void WriteAutofillProfile(const AutofillProfile& profile,
144 sync_pb::EntitySpecifics* profile_specifics);
146 // Creates |profile_map| from the supplied |profiles| vector. Necessary for
147 // fast processing of the changes.
148 void CreateGUIDToProfileMap(const std::vector<AutofillProfile*>& profiles,
149 GUIDToProfileMap* profile_map);
151 // Creates or updates a profile based on |data|. Looks at the guid of the data
152 // and if a profile with such guid is present in |profile_map| updates it. If
153 // not, searches through it for similar profiles. If similar profile is
154 // found substitutes it for the new one, otherwise adds a new profile. Returns
155 // iterator pointing to added/updated profile.
156 GUIDToProfileMap::iterator CreateOrUpdateProfile(
157 const syncer::SyncData& data,
158 GUIDToProfileMap* profile_map,
161 // Syncs |change| to the cloud.
162 void ActOnChange(const AutofillProfileChange& change);
164 AutofillTable* GetAutofillTable() const;
166 // Helper to compare the local value and cloud value of a field, copy into
167 // the local value if they differ, and return whether the change happened.
168 static bool UpdateField(ServerFieldType field_type,
169 const std::string& new_value,
170 AutofillProfile* autofill_profile);
171 // The same as |UpdateField|, but for multi-valued fields.
172 static bool UpdateMultivaluedField(
173 ServerFieldType field_type,
174 const ::google::protobuf::RepeatedPtrField<std::string>& new_value,
175 AutofillProfile* autofill_profile);
177 // Calls merge_into->OverwriteWithOrAddTo() and then checks if the
178 // |merge_into| has extra data. Returns |true| if |merge_into| posseses some
179 // multi-valued field values that are not in |merge_from|.
180 // TODO(isherman): Seems like this should return |true| if |merge_into| was
181 // modified at all: http://crbug.com/248440
182 static bool MergeProfile(const AutofillProfile& merge_from,
183 AutofillProfile* merge_into,
184 const std::string& app_locale);
186 AutofillWebDataBackend* webdata_backend_; // WEAK
187 std::string app_locale_;
188 ScopedObserver<AutofillWebDataBackend,
189 AutofillProfileSyncableService> scoped_observer_;
191 // Cached Autofill profiles. *Warning* deleted profiles are still in the
192 // vector - use the |profiles_map_| to iterate through actual profiles.
193 ScopedVector<AutofillProfile> profiles_;
194 GUIDToProfileMap profiles_map_;
196 scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
198 scoped_ptr<syncer::SyncErrorFactory> sync_error_factory_;
200 syncer::SyncableService::StartSyncFlare flare_;
202 DISALLOW_COPY_AND_ASSIGN(AutofillProfileSyncableService);
205 // This object is used in unit tests as well, so it defined here.
206 struct AutofillProfileSyncableService::DataBundle {
210 std::vector<std::string> profiles_to_delete;
211 std::vector<AutofillProfile*> profiles_to_update;
212 std::vector<AutofillProfile*> profiles_to_add;
214 // When we go through sync we find profiles that are similar but unmatched.
215 // Merge such profiles.
216 GUIDToProfileMap candidates_to_merge;
217 // Profiles that have multi-valued fields that are not in sync.
218 std::vector<AutofillProfile*> profiles_to_sync_back;
221 } // namespace autofill
223 #endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_PROFILE_SYNCABLE_SERVICE_H_