| Index: chrome/browser/sync/glue/autofill_profile_change_processor.cc
|
| ===================================================================
|
| --- chrome/browser/sync/glue/autofill_profile_change_processor.cc (revision 99989)
|
| +++ chrome/browser/sync/glue/autofill_profile_change_processor.cc (working copy)
|
| @@ -1,350 +0,0 @@
|
| -// Copyright (c) 2011 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_change_processor.h"
|
| -
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/string_util.h"
|
| -#include "base/tracked.h"
|
| -#include "base/utf_string_conversions.h"
|
| -#include "chrome/browser/autofill/autofill_profile.h"
|
| -#include "chrome/browser/autofill/personal_data_manager.h"
|
| -#include "chrome/browser/sync/glue/autofill_profile_model_associator.h"
|
| -#include "chrome/browser/sync/glue/change_processor.h"
|
| -#include "chrome/browser/sync/glue/do_optimistic_refresh_task.h"
|
| -#include "chrome/browser/sync/internal_api/read_node.h"
|
| -#include "chrome/browser/sync/internal_api/sync_manager.h"
|
| -#include "chrome/browser/sync/internal_api/write_node.h"
|
| -#include "chrome/browser/sync/internal_api/write_transaction.h"
|
| -#include "chrome/browser/sync/unrecoverable_error_handler.h"
|
| -#include "chrome/browser/webdata/autofill_change.h"
|
| -#include "chrome/browser/webdata/autofill_table.h"
|
| -#include "chrome/browser/webdata/web_database.h"
|
| -#include "chrome/common/chrome_notification_types.h"
|
| -#include "chrome/common/guid.h"
|
| -#include "content/common/notification_registrar.h"
|
| -#include "content/common/notification_service.h"
|
| -
|
| -namespace browser_sync {
|
| -
|
| -AutofillProfileChangeProcessor::AutofillProfileChangeProcessor(
|
| - AutofillProfileModelAssociator *model_associator,
|
| - WebDatabase* web_database,
|
| - PersonalDataManager* personal_data_manager,
|
| - UnrecoverableErrorHandler* error_handler)
|
| - : ChangeProcessor(error_handler),
|
| - model_associator_(model_associator),
|
| - observing_(false),
|
| - web_database_(web_database),
|
| - personal_data_(personal_data_manager) {
|
| - DCHECK(model_associator);
|
| - DCHECK(web_database);
|
| - DCHECK(error_handler);
|
| - DCHECK(personal_data_manager);
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
|
| -
|
| - StartObserving();
|
| -}
|
| -
|
| -AutofillProfileChangeProcessor::~AutofillProfileChangeProcessor() {}
|
| -
|
| -void AutofillProfileChangeProcessor::ApplyChangesFromSyncModel(
|
| - const sync_api::BaseTransaction *write_trans,
|
| - const sync_api::SyncManager::ChangeRecord* changes,
|
| - int change_count) {
|
| -
|
| - ScopedStopObserving<AutofillProfileChangeProcessor> observer(this);
|
| -
|
| - sync_api::ReadNode autofill_profile_root(write_trans);
|
| - if (!autofill_profile_root.InitByTagLookup(kAutofillProfileTag)) {
|
| - error_handler()->OnUnrecoverableError(FROM_HERE,
|
| - "Autofill Profile root node lookup failed");
|
| - return;
|
| - }
|
| -
|
| - for (int i = 0; i < change_count; ++i) {
|
| - if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
|
| - changes[i].action) {
|
| - DCHECK(changes[i].specifics.HasExtension(
|
| - sync_pb::autofill_profile));
|
| -
|
| - const sync_pb::AutofillProfileSpecifics& specifics =
|
| - changes[i].specifics.GetExtension(sync_pb::autofill_profile);
|
| -
|
| - autofill_changes_.push_back(AutofillProfileChangeRecord(changes[i].action,
|
| - changes[i].id,
|
| - specifics));
|
| - continue;
|
| - }
|
| -
|
| - // If it is not a delete.
|
| - sync_api::ReadNode sync_node(write_trans);
|
| - if (!sync_node.InitByIdLookup(changes[i].id)) {
|
| - LOG(ERROR) << "Could not find the id in sync db " << changes[i].id;
|
| - continue;
|
| - }
|
| -
|
| - const sync_pb::AutofillProfileSpecifics& autofill(
|
| - sync_node.GetAutofillProfileSpecifics());
|
| -
|
| - autofill_changes_.push_back(AutofillProfileChangeRecord(changes[i].action,
|
| - changes[i].id,
|
| - autofill));
|
| - }
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::Observe(int type,
|
| - const NotificationSource& source,
|
| - const NotificationDetails& details) {
|
| - DCHECK_EQ(type, chrome::NOTIFICATION_AUTOFILL_PROFILE_CHANGED);
|
| - WebDataService* wds = Source<WebDataService>(source).ptr();
|
| -
|
| - if (!wds || wds->GetDatabase() != web_database_)
|
| - return;
|
| -
|
| - sync_api::WriteTransaction trans(FROM_HERE, share_handle());
|
| - sync_api::ReadNode autofill_root(&trans);
|
| - if (!autofill_root.InitByTagLookup(kAutofillProfileTag)) {
|
| - error_handler()->OnUnrecoverableError(FROM_HERE,
|
| - "Server did not create a tolp level node");
|
| - return;
|
| - }
|
| -
|
| - AutofillProfileChange* change = Details<AutofillProfileChange>(details).ptr();
|
| -
|
| - ActOnChange(change, &trans, autofill_root);
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::ActOnChange(
|
| - AutofillProfileChange* change,
|
| - sync_api::WriteTransaction* trans,
|
| - sync_api::ReadNode& autofill_root) {
|
| - DCHECK(change->type() == AutofillProfileChange::REMOVE || change->profile());
|
| - switch (change->type()) {
|
| - case AutofillProfileChange::ADD: {
|
| - AddAutofillProfileSyncNode(trans, autofill_root, *(change->profile()));
|
| - break;
|
| - }
|
| - case AutofillProfileChange::UPDATE: {
|
| - int64 sync_id = model_associator_->GetSyncIdFromChromeId(change->key());
|
| - if (sync_api::kInvalidId == sync_id) {
|
| - LOG(ERROR) << "Sync id is not found for " << change->key();
|
| - break;
|
| - }
|
| - sync_api::WriteNode node(trans);
|
| - if (!node.InitByIdLookup(sync_id)) {
|
| - LOG(ERROR) << "Could not find sync node for id " << sync_id;
|
| - break;
|
| - }
|
| -
|
| - WriteAutofillProfile(*(change->profile()), &node);
|
| - break;
|
| - }
|
| - case AutofillProfileChange::REMOVE: {
|
| - int64 sync_id = model_associator_->GetSyncIdFromChromeId(change->key());
|
| - if (sync_api::kInvalidId == sync_id) {
|
| - LOG(ERROR) << "Sync id is not found for " << change->key();
|
| - break;
|
| - }
|
| - sync_api::WriteNode node(trans);
|
| - if (!node.InitByIdLookup(sync_id)) {
|
| - LOG(ERROR) << "Could not find sync node for id " << sync_id;
|
| - break;
|
| - }
|
| - node.Remove();
|
| - model_associator_->Disassociate(sync_id);
|
| - break;
|
| - }
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::CommitChangesFromSyncModel() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
|
| -
|
| - if (!running())
|
| - return;
|
| -
|
| - ScopedStopObserving<AutofillProfileChangeProcessor> observer(this);
|
| -
|
| - for (unsigned int i = 0;i < autofill_changes_.size(); ++i) {
|
| - if (sync_api::SyncManager::ChangeRecord::ACTION_DELETE ==
|
| - autofill_changes_[i].action_) {
|
| - if (!web_database_->GetAutofillTable()->RemoveAutofillProfile(
|
| - autofill_changes_[i].profile_specifics_.guid())) {
|
| - LOG(ERROR) << "could not delete the profile " <<
|
| - autofill_changes_[i].profile_specifics_.guid();
|
| - continue;
|
| - }
|
| - continue;
|
| - }
|
| -
|
| - // Now for updates and adds.
|
| - ApplyAutofillProfileChange(autofill_changes_[i].action_,
|
| - autofill_changes_[i].profile_specifics_,
|
| - autofill_changes_[i].id_);
|
| - }
|
| -
|
| - autofill_changes_.clear();
|
| -
|
| - PostOptimisticRefreshTask();
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::PostOptimisticRefreshTask() {
|
| - BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
|
| - new DoOptimisticRefreshForAutofill(
|
| - personal_data_));
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::ApplyAutofillProfileChange(
|
| - sync_api::SyncManager::ChangeRecord::Action action,
|
| - const sync_pb::AutofillProfileSpecifics& profile_specifics,
|
| - int64 sync_id) {
|
| -
|
| - DCHECK_NE(sync_api::SyncManager::ChangeRecord::ACTION_DELETE, action);
|
| - switch (action) {
|
| - case sync_api::SyncManager::ChangeRecord::ACTION_ADD: {
|
| - if (guid::IsValidGUID(profile_specifics.guid()) == false) {
|
| - NOTREACHED() << "Guid from the server is invalid " <<
|
| - profile_specifics.guid();
|
| - return;
|
| - }
|
| - AutofillProfile p(profile_specifics.guid());
|
| - AutofillProfileModelAssociator::OverwriteProfileWithServerData(&p,
|
| - profile_specifics);
|
| - if (!web_database_->GetAutofillTable()->AddAutofillProfile(p)) {
|
| - LOG(ERROR) << "could not add autofill profile for guid " << p.guid();
|
| - break;
|
| - }
|
| -
|
| - // Now that the node has been succesfully created we can associate it.
|
| - std::string guid = p.guid();
|
| - model_associator_->Associate(&guid, sync_id);
|
| - break;
|
| - }
|
| - case sync_api::SyncManager::ChangeRecord::ACTION_UPDATE: {
|
| - AutofillProfile *p;
|
| - if (!web_database_->GetAutofillTable()->GetAutofillProfile(
|
| - profile_specifics.guid(), &p)) {
|
| - LOG(ERROR) << "Could not find the autofill profile to update for " <<
|
| - profile_specifics.guid();
|
| - break;
|
| - }
|
| - scoped_ptr<AutofillProfile> autofill_pointer(p);
|
| - AutofillProfileModelAssociator::OverwriteProfileWithServerData(
|
| - autofill_pointer.get(),
|
| - profile_specifics);
|
| -
|
| - if (!web_database_->GetAutofillTable()->UpdateAutofillProfile(
|
| - *(autofill_pointer.get()))) {
|
| - LOG(ERROR) << "Could not update autofill profile for " <<
|
| - profile_specifics.guid();
|
| - break;
|
| - }
|
| - break;
|
| - }
|
| - default: {
|
| - NOTREACHED();
|
| - break;
|
| - }
|
| - }
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::RemoveSyncNode(const std::string& guid,
|
| - sync_api::WriteTransaction* trans) {
|
| - sync_api::WriteNode node(trans);
|
| - int64 sync_id = model_associator_->GetSyncIdFromChromeId(guid);
|
| - if (sync_api::kInvalidId == sync_id) {
|
| - LOG(ERROR) << "Could not find the node in associator " << guid;
|
| - return;
|
| - }
|
| -
|
| - if (!node.InitByIdLookup(sync_id)) {
|
| - LOG(ERROR) << "Could not find the sync node for " << guid;
|
| - return;
|
| - }
|
| -
|
| - model_associator_->Disassociate(sync_id);
|
| - node.Remove();
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::AddAutofillProfileSyncNode(
|
| - sync_api::WriteTransaction* trans,
|
| - sync_api::BaseNode& autofill_profile_root,
|
| - const AutofillProfile& profile) {
|
| -
|
| - std::string guid = profile.guid();
|
| -
|
| - if (guid::IsValidGUID(guid) == false) {
|
| - DCHECK(false) << "Guid set on the profile is invalid " << guid;
|
| - return;
|
| - }
|
| -
|
| - sync_api::WriteNode node(trans);
|
| - if (!node.InitUniqueByCreation(syncable::AUTOFILL_PROFILE,
|
| - autofill_profile_root,
|
| - profile.guid())) {
|
| - LOG(ERROR) << "could not create a sync node ";
|
| - return;
|
| - }
|
| -
|
| - node.SetTitle(UTF8ToWide(profile.guid()));
|
| -
|
| - WriteAutofillProfile(profile, &node);
|
| -
|
| - model_associator_->Associate(&guid, node.GetId());
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::StartObserving() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
|
| - notification_registrar_.Add(this,
|
| - chrome::NOTIFICATION_AUTOFILL_PROFILE_CHANGED,
|
| - NotificationService::AllSources());
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::StopObserving() {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
|
| - notification_registrar_.RemoveAll();
|
| -}
|
| -
|
| -void AutofillProfileChangeProcessor::WriteAutofillProfile(
|
| - const AutofillProfile& profile,
|
| - sync_api::WriteNode* node) {
|
| - sync_pb::AutofillProfileSpecifics specifics;
|
| -
|
| - // This would get compiled out in official builds. The caller is expected to
|
| - // pass in a valid profile object with valid guid.(i.e., the caller might
|
| - // have to a DCHECK and log before calling. Having to check in 2 places is
|
| - // not optimal.)
|
| - DCHECK(guid::IsValidGUID(profile.guid()));
|
| -
|
| - specifics.set_guid(profile.guid());
|
| - specifics.set_name_first(UTF16ToUTF8(profile.GetInfo(NAME_FIRST)));
|
| - specifics.set_name_middle(UTF16ToUTF8(profile.GetInfo(NAME_MIDDLE)));
|
| - specifics.set_name_last(UTF16ToUTF8(profile.GetInfo(NAME_LAST)));
|
| - specifics.set_address_home_line1(
|
| - UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_LINE1)));
|
| - specifics.set_address_home_line2(
|
| - UTF16ToUTF8(profile.GetInfo(ADDRESS_HOME_LINE2)));
|
| - specifics.set_address_home_city(UTF16ToUTF8(profile.GetInfo(
|
| - ADDRESS_HOME_CITY)));
|
| - specifics.set_address_home_state(UTF16ToUTF8(profile.GetInfo(
|
| - ADDRESS_HOME_STATE)));
|
| - specifics.set_address_home_country(UTF16ToUTF8(profile.GetInfo(
|
| - ADDRESS_HOME_COUNTRY)));
|
| - specifics.set_address_home_zip(UTF16ToUTF8(profile.GetInfo(
|
| - ADDRESS_HOME_ZIP)));
|
| - specifics.set_email_address(UTF16ToUTF8(profile.GetInfo(EMAIL_ADDRESS)));
|
| - specifics.set_company_name(UTF16ToUTF8(profile.GetInfo(COMPANY_NAME)));
|
| - specifics.set_phone_fax_whole_number(UTF16ToUTF8(profile.GetInfo(
|
| - PHONE_FAX_WHOLE_NUMBER)));
|
| - specifics.set_phone_home_whole_number(UTF16ToUTF8(profile.GetInfo(
|
| - PHONE_HOME_WHOLE_NUMBER)));
|
| - node->SetAutofillProfileSpecifics(specifics);
|
| -}
|
| -
|
| -} // namespace browser_sync
|
|
|