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 |