Commit 9ec5ab9f authored by Mathieu Perreault's avatar Mathieu Perreault Committed by Commit Bot

[Payments/Sync] Add the PaymentsCustomerData from Sync to AutofillTable.

Receives the data from sync and puts it in the AutofillTable.

Wires the getter/setters all the way to PersonalDataManager.

Bug: 870936
Test: components_unittests
Change-Id: Ic6f262e63e529f42d8f7225042f0a007273e7ab7
Reviewed-on: https://chromium-review.googlesource.com/1170847Reviewed-by: default avatarMarc Treib <treib@chromium.org>
Reviewed-by: default avatarPeter Kasting <pkasting@chromium.org>
Reviewed-by: default avatarSebastien Seguin-Gagnon <sebsg@chromium.org>
Commit-Queue: Mathieu Perreault <mathp@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582556}
parent 817bb8fc
......@@ -127,6 +127,7 @@ jumbo_static_library("browser") {
"payments/full_card_request.h",
"payments/payments_client.cc",
"payments/payments_client.h",
"payments/payments_customer_data.h",
"payments/payments_request.h",
"payments/payments_service_url.cc",
"payments/payments_service_url.h",
......
// 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.
#ifndef COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_CUSTOMER_DATA_H_
#define COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_CUSTOMER_DATA_H_
#include <string>
namespace autofill {
// Represents the Google Payments customer data.
struct PaymentsCustomerData {
explicit PaymentsCustomerData(const std::string& customer_id)
: customer_id(customer_id) {}
bool operator==(const PaymentsCustomerData& other) const {
return customer_id == other.customer_id;
}
// The identifier by which a Google Payments account is identified.
std::string customer_id;
};
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_PAYMENTS_PAYMENTS_CUSTOMER_DATA_H_
\ No newline at end of file
......@@ -456,18 +456,7 @@ class PersonalDatabaseHelper
};
PersonalDataManager::PersonalDataManager(const std::string& app_locale)
: is_data_loaded_(false),
pending_profiles_query_(0),
pending_server_profiles_query_(0),
pending_creditcards_query_(0),
pending_server_creditcards_query_(0),
app_locale_(app_locale),
pref_service_(nullptr),
identity_manager_(nullptr),
sync_service_(nullptr),
is_off_the_record_(false),
has_logged_stored_profile_metrics_(false),
has_logged_stored_credit_card_metrics_(false) {
: app_locale_(app_locale) {
database_helper_ = std::make_unique<PersonalDatabaseHelper>(this);
}
......@@ -492,6 +481,7 @@ void PersonalDataManager::Init(
}
LoadProfiles();
LoadCreditCards();
LoadPaymentsCustomerData();
// Check if profile cleanup has already been performed this major version.
is_autofill_profile_cleanup_pending_ =
......@@ -508,6 +498,7 @@ PersonalDataManager::~PersonalDataManager() {
CancelPendingLocalQuery(&pending_server_profiles_query_);
CancelPendingLocalQuery(&pending_creditcards_query_);
CancelPendingServerQuery(&pending_server_creditcards_query_);
CancelPendingServerQuery(&pending_customer_data_query_);
}
void PersonalDataManager::Shutdown() {
......@@ -565,7 +556,8 @@ void PersonalDataManager::OnWebDataServiceRequestDone(
WebDataServiceBase::Handle h,
std::unique_ptr<WDTypedResult> result) {
DCHECK(pending_profiles_query_ || pending_server_profiles_query_ ||
pending_creditcards_query_ || pending_server_creditcards_query_);
pending_creditcards_query_ || pending_server_creditcards_query_ ||
pending_customer_data_query_);
if (!result) {
// Error from the web database.
......@@ -577,6 +569,8 @@ void PersonalDataManager::OnWebDataServiceRequestDone(
pending_server_creditcards_query_ = 0;
else if (h == pending_server_profiles_query_)
pending_server_profiles_query_ = 0;
else if (h == pending_server_creditcards_query_)
pending_server_profiles_query_ = 0;
} else {
switch (result->GetType()) {
case AUTOFILL_PROFILES_RESULT:
......@@ -608,6 +602,16 @@ void PersonalDataManager::OnWebDataServiceRequestDone(
ResetFullServerCards();
}
break;
case AUTOFILL_CUSTOMERDATA_RESULT:
DCHECK_EQ(h, pending_customer_data_query_)
<< "received customer data from invalid request.";
pending_customer_data_query_ = 0;
payments_customer_data_ =
static_cast<WDResult<std::unique_ptr<PaymentsCustomerData>>*>(
result.get())
->GetValue();
break;
default:
NOTREACHED();
}
......@@ -619,6 +623,7 @@ void PersonalDataManager::OnWebDataServiceRequestDone(
if (pending_profiles_query_ == 0 && pending_creditcards_query_ == 0 &&
pending_server_profiles_query_ == 0 &&
pending_server_creditcards_query_ == 0 &&
pending_customer_data_query_ == 0 &&
database_helper_->GetServerDatabase()) {
// On initial data load, is_data_loaded_ will be false here.
if (!is_data_loaded_) {
......@@ -1147,6 +1152,7 @@ std::vector<CreditCard*> PersonalDataManager::GetCreditCards() const {
void PersonalDataManager::Refresh() {
LoadProfiles();
LoadCreditCards();
LoadPaymentsCustomerData();
}
std::vector<AutofillProfile*> PersonalDataManager::GetProfilesToSuggest()
......@@ -1814,6 +1820,16 @@ void PersonalDataManager::CancelPendingServerQueries() {
// use the account storage.
}
void PersonalDataManager::LoadPaymentsCustomerData() {
if (!database_helper_->GetServerDatabase())
return;
CancelPendingServerQuery(&pending_customer_data_query_);
pending_customer_data_query_ =
database_helper_->GetServerDatabase()->GetPaymentsCustomerData(this);
}
std::string PersonalDataManager::SaveImportedProfile(
const AutofillProfile& imported_profile) {
if (is_off_the_record_)
......
......@@ -21,6 +21,7 @@
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/field_types.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/suggestion.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service_observer.h"
......@@ -459,6 +460,9 @@ class PersonalDataManager : public KeyedService,
// Loads the saved credit cards from the web database.
virtual void LoadCreditCards();
// Loads the payments customer data from the web database.
virtual void LoadPaymentsCustomerData();
// Cancels a pending query to the local web database. |handle| is a pointer
// to the query handle.
void CancelPendingLocalQuery(WebDataServiceBase::Handle* handle);
......@@ -515,7 +519,7 @@ class PersonalDataManager : public KeyedService,
std::unique_ptr<PersonalDatabaseHelper> database_helper_;
// True if personal data has been loaded from the web database.
bool is_data_loaded_;
bool is_data_loaded_ = false;
// The loaded web profiles. These are constructed from entries on web pages
// and from manually editing in the settings.
......@@ -524,6 +528,9 @@ class PersonalDataManager : public KeyedService,
// Profiles read from the user's account stored on the server.
mutable std::vector<std::unique_ptr<AutofillProfile>> server_profiles_;
// Stores the PaymentsCustomerData obtained from the database.
std::unique_ptr<PaymentsCustomerData> payments_customer_data_;
// Storage for web profiles. Contents are weak references. Lifetime managed
// by |web_profiles_|.
mutable std::vector<AutofillProfile*> profiles_;
......@@ -536,10 +543,11 @@ class PersonalDataManager : public KeyedService,
// is queried on another sequence, we record the query handle until we
// get called back. We store handles for both profile and credit card queries
// so they can be loaded at the same time.
WebDataServiceBase::Handle pending_profiles_query_;
WebDataServiceBase::Handle pending_server_profiles_query_;
WebDataServiceBase::Handle pending_creditcards_query_;
WebDataServiceBase::Handle pending_server_creditcards_query_;
WebDataServiceBase::Handle pending_profiles_query_ = 0;
WebDataServiceBase::Handle pending_server_profiles_query_ = 0;
WebDataServiceBase::Handle pending_creditcards_query_ = 0;
WebDataServiceBase::Handle pending_server_creditcards_query_ = 0;
WebDataServiceBase::Handle pending_customer_data_query_ = 0;
// The observers.
base::ObserverList<PersonalDataManagerObserver> observers_;
......@@ -669,23 +677,23 @@ class PersonalDataManager : public KeyedService,
mutable std::string default_country_code_;
// The PrefService that this instance uses. Must outlive this instance.
PrefService* pref_service_;
PrefService* pref_service_ = nullptr;
// The identity manager that this instance uses. Must outlive this instance.
identity::IdentityManager* identity_manager_;
identity::IdentityManager* identity_manager_ = nullptr;
// The sync service this instances uses. Must outlive this instance.
syncer::SyncService* sync_service_;
syncer::SyncService* sync_service_ = nullptr;
// Whether the user is currently operating in an off-the-record context.
// Default value is false.
bool is_off_the_record_;
bool is_off_the_record_ = false;
// Whether we have already logged the stored profile metrics this session.
mutable bool has_logged_stored_profile_metrics_;
mutable bool has_logged_stored_profile_metrics_ = false;
// Whether we have already logged the stored credit card metrics this session.
mutable bool has_logged_stored_credit_card_metrics_;
mutable bool has_logged_stored_credit_card_metrics_ = false;
// An observer to listen for changes to prefs::kAutofillCreditCardEnabled.
std::unique_ptr<BooleanPrefMember> credit_card_enabled_pref_;
......
......@@ -44,4 +44,18 @@ sync_pb::AutofillWalletSpecifics CreateAutofillWalletSpecificsForAddress(
return wallet_specifics;
}
sync_pb::AutofillWalletSpecifics
CreateAutofillWalletSpecificsForPaymentsCustomerData(
const std::string& specifics_id) {
sync_pb::AutofillWalletSpecifics wallet_specifics;
wallet_specifics.set_type(
sync_pb::AutofillWalletSpecifics_WalletInfoType::
AutofillWalletSpecifics_WalletInfoType_CUSTOMER_DATA);
sync_pb::PaymentsCustomerData* customer_data_specifics =
wallet_specifics.mutable_customer_data();
customer_data_specifics->set_id(specifics_id);
return wallet_specifics;
}
} // namespace autofill
\ No newline at end of file
......@@ -24,6 +24,10 @@ sync_pb::AutofillWalletSpecifics CreateAutofillWalletSpecificsForCard(
const std::string& specifics_id,
const std::string& billing_address_id = "");
sync_pb::AutofillWalletSpecifics
CreateAutofillWalletSpecificsForPaymentsCustomerData(
const std::string& specifics_id);
} // namespace autofill
#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_SYNC_BRIDGE_TEST_UTIL_H_
......@@ -10,6 +10,7 @@
#include "components/autofill/core/browser/autofill_data_util.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/autofill/core/common/autofill_util.h"
#include "components/sync/model/entity_data.h"
......@@ -306,6 +307,37 @@ CreditCard CardFromSpecifics(const sync_pb::WalletMaskedCreditCard& card) {
return result;
}
std::unique_ptr<EntityData> CreateEntityDataFromPaymentsCustomerData(
const PaymentsCustomerData& customer_data) {
// We use customer_id as a storage key here.
auto entity_data = std::make_unique<EntityData>();
entity_data->non_unique_name = GetClientTagForSpecificsId(
AutofillWalletSpecifics::CUSTOMER_DATA, customer_data.customer_id);
AutofillWalletSpecifics* wallet_specifics =
entity_data->specifics.mutable_autofill_wallet();
SetAutofillWalletSpecificsFromPaymentsCustomerData(customer_data,
wallet_specifics);
return entity_data;
}
void SetAutofillWalletSpecificsFromPaymentsCustomerData(
const PaymentsCustomerData& customer_data,
AutofillWalletSpecifics* wallet_specifics) {
wallet_specifics->set_type(AutofillWalletSpecifics::CUSTOMER_DATA);
sync_pb::PaymentsCustomerData* mutable_customer_data =
wallet_specifics->mutable_customer_data();
mutable_customer_data->set_id(customer_data.customer_id);
}
PaymentsCustomerData CustomerDataFromSpecifics(
const sync_pb::PaymentsCustomerData& customer_data) {
return PaymentsCustomerData{/*customer_id=*/customer_data.id()};
}
void CopyRelevantWalletMetadataFromDisk(
const AutofillTable& table,
std::vector<CreditCard>* cards_from_server) {
......@@ -333,10 +365,11 @@ void CopyRelevantWalletMetadataFromDisk(
}
}
void PopulateWalletCardsAndAddresses(
void PopulateWalletTypesFromSyncData(
const syncer::EntityChangeList& entity_data,
std::vector<CreditCard>* wallet_cards,
std::vector<AutofillProfile>* wallet_addresses) {
std::vector<AutofillProfile>* wallet_addresses,
std::vector<PaymentsCustomerData>* customer_data) {
std::map<std::string, std::string> ids;
for (const syncer::EntityChange& change : entity_data) {
......@@ -359,6 +392,9 @@ void PopulateWalletCardsAndAddresses(
wallet_addresses->back().server_id();
break;
case sync_pb::AutofillWalletSpecifics::CUSTOMER_DATA:
customer_data->push_back(
CustomerDataFromSpecifics(autofill_specifics.customer_data()));
break;
case sync_pb::AutofillWalletSpecifics::UNKNOWN:
// Just ignore new entry types that the client doesn't know about.
break;
......
......@@ -16,6 +16,7 @@ namespace autofill {
class AutofillProfile;
class AutofillTable;
class CreditCard;
struct PaymentsCustomerData;
// Returns the wallet specifics id for the specified |server_id|.
std::string GetSpecificsIdForEntryServerId(const std::string& server_id);
......@@ -58,6 +59,21 @@ std::unique_ptr<syncer::EntityData> CreateEntityDataFromCard(
// Creates an AutofillProfile from the specified |card| specifics.
CreditCard CardFromSpecifics(const sync_pb::WalletMaskedCreditCard& card);
// Creates a EntityData object corresponding to the specified |customer_data|.
std::unique_ptr<syncer::EntityData> CreateEntityDataFromPaymentsCustomerData(
const PaymentsCustomerData& customer_data);
// Sets the fields of the |wallet_specifics| based on the specified
// |customer_data|.
void SetAutofillWalletSpecificsFromPaymentsCustomerData(
const PaymentsCustomerData& customer_data,
sync_pb::AutofillWalletSpecifics* wallet_specifics);
// Creates a PaymentCustomerData object corresponding to the sync datatype
// |customer_data|.
PaymentsCustomerData CustomerDataFromSpecifics(
const sync_pb::PaymentsCustomerData& customer_data);
// TODO(sebsg): This should probably copy the converted state for the address
// too.
// Copies the metadata from the local cards (if present) to the corresponding
......@@ -68,12 +84,13 @@ void CopyRelevantWalletMetadataFromDisk(
const AutofillTable& table,
std::vector<CreditCard>* cards_from_server);
// Populates the wallet cards and addresses from the sync data and uses the
// sync data to link the card to its billing address.
void PopulateWalletCardsAndAddresses(
// Populates the wallet datatypes from the sync data and uses the sync data to
// link the card to its billing address.
void PopulateWalletTypesFromSyncData(
const ::syncer::EntityChangeList& entity_data,
std::vector<CreditCard>* wallet_cards,
std::vector<AutofillProfile>* wallet_addresses);
std::vector<AutofillProfile>* wallet_addresses,
std::vector<PaymentsCustomerData>* customer_data);
} // namespace autofill
......
......@@ -9,6 +9,7 @@
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
......@@ -62,10 +63,8 @@ class AutofillSyncBridgeUtilTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(AutofillSyncBridgeUtilTest);
};
// Tests that the link between a card and its billing address from sync is
// present in the generated Autofill objects.
TEST_F(AutofillSyncBridgeUtilTest,
PopulateWalletCardsAndAddresses_BillingAddressIdTransfer) {
// Tests that PopulateWalletTypesFromSyncData behaves as expected.
TEST_F(AutofillSyncBridgeUtilTest, PopulateWalletTypesFromSyncData) {
// Add an address and a card that has its billing address id set to the
// address' id.
syncer::EntityChangeList entity_data;
......@@ -81,15 +80,24 @@ TEST_F(AutofillSyncBridgeUtilTest,
/*id=*/"card1", /*billing_address_id=*/address_id),
/*client_tag=*/"card-card1")
.PassToPtr()));
entity_data.push_back(EntityChange::CreateAdd(
"deadbeef",
SpecificsToEntity(CreateAutofillWalletSpecificsForPaymentsCustomerData(
/*specifics_id=*/"deadbeef"),
/*client_tag=*/"customer-deadbeef")
.PassToPtr()));
std::vector<CreditCard> wallet_cards;
std::vector<AutofillProfile> wallet_addresses;
PopulateWalletCardsAndAddresses(entity_data, &wallet_cards,
&wallet_addresses);
std::vector<PaymentsCustomerData> customer_data;
PopulateWalletTypesFromSyncData(entity_data, &wallet_cards, &wallet_addresses,
&customer_data);
ASSERT_EQ(1U, wallet_cards.size());
ASSERT_EQ(1U, wallet_addresses.size());
EXPECT_EQ("deadbeef", customer_data.back().customer_id);
// Make sure the card's billing address id is equal to the address' server id.
EXPECT_EQ(wallet_addresses.back().server_id(),
wallet_cards.back().billing_address_id());
......
......@@ -26,6 +26,7 @@
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/personal_data_manager.h"
#include "components/autofill/core/browser/webdata/autofill_change.h"
#include "components/autofill/core/browser/webdata/autofill_entry.h"
......@@ -413,7 +414,7 @@ bool AutofillTable::CreateTablesIfNecessary() {
InitMaskedCreditCardsTable() && InitUnmaskedCreditCardsTable() &&
InitServerCardMetadataTable() && InitServerAddressesTable() &&
InitServerAddressMetadataTable() && InitAutofillSyncMetadataTable() &&
InitModelTypeStateTable());
InitModelTypeStateTable() && InitPaymentsCustomerDataTable());
}
bool AutofillTable::IsSyncable() {
......@@ -1345,6 +1346,39 @@ bool AutofillTable::UpdateServerAddressMetadata(
return db_->GetLastChangeCount() > 0;
}
void AutofillTable::SetPaymentsCustomerData(
const PaymentsCustomerData* customer_data) {
sql::Transaction transaction(db_);
if (!transaction.Begin())
return;
// Delete all old values.
sql::Statement customer_data_delete(
db_->GetUniqueStatement("DELETE FROM payments_customer_data"));
customer_data_delete.Run();
if (customer_data) {
sql::Statement insert_customer_data(db_->GetUniqueStatement(
"INSERT INTO payments_customer_data (customer_id) VALUES (?)"));
insert_customer_data.BindString(0, customer_data->customer_id);
insert_customer_data.Run();
}
transaction.Commit();
}
bool AutofillTable::GetPaymentsCustomerData(
std::unique_ptr<PaymentsCustomerData>* customer_data) const {
sql::Statement s(db_->GetUniqueStatement(
"SELECT customer_id FROM payments_customer_data"));
if (s.Step()) {
customer_data->reset(
new PaymentsCustomerData(/*customer_id=*/s.ColumnString(0)));
}
return s.Succeeded();
}
bool AutofillTable::ClearAllServerData() {
sql::Transaction transaction(db_);
if (!transaction.Begin())
......@@ -2779,4 +2813,15 @@ bool AutofillTable::InitModelTypeStateTable() {
return true;
}
bool AutofillTable::InitPaymentsCustomerDataTable() {
if (!db_->DoesTableExist("payments_customer_data")) {
if (!db_->Execute("CREATE TABLE payments_customer_data "
"(customer_id VARCHAR)")) {
NOTREACHED();
return false;
}
}
return true;
}
} // namespace autofill
......@@ -33,6 +33,7 @@ class AutofillProfile;
class AutofillTableEncryptor;
class AutofillTableTest;
class CreditCard;
struct PaymentsCustomerData;
struct FormFieldData;
......@@ -263,6 +264,11 @@ struct FormFieldData;
// for one model type, there was an id column with value 1
// for the single entry.
// value The serialized ModelTypeState record.
//
// payments_customer_data
// Contains Google Payments customer data.
//
// customer_id A string representing the Google Payments customer id.
class AutofillTable : public WebDatabaseTable,
public syncer::SyncMetadataStore {
......@@ -398,6 +404,14 @@ class AutofillTable : public WebDatabaseTable,
bool UpdateServerCardMetadata(const CreditCard& credit_card);
bool UpdateServerAddressMetadata(const AutofillProfile& profile);
// Setters and getters related to the Google Payments customer data.
// Passing null to the setter will clear the data.
void SetPaymentsCustomerData(const PaymentsCustomerData* customer_data);
// Getter returns false if it could not execute the database statement, and
// may return true but leave |customer_data| untouched if there is no data.
bool GetPaymentsCustomerData(
std::unique_ptr<PaymentsCustomerData>* customer_data) const;
// Deletes all data from the server card and profile tables. Returns true if
// any data was deleted, false if not (so false means "commit not needed"
// rather than "error").
......@@ -593,6 +607,7 @@ class AutofillTable : public WebDatabaseTable,
bool InitServerAddressMetadataTable();
bool InitAutofillSyncMetadataTable();
bool InitModelTypeStateTable();
bool InitPaymentsCustomerDataTable();
std::unique_ptr<AutofillTableEncryptor> autofill_table_encryptor_;
......
......@@ -24,6 +24,7 @@
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/autofill_type.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/webdata/autofill_change.h"
#include "components/autofill/core/browser/webdata/autofill_entry.h"
#include "components/autofill/core/common/autofill_constants.h"
......@@ -2234,6 +2235,39 @@ TEST_F(AutofillTableTest, DeleteUnmaskedCard) {
outputs.clear();
}
// Test that we can get what we set.
TEST_F(AutofillTableTest, SetGetPaymentsCustomerData) {
PaymentsCustomerData input{/*customer_id=*/"deadbeef"};
table_->SetPaymentsCustomerData(&input);
std::unique_ptr<PaymentsCustomerData> output;
ASSERT_TRUE(table_->GetPaymentsCustomerData(&output));
EXPECT_EQ(input, *output);
}
// We don't set anything in the table. Test that we don't crash.
TEST_F(AutofillTableTest, GetPaymentsCustomerData_NoData) {
std::unique_ptr<PaymentsCustomerData> output;
ASSERT_TRUE(table_->GetPaymentsCustomerData(&output));
EXPECT_FALSE(output);
}
// The latest PaymentsCustomerData that was set is returned.
TEST_F(AutofillTableTest, SetGetPaymentsCustomerData_MultipleSet) {
PaymentsCustomerData input{/*customer_id=*/"deadbeef"};
table_->SetPaymentsCustomerData(&input);
PaymentsCustomerData input2{/*customer_id=*/"wallet"};
table_->SetPaymentsCustomerData(&input2);
PaymentsCustomerData input3{/*customer_id=*/"latest"};
table_->SetPaymentsCustomerData(&input3);
std::unique_ptr<PaymentsCustomerData> output;
ASSERT_TRUE(table_->GetPaymentsCustomerData(&output));
EXPECT_EQ(input3, *output);
}
const size_t kMaxCount = 2;
struct GetFormValuesTestCase {
const char* const field_suggestion[kMaxCount];
......
......@@ -14,6 +14,7 @@
#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/payments/payments_customer_data.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"
......@@ -127,8 +128,10 @@ void AutofillWalletSyncBridge::GetAllDataForDebugging(DataCallback callback) {
std::vector<std::unique_ptr<AutofillProfile>> profiles;
std::vector<std::unique_ptr<CreditCard>> cards;
std::unique_ptr<PaymentsCustomerData> customer_data;
if (!GetAutofillTable()->GetServerProfiles(&profiles) ||
!GetAutofillTable()->GetServerCreditCards(&cards)) {
!GetAutofillTable()->GetServerCreditCards(&cards) ||
!GetAutofillTable()->GetPaymentsCustomerData(&customer_data)) {
change_processor()->ReportError(
{FROM_HERE, "Failed to load entries from table."});
return;
......@@ -144,6 +147,10 @@ void AutofillWalletSyncBridge::GetAllDataForDebugging(DataCallback callback) {
CreateEntityDataFromCard(*entry));
}
if (customer_data) {
batch->Put(GetStorageKeyForEntryServerId(customer_data->customer_id),
CreateEntityDataFromPaymentsCustomerData(*customer_data));
}
std::move(callback).Run(std::move(batch));
}
......@@ -166,10 +173,12 @@ std::string AutofillWalletSyncBridge::GetStorageKey(
void AutofillWalletSyncBridge::SetSyncData(
const syncer::EntityChangeList& entity_data,
bool is_initial_data) {
// Extract the Autofill types from the sync |entity_data|.
std::vector<CreditCard> wallet_cards;
std::vector<AutofillProfile> wallet_addresses;
PopulateWalletCardsAndAddresses(entity_data, &wallet_cards,
&wallet_addresses);
std::vector<PaymentsCustomerData> customer_data;
PopulateWalletTypesFromSyncData(entity_data, &wallet_cards, &wallet_addresses,
&customer_data);
// Users can set billing address of the server credit card locally, but that
// information does not propagate to either Chrome Sync or Google Payments
......@@ -196,6 +205,15 @@ void AutofillWalletSyncBridge::SetSyncData(
if (!addresses_diff.IsEmpty())
table->SetServerProfiles(wallet_addresses);
if (customer_data.empty()) {
// Clears the data only.
table->SetPaymentsCustomerData(nullptr);
} else {
// In case there were multiple entries (and there shouldn't!), we take the
// first entry in the vector.
table->SetPaymentsCustomerData(&customer_data.front());
}
if (!is_initial_data) {
UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCardsAdded",
cards_diff.items_added);
......
......@@ -20,6 +20,7 @@
#include "components/autofill/core/browser/autofill_test_utils.h"
#include "components/autofill/core/browser/country_names.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/webdata/autofill_sync_bridge_test_util.h"
#include "components/autofill/core/browser/webdata/autofill_sync_bridge_util.h"
......@@ -53,13 +54,15 @@ using testing::UnorderedElementsAre;
// Base64 encodings of the server IDs, used as ids in WalletMetadataSpecifics
// (these are suitable for syncing, because they are valid UTF-8).
const char kAddr1SpecificsId[] = "YWRkcjHvv74=";
//const char kAddr2SpecificsId[] = "YWRkcjLvv74=";
const char kCard1SpecificsId[] = "Y2FyZDHvv74=";
//const char kCard2SpecificsId[] = "Y2FyZDLvv74=";
// Represents a Payments customer id.
const char kCustomerDataId[] = "deadbeef";
// Unique sync tags for the server IDs.
const char kAddr1SyncTag[] = "YWRkcjHvv74=";
const char kCard1SyncTag[] = "Y2FyZDHvv74=";
const char kCustomerDataSyncTag[] = "deadbeef";
const char kLocaleString[] = "en-US";
const base::Time kJune2017 = base::Time::FromDoubleT(1497552271);
......@@ -267,7 +270,7 @@ class AutofillWalletSyncBridgeTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(AutofillWalletSyncBridgeTest);
};
// The following 2 tests make sure client tags stay stable.
// The following 3 tests make sure client tags stay stable.
TEST_F(AutofillWalletSyncBridgeTest, GetClientTagForAddress) {
AutofillWalletSpecifics specifics =
CreateAutofillWalletSpecificsForAddress(kAddr1SpecificsId);
......@@ -282,7 +285,15 @@ TEST_F(AutofillWalletSyncBridgeTest, GetClientTagForCard) {
kCard1SyncTag);
}
// The following 2 tests make sure storage keys stay stable.
TEST_F(AutofillWalletSyncBridgeTest, GetClientTagForCustomerData) {
AutofillWalletSpecifics specifics =
CreateAutofillWalletSpecificsForPaymentsCustomerData(
kCustomerDataSyncTag);
EXPECT_EQ(bridge()->GetClientTag(SpecificsToEntity(specifics)),
kCustomerDataSyncTag);
}
// The following 3 tests make sure storage keys stay stable.
TEST_F(AutofillWalletSyncBridgeTest, GetStorageKeyForAddress) {
AutofillWalletSpecifics specifics1 =
CreateAutofillWalletSpecificsForAddress(kAddr1SpecificsId);
......@@ -297,6 +308,13 @@ TEST_F(AutofillWalletSyncBridgeTest, GetStorageKeyForCard) {
kCard1SpecificsId);
}
TEST_F(AutofillWalletSyncBridgeTest, GetStorageKeyForCustomerData) {
AutofillWalletSpecifics specifics3 =
CreateAutofillWalletSpecificsForPaymentsCustomerData(kCustomerDataId);
EXPECT_EQ(bridge()->GetStorageKey(SpecificsToEntity(specifics3)),
kCustomerDataId);
}
TEST_F(AutofillWalletSyncBridgeTest,
GetAllDataForDebugging_ShouldReturnAllData) {
AutofillProfile address1 = test::GetServerProfile();
......@@ -305,6 +323,8 @@ TEST_F(AutofillWalletSyncBridgeTest,
CreditCard card1 = test::GetMaskedServerCard();
CreditCard card2 = test::GetMaskedServerCardAmex();
table()->SetServerCreditCards({card1, card2});
PaymentsCustomerData customer_data{/*customer_id=*/kCustomerDataId};
table()->SetPaymentsCustomerData(&customer_data);
AutofillWalletSpecifics profile_specifics1;
SetAutofillWalletSpecificsFromServerProfile(address1, &profile_specifics1);
......@@ -314,12 +334,16 @@ TEST_F(AutofillWalletSyncBridgeTest,
SetAutofillWalletSpecificsFromServerCard(card1, &card_specifics1);
AutofillWalletSpecifics card_specifics2;
SetAutofillWalletSpecificsFromServerCard(card2, &card_specifics2);
AutofillWalletSpecifics customer_data_specifics;
SetAutofillWalletSpecificsFromPaymentsCustomerData(customer_data,
&customer_data_specifics);
EXPECT_THAT(GetAllLocalData(),
UnorderedElementsAre(EqualsSpecifics(profile_specifics1),
EqualsSpecifics(profile_specifics2),
EqualsSpecifics(card_specifics1),
EqualsSpecifics(card_specifics2)));
EqualsSpecifics(card_specifics2),
EqualsSpecifics(customer_data_specifics)));
}
// Tests that when a new wallet card and new wallet address are sent by the
......@@ -330,6 +354,8 @@ TEST_F(AutofillWalletSyncBridgeTest, MergeSyncData_NewWalletAddressAndCard) {
table()->SetServerProfiles({address1});
CreditCard card1 = test::GetMaskedServerCard();
table()->SetServerCreditCards({card1});
PaymentsCustomerData customer_data{/*customer_id=*/kCustomerDataId};
table()->SetPaymentsCustomerData(&customer_data);
// Create a different profile and a different card on the server.
AutofillProfile address2 = test::GetServerProfile2();
......@@ -338,13 +364,17 @@ TEST_F(AutofillWalletSyncBridgeTest, MergeSyncData_NewWalletAddressAndCard) {
CreditCard card2 = test::GetMaskedServerCardAmex();
AutofillWalletSpecifics card_specifics2;
SetAutofillWalletSpecificsFromServerCard(card2, &card_specifics2);
AutofillWalletSpecifics customer_data_specifics;
SetAutofillWalletSpecificsFromPaymentsCustomerData(customer_data,
&customer_data_specifics);
StartSyncing({profile_specifics2, card_specifics2});
StartSyncing({profile_specifics2, card_specifics2, customer_data_specifics});
// Only the server card should be present on the client.
EXPECT_THAT(GetAllLocalData(),
UnorderedElementsAre(EqualsSpecifics(profile_specifics2),
EqualsSpecifics(card_specifics2)));
EqualsSpecifics(card_specifics2),
EqualsSpecifics(customer_data_specifics)));
}
// Tests that when the server sends no cards or address, the client should
......
......@@ -139,6 +139,11 @@ AutofillProfile ProfileFromWalletCardSpecifics(
return profile;
}
PaymentsCustomerData CustomerDataFromSyncSpecifics(
const sync_pb::PaymentsCustomerData& customer_data) {
return PaymentsCustomerData{/*customer_id=*/customer_data.id()};
}
} // namespace
// static
......@@ -264,10 +269,11 @@ void AutofillWalletSyncableService::InjectStartSyncFlare(
}
// static
void AutofillWalletSyncableService::PopulateWalletCardsAndAddresses(
void AutofillWalletSyncableService::PopulateWalletTypesFromSyncData(
const syncer::SyncDataList& data_list,
std::vector<CreditCard>* wallet_cards,
std::vector<AutofillProfile>* wallet_addresses) {
std::vector<AutofillProfile>* wallet_addresses,
std::vector<PaymentsCustomerData>* customer_data) {
std::map<std::string, std::string> ids;
for (const syncer::SyncData& data : data_list) {
......@@ -288,6 +294,9 @@ void AutofillWalletSyncableService::PopulateWalletCardsAndAddresses(
wallet_addresses->back().server_id();
break;
case sync_pb::AutofillWalletSpecifics::CUSTOMER_DATA:
customer_data->push_back(
CustomerDataFromSyncSpecifics(autofill_specifics.customer_data()));
break;
case sync_pb::AutofillWalletSpecifics::UNKNOWN:
// Just ignore new entry types that the client doesn't know about.
break;
......@@ -335,7 +344,9 @@ syncer::SyncMergeResult AutofillWalletSyncableService::SetSyncData(
bool is_initial_data) {
std::vector<CreditCard> wallet_cards;
std::vector<AutofillProfile> wallet_addresses;
PopulateWalletCardsAndAddresses(data_list, &wallet_cards, &wallet_addresses);
std::vector<PaymentsCustomerData> customer_data;
PopulateWalletTypesFromSyncData(data_list, &wallet_cards, &wallet_addresses,
&customer_data);
// Users can set billing address of the server credit card locally, but that
// information does not propagate to either Chrome Sync or Google Payments
......@@ -367,6 +378,16 @@ syncer::SyncMergeResult AutofillWalletSyncableService::SetSyncData(
merge_result.set_num_items_after_association(
static_cast<int>(wallet_cards.size() + wallet_addresses.size()));
if (customer_data.empty()) {
// Clears the data only.
table->SetPaymentsCustomerData(nullptr);
} else {
// In case there were multiple entries (and there shouldn't!), we take the
// first entry in the vector.
DCHECK_EQ(1u, customer_data.size());
table->SetPaymentsCustomerData(&customer_data.front());
}
if (!is_initial_data) {
UMA_HISTOGRAM_COUNTS_100("Autofill.WalletCardsAdded",
cards_diff.items_added);
......
......@@ -14,6 +14,7 @@
#include "base/threading/thread_checker.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/sync/model/syncable_service.h"
namespace autofill {
......@@ -72,11 +73,13 @@ class AutofillWalletSyncableService
CopyRelevantMetadataFromDisk_OverwriteOtherAddresses);
FRIEND_TEST_ALL_PREFIXES(
AutofillWalletSyncableServiceTest,
PopulateWalletCardsAndAddresses_BillingAddressIdTransfer);
PopulateWalletTypesFromSyncData_BillingAddressIdTransfer);
FRIEND_TEST_ALL_PREFIXES(AutofillWalletSyncableServiceTest,
CopyRelevantMetadataFromDisk_KeepUseStats);
FRIEND_TEST_ALL_PREFIXES(AutofillWalletSyncableServiceTest, NewWalletCard);
FRIEND_TEST_ALL_PREFIXES(AutofillWalletSyncableServiceTest, EmptyNameOnCard);
FRIEND_TEST_ALL_PREFIXES(AutofillWalletSyncableServiceTest,
PaymentsCustomerData);
FRIEND_TEST_ALL_PREFIXES(AutofillWalletSyncableServiceTest, ComputeCardsDiff);
FRIEND_TEST_ALL_PREFIXES(AutofillWalletSyncableServiceTest,
ComputeAddressesDiff);
......@@ -102,12 +105,13 @@ class AutofillWalletSyncableService
syncer::SyncMergeResult SetSyncData(const syncer::SyncDataList& data_list,
bool is_initial_data);
// Populates the wallet cards and addresses from the sync data and uses the
// sync data to link the card to its billing address.
static void PopulateWalletCardsAndAddresses(
// Populates the wallet datatypes from the sync data and uses the sync data to
// link the card to its billing address.
static void PopulateWalletTypesFromSyncData(
const syncer::SyncDataList& data_list,
std::vector<CreditCard>* wallet_cards,
std::vector<AutofillProfile>* wallet_addresses);
std::vector<AutofillProfile>* wallet_addresses,
std::vector<PaymentsCustomerData>* customer_data);
// Finds the copies of the same credit card from the server and on disk and
// overwrites the server version with the use stats saved on disk, and the
......
......@@ -10,6 +10,7 @@
#include "base/strings/utf_string_conversions.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/test_autofill_clock.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
#include "components/sync/protocol/autofill_specifics.pb.h"
......@@ -52,6 +53,21 @@ syncer::SyncData CreateSyncDataForWalletAddress(const std::string& id) {
return syncer::SyncData::CreateLocalData(id, id, specifics);
}
syncer::SyncData CreateSyncDataForPaymentsCustomerData(const std::string& id) {
sync_pb::EntitySpecifics specifics;
sync_pb::AutofillWalletSpecifics* wallet_specifics =
specifics.mutable_autofill_wallet();
wallet_specifics->set_type(
sync_pb::AutofillWalletSpecifics_WalletInfoType::
AutofillWalletSpecifics_WalletInfoType_CUSTOMER_DATA);
sync_pb::PaymentsCustomerData* customer_data_specifics =
wallet_specifics->mutable_customer_data();
customer_data_specifics->set_id(id);
return syncer::SyncData::CreateLocalData(id, id, specifics);
}
class TestAutofillTable : public AutofillTable {
public:
explicit TestAutofillTable(std::vector<CreditCard> cards_on_disk)
......@@ -77,9 +93,10 @@ class TestAutofillTable : public AutofillTable {
// Verify that the link between a card and its billing address from sync is
// present in the generated Autofill objects.
TEST(AutofillWalletSyncableServiceTest,
PopulateWalletCardsAndAddresses_BillingAddressIdTransfer) {
PopulateWalletTypesFromSyncData_BillingAddressIdTransfer) {
std::vector<CreditCard> wallet_cards;
std::vector<AutofillProfile> wallet_addresses;
std::vector<PaymentsCustomerData> customer_data;
syncer::SyncDataList data_list;
// Create a Sync data for a card and its billing address.
......@@ -87,8 +104,8 @@ TEST(AutofillWalletSyncableServiceTest,
data_list.push_back(CreateSyncDataForWalletCreditCard(
"card1" /* id */, "1" /* billing_address_id */));
AutofillWalletSyncableService::PopulateWalletCardsAndAddresses(
data_list, &wallet_cards, &wallet_addresses);
AutofillWalletSyncableService::PopulateWalletTypesFromSyncData(
data_list, &wallet_cards, &wallet_addresses, &customer_data);
ASSERT_EQ(1U, wallet_cards.size());
ASSERT_EQ(1U, wallet_addresses.size());
......@@ -206,6 +223,7 @@ TEST(AutofillWalletSyncableServiceTest, NewWalletCard) {
std::vector<AutofillProfile> wallet_addresses;
std::vector<CreditCard> wallet_cards;
std::vector<PaymentsCustomerData> customer_data;
syncer::SyncDataList data_list;
// Create a Sync data for a card and its billing address.
......@@ -213,8 +231,8 @@ TEST(AutofillWalletSyncableServiceTest, NewWalletCard) {
data_list.push_back(CreateSyncDataForWalletCreditCard(
"card1" /* id */, "1" /* billing_address_id */));
AutofillWalletSyncableService::PopulateWalletCardsAndAddresses(
data_list, &wallet_cards, &wallet_addresses);
AutofillWalletSyncableService::PopulateWalletTypesFromSyncData(
data_list, &wallet_cards, &wallet_addresses, &customer_data);
ASSERT_EQ(1U, wallet_cards.size());
......@@ -227,14 +245,15 @@ TEST(AutofillWalletSyncableServiceTest, NewWalletCard) {
TEST(AutofillWalletSyncableServiceTest, EmptyNameOnCard) {
std::vector<CreditCard> wallet_cards;
std::vector<AutofillProfile> wallet_addresses;
std::vector<PaymentsCustomerData> customer_data;
syncer::SyncDataList data_list;
// Create a Sync data for a card and its billing address.
data_list.push_back(CreateSyncDataForWalletCreditCard(
"card1" /* id */, "1" /* billing_address_id */));
AutofillWalletSyncableService::PopulateWalletCardsAndAddresses(
data_list, &wallet_cards, &wallet_addresses);
AutofillWalletSyncableService::PopulateWalletTypesFromSyncData(
data_list, &wallet_cards, &wallet_addresses, &customer_data);
ASSERT_EQ(1U, wallet_cards.size());
......@@ -247,6 +266,23 @@ TEST(AutofillWalletSyncableServiceTest, EmptyNameOnCard) {
wallet_cards.back().GetRawInfo(autofill::CREDIT_CARD_NAME_LAST).empty());
}
TEST(AutofillWalletSyncableServiceTest, PaymentsCustomerData) {
std::vector<CreditCard> wallet_cards;
std::vector<AutofillProfile> wallet_addresses;
std::vector<PaymentsCustomerData> customer_data;
syncer::SyncDataList data_list;
// Create Sync data for Payments Customer data.
data_list.push_back(
CreateSyncDataForPaymentsCustomerData("deadbeef" /* id */));
AutofillWalletSyncableService::PopulateWalletTypesFromSyncData(
data_list, &wallet_cards, &wallet_addresses, &customer_data);
// Make sure the Payments customer id is there.
EXPECT_EQ("deadbeef", customer_data.back().customer_id);
}
TEST(AutofillWalletSyncableServiceTest, ComputeCardsDiff) {
// Some arbitrary cards for testing.
CreditCard card0(CreditCard::MASKED_SERVER_CARD, "a");
......
......@@ -112,6 +112,13 @@ class AutofillWebData {
const base::string16& full_number) = 0;
virtual void MaskServerCreditCard(const std::string& id) = 0;
// Initiates the request for Payments customer data. The method
// OnWebDataServiceRequestDone of |consumer| gets called when the request is
// finished, with the customer data included in the argument |result|. The
// consumer owns the data.
virtual WebDataServiceBase::Handle GetPaymentsCustomerData(
WebDataServiceConsumer* consumer) = 0;
// Updates the metadata for a server card (masked or not).
virtual void UpdateServerCardMetadata(const CreditCard& credit_card) = 0;
......
......@@ -11,6 +11,7 @@
#include "components/autofill/core/browser/autofill_country.h"
#include "components/autofill/core/browser/autofill_profile.h"
#include "components/autofill/core/browser/credit_card.h"
#include "components/autofill/core/browser/payments/payments_customer_data.h"
#include "components/autofill/core/browser/webdata/autofill_change.h"
#include "components/autofill/core/browser/webdata/autofill_entry.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
......@@ -419,6 +420,15 @@ WebDatabase::State AutofillWebDataBackendImpl::UpdateServerAddressMetadata(
return WebDatabase::COMMIT_NEEDED;
}
std::unique_ptr<WDTypedResult>
AutofillWebDataBackendImpl::GetPaymentsCustomerData(WebDatabase* db) {
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
std::unique_ptr<PaymentsCustomerData> customer_data;
AutofillTable::FromWebDatabase(db)->GetPaymentsCustomerData(&customer_data);
return std::make_unique<WDResult<std::unique_ptr<PaymentsCustomerData>>>(
AUTOFILL_CUSTOMERDATA_RESULT, std::move(customer_data));
}
WebDatabase::State AutofillWebDataBackendImpl::ClearAllServerData(
WebDatabase* db) {
DCHECK(owning_task_runner()->RunsTasksInCurrentSequence());
......
......@@ -163,6 +163,9 @@ class AutofillWebDataBackendImpl
WebDatabase::State UpdateServerAddressMetadata(const AutofillProfile& profile,
WebDatabase* db);
// Returns the PaymentsCustomerData from the database.
std::unique_ptr<WDTypedResult> GetPaymentsCustomerData(WebDatabase* db);
WebDatabase::State ClearAllServerData(WebDatabase* db);
WebDatabase::State ClearAllLocalData(WebDatabase* db);
......
......@@ -213,6 +213,15 @@ void AutofillWebDataService::MaskServerCreditCard(const std::string& id) {
autofill_backend_, id));
}
WebDataServiceBase::Handle AutofillWebDataService::GetPaymentsCustomerData(
WebDataServiceConsumer* consumer) {
return wdbs_->ScheduleDBTaskWithResult(
FROM_HERE,
Bind(&AutofillWebDataBackendImpl::GetPaymentsCustomerData,
autofill_backend_),
consumer);
}
void AutofillWebDataService::ClearAllServerData() {
wdbs_->ScheduleDBTask(
FROM_HERE,
......
......@@ -98,6 +98,10 @@ class AutofillWebDataService : public AutofillWebData,
const base::string16& full_number) override;
void MaskServerCreditCard(const std::string& id) override;
// PaymentsCustomerData.
WebDataServiceBase::Handle GetPaymentsCustomerData(
WebDataServiceConsumer* consumer) override;
void ClearAllServerData();
void ClearAllLocalData();
......
......@@ -332,6 +332,7 @@ class MockPersonalDataManager : public PersonalDataManager {
MOCK_CONST_METHOD0(IsDataLoaded, bool());
MOCK_METHOD0(LoadProfiles, void());
MOCK_METHOD0(LoadCreditCards, void());
MOCK_METHOD0(LoadPaymentsCustomerData, void());
MOCK_METHOD0(Refresh, void());
};
......@@ -373,12 +374,14 @@ class ProfileSyncServiceAutofillTest
EXPECT_CALL(personal_data_manager(), LoadProfiles());
EXPECT_CALL(personal_data_manager(), LoadCreditCards());
EXPECT_CALL(personal_data_manager(), LoadPaymentsCustomerData());
personal_data_manager_->Init(web_data_service_,
/*account_database=*/nullptr,
profile_sync_service_bundle()->pref_service(),
/*identity_manager=*/nullptr,
/*is_off_the_record=*/false);
personal_data_manager_->SetUseAccountStorageForServerCards(false);
web_data_service_->StartSyncableService();
......
......@@ -34,6 +34,8 @@ typedef enum {
AUTOFILL_CREDITCARD_RESULT, // WDResult<CreditCard>
AUTOFILL_CREDITCARDS_RESULT, // WDResult<std::vector<
// std::unique_ptr<CreditCard>>>
AUTOFILL_CUSTOMERDATA_RESULT, // WDResult<std::unique_ptr<
// PaymentsCustomerData>>
#if !defined(OS_IOS)
PAYMENT_WEB_APP_MANIFEST, // WDResult<std::vector<
// mojom::WebAppManifestSectionPtr>>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment