| Index: chrome/browser/webdata/autofill_profile_syncable_service.cc
|
| diff --git a/chrome/browser/webdata/autofill_profile_syncable_service.cc b/chrome/browser/webdata/autofill_profile_syncable_service.cc
|
| deleted file mode 100644
|
| index e9ea5c76527b909d253eee5e9071c3c8bc33c1cf..0000000000000000000000000000000000000000
|
| --- a/chrome/browser/webdata/autofill_profile_syncable_service.cc
|
| +++ /dev/null
|
| @@ -1,650 +0,0 @@
|
| -// Copyright (c) 2012 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/webdata/autofill_profile_syncable_service.h"
|
| -
|
| -#include "base/guid.h"
|
| -#include "base/location.h"
|
| -#include "base/logging.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "components/autofill/core/browser/autofill_country.h"
|
| -#include "components/autofill/core/browser/autofill_profile.h"
|
| -#include "components/autofill/core/browser/form_group.h"
|
| -#include "components/autofill/core/browser/webdata/autofill_table.h"
|
| -#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
|
| -#include "components/webdata/common/web_database.h"
|
| -#include "content/public/browser/browser_thread.h"
|
| -#include "sync/api/sync_error.h"
|
| -#include "sync/api/sync_error_factory.h"
|
| -#include "sync/protocol/sync.pb.h"
|
| -
|
| -using base::ASCIIToUTF16;
|
| -using base::UTF8ToUTF16;
|
| -using base::UTF16ToUTF8;
|
| -using content::BrowserThread;
|
| -
|
| -namespace autofill {
|
| -
|
| -namespace {
|
| -
|
| -std::string LimitData(const std::string& data) {
|
| - std::string sanitized_value(data);
|
| - if (sanitized_value.length() > AutofillTable::kMaxDataLength)
|
| - sanitized_value.resize(AutofillTable::kMaxDataLength);
|
| - return sanitized_value;
|
| -}
|
| -
|
| -void* UserDataKey() {
|
| - // Use the address of a static that COMDAT folding won't ever fold
|
| - // with something else.
|
| - static int user_data_key = 0;
|
| - return reinterpret_cast<void*>(&user_data_key);
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -const char kAutofillProfileTag[] = "google_chrome_autofill_profiles";
|
| -
|
| -AutofillProfileSyncableService::AutofillProfileSyncableService(
|
| - AutofillWebDataBackend* webdata_backend,
|
| - const std::string& app_locale)
|
| - : webdata_backend_(webdata_backend),
|
| - app_locale_(app_locale),
|
| - scoped_observer_(this) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
|
| - DCHECK(webdata_backend_);
|
| -
|
| - scoped_observer_.Add(webdata_backend_);
|
| -}
|
| -
|
| -AutofillProfileSyncableService::~AutofillProfileSyncableService() {
|
| - DCHECK(CalledOnValidThread());
|
| -}
|
| -
|
| -// static
|
| -void AutofillProfileSyncableService::CreateForWebDataServiceAndBackend(
|
| - AutofillWebDataService* web_data_service,
|
| - AutofillWebDataBackend* webdata_backend,
|
| - const std::string& app_locale) {
|
| - web_data_service->GetDBUserData()->SetUserData(
|
| - UserDataKey(),
|
| - new AutofillProfileSyncableService(webdata_backend, app_locale));
|
| -}
|
| -
|
| -// static
|
| -AutofillProfileSyncableService*
|
| -AutofillProfileSyncableService::FromWebDataService(
|
| - AutofillWebDataService* web_data_service) {
|
| - return static_cast<AutofillProfileSyncableService*>(
|
| - web_data_service->GetDBUserData()->GetUserData(UserDataKey()));
|
| -}
|
| -
|
| -AutofillProfileSyncableService::AutofillProfileSyncableService()
|
| - : webdata_backend_(NULL),
|
| - scoped_observer_(this) {
|
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
|
| -}
|
| -
|
| -syncer::SyncMergeResult
|
| -AutofillProfileSyncableService::MergeDataAndStartSyncing(
|
| - syncer::ModelType type,
|
| - const syncer::SyncDataList& initial_sync_data,
|
| - scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
|
| - scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK(!sync_processor_.get());
|
| - DCHECK(sync_processor.get());
|
| - DCHECK(sync_error_factory.get());
|
| - DVLOG(1) << "Associating Autofill: MergeDataAndStartSyncing";
|
| -
|
| - syncer::SyncMergeResult merge_result(type);
|
| - sync_error_factory_ = sync_error_factory.Pass();
|
| - if (!LoadAutofillData(&profiles_.get())) {
|
| - merge_result.set_error(sync_error_factory_->CreateAndUploadError(
|
| - FROM_HERE, "Could not get the autofill data from WebDatabase."));
|
| - return merge_result;
|
| - }
|
| -
|
| - if (DLOG_IS_ON(INFO)) {
|
| - DVLOG(2) << "[AUTOFILL MIGRATION]"
|
| - << "Printing profiles from web db";
|
| -
|
| - for (ScopedVector<AutofillProfile>::const_iterator ix =
|
| - profiles_.begin(); ix != profiles_.end(); ++ix) {
|
| - AutofillProfile* p = *ix;
|
| - DVLOG(2) << "[AUTOFILL MIGRATION] "
|
| - << UTF16ToUTF8(p->GetRawInfo(NAME_FIRST))
|
| - << UTF16ToUTF8(p->GetRawInfo(NAME_LAST))
|
| - << p->guid();
|
| - }
|
| - }
|
| -
|
| - sync_processor_ = sync_processor.Pass();
|
| -
|
| - GUIDToProfileMap remaining_profiles;
|
| - CreateGUIDToProfileMap(profiles_.get(), &remaining_profiles);
|
| -
|
| - DataBundle bundle;
|
| - // Go through and check for all the profiles that sync already knows about.
|
| - for (syncer::SyncDataList::const_iterator sync_iter =
|
| - initial_sync_data.begin();
|
| - sync_iter != initial_sync_data.end();
|
| - ++sync_iter) {
|
| - GUIDToProfileMap::iterator it =
|
| - CreateOrUpdateProfile(*sync_iter, &remaining_profiles, &bundle);
|
| - // |it| points to created/updated profile. Add it to the |profiles_map_| and
|
| - // then remove it from |remaining_profiles|. After this loop is completed
|
| - // |remaining_profiles| will have only those profiles that are not in the
|
| - // sync.
|
| - profiles_map_[it->first] = it->second;
|
| - remaining_profiles.erase(it);
|
| - }
|
| -
|
| - // Check for similar unmatched profiles - they are created independently on
|
| - // two systems, so merge them.
|
| - for (GUIDToProfileMap::iterator it = bundle.candidates_to_merge.begin();
|
| - it != bundle.candidates_to_merge.end(); ++it) {
|
| - GUIDToProfileMap::iterator profile_to_merge =
|
| - remaining_profiles.find(it->first);
|
| - if (profile_to_merge != remaining_profiles.end()) {
|
| - bundle.profiles_to_delete.push_back(profile_to_merge->second->guid());
|
| - if (MergeProfile(*(profile_to_merge->second), it->second, app_locale_))
|
| - bundle.profiles_to_sync_back.push_back(it->second);
|
| - DVLOG(2) << "[AUTOFILL SYNC]"
|
| - << "Found similar profile in sync db but with a different guid: "
|
| - << UTF16ToUTF8(it->second->GetRawInfo(NAME_FIRST))
|
| - << UTF16ToUTF8(it->second->GetRawInfo(NAME_LAST))
|
| - << "New guid " << it->second->guid()
|
| - << ". Profile to be deleted "
|
| - << profile_to_merge->second->guid();
|
| - remaining_profiles.erase(profile_to_merge);
|
| - }
|
| - }
|
| -
|
| - if (!SaveChangesToWebData(bundle)) {
|
| - merge_result.set_error(sync_error_factory_->CreateAndUploadError(
|
| - FROM_HERE,
|
| - "Failed to update webdata."));
|
| - return merge_result;
|
| - }
|
| -
|
| - syncer::SyncChangeList new_changes;
|
| - for (GUIDToProfileMap::iterator i = remaining_profiles.begin();
|
| - i != remaining_profiles.end(); ++i) {
|
| - new_changes.push_back(
|
| - syncer::SyncChange(FROM_HERE,
|
| - syncer::SyncChange::ACTION_ADD,
|
| - CreateData(*(i->second))));
|
| - profiles_map_[i->first] = i->second;
|
| - }
|
| -
|
| - for (size_t i = 0; i < bundle.profiles_to_sync_back.size(); ++i) {
|
| - new_changes.push_back(
|
| - syncer::SyncChange(FROM_HERE,
|
| - syncer::SyncChange::ACTION_UPDATE,
|
| - CreateData(*(bundle.profiles_to_sync_back[i]))));
|
| - }
|
| -
|
| - if (!new_changes.empty()) {
|
| - merge_result.set_error(
|
| - sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes));
|
| - }
|
| -
|
| - if (webdata_backend_)
|
| - webdata_backend_->NotifyOfMultipleAutofillChanges();
|
| -
|
| - return merge_result;
|
| -}
|
| -
|
| -void AutofillProfileSyncableService::StopSyncing(syncer::ModelType type) {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK_EQ(type, syncer::AUTOFILL_PROFILE);
|
| -
|
| - sync_processor_.reset();
|
| - sync_error_factory_.reset();
|
| - profiles_.clear();
|
| - profiles_map_.clear();
|
| -}
|
| -
|
| -syncer::SyncDataList AutofillProfileSyncableService::GetAllSyncData(
|
| - syncer::ModelType type) const {
|
| - DCHECK(CalledOnValidThread());
|
| - DCHECK(sync_processor_.get());
|
| - DCHECK_EQ(type, syncer::AUTOFILL_PROFILE);
|
| -
|
| - syncer::SyncDataList current_data;
|
| -
|
| - for (GUIDToProfileMap::const_iterator i = profiles_map_.begin();
|
| - i != profiles_map_.end(); ++i) {
|
| - current_data.push_back(CreateData(*(i->second)));
|
| - }
|
| - return current_data;
|
| -}
|
| -
|
| -syncer::SyncError AutofillProfileSyncableService::ProcessSyncChanges(
|
| - const tracked_objects::Location& from_here,
|
| - const syncer::SyncChangeList& change_list) {
|
| - DCHECK(CalledOnValidThread());
|
| - if (!sync_processor_.get()) {
|
| - syncer::SyncError error(FROM_HERE,
|
| - syncer::SyncError::DATATYPE_ERROR,
|
| - "Models not yet associated.",
|
| - syncer::AUTOFILL_PROFILE);
|
| - return error;
|
| - }
|
| -
|
| - DataBundle bundle;
|
| -
|
| - for (syncer::SyncChangeList::const_iterator i = change_list.begin();
|
| - i != change_list.end(); ++i) {
|
| - DCHECK(i->IsValid());
|
| - switch (i->change_type()) {
|
| - case syncer::SyncChange::ACTION_ADD:
|
| - case syncer::SyncChange::ACTION_UPDATE:
|
| - CreateOrUpdateProfile(i->sync_data(), &profiles_map_, &bundle);
|
| - break;
|
| - case syncer::SyncChange::ACTION_DELETE: {
|
| - std::string guid = i->sync_data().GetSpecifics().
|
| - autofill_profile().guid();
|
| - bundle.profiles_to_delete.push_back(guid);
|
| - profiles_map_.erase(guid);
|
| - } break;
|
| - default:
|
| - NOTREACHED() << "Unexpected sync change state.";
|
| - return sync_error_factory_->CreateAndUploadError(
|
| - FROM_HERE,
|
| - "ProcessSyncChanges failed on ChangeType " +
|
| - syncer::SyncChange::ChangeTypeToString(i->change_type()));
|
| - }
|
| - }
|
| -
|
| - if (!SaveChangesToWebData(bundle)) {
|
| - return sync_error_factory_->CreateAndUploadError(
|
| - FROM_HERE,
|
| - "Failed to update webdata.");
|
| - }
|
| -
|
| - if (webdata_backend_)
|
| - webdata_backend_->NotifyOfMultipleAutofillChanges();
|
| -
|
| - return syncer::SyncError();
|
| -}
|
| -
|
| -void AutofillProfileSyncableService::AutofillProfileChanged(
|
| - const AutofillProfileChange& change) {
|
| - // Check if sync is on. If we receive notification prior to the sync being set
|
| - // up we are going to process all when MergeData..() is called. If we receive
|
| - // notification after the sync exited, it will be sinced next time Chrome
|
| - // starts.
|
| - if (sync_processor_.get()) {
|
| - ActOnChange(change);
|
| - } else if (!flare_.is_null()) {
|
| - flare_.Run(syncer::AUTOFILL_PROFILE);
|
| - flare_.Reset();
|
| - }
|
| -}
|
| -
|
| -bool AutofillProfileSyncableService::LoadAutofillData(
|
| - std::vector<AutofillProfile*>* profiles) {
|
| - return GetAutofillTable()->GetAutofillProfiles(profiles);
|
| -}
|
| -
|
| -bool AutofillProfileSyncableService::SaveChangesToWebData(
|
| - const DataBundle& bundle) {
|
| - DCHECK(CalledOnValidThread());
|
| -
|
| - AutofillTable* autofill_table = GetAutofillTable();
|
| -
|
| - bool success = true;
|
| - for (size_t i = 0; i< bundle.profiles_to_delete.size(); ++i) {
|
| - if (!autofill_table->RemoveAutofillProfile(bundle.profiles_to_delete[i]))
|
| - success = false;
|
| - }
|
| -
|
| - for (size_t i = 0; i < bundle.profiles_to_add.size(); i++) {
|
| - if (!autofill_table->AddAutofillProfile(*bundle.profiles_to_add[i]))
|
| - success = false;
|
| - }
|
| -
|
| - for (size_t i = 0; i < bundle.profiles_to_update.size(); i++) {
|
| - if (!autofill_table->UpdateAutofillProfile(*bundle.profiles_to_update[i]))
|
| - success = false;
|
| - }
|
| - return success;
|
| -}
|
| -
|
| -// static
|
| -bool AutofillProfileSyncableService::OverwriteProfileWithServerData(
|
| - const sync_pb::AutofillProfileSpecifics& specifics,
|
| - AutofillProfile* profile,
|
| - const std::string& app_locale) {
|
| - bool diff = false;
|
| - if (profile->origin() != specifics.origin()) {
|
| - bool was_verified = profile->IsVerified();
|
| - profile->set_origin(specifics.origin());
|
| - diff = true;
|
| -
|
| - // Verified profiles should never be overwritten by unverified ones.
|
| - DCHECK(!was_verified || profile->IsVerified());
|
| - }
|
| -
|
| - // Update all multivalued fields: names, emails, and phones.
|
| - diff = UpdateMultivaluedField(NAME_FIRST,
|
| - specifics.name_first(), profile) || diff;
|
| - diff = UpdateMultivaluedField(NAME_MIDDLE,
|
| - specifics.name_middle(), profile) || diff;
|
| - diff = UpdateMultivaluedField(NAME_LAST,
|
| - specifics.name_last(), profile) || diff;
|
| - diff = UpdateMultivaluedField(EMAIL_ADDRESS,
|
| - specifics.email_address(), profile) || diff;
|
| - diff = UpdateMultivaluedField(PHONE_HOME_WHOLE_NUMBER,
|
| - specifics.phone_home_whole_number(),
|
| - profile) || diff;
|
| -
|
| - // Update all simple single-valued address fields.
|
| - diff = UpdateField(COMPANY_NAME, specifics.company_name(), profile) || diff;
|
| - diff = UpdateField(ADDRESS_HOME_CITY,
|
| - specifics.address_home_city(), profile) || diff;
|
| - diff = UpdateField(ADDRESS_HOME_STATE,
|
| - specifics.address_home_state(), profile) || diff;
|
| - diff = UpdateField(ADDRESS_HOME_ZIP,
|
| - specifics.address_home_zip(), profile) || diff;
|
| - diff = UpdateField(ADDRESS_HOME_SORTING_CODE,
|
| - specifics.address_home_sorting_code(), profile) || diff;
|
| - diff = UpdateField(ADDRESS_HOME_DEPENDENT_LOCALITY,
|
| - specifics.address_home_dependent_locality(),
|
| - profile) || diff;
|
| -
|
| - // Update the country field, which can contain either a country code (if set
|
| - // by a newer version of Chrome), or a country name (if set by an older
|
| - // version of Chrome).
|
| - base::string16 country_name_or_code =
|
| - ASCIIToUTF16(specifics.address_home_country());
|
| - std::string country_code =
|
| - AutofillCountry::GetCountryCode(country_name_or_code, app_locale);
|
| - diff = UpdateField(ADDRESS_HOME_COUNTRY, country_code, profile) || diff;
|
| -
|
| - // Update the street address. In newer versions of Chrome (M34+), this data
|
| - // is stored in the |address_home_street_address| field. In older versions,
|
| - // this data is stored separated out by address line.
|
| - if (specifics.has_address_home_street_address()) {
|
| - diff = UpdateField(ADDRESS_HOME_STREET_ADDRESS,
|
| - specifics.address_home_street_address(),
|
| - profile) || diff;
|
| - } else {
|
| - diff = UpdateField(ADDRESS_HOME_LINE1,
|
| - specifics.address_home_line1(), profile) || diff;
|
| - diff = UpdateField(ADDRESS_HOME_LINE2,
|
| - specifics.address_home_line2(), profile) || diff;
|
| - }
|
| - return diff;
|
| -}
|
| -
|
| -// static
|
| -void AutofillProfileSyncableService::WriteAutofillProfile(
|
| - const AutofillProfile& profile,
|
| - sync_pb::EntitySpecifics* profile_specifics) {
|
| - sync_pb::AutofillProfileSpecifics* specifics =
|
| - profile_specifics->mutable_autofill_profile();
|
| -
|
| - DCHECK(base::IsValidGUID(profile.guid()));
|
| -
|
| - // Reset all multi-valued fields in the protobuf.
|
| - specifics->clear_name_first();
|
| - specifics->clear_name_middle();
|
| - specifics->clear_name_last();
|
| - specifics->clear_email_address();
|
| - specifics->clear_phone_home_whole_number();
|
| -
|
| - specifics->set_guid(profile.guid());
|
| - specifics->set_origin(profile.origin());
|
| -
|
| - std::vector<base::string16> values;
|
| - profile.GetRawMultiInfo(NAME_FIRST, &values);
|
| - for (size_t i = 0; i < values.size(); ++i) {
|
| - specifics->add_name_first(LimitData(UTF16ToUTF8(values[i])));
|
| - }
|
| -
|
| - profile.GetRawMultiInfo(NAME_MIDDLE, &values);
|
| - for (size_t i = 0; i < values.size(); ++i) {
|
| - specifics->add_name_middle(LimitData(UTF16ToUTF8(values[i])));
|
| - }
|
| -
|
| - profile.GetRawMultiInfo(NAME_LAST, &values);
|
| - for (size_t i = 0; i < values.size(); ++i) {
|
| - specifics->add_name_last(LimitData(UTF16ToUTF8(values[i])));
|
| - }
|
| -
|
| - specifics->set_address_home_line1(
|
| - LimitData(UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_LINE1))));
|
| - specifics->set_address_home_line2(
|
| - LimitData(UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_LINE2))));
|
| - specifics->set_address_home_city(
|
| - LimitData(UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_CITY))));
|
| - specifics->set_address_home_state(
|
| - LimitData(UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STATE))));
|
| - specifics->set_address_home_zip(
|
| - LimitData(UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_ZIP))));
|
| - specifics->set_address_home_country(
|
| - LimitData(UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_COUNTRY))));
|
| - specifics->set_address_home_street_address(
|
| - LimitData(UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_STREET_ADDRESS))));
|
| - specifics->set_address_home_sorting_code(
|
| - LimitData(UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_SORTING_CODE))));
|
| - specifics->set_address_home_dependent_locality(
|
| - LimitData(
|
| - UTF16ToUTF8(profile.GetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY))));
|
| -
|
| - profile.GetRawMultiInfo(EMAIL_ADDRESS, &values);
|
| - for (size_t i = 0; i < values.size(); ++i) {
|
| - specifics->add_email_address(LimitData(UTF16ToUTF8(values[i])));
|
| - }
|
| -
|
| - specifics->set_company_name(
|
| - LimitData(UTF16ToUTF8(profile.GetRawInfo(COMPANY_NAME))));
|
| -
|
| - profile.GetRawMultiInfo(PHONE_HOME_WHOLE_NUMBER, &values);
|
| - for (size_t i = 0; i < values.size(); ++i) {
|
| - specifics->add_phone_home_whole_number(LimitData(UTF16ToUTF8(values[i])));
|
| - }
|
| -}
|
| -
|
| -void AutofillProfileSyncableService::CreateGUIDToProfileMap(
|
| - const std::vector<AutofillProfile*>& profiles,
|
| - GUIDToProfileMap* profile_map) {
|
| - DCHECK(profile_map);
|
| - profile_map->clear();
|
| - for (size_t i = 0; i < profiles.size(); ++i)
|
| - (*profile_map)[profiles[i]->guid()] = profiles[i];
|
| -}
|
| -
|
| -AutofillProfileSyncableService::GUIDToProfileMap::iterator
|
| -AutofillProfileSyncableService::CreateOrUpdateProfile(
|
| - const syncer::SyncData& data,
|
| - GUIDToProfileMap* profile_map,
|
| - DataBundle* bundle) {
|
| - DCHECK(profile_map);
|
| - DCHECK(bundle);
|
| -
|
| - DCHECK_EQ(syncer::AUTOFILL_PROFILE, data.GetDataType());
|
| -
|
| - const sync_pb::EntitySpecifics& specifics = data.GetSpecifics();
|
| - const sync_pb::AutofillProfileSpecifics& autofill_specifics(
|
| - specifics.autofill_profile());
|
| -
|
| - GUIDToProfileMap::iterator existing_profile = profile_map->find(
|
| - autofill_specifics.guid());
|
| - if (existing_profile != profile_map->end()) {
|
| - // The synced profile already exists locally. It might need to be updated.
|
| - if (OverwriteProfileWithServerData(
|
| - autofill_specifics, existing_profile->second, app_locale_)) {
|
| - bundle->profiles_to_update.push_back(existing_profile->second);
|
| - }
|
| - return existing_profile;
|
| - }
|
| -
|
| -
|
| - // New profile synced.
|
| - AutofillProfile* new_profile = new AutofillProfile(
|
| - autofill_specifics.guid(), autofill_specifics.origin());
|
| - OverwriteProfileWithServerData(autofill_specifics, new_profile, app_locale_);
|
| -
|
| - // Check if profile appears under a different guid.
|
| - // Unverified profiles should never overwrite verified ones.
|
| - for (GUIDToProfileMap::iterator it = profile_map->begin();
|
| - it != profile_map->end(); ++it) {
|
| - AutofillProfile* local_profile = it->second;
|
| - if (local_profile->Compare(*new_profile) == 0) {
|
| - // Ensure that a verified profile can never revert back to an unverified
|
| - // one.
|
| - if (local_profile->IsVerified() && !new_profile->IsVerified()) {
|
| - new_profile->set_origin(local_profile->origin());
|
| - bundle->profiles_to_sync_back.push_back(new_profile);
|
| - }
|
| -
|
| - bundle->profiles_to_delete.push_back(local_profile->guid());
|
| - DVLOG(2) << "[AUTOFILL SYNC]"
|
| - << "Found in sync db but with a different guid: "
|
| - << UTF16ToUTF8(local_profile->GetRawInfo(NAME_FIRST))
|
| - << UTF16ToUTF8(local_profile->GetRawInfo(NAME_LAST))
|
| - << "New guid " << new_profile->guid()
|
| - << ". Profile to be deleted " << local_profile->guid();
|
| - profile_map->erase(it);
|
| - break;
|
| - } else if (!local_profile->IsVerified() &&
|
| - !new_profile->IsVerified() &&
|
| - !local_profile->PrimaryValue().empty() &&
|
| - local_profile->PrimaryValue() == new_profile->PrimaryValue()) {
|
| - // Add it to candidates for merge - if there is no profile with this
|
| - // guid we will merge them.
|
| - bundle->candidates_to_merge.insert(
|
| - std::make_pair(local_profile->guid(), new_profile));
|
| - }
|
| - }
|
| - profiles_.push_back(new_profile);
|
| - bundle->profiles_to_add.push_back(new_profile);
|
| - return profile_map->insert(std::make_pair(new_profile->guid(),
|
| - new_profile)).first;
|
| -}
|
| -
|
| -void AutofillProfileSyncableService::ActOnChange(
|
| - const AutofillProfileChange& change) {
|
| - DCHECK((change.type() == AutofillProfileChange::REMOVE &&
|
| - !change.profile()) ||
|
| - (change.type() != AutofillProfileChange::REMOVE && change.profile()));
|
| - DCHECK(sync_processor_.get());
|
| - syncer::SyncChangeList new_changes;
|
| - DataBundle bundle;
|
| - switch (change.type()) {
|
| - case AutofillProfileChange::ADD:
|
| - new_changes.push_back(
|
| - syncer::SyncChange(FROM_HERE,
|
| - syncer::SyncChange::ACTION_ADD,
|
| - CreateData(*(change.profile()))));
|
| - DCHECK(profiles_map_.find(change.profile()->guid()) ==
|
| - profiles_map_.end());
|
| - profiles_.push_back(new AutofillProfile(*(change.profile())));
|
| - profiles_map_[change.profile()->guid()] = profiles_.get().back();
|
| - break;
|
| - case AutofillProfileChange::UPDATE: {
|
| - GUIDToProfileMap::iterator it = profiles_map_.find(
|
| - change.profile()->guid());
|
| - DCHECK(it != profiles_map_.end());
|
| - *(it->second) = *(change.profile());
|
| - new_changes.push_back(
|
| - syncer::SyncChange(FROM_HERE,
|
| - syncer::SyncChange::ACTION_UPDATE,
|
| - CreateData(*(change.profile()))));
|
| - break;
|
| - }
|
| - case AutofillProfileChange::REMOVE: {
|
| - AutofillProfile empty_profile(change.key(), std::string());
|
| - new_changes.push_back(
|
| - syncer::SyncChange(FROM_HERE,
|
| - syncer::SyncChange::ACTION_DELETE,
|
| - CreateData(empty_profile)));
|
| - profiles_map_.erase(change.key());
|
| - break;
|
| - }
|
| - default:
|
| - NOTREACHED();
|
| - }
|
| - syncer::SyncError error =
|
| - sync_processor_->ProcessSyncChanges(FROM_HERE, new_changes);
|
| - if (error.IsSet()) {
|
| - // TODO(isherman): Investigating http://crbug.com/121592
|
| - VLOG(1) << "[AUTOFILL SYNC] "
|
| - << "Failed processing change:\n"
|
| - << " Error: " << error.message() << "\n"
|
| - << " Guid: " << change.key();
|
| - }
|
| -}
|
| -
|
| -syncer::SyncData AutofillProfileSyncableService::CreateData(
|
| - const AutofillProfile& profile) {
|
| - sync_pb::EntitySpecifics specifics;
|
| - WriteAutofillProfile(profile, &specifics);
|
| - return
|
| - syncer::SyncData::CreateLocalData(
|
| - profile.guid(), profile.guid(), specifics);
|
| -}
|
| -
|
| -bool AutofillProfileSyncableService::UpdateField(
|
| - ServerFieldType field_type,
|
| - const std::string& new_value,
|
| - AutofillProfile* autofill_profile) {
|
| - if (UTF16ToUTF8(autofill_profile->GetRawInfo(field_type)) == new_value)
|
| - return false;
|
| - autofill_profile->SetRawInfo(field_type, UTF8ToUTF16(new_value));
|
| - return true;
|
| -}
|
| -
|
| -bool AutofillProfileSyncableService::UpdateMultivaluedField(
|
| - ServerFieldType field_type,
|
| - const ::google::protobuf::RepeatedPtrField<std::string>& new_values,
|
| - AutofillProfile* autofill_profile) {
|
| - std::vector<base::string16> values;
|
| - autofill_profile->GetRawMultiInfo(field_type, &values);
|
| - bool changed = false;
|
| - if (static_cast<size_t>(new_values.size()) != values.size()) {
|
| - values.clear();
|
| - values.resize(static_cast<size_t>(new_values.size()));
|
| - changed = true;
|
| - }
|
| - for (size_t i = 0; i < values.size(); ++i) {
|
| - base::string16 synced_value(
|
| - UTF8ToUTF16(new_values.Get(static_cast<int>(i))));
|
| - if (values[i] != synced_value) {
|
| - values[i] = synced_value;
|
| - changed = true;
|
| - }
|
| - }
|
| - if (changed)
|
| - autofill_profile->SetRawMultiInfo(field_type, values);
|
| - return changed;
|
| -}
|
| -
|
| -bool AutofillProfileSyncableService::MergeProfile(
|
| - const AutofillProfile& merge_from,
|
| - AutofillProfile* merge_into,
|
| - const std::string& app_locale) {
|
| - merge_into->OverwriteWithOrAddTo(merge_from, app_locale);
|
| - return (merge_into->Compare(merge_from) != 0 ||
|
| - merge_into->origin() != merge_from.origin());
|
| -}
|
| -
|
| -AutofillTable* AutofillProfileSyncableService::GetAutofillTable() const {
|
| - return AutofillTable::FromWebDatabase(webdata_backend_->GetDatabase());
|
| -}
|
| -
|
| -void AutofillProfileSyncableService::InjectStartSyncFlare(
|
| - const syncer::SyncableService::StartSyncFlare& flare) {
|
| - flare_ = flare;
|
| -}
|
| -
|
| -AutofillProfileSyncableService::DataBundle::DataBundle() {}
|
| -
|
| -AutofillProfileSyncableService::DataBundle::~DataBundle() {}
|
| -
|
| -} // namespace autofill
|
|
|