blob: bed807414e008040fbb9407c5f69b58f6b74e348 [file] [log] [blame]
// Copyright 2018 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 "components/autofill/core/browser/webdata/autofill_wallet_sync_bridge.h"
#include <utility>
#include "base/base64.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_profile_sync_util.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_backend.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/sync/model/entity_data.h"
#include "components/sync/model/mutable_data_batch.h"
#include "components/sync/model_impl/client_tag_based_model_type_processor.h"
#include "components/sync/model_impl/sync_metadata_store_change_list.h"
using sync_pb::AutofillWalletSpecifics;
using syncer::EntityData;
namespace autofill {
namespace {
// Address to this variable used as the user data key.
static int kAutofillWalletSyncBridgeUserDataKey = 0;
std::string GetStorageKeyFromAutofillWalletSpecifics(
const AutofillWalletSpecifics& specifics) {
switch (specifics.type()) {
case AutofillWalletSpecifics::MASKED_CREDIT_CARD:
return specifics.masked_card().id();
case AutofillWalletSpecifics::POSTAL_ADDRESS:
return specifics.address().id();
case AutofillWalletSpecifics::CUSTOMER_DATA:
return specifics.customer_data().id();
case AutofillWalletSpecifics::UNKNOWN:
NOTREACHED();
return std::string();
}
return std::string();
}
} // namespace
// static
void AutofillWalletSyncBridge::CreateForWebDataServiceAndBackend(
const std::string& app_locale,
AutofillWebDataBackend* web_data_backend,
AutofillWebDataService* web_data_service) {
web_data_service->GetDBUserData()->SetUserData(
&kAutofillWalletSyncBridgeUserDataKey,
std::make_unique<AutofillWalletSyncBridge>(
std::make_unique<syncer::ClientTagBasedModelTypeProcessor>(
syncer::AUTOFILL_WALLET_DATA,
/*dump_stack=*/base::RepeatingClosure()),
web_data_backend));
}
// static
syncer::ModelTypeSyncBridge* AutofillWalletSyncBridge::FromWebDataService(
AutofillWebDataService* web_data_service) {
return static_cast<AutofillWalletSyncBridge*>(
web_data_service->GetDBUserData()->GetUserData(
&kAutofillWalletSyncBridgeUserDataKey));
}
AutofillWalletSyncBridge::AutofillWalletSyncBridge(
std::unique_ptr<syncer::ModelTypeChangeProcessor> change_processor,
AutofillWebDataBackend* web_data_backend)
: ModelTypeSyncBridge(std::move(change_processor)),
web_data_backend_(web_data_backend) {}
AutofillWalletSyncBridge::~AutofillWalletSyncBridge() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
std::unique_ptr<syncer::MetadataChangeList>
AutofillWalletSyncBridge::CreateMetadataChangeList() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return std::make_unique<syncer::SyncMetadataStoreChangeList>(
GetAutofillTable(), syncer::AUTOFILL_WALLET_DATA);
}
base::Optional<syncer::ModelError> AutofillWalletSyncBridge::MergeSyncData(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
return ApplySyncChanges(std::move(metadata_change_list),
std::move(entity_data));
}
base::Optional<syncer::ModelError> AutofillWalletSyncBridge::ApplySyncChanges(
std::unique_ptr<syncer::MetadataChangeList> metadata_change_list,
syncer::EntityChangeList entity_data) {
NOTIMPLEMENTED();
return base::nullopt;
}
void AutofillWalletSyncBridge::GetData(StorageKeyList storage_keys,
DataCallback callback) {
// This data type is never synced "up" so we don't need to implement this.
NOTIMPLEMENTED();
}
void AutofillWalletSyncBridge::GetAllDataForDebugging(DataCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
std::vector<std::unique_ptr<AutofillProfile>> profiles;
std::vector<std::unique_ptr<CreditCard>> cards;
if (!GetAutofillTable()->GetServerProfiles(&profiles) ||
!GetAutofillTable()->GetServerCreditCards(&cards)) {
change_processor()->ReportError(
{FROM_HERE, "Failed to load entries from table."});
return;
}
auto batch = std::make_unique<syncer::MutableDataBatch>();
for (const std::unique_ptr<AutofillProfile>& entry : profiles) {
batch->Put(GetStorageKeyForEntryServerId(entry->server_id()),
CreateEntityDataFromAutofillServerProfile(*entry));
}
for (const std::unique_ptr<CreditCard>& entry : cards) {
batch->Put(GetStorageKeyForEntryServerId(entry->server_id()),
CreateEntityDataFromCard(*entry));
}
std::move(callback).Run(std::move(batch));
}
std::string AutofillWalletSyncBridge::GetClientTag(
const syncer::EntityData& entity_data) {
DCHECK(entity_data.specifics.has_autofill_wallet());
return GetClientTagForSpecificsId(
entity_data.specifics.autofill_wallet().type(),
GetStorageKey(entity_data));
}
std::string AutofillWalletSyncBridge::GetStorageKey(
const syncer::EntityData& entity_data) {
DCHECK(entity_data.specifics.has_autofill_wallet());
return GetStorageKeyFromAutofillWalletSpecifics(
entity_data.specifics.autofill_wallet());
}
AutofillTable* AutofillWalletSyncBridge::GetAutofillTable() {
return AutofillTable::FromWebDatabase(web_data_backend_->GetDatabase());
}
} // namespace autofill