| 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
|
|
|