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_PROFILE_MODEL_ASSOCIATOR_H_ 6 #define CHROME_BROWSER_SYNC_GLUE_AUTOFILL_PROFILE_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 extern const char kAutofillProfileTag[]; 35 36 class AutofillChangeProcessor; 37 class UnrecoverableErrorHandler; 38 39 // Contains all model association related logic: 40 // * Algorithm to associate autofill model and sync model. 41 // We do not check if we have local data before this run; we always 42 // merge and sync. 43 class AutofillProfileModelAssociator 44 : public PerDataTypeAssociatorInterface<std::string, std::string> { 45 public: 46 AutofillProfileModelAssociator(ProfileSyncService* sync_service, 47 WebDatabase* web_database, 48 PersonalDataManager* data_manager); 49 virtual ~AutofillProfileModelAssociator(); 50 51 // A convenience wrapper of a bunch of state we pass around while 52 // associating models, and send to the WebDatabase for persistence. 53 // We do this so we hold the write lock for only a small period. 54 // When storing the web db we are out of the write lock. 55 struct DataBundle; 56 model_type()57 static syncable::ModelType model_type() { return syncable::AUTOFILL_PROFILE; } 58 59 // PerDataTypeAssociatorInterface implementation. 60 // 61 // Iterates through the sync model looking for matched pairs of items. 62 virtual bool AssociateModels(); 63 64 // Clears all associations. 65 virtual bool DisassociateModels(); 66 67 // TODO(lipalani) Bug 64111. 68 // The has_nodes out param is true if the sync model has nodes other 69 // than the permanent tagged nodes. 70 virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes); 71 72 // See ModelAssociator interface. 73 virtual void AbortAssociation(); 74 75 // See ModelAssociator interface. 76 virtual bool CryptoReadyIfNecessary(); 77 78 virtual const std::string* GetChromeNodeFromSyncId(int64 sync_id); 79 80 virtual bool InitSyncNodeFromChromeId(const std::string& node_id, 81 sync_api::BaseNode* sync_node); 82 83 // Returns the sync id for the given autofill name, or sync_api::kInvalidId 84 // if the autofill name is not associated to any sync id. 85 virtual int64 GetSyncIdFromChromeId(const std::string& node_id); 86 87 // Associates the given autofill name with the given sync id. 88 virtual void Associate(const std::string* node, int64 sync_id); 89 90 // Remove the association that corresponds to the given sync id. 91 virtual void Disassociate(int64 sync_id); 92 93 // TODO(lipalani) Bug 64111. Returns whether a node with the 94 // given permanent tag was found and update 95 // |sync_id| with that node's id. No current use. To Implement 96 // only for completeness. 97 virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id); 98 99 static bool OverwriteProfileWithServerData( 100 AutofillProfile* merge_into, 101 const sync_pb::AutofillProfileSpecifics& specifics); 102 103 protected: 104 AutofillProfileModelAssociator(); 105 bool TraverseAndAssociateChromeAutofillProfiles( 106 sync_api::WriteTransaction* write_trans, 107 const sync_api::ReadNode& autofill_root, 108 const std::vector<AutofillProfile*>& all_profiles_from_db, 109 std::set<std::string>* current_profiles, 110 std::vector<AutofillProfile*>* updated_profiles, 111 std::vector<AutofillProfile*>* new_profiles, 112 std::vector<std::string>* profiles_to_delete); 113 114 // Helper to insert an AutofillProfile into the WebDatabase (e.g. in response 115 // to encountering a sync node that doesn't exist yet locally). 116 virtual void AddNativeProfileIfNeeded( 117 const sync_pb::AutofillProfileSpecifics& profile, 118 DataBundle* bundle, 119 const sync_api::ReadNode& node); 120 121 // Helper to insert a sync node for the given AutofillProfile (e.g. in 122 // response to encountering a native profile that doesn't exist yet in the 123 // cloud). 124 virtual bool MakeNewAutofillProfileSyncNodeIfNeeded( 125 sync_api::WriteTransaction* trans, 126 const sync_api::BaseNode& autofill_root, 127 const AutofillProfile& profile, 128 std::vector<AutofillProfile*>* new_profiles, 129 std::set<std::string>* current_profiles, 130 std::vector<std::string>* profiles_to_delete); 131 132 // Once the above traversals are complete, we traverse the sync model to 133 // associate all remaining nodes. 134 bool TraverseAndAssociateAllSyncNodes( 135 sync_api::WriteTransaction* write_trans, 136 const sync_api::ReadNode& autofill_root, 137 DataBundle* bundle); 138 139 private: 140 typedef std::map<std::string, int64> AutofillToSyncIdMap; 141 typedef std::map<int64, std::string> SyncIdToAutofillMap; 142 143 // A convenience wrapper of a bunch of state we pass around while associating 144 // models, and send to the WebDatabase for persistence. 145 // struct DataBundle; 146 147 // Helper to query WebDatabase for the current autofill state. 148 bool LoadAutofillData(std::vector<AutofillProfile*>* profiles); 149 150 static bool MergeField(FormGroup* f, 151 AutofillFieldType t, 152 const std::string& specifics_field); 153 154 // Helper to persist any changes that occured during model association to 155 // the WebDatabase. 156 bool SaveChangesToWebData(const DataBundle& bundle); 157 158 // Called at various points in model association to determine if the 159 // user requested an abort. 160 bool IsAbortPending(); 161 162 int64 FindSyncNodeWithProfile(sync_api::WriteTransaction* trans, 163 const sync_api::BaseNode& autofill_root, 164 const AutofillProfile& profile, 165 std::set<std::string>* current_profiles); 166 167 ProfileSyncService* sync_service_; 168 WebDatabase* web_database_; 169 PersonalDataManager* personal_data_; 170 int64 autofill_node_id_; 171 172 AutofillToSyncIdMap id_map_; 173 SyncIdToAutofillMap id_map_inverse_; 174 175 // Abort association pending flag and lock. If this is set to true 176 // (via the AbortAssociation method), return from the 177 // AssociateModels method as soon as possible. 178 base::Lock abort_association_pending_lock_; 179 bool abort_association_pending_; 180 181 int number_of_profiles_created_; 182 183 DISALLOW_COPY_AND_ASSIGN(AutofillProfileModelAssociator); 184 }; 185 186 struct AutofillProfileModelAssociator::DataBundle { 187 DataBundle(); 188 ~DataBundle(); 189 190 std::set<std::string> current_profiles; 191 std::vector<std::string> profiles_to_delete; 192 std::vector<AutofillProfile*> updated_profiles; 193 std::vector<AutofillProfile*> new_profiles; // We own these pointers. 194 }; 195 196 } // namespace browser_sync 197 198 #endif // CHROME_BROWSER_SYNC_GLUE_AUTOFILL_PROFILE_MODEL_ASSOCIATOR_H_ 199 200