Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / autofill / core / browser / webdata / autofill_profile_syncable_service.h
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_
6
7 #if !defined(AUTOFILL_ENABLE_SYNC)
8 #error "This file should be built only when sync is enabled in Autofill"
9 #endif
10
11 #include <map>
12 #include <string>
13 #include <vector>
14
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"
32
33 class ProfileSyncServiceAutofillTest;
34 class WebDataServiceBase;
35
36 namespace autofill {
37
38 class AutofillProfile;
39 class AutofillTable;
40 class AutofillWebDataService;
41 class FormGroup;
42
43 extern const char kAutofillProfileTag[];
44
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 {
54  public:
55   virtual ~AutofillProfileSyncableService();
56
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);
64
65   // Retrieves the AutofillProfileSyncableService stored on |web_data_service|.
66   static AutofillProfileSyncableService* FromWebDataService(
67       AutofillWebDataService* web_data_service);
68
69   static syncer::ModelType model_type() { return syncer::AUTOFILL_PROFILE; }
70
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;
83
84   // AutofillWebDataServiceObserverOnDBThread implementation.
85   virtual void AutofillProfileChanged(
86       const AutofillProfileChange& change) OVERRIDE;
87
88   // Provides a StartSyncFlare to the SyncableService. See
89   // sync_start_util for more.
90   void InjectStartSyncFlare(
91       const syncer::SyncableService::StartSyncFlare& flare);
92
93  protected:
94   AutofillProfileSyncableService(AutofillWebDataBackend* webdata_backend,
95                                  const std::string& app_locale);
96
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.
101   struct DataBundle;
102
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);
107
108   // Helper to persist any changes that occured during model association to
109   // the WebDatabase.
110   // Made virtual for ease of mocking in unit tests.
111   virtual bool SaveChangesToWebData(const DataBundle& bundle);
112
113   // For unit tests.
114   AutofillProfileSyncableService();
115   void set_sync_processor(syncer::SyncChangeProcessor* sync_processor) {
116     sync_processor_.reset(sync_processor);
117   }
118
119   // Creates syncer::SyncData based on supplied |profile|.
120   // Exposed for unit tests.
121   static syncer::SyncData CreateData(const AutofillProfile& profile);
122
123  private:
124   friend class ::ProfileSyncServiceAutofillTest;
125   FRIEND_TEST_ALL_PREFIXES(AutofillProfileSyncableServiceTest,
126                            UpdateField);
127   FRIEND_TEST_ALL_PREFIXES(AutofillProfileSyncableServiceTest,
128                            UpdateMultivaluedField);
129   FRIEND_TEST_ALL_PREFIXES(AutofillProfileSyncableServiceTest,
130                            MergeProfile);
131
132   // The map of the guid to profiles owned by the |profiles_| vector.
133   typedef std::map<std::string, AutofillProfile*> GUIDToProfileMap;
134
135   // Helper function that overwrites |profile| with data from proto-buffer
136   // |specifics|.
137   static bool OverwriteProfileWithServerData(
138       const sync_pb::AutofillProfileSpecifics& specifics,
139       AutofillProfile* profile,
140       const std::string& app_locale);
141
142   // Writes |profile| data into supplied |profile_specifics|.
143   static void WriteAutofillProfile(const AutofillProfile& profile,
144                                    sync_pb::EntitySpecifics* profile_specifics);
145
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);
150
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,
159       DataBundle* bundle);
160
161   // Syncs |change| to the cloud.
162   void ActOnChange(const AutofillProfileChange& change);
163
164   AutofillTable* GetAutofillTable() const;
165
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);
176
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);
185
186   AutofillWebDataBackend* webdata_backend_;  // WEAK
187   std::string app_locale_;
188   ScopedObserver<AutofillWebDataBackend,
189                  AutofillProfileSyncableService> scoped_observer_;
190
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_;
195
196   scoped_ptr<syncer::SyncChangeProcessor> sync_processor_;
197
198   scoped_ptr<syncer::SyncErrorFactory> sync_error_factory_;
199
200   syncer::SyncableService::StartSyncFlare flare_;
201
202   DISALLOW_COPY_AND_ASSIGN(AutofillProfileSyncableService);
203 };
204
205 // This object is used in unit tests as well, so it defined here.
206 struct AutofillProfileSyncableService::DataBundle {
207   DataBundle();
208   ~DataBundle();
209
210   std::vector<std::string> profiles_to_delete;
211   std::vector<AutofillProfile*> profiles_to_update;
212   std::vector<AutofillProfile*> profiles_to_add;
213
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;
219 };
220
221 }  // namespace autofill
222
223 #endif  // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_PROFILE_SYNCABLE_SERVICE_H_