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 23 class AutofillProfile; 24 25 class ProfileSyncService; 26 class WebDatabase; 27 28 namespace sync_api { 29 class WriteTransaction; 30 } 31 32 namespace browser_sync { 33 34 class AutofillChangeProcessor; 35 class UnrecoverableErrorHandler; 36 37 extern const char kAutofillTag[]; 38 extern const char kAutofillProfileNamespaceTag[]; 39 extern 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. 45 class 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