diff options
Diffstat (limited to 'chrome/browser')
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(), - ×tamps)) { - 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(), - ×tamps)) { - 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(), ×tamps)) { - 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(), - ¤t_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), - _, - ¤t_profiles, - NULL)) - .WillOnce(Return(true)); - - profiles_from_web_db.push_back(profile); - - associator_.TraverseAndAssociateChromeAutoFillProfilesWrapper(&write_trans, - autofill_root, - profiles_from_web_db.get(), - ¤t_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_ - |