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