autofill_model_associator.h revision ddb351dbec246cf1fab5ec20d2d5520909041de1
1// Copyright (c) 2011 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
5#ifndef CHROME_BROWSER_SYNC_GLUE_AUTOFILL_MODEL_ASSOCIATOR_H_
6#define CHROME_BROWSER_SYNC_GLUE_AUTOFILL_MODEL_ASSOCIATOR_H_
7#pragma once
8
9#include <map>
10#include <set>
11#include <string>
12#include <vector>
13
14#include "base/basictypes.h"
15#include "base/memory/ref_counted.h"
16#include "base/synchronization/lock.h"
17#include "chrome/browser/autofill/personal_data_manager.h"
18#include "chrome/browser/sync/engine/syncapi.h"
19#include "chrome/browser/sync/glue/model_associator.h"
20#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
21#include "chrome/browser/webdata/autofill_entry.h"
22
23class AutofillProfile;
24
25class ProfileSyncService;
26class WebDatabase;
27
28namespace sync_api {
29class WriteTransaction;
30}
31
32namespace browser_sync {
33
34class AutofillChangeProcessor;
35class UnrecoverableErrorHandler;
36
37extern const char kAutofillTag[];
38extern const char kAutofillProfileNamespaceTag[];
39extern const char kAutofillEntryNamespaceTag[];
40
41// Contains all model association related logic:
42// * Algorithm to associate autofill model and sync model.
43// We do not check if we have local data before this run; we always
44// merge and sync.
45class AutofillModelAssociator
46    : public PerDataTypeAssociatorInterface<std::string, std::string> {
47 public:
48  static syncable::ModelType model_type() { return syncable::AUTOFILL; }
49  AutofillModelAssociator(ProfileSyncService* sync_service,
50                          WebDatabase* web_database,
51                          PersonalDataManager* data_manager);
52  virtual ~AutofillModelAssociator();
53
54  // PerDataTypeAssociatorInterface implementation.
55  //
56  // Iterates through the sync model looking for matched pairs of items.
57  virtual bool AssociateModels();
58
59  // Clears all associations.
60  virtual bool DisassociateModels();
61
62  // The has_nodes out param is true if the sync model has nodes other
63  // than the permanent tagged nodes.
64  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
65
66  // See ModelAssociator interface.
67  virtual void AbortAssociation();
68
69  // See ModelAssociator interface.
70  virtual bool CryptoReadyIfNecessary();
71
72  // Not implemented.
73  virtual const std::string* GetChromeNodeFromSyncId(int64 sync_id);
74
75  // Not implemented.
76  virtual bool InitSyncNodeFromChromeId(const std::string& node_id,
77                                        sync_api::BaseNode* sync_node);
78
79  // Returns the sync id for the given autofill name, or sync_api::kInvalidId
80  // if the autofill name is not associated to any sync id.
81  virtual int64 GetSyncIdFromChromeId(const std::string& node_id);
82
83  // Associates the given autofill name with the given sync id.
84  virtual void Associate(const std::string* node, int64 sync_id);
85
86  // Remove the association that corresponds to the given sync id.
87  virtual void Disassociate(int64 sync_id);
88
89  // Returns whether a node with the given permanent tag was found and update
90  // |sync_id| with that node's id.
91  virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
92
93  static std::string KeyToTag(const string16& name, const string16& value);
94
95  static bool MergeTimestamps(const sync_pb::AutofillSpecifics& autofill,
96                              const std::vector<base::Time>& timestamps,
97                              std::vector<base::Time>* new_timestamps);
98  static bool FillProfileWithServerData(
99      AutofillProfile* merge_into,
100      const sync_pb::AutofillProfileSpecifics& specifics);
101
102  // TODO(georgey) : add the same processing for CC info (already in protocol
103  // buffers).
104
105  // Is called to determine if we need to upgrade to the new
106  // autofillprofile2 data type. If so we need to sync up autofillprofile
107  // first to the latest available changes on the server and then upgrade
108  // to autofillprofile2.
109  virtual bool HasNotMigratedYet(const sync_api::BaseTransaction* trans);
110
111 protected:
112  // Given a profile from sync db it tries to match the profile against
113  // one in web db. it ignores the guid and compares the actual data.
114  AutofillProfile* FindCorrespondingNodeFromWebDB(
115      const sync_pb::AutofillProfileSpecifics& profile,
116      const std::vector<AutofillProfile*>& all_profiles_from_db);
117
118 private:
119  typedef std::map<std::string, int64> AutofillToSyncIdMap;
120  typedef std::map<int64, std::string> SyncIdToAutofillMap;
121
122  // A convenience wrapper of a bunch of state we pass around while associating
123  // models, and send to the WebDatabase for persistence.
124  struct DataBundle;
125
126  // Helper to query WebDatabase for the current autofill state.
127  bool LoadAutofillData(std::vector<AutofillEntry>* entries,
128                        std::vector<AutofillProfile*>* profiles);
129
130  // We split up model association first by autofill sub-type (entries, and
131  // profiles.  There is a Traverse* method for each of these.
132  bool TraverseAndAssociateChromeAutofillEntries(
133      sync_api::WriteTransaction* write_trans,
134      const sync_api::ReadNode& autofill_root,
135      const std::vector<AutofillEntry>& all_entries_from_db,
136      std::set<AutofillKey>* current_entries,
137      std::vector<AutofillEntry>* new_entries);
138  bool TraverseAndAssociateChromeAutofillProfiles(
139      sync_api::WriteTransaction* write_trans,
140      const sync_api::ReadNode& autofill_root,
141      const std::vector<AutofillProfile*>& all_profiles_from_db,
142      std::set<string16>* current_profiles,
143      std::vector<AutofillProfile*>* updated_profiles);
144
145  // Once the above traversals are complete, we traverse the sync model to
146  // associate all remaining nodes.
147  bool TraverseAndAssociateAllSyncNodes(
148      sync_api::WriteTransaction* write_trans,
149      const sync_api::ReadNode& autofill_root,
150      DataBundle* bundle,
151      const std::vector<AutofillProfile*>& all_profiles_from_db);
152
153  // Helper to persist any changes that occured during model association to
154  // the WebDatabase.
155  bool SaveChangesToWebData(const DataBundle& bundle);
156
157  // Helper to insert an AutofillEntry into the WebDatabase (e.g. in response
158  // to encountering a sync node that doesn't exist yet locally).
159  void AddNativeEntryIfNeeded(const sync_pb::AutofillSpecifics& autofill,
160                              DataBundle* bundle,
161                              const sync_api::ReadNode& node);
162
163  // Helper to insert an AutofillProfile into the WebDatabase (e.g. in response
164  // to encountering a sync node that doesn't exist yet locally).
165  void AddNativeProfileIfNeeded(
166      const sync_pb::AutofillProfileSpecifics& profile,
167      DataBundle* bundle,
168      const sync_api::ReadNode& node,
169      const std::vector<AutofillProfile*>& all_profiles_from_db);
170
171  // Called at various points in model association to determine if the
172  // user requested an abort.
173  bool IsAbortPending();
174
175  ProfileSyncService* sync_service_;
176  WebDatabase* web_database_;
177  PersonalDataManager* personal_data_;
178  int64 autofill_node_id_;
179
180  AutofillToSyncIdMap id_map_;
181  SyncIdToAutofillMap id_map_inverse_;
182
183  // Abort association pending flag and lock.  If this is set to true
184  // (via the AbortAssociation method), return from the
185  // AssociateModels method as soon as possible.
186  base::Lock abort_association_pending_lock_;
187  bool abort_association_pending_;
188  int number_of_entries_created_;
189
190  DISALLOW_COPY_AND_ASSIGN(AutofillModelAssociator);
191};
192
193}  // namespace browser_sync
194
195#endif  // CHROME_BROWSER_SYNC_GLUE_AUTOFILL_MODEL_ASSOCIATOR_H_
196