Index: chrome/browser/sync/glue/autofill_model_associator.cc |
diff --git a/chrome/browser/sync/glue/autofill_model_associator.cc b/chrome/browser/sync/glue/autofill_model_associator.cc |
index b550ab54b105160eaf6838ae3770c5f484d652e8..ab15f65cab63c9d395b5d29a6c1af9108dfd8014 100644 |
--- a/chrome/browser/sync/glue/autofill_model_associator.cc |
+++ b/chrome/browser/sync/glue/autofill_model_associator.cc |
@@ -12,6 +12,7 @@ |
#include "base/utf_string_conversions.h" |
#include "chrome/browser/autofill/autofill_profile.h" |
#include "chrome/browser/browser_thread.h" |
+#include "chrome/browser/guid.h" |
#include "chrome/browser/profile.h" |
#include "chrome/browser/sync/engine/syncapi.h" |
#include "chrome/browser/sync/glue/autofill_change_processor.h" |
@@ -26,9 +27,6 @@ namespace browser_sync { |
const char kAutofillTag[] = "google_chrome_autofill"; |
const char kAutofillEntryNamespaceTag[] = "autofill_entry|"; |
-const char kAutofillProfileNamespaceTag[] = "autofill_profile|"; |
- |
-static const int kMaxNumAttemptsToFindUniqueLabel = 100; |
struct AutofillModelAssociator::DataBundle { |
std::set<AutofillKey> current_entries; |
@@ -123,87 +121,6 @@ bool AutofillModelAssociator::TraverseAndAssociateChromeAutofillEntries( |
return true; |
} |
-bool AutofillModelAssociator::TraverseAndAssociateChromeAutoFillProfiles( |
- sync_api::WriteTransaction* write_trans, |
- const sync_api::ReadNode& autofill_root, |
- const std::vector<AutoFillProfile*>& all_profiles_from_db, |
- std::set<string16>* current_profiles, |
- std::vector<AutoFillProfile*>* updated_profiles) { |
- const std::vector<AutoFillProfile*>& profiles = all_profiles_from_db; |
- for (std::vector<AutoFillProfile*>::const_iterator ix = profiles.begin(); |
- ix != profiles.end(); ++ix) { |
- string16 label((*ix)->Label()); |
- std::string tag(ProfileLabelToTag(label)); |
- |
- sync_api::ReadNode node(write_trans); |
- if (node.InitByClientTagLookup(syncable::AUTOFILL, tag)) { |
- const sync_pb::AutofillSpecifics& autofill(node.GetAutofillSpecifics()); |
- DCHECK(autofill.has_profile()); |
- DCHECK_EQ(ProfileLabelToTag(UTF8ToUTF16(autofill.profile().label())), |
- tag); |
- int64 sync_id = node.GetId(); |
- if (id_map_.find(tag) != id_map_.end()) { |
- // We just looked up something we already associated. Move aside. |
- label = MakeUniqueLabel(label, string16(), write_trans); |
- if (label.empty()) { |
- return false; |
- } |
- tag = ProfileLabelToTag(label); |
- // TODO(dhollowa): Replace with |AutoFillProfile::set_guid|. |
- // http://crbug.com/58813 |
- (*ix)->set_label(label); |
- if (!MakeNewAutofillProfileSyncNode(write_trans, autofill_root, |
- tag, **ix, &sync_id)) { |
- return false; |
- } |
- updated_profiles->push_back(*ix); |
- } else { |
- // Overwrite local with cloud state. |
- if (OverwriteProfileWithServerData(*ix, autofill.profile())) |
- updated_profiles->push_back(*ix); |
- sync_id = node.GetId(); |
- } |
- |
- Associate(&tag, sync_id); |
- } else { |
- int64 id; |
- if (!MakeNewAutofillProfileSyncNode(write_trans, autofill_root, |
- tag, **ix, &id)) { |
- return false; |
- } |
- Associate(&tag, id); |
- } |
- current_profiles->insert(label); |
- } |
- return true; |
-} |
- |
-// static |
-string16 AutofillModelAssociator::MakeUniqueLabel( |
- const string16& non_unique_label, |
- const string16& existing_unique_label, |
- sync_api::BaseTransaction* trans) { |
- if (!non_unique_label.empty() && non_unique_label == existing_unique_label) { |
- return existing_unique_label; |
- } |
- int unique_id = 1; // Priming so we start by appending "2". |
- while (unique_id++ < kMaxNumAttemptsToFindUniqueLabel) { |
- string16 suffix(base::IntToString16(unique_id)); |
- string16 unique_label = non_unique_label + suffix; |
- if (unique_label == existing_unique_label) |
- return unique_label; // We'll use the one we already have. |
- sync_api::ReadNode node(trans); |
- if (node.InitByClientTagLookup(syncable::AUTOFILL, |
- ProfileLabelToTag(unique_label))) { |
- continue; |
- } |
- return unique_label; |
- } |
- |
- LOG(ERROR) << "Couldn't create unique tag for autofill node. Srsly?!"; |
- return string16(); |
-} |
- |
bool AutofillModelAssociator::MakeNewAutofillProfileSyncNode( |
sync_api::WriteTransaction* trans, const sync_api::BaseNode& autofill_root, |
const std::string& tag, const AutoFillProfile& profile, int64* sync_id) { |
@@ -265,12 +182,17 @@ bool AutofillModelAssociator::AssociateModels() { |
} |
if (!TraverseAndAssociateChromeAutofillEntries(&trans, autofill_root, |
- entries, &bundle.current_entries, &bundle.new_entries) || |
- !TraverseAndAssociateChromeAutoFillProfiles(&trans, autofill_root, |
- profiles.get(), &bundle.current_profiles, |
- &bundle.updated_profiles) || |
- !TraverseAndAssociateAllSyncNodes(&trans, autofill_root, &bundle)) { |
- return false; |
+ entries, &bundle.current_entries, &bundle.new_entries)) { |
+ return false; |
+ } |
+ if(IsUpgrading()) { |
+ if(!TraverseAndAssociateAllSyncNodes( |
+ &trans, |
+ autofill_root, |
+ &bundle, |
+ profiles.get())) { |
+ return false; |
+ } |
} |
} |
@@ -319,7 +241,8 @@ bool AutofillModelAssociator::SaveChangesToWebData(const DataBundle& bundle) { |
bool AutofillModelAssociator::TraverseAndAssociateAllSyncNodes( |
sync_api::WriteTransaction* write_trans, |
const sync_api::ReadNode& autofill_root, |
- DataBundle* bundle) { |
+ DataBundle* bundle, |
+ std::vector<AutoFillProfile*>& all_profiles_from_db) { |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
int64 sync_child_id = autofill_root.GetFirstChildId(); |
@@ -334,8 +257,13 @@ bool AutofillModelAssociator::TraverseAndAssociateAllSyncNodes( |
if (autofill.has_value()) |
AddNativeEntryIfNeeded(autofill, bundle, sync_child); |
- else if (autofill.has_profile()) |
- AddNativeProfileIfNeeded(autofill.profile(), bundle, sync_child); |
+ else if (autofill.has_profile()) { |
+ DCHECK(IsUpgrading()); |
+ AddNativeProfileIfNeeded( |
+ autofill.profile(), |
+ bundle, sync_child, |
+ all_profiles_from_db); |
+ } |
else |
NOTREACHED() << "AutofillSpecifics has no autofill data!"; |
@@ -344,6 +272,50 @@ bool AutofillModelAssociator::TraverseAndAssociateAllSyncNodes( |
return true; |
} |
+// [TODO] fix the p1 and p2. |
+bool CompareAutofillProfiles(const AutoFillProfile& p1, |
+ const AutoFillProfile& p2) |
+{ |
+ if(p1.Compare(p2) == 0) |
+ return true; |
+ else return false; |
+} |
+ |
+// Define the functor to be used as the predicate in find_if call. |
+struct CompareProfiles : |
+ public std::binary_function<AutoFillProfile*, |
+ AutoFillProfile*, |
+ bool> { |
+ bool operator() (AutoFillProfile* p1, AutoFillProfile* p2) const { |
+ return CompareAutofillProfiles(*p1, *p2); |
+ } |
+ |
+}; |
+ |
+AutoFillProfile* AutofillModelAssociator::FindCorrespondingNodeFromWebDB( |
+ const sync_pb::AutofillProfileSpecifics& profile, |
+ const std::vector<AutoFillProfile*>& all_profiles_from_db) { |
+ |
+ static std::string guid(guid::GenerateGUID()); |
+ AutoFillProfile p; |
+ p.set_guid(guid); |
+ if(!OverwriteProfileWithServerData(&p, profile)) |
+ { |
+ // Not a big deal. We encountered an error. Just say this profile does not |
+ // exist. |
+ LOG(ERROR) << " Profile could not be associated"; |
+ return NULL; |
+ } |
+ |
+ // Now instantiate the functor and call find_if. |
+ std::vector<AutoFillProfile*>::const_iterator ix = |
+ std::find_if(all_profiles_from_db.begin(), |
+ all_profiles_from_db.end(), |
+ std::bind2nd(CompareProfiles(), &p)); |
+ |
+ return (ix == all_profiles_from_db.end()) ? NULL : *ix; |
+} |
+ |
void AutofillModelAssociator::AddNativeEntryIfNeeded( |
const sync_pb::AutofillSpecifics& autofill, DataBundle* bundle, |
const sync_api::ReadNode& node) { |
@@ -364,21 +336,31 @@ void AutofillModelAssociator::AddNativeEntryIfNeeded( |
} |
void AutofillModelAssociator::AddNativeProfileIfNeeded( |
- const sync_pb::AutofillProfileSpecifics& profile, DataBundle* bundle, |
- const sync_api::ReadNode& node) { |
+ const sync_pb::AutofillProfileSpecifics& profile, |
+ DataBundle* bundle, |
+ const sync_api::ReadNode& node, |
+ std::vector<AutoFillProfile*>& all_profiles_from_db) { |
+ |
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
- if (bundle->current_profiles.find(UTF8ToUTF16(profile.label())) == |
- bundle->current_profiles.end()) { |
- std::string tag(ProfileLabelToTag(UTF8ToUTF16(profile.label()))); |
- Associate(&tag, node.GetId()); |
- AutoFillProfile* p = personal_data_-> |
- CreateNewEmptyAutoFillProfileForDBThread(UTF8ToUTF16(profile.label())); |
+ |
+ scoped_ptr<AutoFillProfile> profile_in_web_db(FindCorrespondingNodeFromWebDB( |
+ profile, all_profiles_from_db)); |
+ |
+ if(profile_in_web_db.get() != NULL) { |
+ int64 sync_id = node.GetId(); |
+ Associate(&(profile_in_web_db->guid()), sync_id); |
+ return; |
+ } else { // Create a new node. |
+ std::string guid = guid::GenerateGUID(); |
+ Associate(&guid, node.GetId()); |
+ AutoFillProfile* p = new AutoFillProfile(guid); |
OverwriteProfileWithServerData(p, profile); |
bundle->new_profiles.push_back(p); |
} |
} |
bool AutofillModelAssociator::DisassociateModels() { |
+ |
id_map_.clear(); |
id_map_inverse_.clear(); |
return true; |
@@ -417,7 +399,8 @@ void AutofillModelAssociator::AbortAssociation() { |
const std::string* |
AutofillModelAssociator::GetChromeNodeFromSyncId(int64 sync_id) { |
- return NULL; |
+ SyncIdToAutofillMap::const_iterator iter = id_map_inverse_.find(sync_id); |
+ return iter == id_map_inverse_.end() ? NULL : &(iter->second); |
} |
bool AutofillModelAssociator::InitSyncNodeFromChromeId( |
@@ -476,12 +459,6 @@ std::string AutofillModelAssociator::KeyToTag(const string16& name, |
} |
// static |
-std::string AutofillModelAssociator::ProfileLabelToTag(const string16& label) { |
- std::string ns(kAutofillProfileNamespaceTag); |
- return ns + EscapePath(UTF16ToUTF8(label)); |
-} |
- |
-// static |
bool AutofillModelAssociator::MergeTimestamps( |
const sync_pb::AutofillSpecifics& autofill, |
const std::vector<base::Time>& timestamps, |
@@ -543,4 +520,9 @@ bool AutofillModelAssociator::OverwriteProfileWithServerData( |
return diff; |
} |
+bool AutofillModelAssociator::IsUpgrading() |
+{ |
+ return true; |
+} |
+ |
} // namespace browser_sync |