summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser')
-rwxr-xr-xchrome/browser/sync/engine/read_node_mock.h29
-rw-r--r--chrome/browser/sync/engine/syncapi.cc11
-rw-r--r--chrome/browser/sync/engine/syncapi.h24
-rwxr-xr-xchrome/browser/sync/engine/syncapi_mock.h26
-rw-r--r--chrome/browser/sync/glue/autofill_change_processor.cc201
-rw-r--r--chrome/browser/sync/glue/autofill_change_processor.h35
-rwxr-xr-xchrome/browser/sync/glue/autofill_change_processor2.cc584
-rwxr-xr-xchrome/browser/sync/glue/autofill_change_processor2.h172
-rw-r--r--chrome/browser/sync/glue/autofill_model_associator.cc192
-rw-r--r--chrome/browser/sync/glue/autofill_model_associator.h31
-rwxr-xr-xchrome/browser/sync/glue/autofill_model_associator2.cc547
-rwxr-xr-xchrome/browser/sync/glue/autofill_model_associator2.h212
-rw-r--r--chrome/browser/sync/glue/autofill_model_associator_unittest.cc12
-rwxr-xr-xchrome/browser/sync/glue/autofill_profile_model_associator.cc371
-rwxr-xr-xchrome/browser/sync/glue/autofill_profile_model_associator_unittest.cc261
-rw-r--r--chrome/browser/sync/profile_sync_factory_impl.cc38
-rw-r--r--chrome/browser/sync/profile_sync_service_autofill_unittest.cc26
-rw-r--r--chrome/browser/sync/syncable/model_type.cc12
-rw-r--r--chrome/browser/sync/syncable/model_type.h2
-rw-r--r--chrome/browser/sync/syncable/syncable.cc20
-rw-r--r--chrome/browser/sync/syncable/syncable.h18
-rwxr-xr-xchrome/browser/sync/syncable/syncable_mock.h40
22 files changed, 358 insertions, 2506 deletions
diff --git a/chrome/browser/sync/engine/read_node_mock.h b/chrome/browser/sync/engine/read_node_mock.h
deleted file mode 100755
index f13eddd..0000000
--- a/chrome/browser/sync/engine/read_node_mock.h
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SYNC_ENGINE_READ_NODE_MOCK_H_
-#define CHROME_BROWSER_SYNC_ENGINE_READ_NODE_MOCK_H_
-#pragma once
-
-#include <string>
-
-#include "chrome/browser/sync/engine/syncapi.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-class ReadNodeMock : public sync_api::ReadNode {
- public:
- ReadNodeMock() { }
- virtual ~ReadNodeMock() {}
- MOCK_METHOD2(InitByClientTagLookup,
- bool(syncable::ModelType model_type, const std::string& tag));
- MOCK_CONST_METHOD0(GetAutofillProfileSpecifics,
- const sync_pb::AutofillProfileSpecifics&());
- MOCK_CONST_METHOD0(GetId, int64());
- MOCK_CONST_METHOD0(GetFirstChildId, int64());
- MOCK_CONST_METHOD0(GetFirstChild, int64());
- MOCK_CONST_METHOD0(GetSuccessorId, int64());
- MOCK_METHOD1(InitByIdLookup, bool(int64 id));
-};
-#endif // CHROME_BROWSER_SYNC_ENGINE_READ_NODE_MOCK_H_
-
diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc
index bc34982..5a71eb8 100644
--- a/chrome/browser/sync/engine/syncapi.cc
+++ b/chrome/browser/sync/engine/syncapi.cc
@@ -83,7 +83,6 @@ using syncable::Directory;
using syncable::DirectoryManager;
using syncable::Entry;
using syncable::SPECIFICS;
-using sync_pb::AutofillProfileSpecifics;
typedef GoogleServiceAuthError AuthError;
@@ -282,11 +281,6 @@ const sync_pb::AutofillSpecifics& BaseNode::GetAutofillSpecifics() const {
return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::autofill);
}
-const AutofillProfileSpecifics& BaseNode::GetAutofillProfileSpecifics() const {
- DCHECK_EQ(GetModelType(), syncable::AUTOFILL_PROFILE);
- return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::autofill_profile);
-}
-
const sync_pb::BookmarkSpecifics& BaseNode::GetBookmarkSpecifics() const {
DCHECK(GetModelType() == syncable::BOOKMARKS);
return GetEntry()->Get(SPECIFICS).GetExtension(sync_pb::bookmark);
@@ -763,11 +757,6 @@ ReadNode::ReadNode(const BaseTransaction* transaction)
DCHECK(transaction);
}
-ReadNode::ReadNode() {
- entry_ = NULL;
- transaction_ = NULL;
-}
-
ReadNode::~ReadNode() {
delete entry_;
}
diff --git a/chrome/browser/sync/engine/syncapi.h b/chrome/browser/sync/engine/syncapi.h
index 2019f41..95facaf 100644
--- a/chrome/browser/sync/engine/syncapi.h
+++ b/chrome/browser/sync/engine/syncapi.h
@@ -81,7 +81,6 @@ class WriteTransaction;
namespace sync_pb {
class AppSpecifics;
class AutofillSpecifics;
-class AutofillProfileSpecifics;
class BookmarkSpecifics;
class EntitySpecifics;
class ExtensionSpecifics;
@@ -150,7 +149,7 @@ class BaseNode {
// metahandle). These ids are strictly local handles. They will persist
// on this client, but the same object on a different client may have a
// different ID value.
- virtual int64 GetId() const;
+ int64 GetId() const;
// Nodes are hierarchically arranged into a single-rooted tree.
// InitByRootLookup on ReadNode allows access to the root. GetParentId is
@@ -196,9 +195,6 @@ class BaseNode {
// data. Can only be called if GetModelType() == AUTOFILL.
const sync_pb::AutofillSpecifics& GetAutofillSpecifics() const;
- virtual const sync_pb::AutofillProfileSpecifics&
- GetAutofillProfileSpecifics() const;
-
// Getter specific to the NIGORI datatype. Returns protobuf
// data. Can only be called if GetModelType() == NIGORI.
const sync_pb::NigoriSpecifics& GetNigoriSpecifics() const;
@@ -236,11 +232,11 @@ class BaseNode {
// Return the ID of the node immediately after this in the sibling order.
// For the last node in the ordering, return 0.
- virtual int64 GetSuccessorId() const;
+ int64 GetSuccessorId() const;
// Return the ID of the first child of this node. If this node has no
// children, return 0.
- virtual int64 GetFirstChildId() const;
+ int64 GetFirstChildId() const;
// These virtual accessors provide access to data members of derived classes.
virtual const syncable::Entry* GetEntry() const = 0;
@@ -260,7 +256,8 @@ class BaseNode {
bool DecryptIfNecessary(syncable::Entry* entry);
private:
- void* operator new(size_t size); // Node is meant for stack use only.
+ // Node is meant for stack use only.
+ void* operator new(size_t size);
// If this node represents a password, this field will hold the actual
// decrypted password data.
@@ -460,9 +457,6 @@ class ReadNode : public BaseNode {
virtual const syncable::Entry* GetEntry() const;
virtual const BaseTransaction* GetTransaction() const;
- protected:
- ReadNode();
-
private:
void* operator new(size_t size); // Node is meant for stack use only.
@@ -498,8 +492,6 @@ class BaseTransaction {
explicit BaseTransaction(UserShare* share);
virtual ~BaseTransaction();
- BaseTransaction() { lookup_= NULL; }
-
private:
// A syncable ScopedDirLookup, which is the parent of syncable transactions.
syncable::ScopedDirLookup* lookup_;
@@ -545,12 +537,6 @@ class WriteTransaction : public BaseTransaction {
virtual syncable::BaseTransaction* GetWrappedTrans() const;
syncable::WriteTransaction* GetWrappedWriteTrans() { return transaction_; }
- protected:
- WriteTransaction() {}
-
- void SetTransaction(syncable::WriteTransaction* trans) {
- transaction_ = trans;}
-
private:
void* operator new(size_t size); // Transaction is meant for stack use only.
diff --git a/chrome/browser/sync/engine/syncapi_mock.h b/chrome/browser/sync/engine/syncapi_mock.h
deleted file mode 100755
index ada0a56..0000000
--- a/chrome/browser/sync/engine/syncapi_mock.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCAPI_MOCK_H_
-#define CHROME_BROWSER_SYNC_ENGINE_SYNCAPI_MOCK_H_
-#pragma once
-
-#include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/syncable/syncable.h"
-#include "chrome/browser/sync/syncable/syncable_mock.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using sync_api::WriteTransaction;
-
-class MockWriteTransaction : public sync_api::WriteTransaction {
- public:
- explicit MockWriteTransaction(Directory* directory)
- : sync_api::WriteTransaction() {
- this->SetTransaction(new MockSyncableWriteTransaction(directory));
- }
-};
-
-#endif // CHROME_BROWSER_SYNC_ENGINE_SYNCAPI_MOCK_H_
-
diff --git a/chrome/browser/sync/glue/autofill_change_processor.cc b/chrome/browser/sync/glue/autofill_change_processor.cc
index d415950..d93f25d 100644
--- a/chrome/browser/sync/glue/autofill_change_processor.cc
+++ b/chrome/browser/sync/glue/autofill_change_processor.cc
@@ -9,10 +9,8 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
-#include "chrome/browser/guid.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/autofill/personal_data_manager.h"
-#include "chrome/browser/sync/glue/autofill_change_processor2.h"
#include "chrome/browser/sync/glue/autofill_model_associator.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/webdata/autofill_change.h"
@@ -75,10 +73,62 @@ void AutofillChangeProcessor::Observe(NotificationType type,
return;
}
- DCHECK(type.value == NotificationType::AUTOFILL_ENTRIES_CHANGED);
+ switch (type.value) {
+ case NotificationType::AUTOFILL_ENTRIES_CHANGED: {
+ AutofillChangeList* changes = Details<AutofillChangeList>(details).ptr();
+ ObserveAutofillEntriesChanged(changes, &trans, autofill_root);
+ break;
+ }
+ case NotificationType::AUTOFILL_PROFILE_CHANGED: {
+ AutofillProfileChange* change =
+ Details<AutofillProfileChange>(details).ptr();
+ ObserveAutofillProfileChanged(change, &trans, autofill_root);
+ break;
+ }
+ default:
+ NOTREACHED() << "Invalid NotificationType.";
+ }
+}
- AutofillChangeList* changes = Details<AutofillChangeList>(details).ptr();
- ObserveAutofillEntriesChanged(changes, &trans, autofill_root);
+void AutofillChangeProcessor::ChangeProfileLabelIfAlreadyTaken(
+ sync_api::BaseTransaction* trans,
+ const string16& pre_update_label,
+ AutoFillProfile* profile,
+ std::string* tag) {
+ DCHECK_EQ(AutofillModelAssociator::ProfileLabelToTag(profile->Label()),
+ *tag);
+ sync_api::ReadNode read_node(trans);
+ if (!pre_update_label.empty() && pre_update_label == profile->Label())
+ return;
+ if (read_node.InitByClientTagLookup(syncable::AUTOFILL, *tag)) {
+ // Handle the edge case of duplicate labels.
+ string16 new_label(AutofillModelAssociator::MakeUniqueLabel(
+ profile->Label(), pre_update_label, trans));
+ if (new_label.empty()) {
+ error_handler()->OnUnrecoverableError(FROM_HERE,
+ "No unique label; can't move aside");
+ return;
+ }
+ OverrideProfileLabel(new_label, profile, tag);
+ }
+}
+
+void AutofillChangeProcessor::OverrideProfileLabel(
+ const string16& new_label,
+ AutoFillProfile* profile_to_update,
+ std::string* tag_to_update) {
+ tag_to_update->assign(AutofillModelAssociator::ProfileLabelToTag(new_label));
+
+ profile_to_update->set_label(new_label);
+ if (!web_database_->UpdateAutoFillProfile(*profile_to_update)) {
+ std::string err = "Failed to overwrite label for node ";
+ err += UTF16ToUTF8(new_label);
+ error_handler()->OnUnrecoverableError(FROM_HERE, err);
+ return;
+ }
+
+ // Notify the PersonalDataManager that it's out of date.
+ PostOptimisticRefreshTask();
}
void AutofillChangeProcessor::PostOptimisticRefreshTask() {
@@ -87,6 +137,71 @@ void AutofillChangeProcessor::PostOptimisticRefreshTask() {
personal_data_));
}
+void AutofillChangeProcessor::AddAutofillProfileSyncNode(
+ sync_api::WriteTransaction* trans, const sync_api::BaseNode& autofill,
+ const std::string& tag, const AutoFillProfile* profile) {
+ sync_api::WriteNode sync_node(trans);
+ if (!sync_node.InitUniqueByCreation(syncable::AUTOFILL, autofill, tag)) {
+ error_handler()->OnUnrecoverableError(FROM_HERE,
+ "Failed to create autofill sync node.");
+ return;
+ }
+ sync_node.SetTitle(UTF8ToWide(tag));
+
+ WriteAutofillProfile(*profile, &sync_node);
+ model_associator_->Associate(&tag, sync_node.GetId());
+}
+
+void AutofillChangeProcessor::ObserveAutofillProfileChanged(
+ AutofillProfileChange* change, sync_api::WriteTransaction* trans,
+ const sync_api::ReadNode& autofill_root) {
+ std::string tag(AutofillModelAssociator::ProfileLabelToTag(change->key()));
+ switch (change->type()) {
+ case AutofillProfileChange::ADD: {
+ scoped_ptr<AutoFillProfile> clone(
+ static_cast<AutoFillProfile*>(change->profile()->Clone()));
+ DCHECK_EQ(clone->Label(), change->key());
+ ChangeProfileLabelIfAlreadyTaken(trans, string16(), clone.get(), &tag);
+ AddAutofillProfileSyncNode(trans, autofill_root, tag, clone.get());
+ break;
+ }
+ case AutofillProfileChange::UPDATE: {
+ scoped_ptr<AutoFillProfile> clone(
+ static_cast<AutoFillProfile*>(change->profile()->Clone()));
+ std::string pre_update_tag = AutofillModelAssociator::ProfileLabelToTag(
+ change->pre_update_label());
+ DCHECK_EQ(clone->Label(), change->key());
+ sync_api::WriteNode sync_node(trans);
+ ChangeProfileLabelIfAlreadyTaken(trans, change->pre_update_label(),
+ clone.get(), &tag);
+ if (pre_update_tag != tag) {
+ // If the label changes, replace the node instead of updating it.
+ RemoveSyncNode(pre_update_tag, trans);
+ AddAutofillProfileSyncNode(trans, autofill_root, tag, clone.get());
+ return;
+ }
+ int64 sync_id = model_associator_->GetSyncIdFromChromeId(tag);
+ if (sync_api::kInvalidId == sync_id) {
+ std::string err = "Unexpected notification for: " + tag;
+ error_handler()->OnUnrecoverableError(FROM_HERE, err);
+ return;
+ } else {
+ if (!sync_node.InitByIdLookup(sync_id)) {
+ error_handler()->OnUnrecoverableError(FROM_HERE,
+ "Autofill node lookup failed.");
+ return;
+ }
+ WriteAutofillProfile(*clone.get(), &sync_node);
+ }
+ break;
+ }
+ case AutofillProfileChange::REMOVE: {
+ RemoveSyncNode(tag, trans);
+ break;
+ }
+ }
+}
+
void AutofillChangeProcessor::ObserveAutofillEntriesChanged(
AutofillChangeList* changes, sync_api::WriteTransaction* trans,
const sync_api::ReadNode& autofill_root) {
@@ -209,8 +324,7 @@ void AutofillChangeProcessor::ApplyChangesFromSyncModel(
<< "Autofill specifics data not present on delete!";
const sync_pb::AutofillSpecifics& autofill =
changes[i].specifics.GetExtension(sync_pb::autofill);
- if (autofill.has_value() ||
- (HasNotMigratedYet() && autofill.has_profile())) {
+ if (autofill.has_value() || autofill.has_profile()) {
autofill_changes_.push_back(AutofillChangeRecord(changes[i].action,
changes[i].id,
autofill));
@@ -235,8 +349,7 @@ void AutofillChangeProcessor::ApplyChangesFromSyncModel(
const sync_pb::AutofillSpecifics& autofill(
sync_node.GetAutofillSpecifics());
int64 sync_id = sync_node.GetId();
- if (autofill.has_value() ||
- (HasNotMigratedYet() && autofill.has_profile())) {
+ if (autofill.has_value() || autofill.has_profile()) {
autofill_changes_.push_back(AutofillChangeRecord(changes[i].action,
sync_id, autofill));
} else {
@@ -261,8 +374,8 @@ void AutofillChangeProcessor::CommitChangesFromSyncModel() {
if (autofill_changes_[i].autofill_.has_value()) {
ApplySyncAutofillEntryDelete(autofill_changes_[i].autofill_);
} else if (autofill_changes_[i].autofill_.has_profile()) {
- DCHECK(HasNotMigratedYet());
- ApplySyncAutofillProfileDelete(autofill_changes_[i].id_);
+ ApplySyncAutofillProfileDelete(autofill_changes_[i].autofill_.profile(),
+ autofill_changes_[i].id_);
} else {
NOTREACHED() << "Autofill's CommitChanges received change with no"
" data!";
@@ -276,7 +389,6 @@ void AutofillChangeProcessor::CommitChangesFromSyncModel() {
autofill_changes_[i].autofill_, &new_entries,
autofill_changes_[i].id_);
} else if (autofill_changes_[i].autofill_.has_profile()) {
- DCHECK(HasNotMigratedYet());
ApplySyncAutofillProfileChange(autofill_changes_[i].action_,
autofill_changes_[i].autofill_.profile(),
autofill_changes_[i].id_);
@@ -336,42 +448,38 @@ void AutofillChangeProcessor::ApplySyncAutofillProfileChange(
int64 sync_id) {
DCHECK_NE(sync_api::SyncManager::ChangeRecord::ACTION_DELETE, action);
+ std::string tag(AutofillModelAssociator::ProfileLabelToTag(
+ UTF8ToUTF16(profile.label())));
switch (action) {
case sync_api::SyncManager::ChangeRecord::ACTION_ADD: {
- std::string guid(guid::GenerateGUID());
- scoped_ptr<AutoFillProfile> p(new AutoFillProfile);
- p->set_guid(guid);
- AutofillModelAssociator::FillProfileWithServerData(p.get(),
+ PersonalDataManager* pdm = model_associator_->sync_service()->
+ profile()->GetPersonalDataManager();
+ scoped_ptr<AutoFillProfile> p(
+ pdm->CreateNewEmptyAutoFillProfileForDBThread(
+ UTF8ToUTF16(profile.label())));
+ AutofillModelAssociator::OverwriteProfileWithServerData(p.get(),
profile);
+
+ model_associator_->Associate(&tag, sync_id);
if (!web_database_->AddAutoFillProfile(*p.get())) {
- NOTREACHED() << "Couldn't add autofill profile: " << guid;
+ NOTREACHED() << "Couldn't add autofill profile: " << profile.label();
return;
}
- model_associator_->Associate(&guid, sync_id);
break;
}
case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: {
- const std::string* guid = model_associator_->GetChromeNodeFromSyncId(
- sync_id);
- if (guid == NULL) {
- LOG(ERROR) << " Model association has not happened for " << sync_id;
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "model association has not happened");
+ AutoFillProfile* p = NULL;
+ string16 label = UTF8ToUTF16(profile.label());
+ if (!web_database_->GetAutoFillProfileForLabel(label, &p)) {
+ NOTREACHED() << "Couldn't retrieve autofill profile: " << label;
return;
}
- AutoFillProfile *temp_ptr;
- if (!web_database_->GetAutoFillProfileForGUID(*guid, &temp_ptr)) {
- LOG(ERROR) << "Autofill profile not found for " << *guid;
- return;
- }
-
- scoped_ptr<AutoFillProfile> p(temp_ptr);
-
- AutofillModelAssociator::FillProfileWithServerData(p.get(), profile);
- if (!web_database_->UpdateAutoFillProfile(*(p.get()))) {
- LOG(ERROR) << "Couldn't update autofill profile: " << guid;
+ AutofillModelAssociator::OverwriteProfileWithServerData(p, profile);
+ if (!web_database_->UpdateAutoFillProfile(*p)) {
+ NOTREACHED() << "Couldn't update autofill profile: " << label;
return;
}
+ delete p;
break;
}
default:
@@ -380,19 +488,20 @@ void AutofillChangeProcessor::ApplySyncAutofillProfileChange(
}
void AutofillChangeProcessor::ApplySyncAutofillProfileDelete(
+ const sync_pb::AutofillProfileSpecifics& profile,
int64 sync_id) {
-
- const std::string *guid = model_associator_->GetChromeNodeFromSyncId(sync_id);
- if (guid == NULL) {
- LOG(ERROR)<< "The profile is not associated";
+ string16 label(UTF8ToUTF16(profile.label()));
+ AutoFillProfile* ptr = NULL;
+ bool get_success = web_database_->GetAutoFillProfileForLabel(label, &ptr);
+ scoped_ptr<AutoFillProfile> p(ptr);
+ if (!get_success) {
+ NOTREACHED() << "Couldn't retrieve autofill profile: " << label;
return;
}
-
- if (!web_database_->RemoveAutoFillProfile(*guid)) {
- LOG(ERROR) << "Could not remove the profile";
+ if (!web_database_->RemoveAutoFillProfile(p->guid())) {
+ NOTREACHED() << "Couldn't remove autofill profile: " << label;
return;
}
-
model_associator_->Disassociate(sync_id);
}
@@ -411,6 +520,8 @@ void AutofillChangeProcessor::StartObserving() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
notification_registrar_.Add(this, NotificationType::AUTOFILL_ENTRIES_CHANGED,
NotificationService::AllSources());
+ notification_registrar_.Add(this, NotificationType::AUTOFILL_PROFILE_CHANGED,
+ NotificationService::AllSources());
}
void AutofillChangeProcessor::StopObserving() {
@@ -438,6 +549,7 @@ void AutofillChangeProcessor::WriteAutofillProfile(
const AutoFillProfile& profile, sync_api::WriteNode* node) {
sync_pb::AutofillSpecifics autofill;
sync_pb::AutofillProfileSpecifics* s(autofill.mutable_profile());
+ s->set_label(UTF16ToUTF8(profile.Label()));
s->set_name_first(UTF16ToUTF8(
profile.GetFieldText(AutoFillType(NAME_FIRST))));
s->set_name_middle(UTF16ToUTF8(
@@ -465,8 +577,5 @@ void AutofillChangeProcessor::WriteAutofillProfile(
AutoFillType(PHONE_HOME_WHOLE_NUMBER))));
node->SetAutofillSpecifics(autofill);
}
-bool AutofillChangeProcessor::HasNotMigratedYet() {
- return true;
-}
} // namespace browser_sync
diff --git a/chrome/browser/sync/glue/autofill_change_processor.h b/chrome/browser/sync/glue/autofill_change_processor.h
index e901c8e..7a84520 100644
--- a/chrome/browser/sync/glue/autofill_change_processor.h
+++ b/chrome/browser/sync/glue/autofill_change_processor.h
@@ -12,7 +12,6 @@
#include "chrome/browser/autofill/credit_card.h"
#include "chrome/browser/autofill/personal_data_manager.h"
#include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/glue/autofill_change_processor2.h"
#include "chrome/browser/sync/glue/change_processor.h"
#include "chrome/browser/sync/glue/sync_backend_host.h"
#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
@@ -105,15 +104,43 @@ class AutofillChangeProcessor : public ChangeProcessor,
void ApplySyncAutofillEntryDelete(
const sync_pb::AutofillSpecifics& autofill);
void ApplySyncAutofillProfileDelete(
+ const sync_pb::AutofillProfileSpecifics& profile,
int64 sync_id);
+ // If the chrome model tries to add an AutoFillProfile with a label that
+ // is already in use, we perform a move-aside by calling-back into the chrome
+ // model and overwriting the label with a unique value we can apply for sync.
+ // This method should be called on an ADD notification from the chrome model.
+ // |tag| contains the unique sync client tag identifier for |profile|, which
+ // is derived from the profile label using ProfileLabelToTag.
+ // |existing_unique_label| is the current label of the object, if any; this
+ // is an allowed value, because it's taken by the item in question.
+ // For new items, set |existing_unique_label| to the empty string.
+ void ChangeProfileLabelIfAlreadyTaken(
+ sync_api::BaseTransaction* trans,
+ const string16& existing_unique_label,
+ AutoFillProfile* profile,
+ std::string* tag);
+
+ // Reassign the label of the profile, write this back to the web database,
+ // and update |tag| with the tag corresponding to the new label.
+ void OverrideProfileLabel(
+ const string16& new_label,
+ AutoFillProfile* profile_to_update,
+ std::string* tag_to_update);
+
+ // Helper to create a sync node with tag |tag|, storing |profile| as
+ // the node's AutofillSpecifics.
+ void AddAutofillProfileSyncNode(
+ sync_api::WriteTransaction* trans,
+ const sync_api::BaseNode& autofill,
+ const std::string& tag,
+ const AutoFillProfile* profile);
+
// Helper to post a task to the UI loop to inform the PersonalDataManager
// it needs to refresh itself.
void PostOptimisticRefreshTask();
- // Called to see if we need to upgrade to the new autofill2 profile.
- bool HasNotMigratedYet();
-
// The two models should be associated according to this ModelAssociator.
AutofillModelAssociator* model_associator_;
diff --git a/chrome/browser/sync/glue/autofill_change_processor2.cc b/chrome/browser/sync/glue/autofill_change_processor2.cc
deleted file mode 100755
index b2b564e..0000000
--- a/chrome/browser/sync/glue/autofill_change_processor2.cc
+++ /dev/null
@@ -1,584 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/sync/glue/autofill_change_processor2.h"
-
-#include <string>
-#include <vector>
-
-#include "base/string_util.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/autofill/personal_data_manager.h"
-#include "chrome/browser/sync/glue/autofill_model_associator.h"
-#include "chrome/browser/sync/glue/autofill_model_associator2.h"
-#include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/browser/webdata/autofill_change.h"
-#include "chrome/browser/webdata/web_data_service.h"
-#include "chrome/browser/webdata/web_database.h"
-#include "chrome/common/notification_service.h"
-
-namespace browser_sync {
-
-class AutofillModelAssociator2;
-struct AutofillChangeProcessor2::AutofillChangeRecord {
- sync_api::SyncManager::ChangeRecord::Action action_;
- int64 id_;
- sync_pb::AutofillSpecifics autofill_;
- AutofillChangeRecord(sync_api::SyncManager::ChangeRecord::Action action,
- int64 id, const sync_pb::AutofillSpecifics& autofill)
- : action_(action),
- id_(id),
- autofill_(autofill) { }
-};
-
-AutofillChangeProcessor2::AutofillChangeProcessor2(
- AutofillModelAssociator2* model_associator,
- WebDatabase* web_database,
- PersonalDataManager* personal_data,
- UnrecoverableErrorHandler* error_handler)
- : ChangeProcessor(error_handler),
- model_associator_(model_associator),
- web_database_(web_database),
- personal_data_(personal_data),
- observing_(false) {
- DCHECK(model_associator);
- DCHECK(web_database);
- DCHECK(error_handler);
- DCHECK(personal_data);
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- StartObserving();
-}
-
-AutofillChangeProcessor2::~AutofillChangeProcessor2() {}
-
-void AutofillChangeProcessor2::Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details) {
- // Ensure this notification came from our web database.
- WebDataService* wds = Source<WebDataService>(source).ptr();
- if (!wds || wds->GetDatabase() != web_database_)
- return;
-
- DCHECK(running());
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- if (!observing_)
- return;
-
- sync_api::WriteTransaction trans(share_handle());
- sync_api::ReadNode autofill_root(&trans);
- if (!autofill_root.InitByTagLookup(kAutofillTag)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Server did not create the top-level autofill node. "
- "We might be running against an out-of-date server.");
- return;
- }
-
- switch (type.value) {
- case NotificationType::AUTOFILL_ENTRIES_CHANGED: {
- AutofillChangeList* changes = Details<AutofillChangeList>(details).ptr();
- ObserveAutofillEntriesChanged(changes, &trans, autofill_root);
- break;
- }
- case NotificationType::AUTOFILL_PROFILE_CHANGED: {
- AutofillProfileChange* change =
- Details<AutofillProfileChange>(details).ptr();
- ObserveAutofillProfileChanged(change, &trans, autofill_root);
- break;
- }
- default:
- NOTREACHED() << "Invalid NotificationType.";
- }
-}
-
-void AutofillChangeProcessor2::ChangeProfileLabelIfAlreadyTaken(
- sync_api::BaseTransaction* trans,
- const string16& pre_update_label,
- AutoFillProfile* profile,
- std::string* tag) {
- DCHECK_EQ(AutofillModelAssociator2::ProfileLabelToTag(profile->Label()),
- *tag);
- sync_api::ReadNode read_node(trans);
- if (!pre_update_label.empty() && pre_update_label == profile->Label())
- return;
- if (read_node.InitByClientTagLookup(syncable::AUTOFILL, *tag)) {
- // Handle the edge case of duplicate labels.
- string16 new_label(AutofillModelAssociator2::MakeUniqueLabel(
- profile->Label(), pre_update_label, trans));
- if (new_label.empty()) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "No unique label; can't move aside");
- return;
- }
- OverrideProfileLabel(new_label, profile, tag);
- }
-}
-
-void AutofillChangeProcessor2::OverrideProfileLabel(
- const string16& new_label,
- AutoFillProfile* profile_to_update,
- std::string* tag_to_update) {
- tag_to_update->assign(AutofillModelAssociator2::ProfileLabelToTag(new_label));
-
- profile_to_update->set_label(new_label);
- if (!web_database_->UpdateAutoFillProfile(*profile_to_update)) {
- std::string err = "Failed to overwrite label for node ";
- err += UTF16ToUTF8(new_label);
- error_handler()->OnUnrecoverableError(FROM_HERE, err);
- return;
- }
-
- // Notify the PersonalDataManager that it's out of date.
- PostOptimisticRefreshTask();
-}
-
-void AutofillChangeProcessor2::PostOptimisticRefreshTask() {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- new AutofillModelAssociator2::DoOptimisticRefreshTask(
- personal_data_));
-}
-
-void AutofillChangeProcessor2::AddAutofillProfileSyncNode(
- sync_api::WriteTransaction* trans, const sync_api::BaseNode& autofill,
- const std::string& tag, const AutoFillProfile* profile) {
- sync_api::WriteNode sync_node(trans);
- if (!sync_node.InitUniqueByCreation(syncable::AUTOFILL, autofill, tag)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Failed to create autofill sync node.");
- return;
- }
- sync_node.SetTitle(UTF8ToWide(tag));
-
- WriteAutofillProfile(*profile, &sync_node);
- model_associator_->Associate(&tag, sync_node.GetId());
-}
-
-void AutofillChangeProcessor2::ObserveAutofillProfileChanged(
- AutofillProfileChange* change, sync_api::WriteTransaction* trans,
- const sync_api::ReadNode& autofill_root) {
- std::string tag(AutofillModelAssociator2::ProfileLabelToTag(change->key()));
- switch (change->type()) {
- case AutofillProfileChange::ADD: {
- scoped_ptr<AutoFillProfile> clone(
- static_cast<AutoFillProfile*>(change->profile()->Clone()));
- DCHECK_EQ(clone->Label(), change->key());
- ChangeProfileLabelIfAlreadyTaken(trans, string16(), clone.get(), &tag);
- AddAutofillProfileSyncNode(trans, autofill_root, tag, clone.get());
- break;
- }
- case AutofillProfileChange::UPDATE: {
- scoped_ptr<AutoFillProfile> clone(
- static_cast<AutoFillProfile*>(change->profile()->Clone()));
- std::string pre_update_tag = AutofillModelAssociator2::ProfileLabelToTag(
- change->pre_update_label());
- DCHECK_EQ(clone->Label(), change->key());
- sync_api::WriteNode sync_node(trans);
- ChangeProfileLabelIfAlreadyTaken(trans, change->pre_update_label(),
- clone.get(), &tag);
- if (pre_update_tag != tag) {
- // If the label changes, replace the node instead of updating it.
- RemoveSyncNode(pre_update_tag, trans);
- AddAutofillProfileSyncNode(trans, autofill_root, tag, clone.get());
- return;
- }
- int64 sync_id = model_associator_->GetSyncIdFromChromeId(tag);
- if (sync_api::kInvalidId == sync_id) {
- std::string err = "Unexpected notification for: " + tag;
- error_handler()->OnUnrecoverableError(FROM_HERE, err);
- return;
- } else {
- if (!sync_node.InitByIdLookup(sync_id)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Autofill node lookup failed.");
- return;
- }
- WriteAutofillProfile(*clone.get(), &sync_node);
- }
- break;
- }
- case AutofillProfileChange::REMOVE: {
- RemoveSyncNode(tag, trans);
- break;
- }
- }
-}
-
-void AutofillChangeProcessor2::ObserveAutofillEntriesChanged(
- AutofillChangeList* changes, sync_api::WriteTransaction* trans,
- const sync_api::ReadNode& autofill_root) {
- for (AutofillChangeList::iterator change = changes->begin();
- change != changes->end(); ++change) {
- switch (change->type()) {
- case AutofillChange::ADD:
- {
- sync_api::WriteNode sync_node(trans);
- std::string tag =
- AutofillModelAssociator2::KeyToTag(change->key().name(),
- change->key().value());
- if (!sync_node.InitUniqueByCreation(syncable::AUTOFILL,
- autofill_root, tag)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Failed to create autofill sync node.");
- return;
- }
-
- std::vector<base::Time> timestamps;
- if (!web_database_->GetAutofillTimestamps(
- change->key().name(),
- change->key().value(),
- &timestamps)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Failed to get timestamps.");
- return;
- }
-
- sync_node.SetTitle(UTF8ToWide(tag));
-
- WriteAutofillEntry(AutofillEntry(change->key(), timestamps),
- &sync_node);
- model_associator_->Associate(&tag, sync_node.GetId());
- }
- break;
-
- case AutofillChange::UPDATE:
- {
- sync_api::WriteNode sync_node(trans);
- std::string tag = AutofillModelAssociator2::KeyToTag(
- change->key().name(), change->key().value());
- int64 sync_id = model_associator_->GetSyncIdFromChromeId(tag);
- if (sync_api::kInvalidId == sync_id) {
- std::string err = "Unexpected notification for: " +
- UTF16ToUTF8(change->key().name());
- error_handler()->OnUnrecoverableError(FROM_HERE, err);
- return;
- } else {
- if (!sync_node.InitByIdLookup(sync_id)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Autofill node lookup failed.");
- return;
- }
- }
-
- std::vector<base::Time> timestamps;
- if (!web_database_->GetAutofillTimestamps(
- change->key().name(),
- change->key().value(),
- &timestamps)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Failed to get timestamps.");
- return;
- }
-
- WriteAutofillEntry(AutofillEntry(change->key(), timestamps),
- &sync_node);
- }
- break;
- case AutofillChange::REMOVE: {
- std::string tag = AutofillModelAssociator2::KeyToTag(
- change->key().name(), change->key().value());
- RemoveSyncNode(tag, trans);
- }
- break;
- }
- }
-}
-
-void AutofillChangeProcessor2::RemoveSyncNode(const std::string& tag,
- sync_api::WriteTransaction* trans) {
- sync_api::WriteNode sync_node(trans);
- int64 sync_id = model_associator_->GetSyncIdFromChromeId(tag);
- if (sync_api::kInvalidId == sync_id) {
- std::string err = "Unexpected notification for: " + tag;
- error_handler()->OnUnrecoverableError(FROM_HERE, err);
- return;
- } else {
- if (!sync_node.InitByIdLookup(sync_id)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Autofill node lookup failed.");
- return;
- }
- model_associator_->Disassociate(sync_node.GetId());
- sync_node.Remove();
- }
-}
-
-void AutofillChangeProcessor2::ApplyChangesFromSyncModel(
- const sync_api::BaseTransaction* trans,
- const sync_api::SyncManager::ChangeRecord* changes,
- int change_count) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- if (!running())
- return;
- StopObserving();
-
- sync_api::ReadNode autofill_root(trans);
- if (!autofill_root.InitByTagLookup(kAutofillTag)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Autofill root node lookup failed.");
- return;
- }
-
- for (int i = 0; i < change_count; ++i) {
- sync_api::SyncManager::ChangeRecord::Action action(changes[i].action);
- if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE == action) {
- DCHECK(changes[i].specifics.HasExtension(sync_pb::autofill))
- << "Autofill specifics data not present on delete!";
- const sync_pb::AutofillSpecifics& autofill =
- changes[i].specifics.GetExtension(sync_pb::autofill);
- if (autofill.has_value() || autofill.has_profile()) {
- autofill_changes_.push_back(AutofillChangeRecord(changes[i].action,
- changes[i].id,
- autofill));
- } else {
- NOTREACHED() << "Autofill specifics has no data!";
- }
- continue;
- }
-
- // Handle an update or add.
- sync_api::ReadNode sync_node(trans);
- if (!sync_node.InitByIdLookup(changes[i].id)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Autofill node lookup failed.");
- return;
- }
-
- // Check that the changed node is a child of the autofills folder.
- DCHECK(autofill_root.GetId() == sync_node.GetParentId());
- DCHECK(syncable::AUTOFILL == sync_node.GetModelType());
-
- const sync_pb::AutofillSpecifics& autofill(
- sync_node.GetAutofillSpecifics());
- int64 sync_id = sync_node.GetId();
- if (autofill.has_value() || autofill.has_profile()) {
- autofill_changes_.push_back(AutofillChangeRecord(changes[i].action,
- sync_id, autofill));
- } else {
- NOTREACHED() << "Autofill specifics has no data!";
- }
- }
-
- StartObserving();
-}
-
-void AutofillChangeProcessor2::CommitChangesFromSyncModel() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- if (!running())
- return;
- StopObserving();
-
- std::vector<AutofillEntry> new_entries;
- for (unsigned int i = 0; i < autofill_changes_.size(); i++) {
- // Handle deletions.
- if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
- autofill_changes_[i].action_) {
- if (autofill_changes_[i].autofill_.has_value()) {
- ApplySyncAutofillEntryDelete(autofill_changes_[i].autofill_);
- } else if (autofill_changes_[i].autofill_.has_profile()) {
- ApplySyncAutofillProfileDelete(autofill_changes_[i].autofill_.profile(),
- autofill_changes_[i].id_);
- } else {
- NOTREACHED() << "Autofill's CommitChanges received change with no"
- " data!";
- }
- continue;
- }
-
- // Handle update/adds.
- if (autofill_changes_[i].autofill_.has_value()) {
- ApplySyncAutofillEntryChange(autofill_changes_[i].action_,
- autofill_changes_[i].autofill_, &new_entries,
- autofill_changes_[i].id_);
- } else if (autofill_changes_[i].autofill_.has_profile()) {
- ApplySyncAutofillProfileChange(autofill_changes_[i].action_,
- autofill_changes_[i].autofill_.profile(),
- autofill_changes_[i].id_);
- } else {
- NOTREACHED() << "Autofill's CommitChanges received change with no data!";
- }
- }
- autofill_changes_.clear();
-
- // Make changes
- if (!web_database_->UpdateAutofillEntries(new_entries)) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Could not update autofill entries.");
- return;
- }
-
- PostOptimisticRefreshTask();
-
- StartObserving();
-}
-
-void AutofillChangeProcessor2::ApplySyncAutofillEntryDelete(
- const sync_pb::AutofillSpecifics& autofill) {
- if (!web_database_->RemoveFormElement(
- UTF8ToUTF16(autofill.name()), UTF8ToUTF16(autofill.value()))) {
- error_handler()->OnUnrecoverableError(FROM_HERE,
- "Could not remove autofill node.");
- return;
- }
-}
-
-void AutofillChangeProcessor2::ApplySyncAutofillEntryChange(
- sync_api::SyncManager::ChangeRecord::Action action,
- const sync_pb::AutofillSpecifics& autofill,
- std::vector<AutofillEntry>* new_entries,
- int64 sync_id) {
- DCHECK_NE(sync_api::SyncManager::ChangeRecord::ACTION_DELETE, action);
-
- std::vector<base::Time> timestamps;
- size_t timestamps_size = autofill.usage_timestamp_size();
- for (size_t c = 0; c < timestamps_size; ++c) {
- timestamps.push_back(
- base::Time::FromInternalValue(autofill.usage_timestamp(c)));
- }
- AutofillKey k(UTF8ToUTF16(autofill.name()), UTF8ToUTF16(autofill.value()));
- AutofillEntry new_entry(k, timestamps);
-
- new_entries->push_back(new_entry);
- std::string tag(AutofillModelAssociator2::KeyToTag(k.name(), k.value()));
- if (action == sync_api::SyncManager::ChangeRecord::ACTION_ADD)
- model_associator_->Associate(&tag, sync_id);
-}
-
-void AutofillChangeProcessor2::ApplySyncAutofillProfileChange(
- sync_api::SyncManager::ChangeRecord::Action action,
- const sync_pb::AutofillProfileSpecifics& profile,
- int64 sync_id) {
- DCHECK_NE(sync_api::SyncManager::ChangeRecord::ACTION_DELETE, action);
-
- std::string tag(AutofillModelAssociator2::ProfileLabelToTag(
- UTF8ToUTF16(profile.label())));
- switch (action) {
- case sync_api::SyncManager::ChangeRecord::ACTION_ADD: {
- PersonalDataManager* pdm = model_associator_->sync_service()->
- profile()->GetPersonalDataManager();
- scoped_ptr<AutoFillProfile> p(
- pdm->CreateNewEmptyAutoFillProfileForDBThread(
- UTF8ToUTF16(profile.label())));
- AutofillModelAssociator2::OverwriteProfileWithServerData(p.get(),
- profile);
-
- model_associator_->Associate(&tag, sync_id);
- if (!web_database_->AddAutoFillProfile(*p.get())) {
- NOTREACHED() << "Couldn't add autofill profile: " << profile.label();
- return;
- }
- break;
- }
- case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: {
- AutoFillProfile* p = NULL;
- string16 label = UTF8ToUTF16(profile.label());
- if (!web_database_->GetAutoFillProfileForLabel(label, &p)) {
- NOTREACHED() << "Couldn't retrieve autofill profile: " << label;
- return;
- }
- AutofillModelAssociator2::OverwriteProfileWithServerData(p, profile);
- if (!web_database_->UpdateAutoFillProfile(*p)) {
- NOTREACHED() << "Couldn't update autofill profile: " << label;
- return;
- }
- delete p;
- break;
- }
- default:
- NOTREACHED();
- }
-}
-
-void AutofillChangeProcessor2::ApplySyncAutofillProfileDelete(
- const sync_pb::AutofillProfileSpecifics& profile,
- int64 sync_id) {
- string16 label(UTF8ToUTF16(profile.label()));
- AutoFillProfile* ptr = NULL;
- bool get_success = web_database_->GetAutoFillProfileForLabel(label, &ptr);
- scoped_ptr<AutoFillProfile> p(ptr);
- if (!get_success) {
- NOTREACHED() << "Couldn't retrieve autofill profile: " << label;
- return;
- }
- if (!web_database_->RemoveAutoFillProfile(p->guid())) {
- NOTREACHED() << "Couldn't remove autofill profile: " << label;
- return;
- }
- model_associator_->Disassociate(sync_id);
-}
-
-void AutofillChangeProcessor2::StartImpl(Profile* profile) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- observing_ = true;
-}
-
-void AutofillChangeProcessor2::StopImpl() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- observing_ = false;
-}
-
-
-void AutofillChangeProcessor2::StartObserving() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- notification_registrar_.Add(this, NotificationType::AUTOFILL_ENTRIES_CHANGED,
- NotificationService::AllSources());
- notification_registrar_.Add(this, NotificationType::AUTOFILL_PROFILE_CHANGED,
- NotificationService::AllSources());
-}
-
-void AutofillChangeProcessor2::StopObserving() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- notification_registrar_.RemoveAll();
-}
-
-// static
-void AutofillChangeProcessor2::WriteAutofillEntry(
- const AutofillEntry& entry,
- sync_api::WriteNode* node) {
- sync_pb::AutofillSpecifics autofill;
- autofill.set_name(UTF16ToUTF8(entry.key().name()));
- autofill.set_value(UTF16ToUTF8(entry.key().value()));
- const std::vector<base::Time>& ts(entry.timestamps());
- for (std::vector<base::Time>::const_iterator timestamp = ts.begin();
- timestamp != ts.end(); ++timestamp) {
- autofill.add_usage_timestamp(timestamp->ToInternalValue());
- }
- node->SetAutofillSpecifics(autofill);
-}
-
-// static
-void AutofillChangeProcessor2::WriteAutofillProfile(
- const AutoFillProfile& profile, sync_api::WriteNode* node) {
- sync_pb::AutofillSpecifics autofill;
- sync_pb::AutofillProfileSpecifics* s(autofill.mutable_profile());
- s->set_label(UTF16ToUTF8(profile.Label()));
- s->set_name_first(UTF16ToUTF8(
- profile.GetFieldText(AutoFillType(NAME_FIRST))));
- s->set_name_middle(UTF16ToUTF8(
- profile.GetFieldText(AutoFillType(NAME_MIDDLE))));
- s->set_name_last(UTF16ToUTF8(profile.GetFieldText(AutoFillType(NAME_LAST))));
- s->set_address_home_line1(
- UTF16ToUTF8(profile.GetFieldText(AutoFillType(ADDRESS_HOME_LINE1))));
- s->set_address_home_line2(
- UTF16ToUTF8(profile.GetFieldText(AutoFillType(ADDRESS_HOME_LINE2))));
- s->set_address_home_city(UTF16ToUTF8(profile.GetFieldText(
- AutoFillType(ADDRESS_HOME_CITY))));
- s->set_address_home_state(UTF16ToUTF8(profile.GetFieldText(
- AutoFillType(ADDRESS_HOME_STATE))));
- s->set_address_home_country(UTF16ToUTF8(profile.GetFieldText(
- AutoFillType(ADDRESS_HOME_COUNTRY))));
- s->set_address_home_zip(UTF16ToUTF8(profile.GetFieldText(
- AutoFillType(ADDRESS_HOME_ZIP))));
- s->set_email_address(UTF16ToUTF8(profile.GetFieldText(
- AutoFillType(EMAIL_ADDRESS))));
- s->set_company_name(UTF16ToUTF8(profile.GetFieldText(
- AutoFillType(COMPANY_NAME))));
- s->set_phone_fax_whole_number(UTF16ToUTF8(profile.GetFieldText(
- AutoFillType(PHONE_FAX_WHOLE_NUMBER))));
- s->set_phone_home_whole_number(UTF16ToUTF8(profile.GetFieldText(
- AutoFillType(PHONE_HOME_WHOLE_NUMBER))));
- node->SetAutofillSpecifics(autofill);
-}
-
-} // namespace browser_sync
-
diff --git a/chrome/browser/sync/glue/autofill_change_processor2.h b/chrome/browser/sync/glue/autofill_change_processor2.h
deleted file mode 100755
index 25d7f51..0000000
--- a/chrome/browser/sync/glue/autofill_change_processor2.h
+++ /dev/null
@@ -1,172 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SYNC_GLUE_AUTOFILL_CHANGE_PROCESSOR2_H_
-#define CHROME_BROWSER_SYNC_GLUE_AUTOFILL_CHANGE_PROCESSOR2_H_
-#pragma once
-
-#include <string>
-#include <vector>
-
-#include "chrome/browser/autofill/autofill_profile.h"
-#include "chrome/browser/autofill/credit_card.h"
-#include "chrome/browser/autofill/personal_data_manager.h"
-#include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/glue/change_processor.h"
-#include "chrome/browser/sync/glue/sync_backend_host.h"
-#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
-#include "chrome/browser/webdata/web_data_service.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_registrar.h"
-
-class AutofillCreditCardChange;
-class AutofillEntry;
-class AutofillProfileChange;
-class PersonalDataManager;
-class WebDatabase;
-
-namespace browser_sync {
-
-class AutofillModelAssociator2;
-class UnrecoverableErrorHandler;
-
-// This class is responsible for taking changes from the web data service and
-// applying them to the sync_api 'syncable' model, and vice versa. All
-// operations and use of this class are from the DB thread.
-class AutofillChangeProcessor2 : public ChangeProcessor,
- public NotificationObserver {
- public:
- AutofillChangeProcessor2(AutofillModelAssociator2* model_associator,
- WebDatabase* web_database,
- PersonalDataManager* personal_data,
- UnrecoverableErrorHandler* error_handler);
- virtual ~AutofillChangeProcessor2();
-
- // NotificationObserver implementation.
- // WebDataService -> sync_api model change application.
- virtual void Observe(NotificationType type,
- const NotificationSource& source,
- const NotificationDetails& details);
-
- // sync_api model -> WebDataService change application.
- virtual void ApplyChangesFromSyncModel(
- const sync_api::BaseTransaction* trans,
- const sync_api::SyncManager::ChangeRecord* changes,
- int change_count);
-
- // Commit any changes from ApplyChangesFromSyncModel buffered in
- // autofill_changes_.
- virtual void CommitChangesFromSyncModel();
-
- // Copy the properties of the given Autofill entry into the sync
- // node.
- static void WriteAutofillEntry(const AutofillEntry& entry,
- sync_api::WriteNode* node);
- // As above, for autofill profiles.
- static void WriteAutofillProfile(const AutoFillProfile& profile,
- sync_api::WriteNode* node);
- // TODO(georgey) : add the same processing for CC info (already in protocol
- // buffers).
-
- protected:
- virtual void StartImpl(Profile* profile);
- virtual void StopImpl();
-
- private:
- void StartObserving();
- void StopObserving();
-
- // A function to remove the sync node for an autofill entry or profile.
- void RemoveSyncNode(const std::string& tag,
- sync_api::WriteTransaction* trans);
-
- // These two methods are dispatched to by Observe depending on the type.
- void ObserveAutofillEntriesChanged(AutofillChangeList* changes,
- sync_api::WriteTransaction* trans,
- const sync_api::ReadNode& autofill_root);
- void ObserveAutofillProfileChanged(AutofillProfileChange* change,
- sync_api::WriteTransaction* trans,
- const sync_api::ReadNode& autofill_root);
-
- // The following methods are the implementation of ApplyChangeFromSyncModel
- // for the respective autofill subtypes.
- void ApplySyncAutofillEntryChange(
- sync_api::SyncManager::ChangeRecord::Action action,
- const sync_pb::AutofillSpecifics& autofill,
- std::vector<AutofillEntry>* new_entries,
- int64 sync_id);
- void ApplySyncAutofillProfileChange(
- sync_api::SyncManager::ChangeRecord::Action action,
- const sync_pb::AutofillProfileSpecifics& profile,
- int64 sync_id);
-
- // Delete is a special case of change application.
- void ApplySyncAutofillEntryDelete(
- const sync_pb::AutofillSpecifics& autofill);
- void ApplySyncAutofillProfileDelete(
- const sync_pb::AutofillProfileSpecifics& profile,
- int64 sync_id);
-
- // If the chrome model tries to add an AutoFillProfile with a label that
- // is already in use, we perform a move-aside by calling-back into the chrome
- // model and overwriting the label with a unique value we can apply for sync.
- // This method should be called on an ADD notification from the chrome model.
- // |tag| contains the unique sync client tag identifier for |profile|, which
- // is derived from the profile label using ProfileLabelToTag.
- // |existing_unique_label| is the current label of the object, if any; this
- // is an allowed value, because it's taken by the item in question.
- // For new items, set |existing_unique_label| to the empty string.
- void ChangeProfileLabelIfAlreadyTaken(
- sync_api::BaseTransaction* trans,
- const string16& existing_unique_label,
- AutoFillProfile* profile,
- std::string* tag);
-
- // Reassign the label of the profile, write this back to the web database,
- // and update |tag| with the tag corresponding to the new label.
- void OverrideProfileLabel(
- const string16& new_label,
- AutoFillProfile* profile_to_update,
- std::string* tag_to_update);
-
- // Helper to create a sync node with tag |tag|, storing |profile| as
- // the node's AutofillSpecifics.
- void AddAutofillProfileSyncNode(
- sync_api::WriteTransaction* trans,
- const sync_api::BaseNode& autofill,
- const std::string& tag,
- const AutoFillProfile* profile);
-
- // Helper to post a task to the UI loop to inform the PersonalDataManager
- // it needs to refresh itself.
- void PostOptimisticRefreshTask();
-
- // The two models should be associated according to this ModelAssociator.
- AutofillModelAssociator2* model_associator_;
-
- // The model we are processing changes from. This is owned by the
- // WebDataService which is kept alive by our data type controller
- // holding a reference.
- WebDatabase* web_database_;
-
- // We periodically tell the PersonalDataManager to refresh as we make
- // changes to the autofill data in the WebDatabase.
- PersonalDataManager* personal_data_;
-
- NotificationRegistrar notification_registrar_;
-
- bool observing_;
-
- // Record of changes from ApplyChangesFromSyncModel. These are then processed
- // in CommitChangesFromSyncModel.
- struct AutofillChangeRecord;
- std::vector<AutofillChangeRecord> autofill_changes_;
-
- DISALLOW_COPY_AND_ASSIGN(AutofillChangeProcessor2);
-};
-
-} // namespace browser_sync
-
-#endif // CHROME_BROWSER_SYNC_GLUE_AUTOFILL_CHANGE_PROCESSOR2_H_
-
diff --git a/chrome/browser/sync/glue/autofill_model_associator.cc b/chrome/browser/sync/glue/autofill_model_associator.cc
index 6409e9b..b550ab5 100644
--- a/chrome/browser/sync/glue/autofill_model_associator.cc
+++ b/chrome/browser/sync/glue/autofill_model_associator.cc
@@ -12,7 +12,6 @@
#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"
@@ -27,6 +26,9 @@ 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;
@@ -121,6 +123,87 @@ 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) {
@@ -182,15 +265,11 @@ bool AutofillModelAssociator::AssociateModels() {
}
if (!TraverseAndAssociateChromeAutofillEntries(&trans, autofill_root,
- entries, &bundle.current_entries, &bundle.new_entries)) {
- return false;
- }
-
- if (!TraverseAndAssociateAllSyncNodes(
- &trans,
- autofill_root,
- &bundle,
- profiles.get())) {
+ 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;
}
}
@@ -240,8 +319,7 @@ bool AutofillModelAssociator::SaveChangesToWebData(const DataBundle& bundle) {
bool AutofillModelAssociator::TraverseAndAssociateAllSyncNodes(
sync_api::WriteTransaction* write_trans,
const sync_api::ReadNode& autofill_root,
- DataBundle* bundle,
- const std::vector<AutoFillProfile*>& all_profiles_from_db) {
+ DataBundle* bundle) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
int64 sync_child_id = autofill_root.GetFirstChildId();
@@ -254,57 +332,18 @@ bool AutofillModelAssociator::TraverseAndAssociateAllSyncNodes(
const sync_pb::AutofillSpecifics& autofill(
sync_child.GetAutofillSpecifics());
- if (autofill.has_value()) {
+ if (autofill.has_value())
AddNativeEntryIfNeeded(autofill, bundle, sync_child);
- } else if (autofill.has_profile() && HasNotMigratedYet()) {
- // Ignore autofill profiles if we are not upgrading.
- AddNativeProfileIfNeeded(
- autofill.profile(),
- bundle,
- sync_child,
- all_profiles_from_db);
- } else {
+ else if (autofill.has_profile())
+ AddNativeProfileIfNeeded(autofill.profile(), bundle, sync_child);
+ else
NOTREACHED() << "AutofillSpecifics has no autofill data!";
- }
sync_child_id = sync_child.GetSuccessorId();
}
return true;
}
-// 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 {
- if (p1->Compare(*p2) == 0)
- return true;
- else
- return false;
- }
-};
-
-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 (!FillProfileWithServerData(&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) {
@@ -325,26 +364,16 @@ void AutofillModelAssociator::AddNativeEntryIfNeeded(
}
void AutofillModelAssociator::AddNativeProfileIfNeeded(
- const sync_pb::AutofillProfileSpecifics& profile,
- DataBundle* bundle,
- const sync_api::ReadNode& node,
- const std::vector<AutoFillProfile*>& all_profiles_from_db) {
-
+ const sync_pb::AutofillProfileSpecifics& profile, DataBundle* bundle,
+ const sync_api::ReadNode& node) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-
- 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();
- std::string guid = profile_in_web_db->guid();
- Associate(&guid, sync_id);
- return;
- } else { // Create a new node.
- std::string guid = guid::GenerateGUID();
- Associate(&guid, node.GetId());
- AutoFillProfile* p = new AutoFillProfile(guid);
- FillProfileWithServerData(p, profile);
+ 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()));
+ OverwriteProfileWithServerData(p, profile);
bundle->new_profiles.push_back(p);
}
}
@@ -388,8 +417,7 @@ void AutofillModelAssociator::AbortAssociation() {
const std::string*
AutofillModelAssociator::GetChromeNodeFromSyncId(int64 sync_id) {
- SyncIdToAutofillMap::const_iterator iter = id_map_inverse_.find(sync_id);
- return iter == id_map_inverse_.end() ? NULL : &(iter->second);
+ return NULL;
}
bool AutofillModelAssociator::InitSyncNodeFromChromeId(
@@ -448,6 +476,12 @@ 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,
@@ -485,7 +519,7 @@ bool MergeField(FormGroup* f, AutoFillFieldType t,
}
// static
-bool AutofillModelAssociator::FillProfileWithServerData(
+bool AutofillModelAssociator::OverwriteProfileWithServerData(
AutoFillProfile* merge_into,
const sync_pb::AutofillProfileSpecifics& specifics) {
bool diff = false;
@@ -509,8 +543,4 @@ bool AutofillModelAssociator::FillProfileWithServerData(
return diff;
}
-bool AutofillModelAssociator::HasNotMigratedYet() {
- return true;
-}
-
} // namespace browser_sync
diff --git a/chrome/browser/sync/glue/autofill_model_associator.h b/chrome/browser/sync/glue/autofill_model_associator.h
index ee81ed0..d4e5363 100644
--- a/chrome/browser/sync/glue/autofill_model_associator.h
+++ b/chrome/browser/sync/glue/autofill_model_associator.h
@@ -16,7 +16,6 @@
#include "base/ref_counted.h"
#include "chrome/browser/autofill/personal_data_manager.h"
#include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/glue/autofill_model_associator2.h"
#include "chrome/browser/sync/glue/model_associator.h"
#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
#include "chrome/browser/webdata/autofill_entry.h"
@@ -100,11 +99,12 @@ class AutofillModelAssociator
virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
static std::string KeyToTag(const string16& name, const string16& value);
+ static std::string ProfileLabelToTag(const string16& label);
static bool MergeTimestamps(const sync_pb::AutofillSpecifics& autofill,
const std::vector<base::Time>& timestamps,
std::vector<base::Time>* new_timestamps);
- static bool FillProfileWithServerData(
+ static bool OverwriteProfileWithServerData(
AutoFillProfile* merge_into,
const sync_pb::AutofillProfileSpecifics& specifics);
@@ -114,18 +114,15 @@ class AutofillModelAssociator
// Returns sync service instance.
ProfileSyncService* sync_service() { return sync_service_; }
- protected:
- // Is called to determine if we need to upgrade to the new
- // autofillprofile2 data type. If so we need to sync up autofillprofile
- // first to the latest available changes on the server and then upgrade
- // to autofillprofile2.
- virtual bool HasNotMigratedYet();
-
- // Given a profile from sync db it tries to match the profile against
- // one in web db. it ignores the guid and compares the actual data.
- AutoFillProfile* FindCorrespondingNodeFromWebDB(
- const sync_pb::AutofillProfileSpecifics& profile,
- const std::vector<AutoFillProfile*>& all_profiles_from_db);
+ // Compute and apply suffix to a label so that the resulting label is
+ // unique in the sync database.
+ // |new_non_unique_label| is the colliding label which is to be uniquified.
+ // |existing_unique_label| is the current label of the object, if any; this
+ // is treated as a unique label even if colliding. If no such label is
+ // available, |existing_unique_label| may be empty.
+ static string16 MakeUniqueLabel(const string16& new_non_unique_label,
+ const string16& existing_unique_label,
+ sync_api::BaseTransaction* trans);
private:
typedef std::map<std::string, int64> AutofillToSyncIdMap;
@@ -159,8 +156,7 @@ class AutofillModelAssociator
bool TraverseAndAssociateAllSyncNodes(
sync_api::WriteTransaction* write_trans,
const sync_api::ReadNode& autofill_root,
- DataBundle* bundle,
- const std::vector<AutoFillProfile*>& all_profiles_from_db);
+ DataBundle* bundle);
// Helper to persist any changes that occured during model association to
// the WebDatabase.
@@ -177,8 +173,7 @@ class AutofillModelAssociator
void AddNativeProfileIfNeeded(
const sync_pb::AutofillProfileSpecifics& profile,
DataBundle* bundle,
- const sync_api::ReadNode& node,
- const std::vector<AutoFillProfile*>& all_profiles_from_db);
+ const sync_api::ReadNode& node);
// Helper to insert a sync node for the given AutoFillProfile (e.g. in
// response to encountering a native profile that doesn't exist yet in the
diff --git a/chrome/browser/sync/glue/autofill_model_associator2.cc b/chrome/browser/sync/glue/autofill_model_associator2.cc
deleted file mode 100755
index 272c8ae..0000000
--- a/chrome/browser/sync/glue/autofill_model_associator2.cc
+++ /dev/null
@@ -1,547 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/sync/glue/autofill_model_associator2.h"
-
-#include <vector>
-
-#include "base/task.h"
-#include "base/time.h"
-#include "base/string_number_conversions.h"
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/autofill/autofill_profile.h"
-#include "chrome/browser/browser_thread.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/glue/autofill_change_processor.h"
-#include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
-#include "chrome/browser/webdata/web_database.h"
-#include "net/base/escape.h"
-
-using base::TimeTicks;
-
-namespace browser_sync {
-
-extern const char kAutofillTag[];
-extern const char kAutofillEntryNamespaceTag[];
-const char kAutofillProfileNamespaceTag[] = "autofill_profile|";
-
-static const int kMaxNumAttemptsToFindUniqueLabel = 100;
-
-struct AutofillModelAssociator2::DataBundle {
- std::set<AutofillKey> current_entries;
- std::vector<AutofillEntry> new_entries;
- std::set<string16> current_profiles;
- std::vector<AutoFillProfile*> updated_profiles;
- std::vector<AutoFillProfile*> new_profiles; // We own these pointers.
- ~DataBundle() { STLDeleteElements(&new_profiles); }
-};
-
-AutofillModelAssociator2::DoOptimisticRefreshTask::DoOptimisticRefreshTask(
- PersonalDataManager* pdm) : pdm_(pdm) {}
-
-AutofillModelAssociator2::DoOptimisticRefreshTask::~DoOptimisticRefreshTask() {}
-
-void AutofillModelAssociator2::DoOptimisticRefreshTask::Run() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- pdm_->Refresh();
-}
-
-AutofillModelAssociator2::AutofillModelAssociator2(
- ProfileSyncService* sync_service,
- WebDatabase* web_database,
- PersonalDataManager* personal_data)
- : sync_service_(sync_service),
- web_database_(web_database),
- personal_data_(personal_data),
- autofill_node_id_(sync_api::kInvalidId),
- abort_association_pending_(false) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- DCHECK(sync_service_);
- DCHECK(web_database_);
- DCHECK(personal_data_);
-}
-
-AutofillModelAssociator2::~AutofillModelAssociator2() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-}
-
-bool AutofillModelAssociator2::TraverseAndAssociateChromeAutofillEntries(
- sync_api::WriteTransaction* write_trans,
- const sync_api::ReadNode& autofill_root,
- const std::vector<AutofillEntry>& all_entries_from_db,
- std::set<AutofillKey>* current_entries,
- std::vector<AutofillEntry>* new_entries) {
-
- const std::vector<AutofillEntry>& entries = all_entries_from_db;
- for (std::vector<AutofillEntry>::const_iterator ix = entries.begin();
- ix != entries.end(); ++ix) {
- std::string tag = KeyToTag(ix->key().name(), ix->key().value());
- if (id_map_.find(tag) != id_map_.end()) {
- // It seems that name/value pairs are not unique in the web database.
- // As a result, we have to filter out duplicates here. This is probably
- // a bug in the database.
- continue;
- }
-
- sync_api::ReadNode node(write_trans);
- if (node.InitByClientTagLookup(syncable::AUTOFILL, tag)) {
- const sync_pb::AutofillSpecifics& autofill(node.GetAutofillSpecifics());
- DCHECK_EQ(tag, KeyToTag(UTF8ToUTF16(autofill.name()),
- UTF8ToUTF16(autofill.value())));
-
- std::vector<base::Time> timestamps;
- if (MergeTimestamps(autofill, ix->timestamps(), &timestamps)) {
- AutofillEntry new_entry(ix->key(), timestamps);
- new_entries->push_back(new_entry);
-
- sync_api::WriteNode write_node(write_trans);
- if (!write_node.InitByClientTagLookup(syncable::AUTOFILL, tag)) {
- LOG(ERROR) << "Failed to write autofill sync node.";
- return false;
- }
- AutofillChangeProcessor2::WriteAutofillEntry(new_entry, &write_node);
- }
-
- Associate(&tag, node.GetId());
- } else {
- sync_api::WriteNode node(write_trans);
- if (!node.InitUniqueByCreation(syncable::AUTOFILL,
- autofill_root, tag)) {
- LOG(ERROR) << "Failed to create autofill sync node.";
- return false;
- }
- node.SetTitle(UTF8ToWide(tag));
- AutofillChangeProcessor2::WriteAutofillEntry(*ix, &node);
- Associate(&tag, node.GetId());
- }
-
- current_entries->insert(ix->key());
- }
- return true;
-}
-
-bool AutofillModelAssociator2::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 AutofillModelAssociator2::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 AutofillModelAssociator2::MakeNewAutofillProfileSyncNode(
- sync_api::WriteTransaction* trans, const sync_api::BaseNode& autofill_root,
- const std::string& tag, const AutoFillProfile& profile, int64* sync_id) {
- sync_api::WriteNode node(trans);
- if (!node.InitUniqueByCreation(syncable::AUTOFILL, autofill_root, tag)) {
- LOG(ERROR) << "Failed to create autofill sync node.";
- return false;
- }
- node.SetTitle(UTF8ToWide(tag));
- AutofillChangeProcessor2::WriteAutofillProfile(profile, &node);
- *sync_id = node.GetId();
- return true;
-}
-
-
-bool AutofillModelAssociator2::LoadAutofillData(
- std::vector<AutofillEntry>* entries,
- std::vector<AutoFillProfile*>* profiles) {
- if (IsAbortPending())
- return false;
- if (!web_database_->GetAllAutofillEntries(entries))
- return false;
-
- if (IsAbortPending())
- return false;
- if (!web_database_->GetAutoFillProfiles(profiles))
- return false;
-
- return true;
-}
-
-bool AutofillModelAssociator2::AssociateModels() {
- VLOG(1) << "Associating Autofill Models";
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- {
- AutoLock lock(abort_association_pending_lock_);
- abort_association_pending_ = false;
- }
-
- // TODO(zork): Attempt to load the model association from storage.
- std::vector<AutofillEntry> entries;
- ScopedVector<AutoFillProfile> profiles;
-
- if (!LoadAutofillData(&entries, &profiles.get())) {
- LOG(ERROR) << "Could not get the autofill data from WebDatabase.";
- return false;
- }
-
- DataBundle bundle;
- {
- sync_api::WriteTransaction trans(
- sync_service_->backend()->GetUserShareHandle());
-
- sync_api::ReadNode autofill_root(&trans);
- if (!autofill_root.InitByTagLookup(kAutofillTag)) {
- LOG(ERROR) << "Server did not create the top-level autofill node. We "
- << "might be running against an out-of-date server.";
- return false;
- }
-
- 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;
- }
- }
-
- // Since we're on the DB thread, we don't have to worry about updating
- // the autofill database after closing the write transaction, since
- // this is the only thread that writes to the database. We also don't have
- // to worry about the sync model getting out of sync, because changes are
- // propogated to the ChangeProcessor on this thread.
- if (!SaveChangesToWebData(bundle)) {
- LOG(ERROR) << "Failed to update autofill entries.";
- return false;
- }
-
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- new DoOptimisticRefreshTask(personal_data_));
- return true;
-}
-
-bool AutofillModelAssociator2::SaveChangesToWebData(const DataBundle& bundle) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-
- if (IsAbortPending())
- return false;
-
- if (bundle.new_entries.size() &&
- !web_database_->UpdateAutofillEntries(bundle.new_entries)) {
- return false;
- }
-
- for (size_t i = 0; i < bundle.new_profiles.size(); i++) {
- if (IsAbortPending())
- return false;
- if (!web_database_->AddAutoFillProfile(*bundle.new_profiles[i]))
- return false;
- }
-
- for (size_t i = 0; i < bundle.updated_profiles.size(); i++) {
- if (IsAbortPending())
- return false;
- if (!web_database_->UpdateAutoFillProfile(*bundle.updated_profiles[i]))
- return false;
- }
- return true;
-}
-
-bool AutofillModelAssociator2::TraverseAndAssociateAllSyncNodes(
- sync_api::WriteTransaction* write_trans,
- const sync_api::ReadNode& autofill_root,
- DataBundle* bundle) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-
- int64 sync_child_id = autofill_root.GetFirstChildId();
- while (sync_child_id != sync_api::kInvalidId) {
- sync_api::ReadNode sync_child(write_trans);
- if (!sync_child.InitByIdLookup(sync_child_id)) {
- LOG(ERROR) << "Failed to fetch child node.";
- return false;
- }
- const sync_pb::AutofillSpecifics& autofill(
- sync_child.GetAutofillSpecifics());
-
- if (autofill.has_value())
- AddNativeEntryIfNeeded(autofill, bundle, sync_child);
- else if (autofill.has_profile())
- AddNativeProfileIfNeeded(autofill.profile(), bundle, sync_child);
- else
- NOTREACHED() << "AutofillSpecifics has no autofill data!";
-
- sync_child_id = sync_child.GetSuccessorId();
- }
- return true;
-}
-
-void AutofillModelAssociator2::AddNativeEntryIfNeeded(
- const sync_pb::AutofillSpecifics& autofill, DataBundle* bundle,
- const sync_api::ReadNode& node) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- AutofillKey key(UTF8ToUTF16(autofill.name()), UTF8ToUTF16(autofill.value()));
-
- if (bundle->current_entries.find(key) == bundle->current_entries.end()) {
- std::vector<base::Time> timestamps;
- int timestamps_count = autofill.usage_timestamp_size();
- for (int c = 0; c < timestamps_count; ++c) {
- timestamps.push_back(base::Time::FromInternalValue(
- autofill.usage_timestamp(c)));
- }
- std::string tag(KeyToTag(key.name(), key.value()));
- Associate(&tag, node.GetId());
- bundle->new_entries.push_back(AutofillEntry(key, timestamps));
- }
-}
-
-void AutofillModelAssociator2::AddNativeProfileIfNeeded(
- const sync_pb::AutofillProfileSpecifics& profile, DataBundle* bundle,
- const sync_api::ReadNode& node) {
- 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()));
- OverwriteProfileWithServerData(p, profile);
- bundle->new_profiles.push_back(p);
- }
-}
-
-bool AutofillModelAssociator2::DisassociateModels() {
- id_map_.clear();
- id_map_inverse_.clear();
- return true;
-}
-
-bool AutofillModelAssociator2::SyncModelHasUserCreatedNodes(bool* has_nodes) {
- DCHECK(has_nodes);
- *has_nodes = false;
- int64 autofill_sync_id;
- if (!GetSyncIdForTaggedNode(kAutofillTag, &autofill_sync_id)) {
- LOG(ERROR) << "Server did not create the top-level autofill node. We "
- << "might be running against an out-of-date server.";
- return false;
- }
- sync_api::ReadTransaction trans(
- sync_service_->backend()->GetUserShareHandle());
-
- sync_api::ReadNode autofill_node(&trans);
- if (!autofill_node.InitByIdLookup(autofill_sync_id)) {
- LOG(ERROR) << "Server did not create the top-level autofill node. We "
- << "might be running against an out-of-date server.";
- return false;
- }
-
- // The sync model has user created nodes if the autofill folder has any
- // children.
- *has_nodes = sync_api::kInvalidId != autofill_node.GetFirstChildId();
- return true;
-}
-
-void AutofillModelAssociator2::AbortAssociation() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- AutoLock lock(abort_association_pending_lock_);
- abort_association_pending_ = true;
-}
-
-const std::string*
-AutofillModelAssociator2::GetChromeNodeFromSyncId(int64 sync_id) {
- return NULL;
-}
-
-bool AutofillModelAssociator2::InitSyncNodeFromChromeId(
- std::string node_id,
- sync_api::BaseNode* sync_node) {
- return false;
-}
-
-int64 AutofillModelAssociator2::GetSyncIdFromChromeId(
- const std::string autofill) {
- AutofillToSyncIdMap::const_iterator iter = id_map_.find(autofill);
- return iter == id_map_.end() ? sync_api::kInvalidId : iter->second;
-}
-
-void AutofillModelAssociator2::Associate(
- const std::string* autofill, int64 sync_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- DCHECK_NE(sync_api::kInvalidId, sync_id);
- DCHECK(id_map_.find(*autofill) == id_map_.end());
- DCHECK(id_map_inverse_.find(sync_id) == id_map_inverse_.end());
- id_map_[*autofill] = sync_id;
- id_map_inverse_[sync_id] = *autofill;
-}
-
-void AutofillModelAssociator2::Disassociate(int64 sync_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- SyncIdToAutofillMap::iterator iter = id_map_inverse_.find(sync_id);
- if (iter == id_map_inverse_.end())
- return;
- CHECK(id_map_.erase(iter->second));
- id_map_inverse_.erase(iter);
-}
-
-bool AutofillModelAssociator2::GetSyncIdForTaggedNode(const std::string& tag,
- int64* sync_id) {
- sync_api::ReadTransaction trans(
- sync_service_->backend()->GetUserShareHandle());
- sync_api::ReadNode sync_node(&trans);
- if (!sync_node.InitByTagLookup(tag.c_str()))
- return false;
- *sync_id = sync_node.GetId();
- return true;
-}
-
-bool AutofillModelAssociator2::IsAbortPending() {
- AutoLock lock(abort_association_pending_lock_);
- return abort_association_pending_;
-}
-
-// static
-std::string AutofillModelAssociator2::KeyToTag(const string16& name,
- const string16& value) {
- std::string ns(kAutofillEntryNamespaceTag);
- return ns + EscapePath(UTF16ToUTF8(name)) + "|" +
- EscapePath(UTF16ToUTF8(value));
-}
-
-// static
-std::string AutofillModelAssociator2::ProfileLabelToTag(const string16& label) {
- std::string ns(kAutofillProfileNamespaceTag);
- return ns + EscapePath(UTF16ToUTF8(label));
-}
-
-// static
-bool AutofillModelAssociator2::MergeTimestamps(
- const sync_pb::AutofillSpecifics& autofill,
- const std::vector<base::Time>& timestamps,
- std::vector<base::Time>* new_timestamps) {
- DCHECK(new_timestamps);
- std::set<base::Time> timestamp_union(timestamps.begin(),
- timestamps.end());
-
- size_t timestamps_count = autofill.usage_timestamp_size();
-
- bool different = timestamps.size() != timestamps_count;
- for (size_t c = 0; c < timestamps_count; ++c) {
- if (timestamp_union.insert(base::Time::FromInternalValue(
- autofill.usage_timestamp(c))).second) {
- different = true;
- }
- }
-
- if (different) {
- new_timestamps->insert(new_timestamps->begin(),
- timestamp_union.begin(),
- timestamp_union.end());
- }
- return different;
-}
-
-// Helper to compare the local value and cloud value of a field, merge into
-// the local value if they differ, and return whether the merge happened.
-bool MergeField2(FormGroup* f, AutoFillFieldType t,
- const std::string& specifics_field) {
- if (UTF16ToUTF8(f->GetFieldText(AutoFillType(t))) == specifics_field)
- return false;
- f->SetInfo(AutoFillType(t), UTF8ToUTF16(specifics_field));
- return true;
-}
-
-// static
-bool AutofillModelAssociator2::OverwriteProfileWithServerData(
- AutoFillProfile* merge_into,
- const sync_pb::AutofillProfileSpecifics& specifics) {
- bool diff = false;
- AutoFillProfile* p = merge_into;
- const sync_pb::AutofillProfileSpecifics& s(specifics);
- diff = MergeField2(p, NAME_FIRST, s.name_first()) || diff;
- diff = MergeField2(p, NAME_LAST, s.name_last()) || diff;
- diff = MergeField2(p, NAME_MIDDLE, s.name_middle()) || diff;
- diff = MergeField2(p, ADDRESS_HOME_LINE1, s.address_home_line1()) || diff;
- diff = MergeField2(p, ADDRESS_HOME_LINE2, s.address_home_line2()) || diff;
- diff = MergeField2(p, ADDRESS_HOME_CITY, s.address_home_city()) || diff;
- diff = MergeField2(p, ADDRESS_HOME_STATE, s.address_home_state()) || diff;
- diff = MergeField2(p, ADDRESS_HOME_COUNTRY, s.address_home_country()) || diff;
- diff = MergeField2(p, ADDRESS_HOME_ZIP, s.address_home_zip()) || diff;
- diff = MergeField2(p, EMAIL_ADDRESS, s.email_address()) || diff;
- diff = MergeField2(p, COMPANY_NAME, s.company_name()) || diff;
- diff = MergeField2(p, PHONE_FAX_WHOLE_NUMBER, s.phone_fax_whole_number())
- || diff;
- diff = MergeField2(p, PHONE_HOME_WHOLE_NUMBER, s.phone_home_whole_number())
- || diff;
- return diff;
-}
-
-} // namespace browser_sync
-
diff --git a/chrome/browser/sync/glue/autofill_model_associator2.h b/chrome/browser/sync/glue/autofill_model_associator2.h
deleted file mode 100755
index 0ad37de..0000000
--- a/chrome/browser/sync/glue/autofill_model_associator2.h
+++ /dev/null
@@ -1,212 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SYNC_GLUE_AUTOFILL_MODEL_ASSOCIATOR2_H_
-#define CHROME_BROWSER_SYNC_GLUE_AUTOFILL_MODEL_ASSOCIATOR2_H_
-#pragma once
-
-#include <map>
-#include <set>
-#include <string>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/lock.h"
-#include "base/ref_counted.h"
-#include "chrome/browser/autofill/personal_data_manager.h"
-#include "chrome/browser/sync/engine/syncapi.h"
-#include "chrome/browser/sync/glue/model_associator.h"
-#include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
-#include "chrome/browser/webdata/autofill_entry.h"
-
-class AutoFillProfile;
-
-class ProfileSyncService;
-class WebDatabase;
-
-namespace sync_api {
-class WriteTransaction;
-}
-
-namespace browser_sync {
-
-class AutofillChangeProcessor;
-class UnrecoverableErrorHandler;
-
-extern const char kAutofillTag[];
-extern const char kAutofillProfileNamespaceTag[];
-extern const char kAutofillEntryNamespaceTag[];
-
-// Contains all model association related logic:
-// * Algorithm to associate autofill model and sync model.
-// We do not check if we have local data before this run; we always
-// merge and sync.
-class AutofillModelAssociator2
- : public PerDataTypeAssociatorInterface<std::string, std::string> {
- public:
- static syncable::ModelType model_type() { return syncable::AUTOFILL; }
- AutofillModelAssociator2(ProfileSyncService* sync_service,
- WebDatabase* web_database,
- PersonalDataManager* data_manager);
- virtual ~AutofillModelAssociator2();
-
- // A task used by this class and the change processor to inform the
- // PersonalDataManager living on the UI thread that it needs to refresh.
- class DoOptimisticRefreshTask : public Task {
- public:
- explicit DoOptimisticRefreshTask(PersonalDataManager* pdm);
- virtual ~DoOptimisticRefreshTask();
- virtual void Run();
- private:
- scoped_refptr<PersonalDataManager> pdm_;
- };
-
- // PerDataTypeAssociatorInterface implementation.
- //
- // Iterates through the sync model looking for matched pairs of items.
- virtual bool AssociateModels();
-
- // Clears all associations.
- virtual bool DisassociateModels();
-
- // The has_nodes out param is true if the sync model has nodes other
- // than the permanent tagged nodes.
- virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
-
- // See ModelAssociator interface.
- virtual void AbortAssociation();
-
- // Not implemented.
- virtual const std::string* GetChromeNodeFromSyncId(int64 sync_id);
-
- // Not implemented.
- virtual bool InitSyncNodeFromChromeId(std::string node_id,
- sync_api::BaseNode* sync_node);
-
- // Returns the sync id for the given autofill name, or sync_api::kInvalidId
- // if the autofill name is not associated to any sync id.
- virtual int64 GetSyncIdFromChromeId(std::string node_id);
-
- // Associates the given autofill name with the given sync id.
- virtual void Associate(const std::string* node, int64 sync_id);
-
- // Remove the association that corresponds to the given sync id.
- virtual void Disassociate(int64 sync_id);
-
- // Returns whether a node with the given permanent tag was found and update
- // |sync_id| with that node's id.
- virtual bool GetSyncIdForTaggedNode(const std::string& tag, int64* sync_id);
-
- static std::string KeyToTag(const string16& name, const string16& value);
- static std::string ProfileLabelToTag(const string16& label);
-
- static bool MergeTimestamps(const sync_pb::AutofillSpecifics& autofill,
- const std::vector<base::Time>& timestamps,
- std::vector<base::Time>* new_timestamps);
- static bool OverwriteProfileWithServerData(
- AutoFillProfile* merge_into,
- const sync_pb::AutofillProfileSpecifics& specifics);
-
- // TODO(georgey) : add the same processing for CC info (already in protocol
- // buffers).
-
- // Returns sync service instance.
- ProfileSyncService* sync_service() { return sync_service_; }
-
- // Compute and apply suffix to a label so that the resulting label is
- // unique in the sync database.
- // |new_non_unique_label| is the colliding label which is to be uniquified.
- // |existing_unique_label| is the current label of the object, if any; this
- // is treated as a unique label even if colliding. If no such label is
- // available, |existing_unique_label| may be empty.
- static string16 MakeUniqueLabel(const string16& new_non_unique_label,
- const string16& existing_unique_label,
- sync_api::BaseTransaction* trans);
-
- private:
- typedef std::map<std::string, int64> AutofillToSyncIdMap;
- typedef std::map<int64, std::string> SyncIdToAutofillMap;
-
- // A convenience wrapper of a bunch of state we pass around while associating
- // models, and send to the WebDatabase for persistence.
- struct DataBundle;
-
- // Helper to query WebDatabase for the current autofill state.
- bool LoadAutofillData(std::vector<AutofillEntry>* entries,
- std::vector<AutoFillProfile*>* profiles);
-
- // We split up model association first by autofill sub-type (entries, and
- // profiles. There is a Traverse* method for each of these.
- bool TraverseAndAssociateChromeAutofillEntries(
- sync_api::WriteTransaction* write_trans,
- const sync_api::ReadNode& autofill_root,
- const std::vector<AutofillEntry>& all_entries_from_db,
- std::set<AutofillKey>* current_entries,
- std::vector<AutofillEntry>* new_entries);
- bool 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);
-
- // Once the above traversals are complete, we traverse the sync model to
- // associate all remaining nodes.
- bool TraverseAndAssociateAllSyncNodes(
- sync_api::WriteTransaction* write_trans,
- const sync_api::ReadNode& autofill_root,
- DataBundle* bundle);
-
- // Helper to persist any changes that occured during model association to
- // the WebDatabase.
- bool SaveChangesToWebData(const DataBundle& bundle);
-
- // Helper to insert an AutofillEntry into the WebDatabase (e.g. in response
- // to encountering a sync node that doesn't exist yet locally).
- void AddNativeEntryIfNeeded(const sync_pb::AutofillSpecifics& autofill,
- DataBundle* bundle,
- const sync_api::ReadNode& node);
-
- // Helper to insert an AutoFillProfile into the WebDatabase (e.g. in response
- // to encountering a sync node that doesn't exist yet locally).
- void AddNativeProfileIfNeeded(
- const sync_pb::AutofillProfileSpecifics& profile,
- DataBundle* bundle,
- const sync_api::ReadNode& node);
-
- // Helper to insert a sync node for the given AutoFillProfile (e.g. in
- // response to encountering a native profile that doesn't exist yet in the
- // cloud).
- bool MakeNewAutofillProfileSyncNode(
- sync_api::WriteTransaction* trans,
- const sync_api::BaseNode& autofill_root,
- const std::string& tag,
- const AutoFillProfile& profile,
- int64* sync_id);
-
- // Called at various points in model association to determine if the
- // user requested an abort.
- bool IsAbortPending();
-
- ProfileSyncService* sync_service_;
- WebDatabase* web_database_;
- PersonalDataManager* personal_data_;
- int64 autofill_node_id_;
-
- AutofillToSyncIdMap id_map_;
- SyncIdToAutofillMap id_map_inverse_;
-
- // Abort association pending flag and lock. If this is set to true
- // (via the AbortAssociation method), return from the
- // AssociateModels method as soon as possible.
- Lock abort_association_pending_lock_;
- bool abort_association_pending_;
-
- DISALLOW_COPY_AND_ASSIGN(AutofillModelAssociator2);
-};
-
-} // namespace browser_sync
-
-#endif // CHROME_BROWSER_SYNC_GLUE_AUTOFILL_MODEL_ASSOCIATOR2_H_
-
diff --git a/chrome/browser/sync/glue/autofill_model_associator_unittest.cc b/chrome/browser/sync/glue/autofill_model_associator_unittest.cc
index a76f634..cfd7e8d 100644
--- a/chrome/browser/sync/glue/autofill_model_associator_unittest.cc
+++ b/chrome/browser/sync/glue/autofill_model_associator_unittest.cc
@@ -26,3 +26,15 @@ TEST_F(AutofillModelAssociatorTest, KeyToTag) {
AutofillModelAssociator::KeyToTag(UTF8ToUTF16(""),
UTF8ToUTF16("|")));
}
+
+TEST_F(AutofillModelAssociatorTest, ProfileLabelToTag) {
+ string16 label(ASCIIToUTF16("awesome_address"));
+ EXPECT_EQ("autofill_profile|awesome_address",
+ AutofillModelAssociator::ProfileLabelToTag(label));
+
+ EXPECT_EQ("autofill_profile|%7C%7C",
+ AutofillModelAssociator::ProfileLabelToTag(ASCIIToUTF16("||")));
+ EXPECT_NE(AutofillModelAssociator::KeyToTag(ASCIIToUTF16("autofill_profile"),
+ ASCIIToUTF16("home")),
+ AutofillModelAssociator::ProfileLabelToTag(ASCIIToUTF16("home")));
+}
diff --git a/chrome/browser/sync/glue/autofill_profile_model_associator.cc b/chrome/browser/sync/glue/autofill_profile_model_associator.cc
deleted file mode 100755
index 0680da8..0000000
--- a/chrome/browser/sync/glue/autofill_profile_model_associator.cc
+++ /dev/null
@@ -1,371 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
-
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/sync/profile_sync_service.h"
-#include "chrome/browser/webdata/web_database.h"
-
-using sync_api::ReadNode;
-namespace browser_sync {
-
-const char kAutofillProfileTag[] = "google_chrome_autofill_profile";
-
-AutofillProfileModelAssociator::AutofillProfileModelAssociator(
- ProfileSyncService* sync_service,
- WebDatabase* web_database,
- PersonalDataManager* personal_data)
- : sync_service_(sync_service),
- web_database_(web_database),
- personal_data_(personal_data),
- autofill_node_id_(sync_api::kInvalidId),
- abort_association_pending_(false) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- DCHECK(sync_service_);
- DCHECK(web_database_);
- DCHECK(personal_data_);
-}
-
-AutofillProfileModelAssociator::~AutofillProfileModelAssociator() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-}
-
-bool AutofillProfileModelAssociator::TraverseAndAssociateChromeAutoFillProfiles(
- sync_api::WriteTransaction* write_trans,
- const sync_api::ReadNode& autofill_root,
- const std::vector<AutoFillProfile*>& all_profiles_from_db,
- std::set<std::string>* current_profiles,
- std::vector<AutoFillProfile*>* updated_profiles,
- std::vector<AutoFillProfile*>* new_profiles,
- std::vector<std::string>* profiles_to_delete) {
-
- // Alias the all_profiles_from_db so we fit in 80 characters
- const std::vector<AutoFillProfile*>& profiles(all_profiles_from_db);
- for (std::vector<AutoFillProfile*>::const_iterator ix = profiles.begin();
- ix != profiles.end();
- ++ix) {
- std::string guid((*ix)->guid());
-
- ReadNode node(write_trans);
- if (node.InitByClientTagLookup(syncable::AUTOFILL_PROFILE, guid)) {
- const sync_pb::AutofillProfileSpecifics& autofill(
- node.GetAutofillProfileSpecifics());
- if (OverwriteProfileWithServerData(*ix, autofill)) {
- updated_profiles->push_back(*ix);
- }
- Associate(&guid, node.GetId());
- current_profiles->insert(guid);
- } else {
- MakeNewAutofillProfileSyncNodeIfNeeded(write_trans,
- autofill_root,
- (**ix),
- new_profiles,
- current_profiles,
- profiles_to_delete);
- }
- }
-
- return true;
-}
-
-bool AutofillProfileModelAssociator::LoadAutofillData(
- std::vector<AutoFillProfile*>* profiles) {
- if (IsAbortPending())
- return false;
-
- if (!web_database_->GetAutoFillProfiles(profiles))
- return false;
-
- return true;
-}
-
-bool AutofillProfileModelAssociator::AssociateModels() {
- VLOG(1) << "Associating Autofill Models";
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- {
- AutoLock lock(abort_association_pending_lock_);
- abort_association_pending_ = false;
- }
-
- ScopedVector<AutoFillProfile> profiles;
-
- if (!LoadAutofillData(&profiles.get())) {
- LOG(ERROR) << "Could not get the autofill data from WebDatabase.";
- return false;
- }
-
- DataBundle bundle;
- {
- // The write transaction lock is held inside this block.
- // We do all the web db operations outside this block.
- sync_api::WriteTransaction trans(
- sync_service_->backend()->GetUserShareHandle());
-
- sync_api::ReadNode autofill_root(&trans);
- if (!autofill_root.InitByTagLookup(kAutofillProfileTag)) {
- LOG(ERROR) << "Server did not create the top-level autofill node. We "
- << "might be running against an out-of-date server.";
- return false;
- }
-
- if (!TraverseAndAssociateChromeAutoFillProfiles(&trans, autofill_root,
- profiles.get(), &bundle.current_profiles,
- &bundle.updated_profiles,
- &bundle.new_profiles,
- &bundle.profiles_to_delete) ||
- !TraverseAndAssociateAllSyncNodes(&trans, autofill_root, &bundle)) {
- return false;
- }
- }
-
- if (!SaveChangesToWebData(bundle)) {
- LOG(ERROR) << "Failed to update autofill entries.";
- return false;
- }
-
- // TODO(lipalani) Bug 64111- split out the OptimisticRefreshTask
- // into its own class
- // from autofill_model_associator
- // Will be done as part of the autofill_model_associator work.
- // BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- // new DoOptimisticRefreshTask(personal_data_));
- return true;
-}
-
-bool AutofillProfileModelAssociator::DisassociateModels() {
- id_map_.clear();
- id_map_inverse_.clear();
- return true;
-}
-
-// Helper to compare the local value and cloud value of a field, merge into
-// the local value if they differ, and return whether the merge happened.
-bool AutofillProfileModelAssociator::MergeField(FormGroup* f,
- AutoFillFieldType t,
- const std::string& specifics_field) {
- if (UTF16ToUTF8(f->GetFieldText(AutoFillType(t))) == specifics_field)
- return false;
- f->SetInfo(AutoFillType(t), UTF8ToUTF16(specifics_field));
- return true;
-}
-bool AutofillProfileModelAssociator::SyncModelHasUserCreatedNodes(
- bool *has_nodes) {
- CHECK_NE(has_nodes, reinterpret_cast<bool*>(NULL));
- sync_api::ReadTransaction trans(
- sync_service_->backend()->GetUserShareHandle());
-
- sync_api::ReadNode node(&trans);
-
- if (!node.InitByClientTagLookup(
- syncable::AUTOFILL_PROFILE,
- kAutofillProfileTag)) {
- LOG(ERROR) << "Sever did not create a top level node"
- << "Out of data server or autofill type not enabled";
- return false;
- }
-
- *has_nodes = sync_api::kInvalidId != node.GetFirstChildId();
- return true;
-}
-// static
-bool AutofillProfileModelAssociator::OverwriteProfileWithServerData(
- AutoFillProfile* merge_into,
- const sync_pb::AutofillProfileSpecifics& specifics) {
- bool diff = false;
- AutoFillProfile* p = merge_into;
- const sync_pb::AutofillProfileSpecifics& s(specifics);
- diff = MergeField(p, NAME_FIRST, s.name_first()) || diff;
- diff = MergeField(p, NAME_LAST, s.name_last()) || diff;
- diff = MergeField(p, NAME_MIDDLE, s.name_middle()) || diff;
- diff = MergeField(p, ADDRESS_HOME_LINE1, s.address_home_line1()) || diff;
- diff = MergeField(p, ADDRESS_HOME_LINE2, s.address_home_line2()) || diff;
- diff = MergeField(p, ADDRESS_HOME_CITY, s.address_home_city()) || diff;
- diff = MergeField(p, ADDRESS_HOME_STATE, s.address_home_state()) || diff;
- diff = MergeField(p, ADDRESS_HOME_COUNTRY, s.address_home_country()) || diff;
- diff = MergeField(p, ADDRESS_HOME_ZIP, s.address_home_zip()) || diff;
- diff = MergeField(p, EMAIL_ADDRESS, s.email_address()) || diff;
- diff = MergeField(p, COMPANY_NAME, s.company_name()) || diff;
- diff = MergeField(p, PHONE_FAX_WHOLE_NUMBER, s.phone_fax_whole_number())
- || diff;
- diff = MergeField(p, PHONE_HOME_WHOLE_NUMBER, s.phone_home_whole_number())
- || diff;
- return diff;
-}
-
-
-int64 AutofillProfileModelAssociator::FindSyncNodeWithProfile(
- sync_api::WriteTransaction* trans,
- const sync_api::BaseNode& autofill_root,
- const AutoFillProfile& profile_from_db) {
- int64 sync_child_id = autofill_root.GetFirstChildId();
- while (sync_child_id != sync_api::kInvalidId) {
- ReadNode read_node(trans);
- AutoFillProfile p;
- if (read_node.InitByIdLookup(sync_child_id)) {
- LOG(ERROR) << "unable to find the id given by getfirst child " <<
- sync_child_id;
- return sync_api::kInvalidId;
- }
- const sync_pb::AutofillProfileSpecifics& autofill_specifics(
- read_node.GetAutofillProfileSpecifics());
- OverwriteProfileWithServerData(&p, autofill_specifics);
- if (p.Compare(profile_from_db) == 0) {
- return sync_child_id;
- }
- sync_child_id = read_node.GetSuccessorId();
- }
-
- return sync_api::kInvalidId;
-}
-bool AutofillProfileModelAssociator::MakeNewAutofillProfileSyncNodeIfNeeded(
- sync_api::WriteTransaction* trans,
- const sync_api::BaseNode& autofill_root,
- const AutoFillProfile& profile,
- std::vector<AutoFillProfile*>* new_profiles,
- std::set<std::string>* current_profiles,
- std::vector<std::string>* profiles_to_delete) {
-
- int64 sync_node_id = FindSyncNodeWithProfile(trans, autofill_root, profile);
- if (sync_node_id != sync_api::kInvalidId) {
- // In case of duplicates throw away the local profile and apply the
- // server profile.(The only difference between the 2 profiles are the guids)
- profiles_to_delete->push_back(profile.guid());
- sync_api::ReadNode read_node(trans);
- if (!read_node.InitByIdLookup(sync_node_id)) {
- LOG(ERROR);
- return false;
- }
- const sync_pb::AutofillProfileSpecifics& autofill_specifics(
- read_node.GetAutofillProfileSpecifics());
- AutoFillProfile* p = new AutoFillProfile(autofill_specifics.guid());
- OverwriteProfileWithServerData(p, autofill_specifics);
- new_profiles->push_back(p);
- std::string guid = autofill_specifics.guid();
- Associate(&guid, sync_node_id);
- current_profiles->insert(autofill_specifics.guid());
- } else {
- sync_api::WriteNode node(trans);
- if (!node.InitUniqueByCreation(
- syncable::AUTOFILL_PROFILE, autofill_root, profile.guid())) {
- LOG(ERROR) << "Failed to create autofill sync node.";
- return false;
- }
- node.SetTitle(UTF8ToWide(profile.guid()));
-
- // TODO(lipalani) -Bug 64111 This needs rewriting. This will be tackled
- // when rewriting autofill change processor.
- // AutofillChangeProcessor::WriteAutofillProfile(profile, &node);
- }
- return true;
-}
-
-bool AutofillProfileModelAssociator::TraverseAndAssociateAllSyncNodes(
- sync_api::WriteTransaction* write_trans,
- const sync_api::ReadNode& autofill_root,
- DataBundle* bundle) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-
- int64 sync_child_id = autofill_root.GetFirstChildId();
- while (sync_child_id != sync_api::kInvalidId) {
- ReadNode sync_child(write_trans);
- if (!sync_child.InitByIdLookup(sync_child_id)) {
- LOG(ERROR) << "Failed to fetch child node.";
- return false;
- }
- const sync_pb::AutofillProfileSpecifics& autofill(
- sync_child.GetAutofillProfileSpecifics());
-
- AddNativeProfileIfNeeded(autofill, bundle, sync_child);
-
- sync_child_id = sync_child.GetSuccessorId();
- }
- return true;
-}
-
-void AutofillProfileModelAssociator::AddNativeProfileIfNeeded(
- const sync_pb::AutofillProfileSpecifics& profile,
- DataBundle* bundle,
- const sync_api::ReadNode& node) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-
- if (bundle->current_profiles.find(profile.guid()) ==
- bundle->current_profiles.end()) {
- std::string guid(profile.guid());
- Associate(&guid, node.GetId());
- AutoFillProfile* p = new AutoFillProfile(profile.guid());
- OverwriteProfileWithServerData(p, profile);
- bundle->new_profiles.push_back(p);
- }
-}
-
-bool AutofillProfileModelAssociator::SaveChangesToWebData(
- const DataBundle& bundle) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
-
- if (IsAbortPending())
- return false;
-
- for (size_t i = 0; i < bundle.new_profiles.size(); i++) {
- if (IsAbortPending())
- return false;
- if (!web_database_->AddAutoFillProfile(*bundle.new_profiles[i]))
- return false;
- }
-
- for (size_t i = 0; i < bundle.updated_profiles.size(); i++) {
- if (IsAbortPending())
- return false;
- if (!web_database_->UpdateAutoFillProfile(*bundle.updated_profiles[i]))
- return false;
- }
-
- for (size_t i = 0; i< bundle.profiles_to_delete.size(); ++i) {
- if (IsAbortPending())
- return false;
- if (!web_database_->RemoveAutoFillProfile(bundle.profiles_to_delete[i]))
- return false;
- }
- return true;
-}
-
-void AutofillProfileModelAssociator::Associate(
- const std::string* autofill,
- int64 sync_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- DCHECK_NE(sync_api::kInvalidId, sync_id);
- DCHECK(id_map_.find(*autofill) == id_map_.end());
- DCHECK(id_map_inverse_.find(sync_id) == id_map_inverse_.end());
- id_map_[*autofill] = sync_id;
- id_map_inverse_[sync_id] = *autofill;
-}
-
-void AutofillProfileModelAssociator::Disassociate(int64 sync_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
- SyncIdToAutofillMap::iterator iter = id_map_inverse_.find(sync_id);
- if (iter == id_map_inverse_.end())
- return;
- CHECK(id_map_.erase(iter->second));
- id_map_inverse_.erase(iter);
-}
-
-int64 AutofillProfileModelAssociator::GetSyncIdFromChromeId(
- const std::string autofill) {
- AutofillToSyncIdMap::const_iterator iter = id_map_.find(autofill);
- return iter == id_map_.end() ? sync_api::kInvalidId : iter->second;
-}
-
-void AutofillProfileModelAssociator::AbortAssociation() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- AutoLock lock(abort_association_pending_lock_);
- abort_association_pending_ = true;
-}
-
-bool AutofillProfileModelAssociator::IsAbortPending() {
- AutoLock lock(abort_association_pending_lock_);
- return abort_association_pending_;
-}
-
-} // namespace browser_sync
-
diff --git a/chrome/browser/sync/glue/autofill_profile_model_associator_unittest.cc b/chrome/browser/sync/glue/autofill_profile_model_associator_unittest.cc
deleted file mode 100755
index ee6a9fc..0000000
--- a/chrome/browser/sync/glue/autofill_profile_model_associator_unittest.cc
+++ /dev/null
@@ -1,261 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/utf_string_conversions.h"
-#include "chrome/browser/sync/engine/read_node_mock.h"
-#include "chrome/browser/sync/engine/syncapi_mock.h"
-#include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
-#include "chrome/browser/sync/syncable/syncable.h"
-#include "chrome/browser/sync/syncable/syncable_mock.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using ::testing::_;
-using ::testing::Return;
-using ::testing::DoDefault;
-using ::testing::ReturnRef;
-using ::testing::Pointee;
-using ::testing::Ref;
-using ::testing::Invoke;
-class AutoFillProfile;
-
-using browser_sync::AutofillProfileModelAssociator;
-
-// Note this is not a generic mock. This is a mock used to
-// test AutofillProfileModelAssociator class itself by mocking
-// other functions that are called by the functions we need to test.
-class MockAutofillProfileModelAssociator
- : public AutofillProfileModelAssociator {
- public:
- MockAutofillProfileModelAssociator() {
- }
- virtual ~MockAutofillProfileModelAssociator() {}
- bool TraverseAndAssociateChromeAutoFillProfilesWrapper(
- sync_api::WriteTransaction* write_trans,
- const sync_api::ReadNode& autofill_root,
- const std::vector<AutoFillProfile*>& all_profiles_from_db,
- std::set<std::string>* current_profiles,
- std::vector<AutoFillProfile*>* updated_profiles,
- std::vector<AutoFillProfile*>* new_profiles,
- std::vector<std::string>* profiles_to_delete) {
- return TraverseAndAssociateChromeAutoFillProfiles(write_trans,
- autofill_root,
- all_profiles_from_db,
- current_profiles,
- updated_profiles,
- new_profiles,
- profiles_to_delete);
- }
- MOCK_METHOD3(AddNativeProfileIfNeeded,
- void(const sync_pb::AutofillProfileSpecifics&,
- DataBundle*,
- const sync_api::ReadNode&));
- MOCK_METHOD2(OverwriteProfileWithServerData,
- bool(AutoFillProfile*,
- const sync_pb::AutofillProfileSpecifics&));
- MOCK_METHOD6(MakeNewAutofillProfileSyncNodeIfNeeded,
- bool(sync_api::WriteTransaction*,
- const sync_api::BaseNode&,
- const AutoFillProfile&,
- std::vector<AutoFillProfile*>*,
- std::set<std::string>*,
- std::vector<std::string>*));
- MOCK_METHOD2(Associate, void(const std::string*, int64));
-
- bool TraverseAndAssociateAllSyncNodesWrapper(
- sync_api::WriteTransaction *trans,
- const sync_api::ReadNode &autofill_root,
- browser_sync::AutofillProfileModelAssociator::DataBundle *bundle) {
- return TraverseAndAssociateAllSyncNodes(trans, autofill_root, bundle);
- }
-
- void AddNativeProfileIfNeededWrapper(
- const sync_pb::AutofillProfileSpecifics& profile,
- DataBundle* bundle,
- const sync_api::ReadNode& node) {
- AutofillProfileModelAssociator::AddNativeProfileIfNeeded(
- profile,
- bundle,
- node);
- }
-};
-
-class AutofillProfileModelAssociatorTest : public testing::Test {
- public:
- AutofillProfileModelAssociatorTest()
- : db_thread_(BrowserThread::DB, &message_loop_) {}
-
- protected:
- MessageLoop message_loop_;
- BrowserThread db_thread_;
- MockAutofillProfileModelAssociator associator_;
-};
-
-TEST_F(AutofillProfileModelAssociatorTest,
- TestAssociateProfileInWebDBWithSyncDB) {
- ScopedVector<AutoFillProfile> profiles_from_web_db;
- std::string guid = "abc";
-
- sync_pb::EntitySpecifics specifics;
- MockDirectory mock_directory;
- sync_pb::AutofillProfileSpecifics *profile_specifics =
- specifics.MutableExtension(sync_pb::autofill_profile);
-
- profile_specifics->set_guid(guid);
-
- std::set<std::string> current_profiles;
-
- // This will be released inside the function
- // TraverseAndAssociateChromeAutofillProfiles
- AutoFillProfile *profile = new AutoFillProfile(guid);
-
- // Set up the entry kernel with what we want.
- EntryKernel kernel;
- kernel.put(syncable::SPECIFICS, specifics);
- kernel.put(syncable::META_HANDLE, 1);
-
- MockWriteTransaction write_trans(&mock_directory);
- EXPECT_CALL(mock_directory, GetEntryByClientTag(_))
- .WillOnce(Return(&kernel));
-
- sync_api::ReadNode read_node(&write_trans);
-
- EXPECT_CALL(associator_, Associate(Pointee(guid), 1));
-
- profiles_from_web_db.push_back(profile);
-
- associator_.TraverseAndAssociateChromeAutoFillProfilesWrapper(&write_trans,
- read_node,
- profiles_from_web_db.get(),
- &current_profiles,
- NULL,
- NULL,
- NULL);
-
- EXPECT_EQ((unsigned int)1, current_profiles.size());
-}
-
-TEST_F(AutofillProfileModelAssociatorTest, TestAssociatingMissingWebDBProfile) {
- ScopedVector<AutoFillProfile> profiles_from_web_db;
- MockDirectory mock_directory;
-
- MockWriteTransaction write_trans(&mock_directory);
- EXPECT_CALL(mock_directory,
- GetEntryByClientTag(_))
- .WillOnce(Return(reinterpret_cast<EntryKernel*>(NULL)));
-
- sync_api::ReadNode autofill_root(&write_trans);
-
- std::string guid = "abc";
- std::set<std::string> current_profiles;
- AutoFillProfile *profile = new AutoFillProfile(guid);
-
- EXPECT_CALL(associator_,
- MakeNewAutofillProfileSyncNodeIfNeeded(&write_trans,
- Ref(autofill_root),
- Ref(*profile),
- _,
- &current_profiles,
- NULL))
- .WillOnce(Return(true));
-
- profiles_from_web_db.push_back(profile);
-
- associator_.TraverseAndAssociateChromeAutoFillProfilesWrapper(&write_trans,
- autofill_root,
- profiles_from_web_db.get(),
- &current_profiles,
- NULL,
- NULL,
- NULL);
-}
-
-TEST_F(AutofillProfileModelAssociatorTest,
- TestAssociateProfileInSyncDBWithWebDB) {
- ReadNodeMock autofill_root;
-
- // The constrcutor itself will initialize the id to root.
- syncable::Id root_id;
-
- sync_pb::EntitySpecifics specifics;
- MockDirectory mock_directory;
- sync_pb::AutofillProfileSpecifics *profile_specifics =
- specifics.MutableExtension(sync_pb::autofill_profile);
-
- profile_specifics->set_guid("abc");
-
- // Set up the entry kernel with what we want.
- EntryKernel kernel;
- kernel.put(syncable::SPECIFICS, specifics);
- kernel.put(syncable::META_HANDLE, 1);
- kernel.put(syncable::ID, root_id);
-
- MockWriteTransaction write_trans(&mock_directory);
-
- browser_sync::AutofillProfileModelAssociator::DataBundle bundle;
-
- EXPECT_CALL(autofill_root, GetFirstChildId())
- .WillOnce(Return(1));
-
- EXPECT_CALL(mock_directory,
- GetEntryByHandle(_))
- .WillOnce(Return(&kernel));
-
- EXPECT_CALL(associator_,
- AddNativeProfileIfNeeded(_,
- &bundle,
- _));
-
- associator_.TraverseAndAssociateAllSyncNodesWrapper(&write_trans,
- autofill_root,
- &bundle);
-}
-
-TEST_F(AutofillProfileModelAssociatorTest, TestDontNeedToAddNativeProfile) {
- ::testing::StrictMock<MockAutofillProfileModelAssociator> associator;
- sync_pb::AutofillProfileSpecifics profile_specifics;
- ReadNodeMock read_node;
- std::string guid = "abc";
- std::set<std::string> current_profiles;
- browser_sync::AutofillProfileModelAssociator::DataBundle bundle;
-
- profile_specifics.set_guid(guid);
-
- bundle.current_profiles.insert(guid);
-
- // We have no expectations to set. We have used a strict mock.
- // If the profile is already present no other function
- // should be called.
- associator.AddNativeProfileIfNeededWrapper(profile_specifics, &bundle,
- read_node);
-}
-
-TEST_F(AutofillProfileModelAssociatorTest, TestNeedToAddNativeProfile) {
- sync_pb::AutofillProfileSpecifics profile_specifics;
- ReadNodeMock read_node;
- std::string guid = "abc";
- std::set<std::string> current_profiles;
- browser_sync::AutofillProfileModelAssociator::DataBundle bundle;
- std::string first_name = "lingesh";
-
- profile_specifics.set_guid(guid);
- profile_specifics.set_name_first(first_name);
-
- EXPECT_CALL(read_node, GetId())
- .WillOnce(Return(1));
-
- EXPECT_CALL(associator_,
- Associate(Pointee(guid), 1));
-
- associator_.AddNativeProfileIfNeededWrapper(
- profile_specifics,
- &bundle,
- read_node);
-
- EXPECT_EQ(bundle.new_profiles.size(), (unsigned int)1);
- EXPECT_EQ(
- bundle.new_profiles.front()->GetFieldText(AutoFillType(NAME_FIRST)),
- UTF8ToUTF16(first_name));
-}
-
diff --git a/chrome/browser/sync/profile_sync_factory_impl.cc b/chrome/browser/sync/profile_sync_factory_impl.cc
index 3e3945e5..ed8f429 100644
--- a/chrome/browser/sync/profile_sync_factory_impl.cc
+++ b/chrome/browser/sync/profile_sync_factory_impl.cc
@@ -7,10 +7,8 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/sync/glue/app_data_type_controller.h"
#include "chrome/browser/sync/glue/autofill_change_processor.h"
-#include "chrome/browser/sync/glue/autofill_change_processor2.h"
#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
#include "chrome/browser/sync/glue/autofill_model_associator.h"
-#include "chrome/browser/sync/glue/autofill_model_associator2.h"
#include "chrome/browser/sync/glue/bookmark_change_processor.h"
#include "chrome/browser/sync/glue/bookmark_data_type_controller.h"
#include "chrome/browser/sync/glue/bookmark_model_associator.h"
@@ -42,10 +40,8 @@
using browser_sync::AppDataTypeController;
using browser_sync::AutofillChangeProcessor;
-using browser_sync::AutofillChangeProcessor2;
using browser_sync::AutofillDataTypeController;
using browser_sync::AutofillModelAssociator;
-using browser_sync::AutofillModelAssociator2;
using browser_sync::BookmarkChangeProcessor;
using browser_sync::BookmarkDataTypeController;
using browser_sync::BookmarkModelAssociator;
@@ -176,30 +172,16 @@ ProfileSyncFactoryImpl::CreateAutofillSyncComponents(
WebDatabase* web_database,
PersonalDataManager* personal_data,
browser_sync::UnrecoverableErrorHandler* error_handler) {
-
- if (command_line_->HasSwitch(switches::kEnableSyncNewAutofill)) {
- AutofillModelAssociator* model_associator =
- new AutofillModelAssociator(profile_sync_service,
- web_database,
- personal_data);
- AutofillChangeProcessor* change_processor =
- new AutofillChangeProcessor(model_associator,
- web_database,
- personal_data,
- error_handler);
- return SyncComponents(model_associator, change_processor);
- } else {
- AutofillModelAssociator2* model_associator =
- new AutofillModelAssociator2(profile_sync_service,
- web_database,
- personal_data);
- AutofillChangeProcessor2* change_processor =
- new AutofillChangeProcessor2(model_associator,
- web_database,
- personal_data,
- error_handler);
- return SyncComponents(model_associator, change_processor);
- }
+ AutofillModelAssociator* model_associator =
+ new AutofillModelAssociator(profile_sync_service,
+ web_database,
+ personal_data);
+ AutofillChangeProcessor* change_processor =
+ new AutofillChangeProcessor(model_associator,
+ web_database,
+ personal_data,
+ error_handler);
+ return SyncComponents(model_associator, change_processor);
}
ProfileSyncFactory::SyncComponents
diff --git a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
index a7b929a..17354b0 100644
--- a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
+++ b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc
@@ -24,10 +24,8 @@
#include "chrome/browser/sync/engine/syncapi.h"
#include "chrome/browser/sync/engine/syncer_util.h"
#include "chrome/browser/sync/glue/autofill_change_processor.h"
-#include "chrome/browser/sync/glue/autofill_change_processor2.h"
#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
#include "chrome/browser/sync/glue/autofill_model_associator.h"
-#include "chrome/browser/sync/glue/autofill_model_associator2.h"
#include "chrome/browser/sync/profile_sync_factory.h"
#include "chrome/browser/sync/profile_sync_service.h"
#include "chrome/browser/sync/profile_sync_test_util.h"
@@ -47,9 +45,9 @@
using base::Time;
using base::WaitableEvent;
-using browser_sync::AutofillChangeProcessor2;
+using browser_sync::AutofillChangeProcessor;
using browser_sync::AutofillDataTypeController;
-using browser_sync::AutofillModelAssociator2;
+using browser_sync::AutofillModelAssociator;
using browser_sync::GROUP_DB;
using browser_sync::kAutofillTag;
using browser_sync::SyncBackendHostForProfileSyncTest;
@@ -130,10 +128,10 @@ ACTION_P4(MakeAutofillSyncComponents, service, wd, pdm, dtc) {
EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::DB));
if (!BrowserThread::CurrentlyOn(BrowserThread::DB))
return ProfileSyncFactory::SyncComponents(NULL, NULL);
- AutofillModelAssociator2* model_associator =
- new AutofillModelAssociator2(service, wd, pdm);
- AutofillChangeProcessor2* change_processor =
- new AutofillChangeProcessor2(model_associator, wd, pdm, dtc);
+ AutofillModelAssociator* model_associator =
+ new AutofillModelAssociator(service, wd, pdm);
+ AutofillChangeProcessor* change_processor =
+ new AutofillChangeProcessor(model_associator, wd, pdm, dtc);
return ProfileSyncFactory::SyncComponents(model_associator,
change_processor);
}
@@ -214,12 +212,12 @@ class ProfileSyncServiceAutofillTest : public AbstractProfileSyncServiceTest {
return false;
sync_api::WriteNode node(&trans);
- std::string tag = AutofillModelAssociator2::KeyToTag(entry.key().name(),
+ std::string tag = AutofillModelAssociator::KeyToTag(entry.key().name(),
entry.key().value());
if (!node.InitUniqueByCreation(syncable::AUTOFILL, autofill_root, tag))
return false;
- AutofillChangeProcessor2::WriteAutofillEntry(entry, &node);
+ AutofillChangeProcessor::WriteAutofillEntry(entry, &node);
return true;
}
@@ -230,11 +228,11 @@ class ProfileSyncServiceAutofillTest : public AbstractProfileSyncServiceTest {
if (!autofill_root.InitByTagLookup(browser_sync::kAutofillTag))
return false;
sync_api::WriteNode node(&trans);
- std::string tag = browser_sync::AutofillModelAssociator2::ProfileLabelToTag(
+ std::string tag = AutofillModelAssociator::ProfileLabelToTag(
profile.Label());
if (!node.InitUniqueByCreation(syncable::AUTOFILL, autofill_root, tag))
return false;
- AutofillChangeProcessor2::WriteAutofillProfile(profile, &node);
+ AutofillChangeProcessor::WriteAutofillProfile(profile, &node);
sync_pb::AutofillSpecifics s(node.GetAutofillSpecifics());
s.mutable_profile()->set_label(UTF16ToUTF8(profile.Label()));
node.SetAutofillSpecifics(s);
@@ -269,7 +267,7 @@ class ProfileSyncServiceAutofillTest : public AbstractProfileSyncServiceTest {
} else if (autofill.has_profile()) {
AutoFillProfile p;
p.set_label(UTF8ToUTF16(autofill.profile().label()));
- AutofillModelAssociator2::OverwriteProfileWithServerData(&p,
+ AutofillModelAssociator::OverwriteProfileWithServerData(&p,
autofill.profile());
profiles->push_back(p);
}
@@ -392,7 +390,7 @@ class FakeServerUpdater: public base::RefCountedThreadSafe<FakeServerUpdater> {
ASSERT_TRUE(dir.good());
// Create autofill protobuf
- std::string tag = AutofillModelAssociator2::KeyToTag(entry_.key().name(),
+ std::string tag = AutofillModelAssociator::KeyToTag(entry_.key().name(),
entry_.key().value());
sync_pb::AutofillSpecifics new_autofill;
new_autofill.set_name(UTF16ToUTF8(entry_.key().name()));
diff --git a/chrome/browser/sync/syncable/model_type.cc b/chrome/browser/sync/syncable/model_type.cc
index c95daa8..7a7d3f1 100644
--- a/chrome/browser/sync/syncable/model_type.cc
+++ b/chrome/browser/sync/syncable/model_type.cc
@@ -37,9 +37,6 @@ void AddDefaultExtensionValue(syncable::ModelType datatype,
case AUTOFILL:
specifics->MutableExtension(sync_pb::autofill);
break;
- case AUTOFILL_PROFILE:
- specifics->MutableExtension(sync_pb::autofill_profile);
- break;
case THEMES:
specifics->MutableExtension(sync_pb::theme);
break;
@@ -107,9 +104,6 @@ ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
if (specifics.HasExtension(sync_pb::autofill))
return AUTOFILL;
- if (specifics.HasExtension(sync_pb::autofill_profile))
- return AUTOFILL_PROFILE;
-
if (specifics.HasExtension(sync_pb::theme))
return THEMES;
@@ -267,9 +261,6 @@ const char kExtensionNotificationType[] = "EXTENSION";
const char kNigoriNotificationType[] = "NIGORI";
const char kAppNotificationType[] = "APP";
const char kSessionNotificationType[] = "SESSION";
-// TODO(lipalani) Bug 64111.
-// talk to akalin to make sure this is what I understand this to be.
-const char kAutofillProfileType[] = "AUTOFILL_PROFILE";
// TODO(akalin): This is a hack to make new sync data types work with
// server-issued notifications. Remove this when it's not needed
// anymore.
@@ -309,9 +300,6 @@ bool RealModelTypeToNotificationType(ModelType model_type,
case SESSIONS:
*notification_type = kSessionNotificationType;
return true;
- case AUTOFILL_PROFILE:
- *notification_type = kAutofillProfileType;
- return true;
// TODO(akalin): This is a hack to make new sync data types work with
// server-issued notifications. Remove this when it's not needed
// anymore.
diff --git a/chrome/browser/sync/syncable/model_type.h b/chrome/browser/sync/syncable/model_type.h
index 442e462..2831bd2 100644
--- a/chrome/browser/sync/syncable/model_type.h
+++ b/chrome/browser/sync/syncable/model_type.h
@@ -51,8 +51,6 @@ enum ModelType {
PASSWORDS,
// An autofill folder or an autofill object.
AUTOFILL,
- // An autofill Profile Object
- AUTOFILL_PROFILE,
// A themes folder or a themes object.
THEMES,
// A typed_url folder or a typed_url object.
diff --git a/chrome/browser/sync/syncable/syncable.cc b/chrome/browser/sync/syncable/syncable.cc
index 903b71d..99cc2ba 100644
--- a/chrome/browser/sync/syncable/syncable.cc
+++ b/chrome/browser/sync/syncable/syncable.cc
@@ -352,12 +352,12 @@ EntryKernel* Directory::GetEntryByServerTag(const string& tag) {
return NULL;
}
-EntryKernel* Directory::GetEntryByHandle(int64 metahandle) {
+EntryKernel* Directory::GetEntryByHandle(const int64 metahandle) {
ScopedKernelLock lock(this);
return GetEntryByHandle(metahandle, &lock);
}
-EntryKernel* Directory::GetEntryByHandle(int64 metahandle,
+EntryKernel* Directory::GetEntryByHandle(const int64 metahandle,
ScopedKernelLock* lock) {
// Look up in memory
kernel_->needle.put(META_HANDLE, metahandle);
@@ -998,21 +998,12 @@ void BaseTransaction::Lock() {
}
BaseTransaction::BaseTransaction(Directory* directory, const char* name,
- const char* source_file, int line, WriterTag writer)
+ const char* source_file, int line, WriterTag writer)
: directory_(directory), dirkernel_(directory->kernel_), name_(name),
source_file_(source_file), line_(line), writer_(writer) {
Lock();
}
-BaseTransaction::BaseTransaction(Directory* directory)
- : directory_(directory),
- dirkernel_(NULL),
- name_(NULL),
- source_file_(NULL),
- line_(NULL),
- writer_(INVALID) {
-}
-
BaseTransaction::~BaseTransaction() {}
void BaseTransaction::UnlockAndLog(OriginalEntries* originals_arg) {
@@ -1107,11 +1098,6 @@ WriteTransaction::WriteTransaction(const ScopedDirLookup& scoped_dir,
originals_(new OriginalEntries) {
}
-WriteTransaction::WriteTransaction(Directory *directory)
- : BaseTransaction(directory),
- originals_(new OriginalEntries) {
-}
-
void WriteTransaction::SaveOriginal(EntryKernel* entry) {
if (NULL == entry)
return;
diff --git a/chrome/browser/sync/syncable/syncable.h b/chrome/browser/sync/syncable/syncable.h
index 19d98ee..c26232f7 100644
--- a/chrome/browser/sync/syncable/syncable.h
+++ b/chrome/browser/sync/syncable/syncable.h
@@ -726,7 +726,7 @@ class Directory {
// an account. We keep this for each datatype. It doesn't actually map
// to any time scale; its name is an historical artifact.
int64 last_download_timestamp(ModelType type) const;
- virtual void set_last_download_timestamp(ModelType type, int64 value);
+ void set_last_download_timestamp(ModelType type, int64 value);
// Find the model type or model types which have the least timestamp, and
// return them along with the types having that timestamp. This is done
@@ -773,12 +773,11 @@ class Directory {
browser_sync::ChannelEventHandler<DirectoryChangeEvent>* observer);
protected: // for friends, mainly used by Entry constructors
- virtual EntryKernel* GetEntryByHandle(int64 handle);
- virtual EntryKernel* GetEntryByHandle(int64 metahandle,
- ScopedKernelLock* lock);
- virtual EntryKernel* GetEntryById(const Id& id);
+ EntryKernel* GetEntryByHandle(const int64 handle);
+ EntryKernel* GetEntryByHandle(const int64 metahandle, ScopedKernelLock* lock);
+ EntryKernel* GetEntryById(const Id& id);
EntryKernel* GetEntryByServerTag(const std::string& tag);
- virtual EntryKernel* GetEntryByClientTag(const std::string& tag);
+ EntryKernel* GetEntryByClientTag(const std::string& tag);
EntryKernel* GetRootEntry();
bool ReindexId(EntryKernel* const entry, const Id& new_id);
void ReindexParentId(EntryKernel* const entry, const Id& new_parent_id);
@@ -824,7 +823,7 @@ class Directory {
// Find the first or last child in the positional ordering under a parent,
// and return its id. Returns a root Id if parent has no children.
- virtual Id GetFirstChildId(BaseTransaction* trans, const Id& parent_id);
+ Id GetFirstChildId(BaseTransaction* trans, const Id& parent_id);
Id GetLastChildId(BaseTransaction* trans, const Id& parent_id);
// SaveChanges works by taking a consistent snapshot of the current Directory
@@ -1059,9 +1058,6 @@ class BaseTransaction {
BaseTransaction(Directory* directory, const char* name,
const char* source_file, int line, WriterTag writer);
- // For unit testing. Everything will be mocked out no point initializing.
- explicit BaseTransaction(Directory* directory);
-
void UnlockAndLog(OriginalEntries* entries);
bool NotifyTransactionChangingAndEnding(OriginalEntries* entries);
virtual void NotifyTransactionComplete();
@@ -1116,8 +1112,6 @@ class WriteTransaction : public BaseTransaction {
// is done.
OriginalEntries* const originals_;
- explicit WriteTransaction(Directory *directory);
-
DISALLOW_COPY_AND_ASSIGN(WriteTransaction);
};
diff --git a/chrome/browser/sync/syncable/syncable_mock.h b/chrome/browser/sync/syncable/syncable_mock.h
deleted file mode 100755
index 9412fe0..0000000
--- a/chrome/browser/sync/syncable/syncable_mock.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_MOCK_H_
-#define CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_MOCK_H_
-#pragma once
-
-#include <string>
-
-#include "chrome/browser/sync/syncable/syncable.h"
-#include "testing/gmock/include/gmock/gmock.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-using syncable::Directory;
-using syncable::EntryKernel;
-
-class MockDirectory : public Directory {
- public:
- MockDirectory() {
- init_kernel("myk");
- }
- MOCK_METHOD1(GetEntryByHandle, syncable::EntryKernel*(int64));
-
- MOCK_METHOD2(set_last_downloadstamp, void(syncable::ModelType, int64));
-
- MOCK_METHOD1(GetEntryByClientTag,
- syncable::EntryKernel*(const std::string&));
-};
-
-class MockSyncableWriteTransaction : public syncable::WriteTransaction {
- public:
- explicit MockSyncableWriteTransaction(Directory *directory) :
- WriteTransaction(directory, syncable::UNITTEST, "dontcare.cpp", 25) {
- }
-};
-
-
-#endif // CHROME_BROWSER_SYNC_SYNCABLE_SYNCABLE_MOCK_H_
-