summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrettw <brettw@chromium.org>2015-02-12 10:44:39 -0800
committerCommit bot <commit-bot@chromium.org>2015-02-12 18:45:23 +0000
commit43eadb637fa97fda1785cf6ad0d4a471c025c06d (patch)
tree842fbc7024de585bb49882965d4d9abdd8d34b05
parent25eff098c77343e5b95f25c4465a0eb09942ab6e (diff)
downloadchromium_src-43eadb637fa97fda1785cf6ad0d4a471c025c06d.zip
chromium_src-43eadb637fa97fda1785cf6ad0d4a471c025c06d.tar.gz
chromium_src-43eadb637fa97fda1785cf6ad0d4a471c025c06d.tar.bz2
Hook up wallet card and address sync
This syncs the masked credit card and addresses from wallet into Chrome autofill. R=estade, zea TBR=isherman (histograms) Review URL: https://codereview.chromium.org/902673002 Cr-Commit-Position: refs/heads/master@{#316008}
-rw-r--r--chrome/browser/sync/glue/autofill_wallet_data_type_controller.cc90
-rw-r--r--chrome/browser/sync/glue/autofill_wallet_data_type_controller.h52
-rw-r--r--chrome/browser/sync/profile_sync_components_factory_impl.cc22
-rw-r--r--chrome/browser/sync/profile_sync_service.cc2
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--components/autofill.gypi4
-rw-r--r--components/autofill/core/browser/BUILD.gn4
-rw-r--r--components/autofill/core/browser/autofill_metrics_unittest.cc6
-rw-r--r--components/autofill/core/browser/credit_card.cc29
-rw-r--r--components/autofill/core/browser/credit_card.h11
-rw-r--r--components/autofill/core/browser/personal_data_manager.cc13
-rw-r--r--components/autofill/core/browser/webdata/autofill_table.cc48
-rw-r--r--components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc259
-rw-r--r--components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h72
-rw-r--r--components/sync_driver/model_association_manager.cc1
-rw-r--r--components/sync_driver/pref_names.cc1
-rw-r--r--components/sync_driver/pref_names.h1
-rw-r--r--components/sync_driver/sync_prefs.cc4
-rw-r--r--components/sync_driver/sync_prefs_unittest.cc1
-rw-r--r--components/webdata_services/web_data_service_wrapper.cc7
-rw-r--r--sync/internal_api/public/base/model_type.h3
-rw-r--r--sync/protocol/proto_enum_conversions.cc40
-rw-r--r--sync/protocol/proto_enum_conversions.h8
-rw-r--r--sync/protocol/proto_value_conversions.cc45
-rw-r--r--sync/protocol/proto_value_conversions.h12
-rw-r--r--sync/protocol/proto_value_conversions_unittest.cc8
-rw-r--r--sync/syncable/model_type.cc33
-rw-r--r--sync/syncable/nigori_util.cc4
-rw-r--r--sync/util/data_type_histogram.h3
-rw-r--r--tools/metrics/histograms/histograms.xml1
30 files changed, 701 insertions, 85 deletions
diff --git a/chrome/browser/sync/glue/autofill_wallet_data_type_controller.cc b/chrome/browser/sync/glue/autofill_wallet_data_type_controller.cc
new file mode 100644
index 0000000..771a568
--- /dev/null
+++ b/chrome/browser/sync/glue/autofill_wallet_data_type_controller.cc
@@ -0,0 +1,90 @@
+// Copyright 2015 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_wallet_data_type_controller.h"
+
+#include "base/bind.h"
+#include "chrome/browser/autofill/personal_data_manager_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/sync/glue/chrome_report_unrecoverable_error.h"
+#include "chrome/browser/sync/profile_sync_components_factory.h"
+#include "chrome/browser/webdata/web_data_service_factory.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
+#include "content/public/browser/browser_thread.h"
+#include "sync/api/sync_error.h"
+#include "sync/api/syncable_service.h"
+
+using content::BrowserThread;
+
+namespace browser_sync {
+
+AutofillWalletDataTypeController::AutofillWalletDataTypeController(
+ ProfileSyncComponentsFactory* profile_sync_factory,
+ Profile* profile)
+ : NonUIDataTypeController(
+ BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI),
+ base::Bind(&ChromeReportUnrecoverableError),
+ profile_sync_factory),
+ profile_(profile),
+ personal_data_(nullptr),
+ callback_registered_(false) {
+}
+
+AutofillWalletDataTypeController::~AutofillWalletDataTypeController() {
+}
+
+syncer::ModelType AutofillWalletDataTypeController::type() const {
+ return syncer::AUTOFILL_WALLET_DATA;
+}
+
+syncer::ModelSafeGroup
+ AutofillWalletDataTypeController::model_safe_group() const {
+ return syncer::GROUP_DB;
+}
+
+bool AutofillWalletDataTypeController::PostTaskOnBackendThread(
+ const tracked_objects::Location& from_here,
+ const base::Closure& task) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ return BrowserThread::PostTask(BrowserThread::DB, from_here, task);
+}
+
+bool AutofillWalletDataTypeController::StartModels() {
+ DCHECK(content::BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK_EQ(state(), MODEL_STARTING);
+
+ personal_data_ =
+ autofill::PersonalDataManagerFactory::GetForProfile(profile_);
+ if (!personal_data_->IsDataLoaded())
+ return false;
+
+ autofill::AutofillWebDataService* web_data_service =
+ WebDataServiceFactory::GetAutofillWebDataForProfile(
+ profile_, ServiceAccessType::EXPLICIT_ACCESS).get();
+
+ if (!web_data_service)
+ return false;
+
+ if (web_data_service->IsDatabaseLoaded())
+ return true;
+
+ if (!callback_registered_) {
+ web_data_service->RegisterDBLoadedCallback(base::Bind(
+ &AutofillWalletDataTypeController::WebDatabaseLoaded, this));
+ callback_registered_ = true;
+ }
+
+ return false;
+}
+
+void AutofillWalletDataTypeController::StopModels() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+}
+
+void AutofillWalletDataTypeController::WebDatabaseLoaded() {
+ OnModelLoaded();
+}
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/glue/autofill_wallet_data_type_controller.h b/chrome/browser/sync/glue/autofill_wallet_data_type_controller.h
new file mode 100644
index 0000000..408f595
--- /dev/null
+++ b/chrome/browser/sync/glue/autofill_wallet_data_type_controller.h
@@ -0,0 +1,52 @@
+// Copyright 2015 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 CHROME_BROWSER_SYNC_GLUE_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
+#define CHROME_BROWSER_SYNC_GLUE_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
+
+#include "base/basictypes.h"
+#include "components/sync_driver/non_ui_data_type_controller.h"
+
+class Profile;
+class ProfileSyncComponentsFactory;
+
+namespace autofill {
+class PersonalDataManager;
+}
+
+namespace browser_sync {
+
+class AutofillWalletDataTypeController
+ : public sync_driver::NonUIDataTypeController {
+ public:
+ AutofillWalletDataTypeController(
+ ProfileSyncComponentsFactory* profile_sync_factory,
+ Profile* profile);
+
+ // NonUIDataTypeController implementation.
+ syncer::ModelType type() const override;
+ syncer::ModelSafeGroup model_safe_group() const override;
+
+ protected:
+ ~AutofillWalletDataTypeController() override;
+
+ private:
+ // NonUIDataTypeController implementation.
+ bool PostTaskOnBackendThread(const tracked_objects::Location& from_here,
+ const base::Closure& task) override;
+ bool StartModels() override;
+ void StopModels() override;
+
+ void WebDatabaseLoaded();
+
+ Profile* const profile_;
+ autofill::PersonalDataManager* personal_data_;
+ bool callback_registered_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutofillWalletDataTypeController);
+};
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_GLUE_AUTOFILL_WALLET_DATA_TYPE_CONTROLLER_H_
diff --git a/chrome/browser/sync/profile_sync_components_factory_impl.cc b/chrome/browser/sync/profile_sync_components_factory_impl.cc
index 2d0edd8..bffaf01 100644
--- a/chrome/browser/sync/profile_sync_components_factory_impl.cc
+++ b/chrome/browser/sync/profile_sync_components_factory_impl.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/signin/signin_manager_factory.h"
#include "chrome/browser/sync/glue/autofill_data_type_controller.h"
#include "chrome/browser/sync/glue/autofill_profile_data_type_controller.h"
+#include "chrome/browser/sync/glue/autofill_wallet_data_type_controller.h"
#include "chrome/browser/sync/glue/bookmark_change_processor.h"
#include "chrome/browser/sync/glue/bookmark_data_type_controller.h"
#include "chrome/browser/sync/glue/bookmark_model_associator.h"
@@ -45,7 +46,10 @@
#include "chrome/common/pref_names.h"
#include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h"
#include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h"
+#include "components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
+#include "components/autofill/core/common/autofill_pref_names.h"
+#include "components/autofill/core/common/autofill_switches.h"
#include "components/dom_distiller/core/dom_distiller_service.h"
#include "components/password_manager/core/browser/password_store.h"
#include "components/search_engines/template_url_service.h"
@@ -213,6 +217,17 @@ void ProfileSyncComponentsFactoryImpl::RegisterCommonDataTypes(
new AutofillProfileDataTypeController(this, profile_));
}
+ if ((base::CommandLine::ForCurrentProcess()->HasSwitch(
+ autofill::switches::kEnableWalletCardImport) ||
+ profile_->GetPrefs()->GetBoolean(
+ autofill::prefs::kAutofillWalletSyncExperimentEnabled)) &&
+ !disabled_types.Has(syncer::AUTOFILL_WALLET_DATA)) {
+ // The feature can be enabled by sync experiment *or* command line flag,
+ // and additionally the sync type must be enabled.
+ pss->RegisterDataTypeController(
+ new browser_sync::AutofillWalletDataTypeController(this, profile_));
+ }
+
// Bookmark sync is enabled by default. Register unless explicitly
// disabled.
if (!disabled_types.Has(syncer::BOOKMARKS)) {
@@ -470,16 +485,19 @@ base::WeakPtr<syncer::SyncableService> ProfileSyncComponentsFactoryImpl::
return PrefServiceSyncable::FromProfile(profile_)->GetSyncableService(
syncer::PRIORITY_PREFERENCES)->AsWeakPtr();
case syncer::AUTOFILL:
- case syncer::AUTOFILL_PROFILE: {
+ case syncer::AUTOFILL_PROFILE:
+ case syncer::AUTOFILL_WALLET_DATA: {
if (!web_data_service_.get())
return base::WeakPtr<syncer::SyncableService>();
if (type == syncer::AUTOFILL) {
return autofill::AutocompleteSyncableService::FromWebDataService(
web_data_service_.get())->AsWeakPtr();
- } else {
+ } else if (type == syncer::AUTOFILL_PROFILE) {
return autofill::AutofillProfileSyncableService::FromWebDataService(
web_data_service_.get())->AsWeakPtr();
}
+ return autofill::AutofillWalletSyncableService::FromWebDataService(
+ web_data_service_.get())->AsWeakPtr();
}
case syncer::SEARCH_ENGINES:
return TemplateURLServiceFactory::GetForProfile(profile_)->AsWeakPtr();
diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc
index acbfb7c..61ad4f3 100644
--- a/chrome/browser/sync/profile_sync_service.cc
+++ b/chrome/browser/sync/profile_sync_service.cc
@@ -1743,7 +1743,7 @@ void ProfileSyncService::UpdateSelectedTypesHistogram(
sync_driver::user_selectable_type::PROXY_TABS,
};
- static_assert(34 == syncer::MODEL_TYPE_COUNT,
+ static_assert(35 == syncer::MODEL_TYPE_COUNT,
"custom config histogram must be updated");
if (!sync_everything) {
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index a0d1ce8..3a95fbd 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2665,6 +2665,8 @@
'browser/sync/glue/autofill_data_type_controller.h',
'browser/sync/glue/autofill_profile_data_type_controller.cc',
'browser/sync/glue/autofill_profile_data_type_controller.h',
+ 'browser/sync/glue/autofill_wallet_data_type_controller.cc',
+ 'browser/sync/glue/autofill_wallet_data_type_controller.h',
'browser/sync/glue/bookmark_change_processor.cc',
'browser/sync/glue/bookmark_change_processor.h',
'browser/sync/glue/bookmark_data_type_controller.cc',
diff --git a/components/autofill.gypi b/components/autofill.gypi
index a2f8015..b0d2c23 100644
--- a/components/autofill.gypi
+++ b/components/autofill.gypi
@@ -200,6 +200,8 @@
'autofill/core/browser/webdata/autofill_profile_syncable_service.h',
'autofill/core/browser/webdata/autofill_table.cc',
'autofill/core/browser/webdata/autofill_table.h',
+ 'autofill/core/browser/webdata/autofill_wallet_syncable_service.cc',
+ 'autofill/core/browser/webdata/autofill_wallet_syncable_service.h',
'autofill/core/browser/webdata/autofill_webdata.h',
'autofill/core/browser/webdata/autofill_webdata_backend.h',
'autofill/core/browser/webdata/autofill_webdata_backend_impl.cc',
@@ -240,6 +242,8 @@
'autofill/core/browser/webdata/autocomplete_syncable_service.h',
'autofill/core/browser/webdata/autofill_profile_syncable_service.cc',
'autofill/core/browser/webdata/autofill_profile_syncable_service.h',
+ 'autofill/core/browser/webdata/autofill_wallet_syncable_service.cc',
+ 'autofill/core/browser/webdata/autofill_wallet_syncable_service.h',
],
}],
],
diff --git a/components/autofill/core/browser/BUILD.gn b/components/autofill/core/browser/BUILD.gn
index f66122c..b839082 100644
--- a/components/autofill/core/browser/BUILD.gn
+++ b/components/autofill/core/browser/BUILD.gn
@@ -133,6 +133,8 @@ static_library("browser") {
"webdata/autofill_profile_syncable_service.h",
"webdata/autofill_table.cc",
"webdata/autofill_table.h",
+ "webdata/autofill_wallet_syncable_service.cc",
+ "webdata/autofill_wallet_syncable_service.h",
"webdata/autofill_webdata.h",
"webdata/autofill_webdata_backend.h",
"webdata/autofill_webdata_backend_impl.cc",
@@ -183,6 +185,8 @@ static_library("browser") {
"webdata/autocomplete_syncable_service.h",
"webdata/autofill_profile_syncable_service.cc",
"webdata/autofill_profile_syncable_service.h",
+ "webdata/autofill_wallet_syncable_service.cc",
+ "webdata/autofill_wallet_syncable_service.h",
]
}
diff --git a/components/autofill/core/browser/autofill_metrics_unittest.cc b/components/autofill/core/browser/autofill_metrics_unittest.cc
index 48c7847..a8672c4 100644
--- a/components/autofill/core/browser/autofill_metrics_unittest.cc
+++ b/components/autofill/core/browser/autofill_metrics_unittest.cc
@@ -1146,6 +1146,12 @@ TEST_F(AutofillMetricsTest, CreditCardFormEventsAreSegmented) {
// Test that we log interacted form event for address only once.
TEST_F(AutofillMetricsTest, AddressFormEventsAreSegmented) {
+ // Enabling server card.
+ base::CommandLine::ForCurrentProcess()->AppendSwitch(
+ ::autofill::switches::kEnableWalletCardImport);
+ autofill_client_.GetPrefs()->SetBoolean(
+ ::autofill::prefs::kAutofillWalletImportEnabled, true);
+
// Set up our form data.
FormData form;
form.name = ASCIIToUTF16("TestForm");
diff --git a/components/autofill/core/browser/credit_card.cc b/components/autofill/core/browser/credit_card.cc
index cfae31b..45430d3 100644
--- a/components/autofill/core/browser/credit_card.cc
+++ b/components/autofill/core/browser/credit_card.cc
@@ -503,6 +503,19 @@ void CreditCard::SetInfoForMonthInputType(const base::string16& value) {
SetExpirationMonth(num);
}
+void CreditCard::SetExpirationMonth(int expiration_month) {
+ if (expiration_month < 0 || expiration_month > 12)
+ return;
+ expiration_month_ = expiration_month;
+}
+
+void CreditCard::SetExpirationYear(int expiration_year) {
+ if (expiration_year != 0 &&
+ (expiration_year < 2006 || expiration_year > 10000))
+ return;
+ expiration_year_ = expiration_year;
+}
+
base::string16 CreditCard::LastFourDigits() const {
static const size_t kNumLastDigits = 4;
@@ -729,22 +742,6 @@ void CreditCard::SetNumber(const base::string16& number) {
type_ = GetCreditCardType(StripSeparators(number_));
}
-void CreditCard::SetExpirationMonth(int expiration_month) {
- if (expiration_month < 0 || expiration_month > 12)
- return;
-
- expiration_month_ = expiration_month;
-}
-
-void CreditCard::SetExpirationYear(int expiration_year) {
- if (expiration_year != 0 &&
- (expiration_year < 2006 || expiration_year > 10000)) {
- return;
- }
-
- expiration_year_ = expiration_year;
-}
-
// So we can compare CreditCards with EXPECT_EQ().
std::ostream& operator<<(std::ostream& os, const CreditCard& credit_card) {
return os
diff --git a/components/autofill/core/browser/credit_card.h b/components/autofill/core/browser/credit_card.h
index d8eda0a9..d8c7feb 100644
--- a/components/autofill/core/browser/credit_card.h
+++ b/components/autofill/core/browser/credit_card.h
@@ -115,6 +115,12 @@ class CreditCard : public AutofillDataModel {
int expiration_month() const { return expiration_month_; }
int expiration_year() const { return expiration_year_; }
+ // These setters verify that the month and year are within appropriate
+ // ranges, or 0. They take integers as an alternative to setting the inputs
+ // from strings via SetInfo().
+ void SetExpirationMonth(int expiration_month);
+ void SetExpirationYear(int expiration_year);
+
const std::string& server_id() const { return server_id_; }
// For use in STL containers.
@@ -184,11 +190,6 @@ class CreditCard : public AutofillDataModel {
// Sets |expiration_year_| to the integer conversion of |text|.
void SetExpirationYearFromString(const base::string16& text);
- // These setters verify that the month and year are within appropriate
- // ranges.
- void SetExpirationMonth(int expiration_month);
- void SetExpirationYear(int expiration_year);
-
// See enum definition above.
RecordType record_type_;
diff --git a/components/autofill/core/browser/personal_data_manager.cc b/components/autofill/core/browser/personal_data_manager.cc
index 131f3ae..f9afcf5 100644
--- a/components/autofill/core/browser/personal_data_manager.cc
+++ b/components/autofill/core/browser/personal_data_manager.cc
@@ -1211,20 +1211,19 @@ const std::vector<AutofillProfile*>& PersonalDataManager::GetProfiles(
#endif // defined(OS_MACOSX) && !defined(OS_IOS)
profiles_.clear();
-
- // Populates |auxiliary_profiles_|.
- if (use_auxiliary_profiles)
- LoadAuxiliaryProfiles(record_metrics);
-
profiles_.insert(profiles_.end(), web_profiles().begin(),
web_profiles().end());
if (use_auxiliary_profiles) {
+ LoadAuxiliaryProfiles(record_metrics);
profiles_.insert(
profiles_.end(), auxiliary_profiles_.begin(),
auxiliary_profiles_.end());
}
- profiles_.insert(
- profiles_.end(), server_profiles_.begin(), server_profiles_.end());
+ if (IsExperimentalWalletIntegrationEnabled() &&
+ pref_service_->GetBoolean(prefs::kAutofillWalletImportEnabled)) {
+ profiles_.insert(
+ profiles_.end(), server_profiles_.begin(), server_profiles_.end());
+ }
return profiles_;
}
diff --git a/components/autofill/core/browser/webdata/autofill_table.cc b/components/autofill/core/browser/webdata/autofill_table.cc
index 4f4c815..da4e3fe 100644
--- a/components/autofill/core/browser/webdata/autofill_table.cc
+++ b/components/autofill/core/browser/webdata/autofill_table.cc
@@ -1257,54 +1257,6 @@ bool AutofillTable::GetServerCreditCards(
credit_cards->push_back(card);
}
- static bool do_once = true;
- // Fake out some masked cards. TODO(estade): remove this block of code.
- if (do_once &&
- base::CommandLine::ForCurrentProcess()->HasSwitch(
- switches::kEnableWalletCardImport)) {
- do_once = false;
- std::vector<CreditCard> fake_masked_cards;
- fake_masked_cards.push_back(
- CreditCard(CreditCard::MASKED_SERVER_CARD, "a123"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_NAME,
- ASCIIToUTF16("Edgar Salazar"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_EXP_MONTH,
- ASCIIToUTF16("03"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR,
- ASCIIToUTF16("2016"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_NUMBER,
- ASCIIToUTF16("8431"));
- fake_masked_cards.back().SetTypeForMaskedCard(kAmericanExpressCard);
-
- fake_masked_cards.push_back(
- CreditCard(CreditCard::MASKED_SERVER_CARD, "b456"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_NAME,
- ASCIIToUTF16("Elena Salazar"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_EXP_MONTH,
- ASCIIToUTF16("05"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR,
- ASCIIToUTF16("2017"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_NUMBER,
- ASCIIToUTF16("9424"));
- fake_masked_cards.back().SetTypeForMaskedCard(kDiscoverCard);
-
- fake_masked_cards.push_back(
- CreditCard(CreditCard::MASKED_SERVER_CARD, "c789"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_NAME,
- ASCIIToUTF16("Efren Salazar, Sr"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_EXP_MONTH,
- ASCIIToUTF16("12"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_EXP_4_DIGIT_YEAR,
- ASCIIToUTF16("2014"));
- fake_masked_cards.back().SetRawInfo(CREDIT_CARD_NUMBER,
- ASCIIToUTF16("1881"));
- fake_masked_cards.back().SetTypeForMaskedCard(kVisaCard);
- fake_masked_cards.back().SetServerStatus(CreditCard::EXPIRED);
-
- SetServerCreditCards(fake_masked_cards);
- return GetServerCreditCards(credit_cards);
- }
-
return s.Succeeded();
}
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc
new file mode 100644
index 0000000..2cd0909
--- /dev/null
+++ b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.cc
@@ -0,0 +1,259 @@
+// Copyright 2015 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_syncable_service.h"
+
+#include <set>
+
+#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/credit_card.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 "sync/api/sync_error_factory.h"
+#include "sync/protocol/sync.pb.h"
+
+namespace autofill {
+
+namespace {
+
+void* UserDataKey() {
+ // Use the address of a static so that COMDAT folding won't ever fold
+ // with something else.
+ static int user_data_key = 0;
+ return reinterpret_cast<void*>(&user_data_key);
+}
+
+const char* CardTypeFromWalletCardType(
+ sync_pb::WalletMaskedCreditCard::WalletCardType type) {
+ switch (type) {
+ case sync_pb::WalletMaskedCreditCard::AMEX:
+ return kAmericanExpressCard;
+ case sync_pb::WalletMaskedCreditCard::DISCOVER:
+ return kDiscoverCard;
+ case sync_pb::WalletMaskedCreditCard::JCB:
+ return kJCBCard;
+ case sync_pb::WalletMaskedCreditCard::MASTER_CARD:
+ return kMasterCard;
+ case sync_pb::WalletMaskedCreditCard::VISA:
+ return kVisaCard;
+
+ // These aren't supported by the client, so just declare a generic card.
+ case sync_pb::WalletMaskedCreditCard::MAESTRO:
+ case sync_pb::WalletMaskedCreditCard::SOLO:
+ case sync_pb::WalletMaskedCreditCard::SWITCH:
+ default:
+ return kGenericCard;
+ }
+}
+
+CreditCard::ServerStatus ServerToLocalStatus(
+ sync_pb::WalletMaskedCreditCard::WalletCardStatus status) {
+ switch (status) {
+ case sync_pb::WalletMaskedCreditCard::VALID:
+ return CreditCard::OK;
+ case sync_pb::WalletMaskedCreditCard::EXPIRED:
+ default:
+ DCHECK_EQ(sync_pb::WalletMaskedCreditCard::EXPIRED, status);
+ return CreditCard::EXPIRED;
+ }
+}
+
+CreditCard CardFromSpecifics(const sync_pb::WalletMaskedCreditCard& card) {
+ CreditCard result(CreditCard::MASKED_SERVER_CARD, card.id());
+ result.SetNumber(base::UTF8ToUTF16(card.last_four()));
+ result.SetServerStatus(ServerToLocalStatus(card.status()));
+ result.SetTypeForMaskedCard(CardTypeFromWalletCardType(card.type()));
+ result.SetRawInfo(CREDIT_CARD_NAME, base::UTF8ToUTF16(card.name_on_card()));
+ result.SetExpirationMonth(card.exp_month());
+ result.SetExpirationYear(card.exp_year());
+ return result;
+}
+
+AutofillProfile ProfileFromSpecifics(
+ const sync_pb::WalletPostalAddress& address) {
+ AutofillProfile profile(AutofillProfile::SERVER_PROFILE, address.id());
+
+ // AutofillProfile stores multi-line addresses with newline separators.
+ std::vector<std::string> street_address(address.street_address().begin(),
+ address.street_address().end());
+ profile.SetRawInfo(ADDRESS_HOME_STREET_ADDRESS,
+ base::UTF8ToUTF16(JoinString(street_address, '\n')));
+
+ profile.SetRawInfo(COMPANY_NAME, base::UTF8ToUTF16(address.company_name()));
+ profile.SetRawInfo(ADDRESS_HOME_STATE,
+ base::UTF8ToUTF16(address.address_1()));
+ profile.SetRawInfo(ADDRESS_HOME_CITY,
+ base::UTF8ToUTF16(address.address_2()));
+ profile.SetRawInfo(ADDRESS_HOME_DEPENDENT_LOCALITY,
+ base::UTF8ToUTF16(address.address_3()));
+ // AutofillProfile doesn't support address_4 ("sub dependent locality").
+ profile.SetRawInfo(ADDRESS_HOME_ZIP,
+ base::UTF8ToUTF16(address.postal_code()));
+ profile.SetRawInfo(ADDRESS_HOME_SORTING_CODE,
+ base::UTF8ToUTF16(address.sorting_code()));
+ profile.SetRawInfo(ADDRESS_HOME_COUNTRY,
+ base::UTF8ToUTF16(address.country_code()));
+ profile.set_language_code(address.language_code());
+
+ return profile;
+}
+
+// Implements operator< for two objects given their pointers.
+template<class Data> struct AutofillDataPtrLessThan {
+ bool operator()(const Data* a, const Data* b) const {
+ return a->Compare(*b) < 0;
+ }
+};
+
+// This function handles conditionally updating the AutofillTable with either
+// a set of CreditCards or AutocompleteProfiles only when the existing data
+// doesn't match.
+//
+// It's passed the getter and setter function on the AutofillTable for the
+// corresponding data type, and expects the types to implement a server_id()
+// and a Compare function.
+//
+// Returns the previous number of items in the table (for sync tracking).
+template<class Data>
+size_t SetDataIfChanged(
+ AutofillTable* table,
+ const std::vector<Data>& data,
+ bool (AutofillTable::*getter)(std::vector<Data*>*),
+ void (AutofillTable::*setter)(const std::vector<Data>&)) {
+ ScopedVector<Data> existing_data;
+ (table->*getter)(&existing_data.get());
+
+ bool difference_found = true;
+ if (existing_data.size() == data.size()) {
+ difference_found = false;
+
+ // Implement this set with pointers using our custom operator that takes
+ // pointers which avoids any copies.
+ std::set<const Data*, AutofillDataPtrLessThan<Data>> existing_data_set;
+ for (const Data* cur : existing_data)
+ existing_data_set.insert(cur);
+
+ for (const Data& new_data : data) {
+ if (existing_data_set.find(&new_data) == existing_data_set.end()) {
+ difference_found = true;
+ break;
+ }
+ }
+ }
+
+ if (difference_found)
+ (table->*setter)(data);
+
+ return existing_data.size();
+}
+
+} // namespace
+
+AutofillWalletSyncableService::AutofillWalletSyncableService(
+ AutofillWebDataBackend* webdata_backend,
+ const std::string& app_locale)
+ : webdata_backend_(webdata_backend) {
+}
+
+AutofillWalletSyncableService::~AutofillWalletSyncableService() {
+}
+
+syncer::SyncMergeResult
+AutofillWalletSyncableService::MergeDataAndStartSyncing(
+ syncer::ModelType type,
+ const syncer::SyncDataList& initial_sync_data,
+ scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
+ scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+
+ std::vector<CreditCard> wallet_cards;
+ std::vector<AutofillProfile> wallet_addresses;
+
+ for (const syncer::SyncData& data : initial_sync_data) {
+ DCHECK_EQ(syncer::AUTOFILL_WALLET_DATA, data.GetDataType());
+ const sync_pb::AutofillWalletSpecifics& autofill_specifics =
+ data.GetSpecifics().autofill_wallet();
+ if (autofill_specifics.type() ==
+ sync_pb::AutofillWalletSpecifics::MASKED_CREDIT_CARD) {
+ wallet_cards.push_back(
+ CardFromSpecifics(autofill_specifics.masked_card()));
+ } else {
+ DCHECK_EQ(sync_pb::AutofillWalletSpecifics::POSTAL_ADDRESS,
+ autofill_specifics.type());
+ wallet_addresses.push_back(
+ ProfileFromSpecifics(autofill_specifics.address()));
+ }
+ }
+
+ // In the common case, the database won't have changed. Committing an update
+ // to the database will require at least one DB page write and will schedule
+ // a fsync. To avoid this I/O, it should be more efficient to do a read and
+ // only do the writes if something changed.
+ AutofillTable* table =
+ AutofillTable::FromWebDatabase(webdata_backend_->GetDatabase());
+ size_t prev_card_count =
+ SetDataIfChanged(table, wallet_cards,
+ &AutofillTable::GetServerCreditCards,
+ &AutofillTable::SetServerCreditCards);
+ size_t prev_address_count =
+ SetDataIfChanged(table, wallet_addresses,
+ &AutofillTable::GetAutofillServerProfiles,
+ &AutofillTable::SetAutofillServerProfiles);
+
+ syncer::SyncMergeResult merge_result(type);
+ merge_result.set_num_items_before_association(
+ static_cast<int>(prev_card_count + prev_address_count));
+ merge_result.set_num_items_after_association(
+ static_cast<int>(wallet_cards.size() + wallet_addresses.size()));
+ return merge_result;
+}
+
+void AutofillWalletSyncableService::StopSyncing(syncer::ModelType type) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ DCHECK_EQ(type, syncer::AUTOFILL_WALLET_DATA);
+}
+
+syncer::SyncDataList AutofillWalletSyncableService::GetAllSyncData(
+ syncer::ModelType type) const {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ syncer::SyncDataList current_data;
+ return current_data;
+}
+
+syncer::SyncError AutofillWalletSyncableService::ProcessSyncChanges(
+ const tracked_objects::Location& from_here,
+ const syncer::SyncChangeList& change_list) {
+ DCHECK(thread_checker_.CalledOnValidThread());
+ // TODO(brettw) handle incremental updates while Chrome is running.
+ return syncer::SyncError();
+}
+
+// static
+void AutofillWalletSyncableService::CreateForWebDataServiceAndBackend(
+ AutofillWebDataService* web_data_service,
+ AutofillWebDataBackend* webdata_backend,
+ const std::string& app_locale) {
+ web_data_service->GetDBUserData()->SetUserData(
+ UserDataKey(),
+ new AutofillWalletSyncableService(webdata_backend, app_locale));
+}
+
+// static
+AutofillWalletSyncableService*
+AutofillWalletSyncableService::FromWebDataService(
+ AutofillWebDataService* web_data_service) {
+ return static_cast<AutofillWalletSyncableService*>(
+ web_data_service->GetDBUserData()->GetUserData(UserDataKey()));
+}
+
+void AutofillWalletSyncableService::InjectStartSyncFlare(
+ const syncer::SyncableService::StartSyncFlare& flare) {
+ flare_ = flare;
+}
+
+} // namespace autofill
diff --git a/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h
new file mode 100644
index 0000000..fd32bae
--- /dev/null
+++ b/components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h
@@ -0,0 +1,72 @@
+// Copyright 2015 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_WEBDATA_AUTOFILL_WALLET_SYNCABLE_SERVICE_H_
+#define COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WALLET_SYNCABLE_SERVICE_H_
+
+#include "base/basictypes.h"
+#include "base/supports_user_data.h"
+#include "base/threading/thread_checker.h"
+#include "sync/api/syncable_service.h"
+
+namespace autofill {
+
+class AutofillWebDataBackend;
+class AutofillWebDataService;
+
+// Syncs masked cards (last 4 digits only) and addresses from the sync user's
+// Wallet account.
+class AutofillWalletSyncableService
+ : public base::SupportsUserData::Data,
+ public syncer::SyncableService {
+ public:
+ ~AutofillWalletSyncableService() override;
+
+ // syncer::SyncableService implementation.
+ syncer::SyncMergeResult MergeDataAndStartSyncing(
+ syncer::ModelType type,
+ const syncer::SyncDataList& initial_sync_data,
+ scoped_ptr<syncer::SyncChangeProcessor> sync_processor,
+ scoped_ptr<syncer::SyncErrorFactory> sync_error_factory) override;
+ void StopSyncing(syncer::ModelType type) override;
+ syncer::SyncDataList GetAllSyncData(syncer::ModelType type) const override;
+ syncer::SyncError ProcessSyncChanges(
+ const tracked_objects::Location& from_here,
+ const syncer::SyncChangeList& change_list) override;
+
+ // Creates a new AutofillWalletSyncableService and hangs it off of
+ // |web_data_service|, which takes ownership. This method should only be
+ // called on |web_data_service|'s DB thread.
+ static void CreateForWebDataServiceAndBackend(
+ AutofillWebDataService* web_data_service,
+ AutofillWebDataBackend* webdata_backend,
+ const std::string& app_locale);
+
+ // Retrieves the AutofillWalletSyncableService stored on |web_data_service|.
+ static AutofillWalletSyncableService* FromWebDataService(
+ AutofillWebDataService* web_data_service);
+
+ // Provides a StartSyncFlare to the SyncableService. See
+ // sync_start_util for more.
+ void InjectStartSyncFlare(
+ const syncer::SyncableService::StartSyncFlare& flare);
+
+ protected:
+ AutofillWalletSyncableService(
+ AutofillWebDataBackend* webdata_backend,
+ const std::string& app_locale);
+
+ private:
+ base::ThreadChecker thread_checker_;
+
+ AutofillWebDataBackend* webdata_backend_; // Weak ref.
+
+ syncer::SyncableService::StartSyncFlare flare_;
+
+ DISALLOW_COPY_AND_ASSIGN(AutofillWalletSyncableService);
+};
+
+} // namespace autofill
+
+#endif // COMPONENTS_AUTOFILL_CORE_BROWSER_WEBDATA_AUTOFILL_WALLET_SYNCABLE_SERVICE_H_
diff --git a/components/sync_driver/model_association_manager.cc b/components/sync_driver/model_association_manager.cc
index 5c2d223..71fbdd5 100644
--- a/components/sync_driver/model_association_manager.cc
+++ b/components/sync_driver/model_association_manager.cc
@@ -30,6 +30,7 @@ static const syncer::ModelType kStartOrder[] = {
syncer::PASSWORDS,
syncer::AUTOFILL,
syncer::AUTOFILL_PROFILE,
+ syncer::AUTOFILL_WALLET_DATA,
syncer::EXTENSION_SETTINGS,
syncer::APP_SETTINGS,
syncer::TYPED_URLS,
diff --git a/components/sync_driver/pref_names.cc b/components/sync_driver/pref_names.cc
index 6ad3763..d4f04d37 100644
--- a/components/sync_driver/pref_names.cc
+++ b/components/sync_driver/pref_names.cc
@@ -36,6 +36,7 @@ const char kSyncAppSettings[] = "sync.app_settings";
const char kSyncApps[] = "sync.apps";
const char kSyncArticles[] = "sync.articles";
const char kSyncAutofillProfile[] = "sync.autofill_profile";
+const char kSyncAutofillWallet[] = "sync.autofill_wallet";
const char kSyncAutofill[] = "sync.autofill";
const char kSyncBookmarks[] = "sync.bookmarks";
const char kSyncDeviceInfo[] = "sync.device_info";
diff --git a/components/sync_driver/pref_names.h b/components/sync_driver/pref_names.h
index 6d77b98..31a605a 100644
--- a/components/sync_driver/pref_names.h
+++ b/components/sync_driver/pref_names.h
@@ -24,6 +24,7 @@ extern const char kSyncAppSettings[];
extern const char kSyncApps[];
extern const char kSyncArticles[];
extern const char kSyncAutofillProfile[];
+extern const char kSyncAutofillWallet[];
extern const char kSyncAutofill[];
extern const char kSyncBookmarks[];
extern const char kSyncDeviceInfo[];
diff --git a/components/sync_driver/sync_prefs.cc b/components/sync_driver/sync_prefs.cc
index e8c3f19..23ccbbf 100644
--- a/components/sync_driver/sync_prefs.cc
+++ b/components/sync_driver/sync_prefs.cc
@@ -129,6 +129,7 @@ void SyncPrefs::RegisterProfilePrefs(
model_set.Put(syncer::PREFERENCES);
model_set.Put(syncer::PASSWORDS);
model_set.Put(syncer::AUTOFILL_PROFILE);
+ model_set.Put(syncer::AUTOFILL_WALLET_DATA);
model_set.Put(syncer::AUTOFILL);
model_set.Put(syncer::THEMES);
model_set.Put(syncer::EXTENSIONS);
@@ -299,6 +300,8 @@ const char* SyncPrefs::GetPrefNameForDataType(syncer::ModelType data_type) {
case syncer::AUTOFILL:
return prefs::kSyncAutofill;
case syncer::AUTOFILL_PROFILE:
+ return prefs::kSyncAutofillWallet;
+ case syncer::AUTOFILL_WALLET_DATA:
return prefs::kSyncAutofillProfile;
case syncer::THEMES:
return prefs::kSyncThemes;
@@ -415,6 +418,7 @@ void SyncPrefs::RegisterPrefGroups() {
pref_groups_[syncer::APPS].Put(syncer::APP_LIST);
pref_groups_[syncer::AUTOFILL].Put(syncer::AUTOFILL_PROFILE);
+ pref_groups_[syncer::AUTOFILL].Put(syncer::AUTOFILL_WALLET_DATA);
pref_groups_[syncer::EXTENSIONS].Put(syncer::EXTENSION_SETTINGS);
diff --git a/components/sync_driver/sync_prefs_unittest.cc b/components/sync_driver/sync_prefs_unittest.cc
index 8380dba..b1f3423 100644
--- a/components/sync_driver/sync_prefs_unittest.cc
+++ b/components/sync_driver/sync_prefs_unittest.cc
@@ -140,6 +140,7 @@ TEST_F(SyncPrefsTest, PreferredTypesNotKeepEverythingSynced) {
syncer::ModelTypeSet expected_preferred_types(preferred_types);
if (it.Get() == syncer::AUTOFILL) {
expected_preferred_types.Put(syncer::AUTOFILL_PROFILE);
+ expected_preferred_types.Put(syncer::AUTOFILL_WALLET_DATA);
}
if (it.Get() == syncer::PREFERENCES) {
expected_preferred_types.Put(syncer::DICTIONARY);
diff --git a/components/webdata_services/web_data_service_wrapper.cc b/components/webdata_services/web_data_service_wrapper.cc
index 6253a17..c1c5deb 100644
--- a/components/webdata_services/web_data_service_wrapper.cc
+++ b/components/webdata_services/web_data_service_wrapper.cc
@@ -11,6 +11,7 @@
#include "components/autofill/core/browser/webdata/autocomplete_syncable_service.h"
#include "components/autofill/core/browser/webdata/autofill_profile_syncable_service.h"
#include "components/autofill/core/browser/webdata/autofill_table.h"
+#include "components/autofill/core/browser/webdata/autofill_wallet_syncable_service.h"
#include "components/autofill/core/browser/webdata/autofill_webdata_service.h"
#include "components/password_manager/core/browser/webdata/logins_table.h"
#include "components/search_engines/keyword_table.h"
@@ -41,10 +42,16 @@ void InitSyncableServicesOnDBThread(
autofill_web_data.get(), autofill_backend);
autofill::AutocompleteSyncableService::FromWebDataService(
autofill_web_data.get())->InjectStartSyncFlare(sync_flare);
+
autofill::AutofillProfileSyncableService::CreateForWebDataServiceAndBackend(
autofill_web_data.get(), autofill_backend, app_locale);
+ autofill::AutofillWalletSyncableService::CreateForWebDataServiceAndBackend(
+ autofill_web_data.get(), autofill_backend, app_locale);
+
autofill::AutofillProfileSyncableService::FromWebDataService(
autofill_web_data.get())->InjectStartSyncFlare(sync_flare);
+ autofill::AutofillWalletSyncableService::FromWebDataService(
+ autofill_web_data.get())->InjectStartSyncFlare(sync_flare);
}
} // namespace
diff --git a/sync/internal_api/public/base/model_type.h b/sync/internal_api/public/base/model_type.h
index e86814c..8695d8e 100644
--- a/sync/internal_api/public/base/model_type.h
+++ b/sync/internal_api/public/base/model_type.h
@@ -63,6 +63,9 @@ enum ModelType {
AUTOFILL_PROFILE,
// An autofill object.
AUTOFILL,
+ // Credit cards and addresses synced from the user's account. These are
+ // read-only on the client.
+ AUTOFILL_WALLET_DATA,
// A themes object.
THEMES,
// A typed_url object.
diff --git a/sync/protocol/proto_enum_conversions.cc b/sync/protocol/proto_enum_conversions.cc
index e531533..7be7453 100644
--- a/sync/protocol/proto_enum_conversions.cc
+++ b/sync/protocol/proto_enum_conversions.cc
@@ -200,6 +200,46 @@ const char* GetLaunchTypeString(sync_pb::AppSpecifics::LaunchType launch_type) {
return "";
}
+const char* GetWalletInfoTypeString(
+ sync_pb::AutofillWalletSpecifics::WalletInfoType wallet_info_type) {
+ ASSERT_ENUM_BOUNDS(sync_pb::AutofillWalletSpecifics, WalletInfoType,
+ UNKNOWN, POSTAL_ADDRESS);
+ switch (wallet_info_type) {
+ ENUM_CASE(sync_pb::AutofillWalletSpecifics, UNKNOWN);
+ ENUM_CASE(sync_pb::AutofillWalletSpecifics, MASKED_CREDIT_CARD);
+ ENUM_CASE(sync_pb::AutofillWalletSpecifics, POSTAL_ADDRESS);
+ }
+ NOTREACHED();
+ return "";
+}
+
+const char* GetWalletCardStatusString(
+ sync_pb::WalletMaskedCreditCard::WalletCardStatus wallet_card_status) {
+ switch (wallet_card_status) {
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, VALID);
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, EXPIRED);
+ }
+ NOTREACHED();
+ return "";
+}
+
+const char* GetWalletCardTypeString(
+ sync_pb::WalletMaskedCreditCard::WalletCardType wallet_card_type) {
+ switch (wallet_card_type) {
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, UNKNOWN);
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, AMEX);
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, DISCOVER);
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, JCB);
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, MAESTRO);
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, MASTER_CARD);
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, SOLO);
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, SWITCH);
+ ENUM_CASE(sync_pb::WalletMaskedCreditCard, VISA);
+ }
+ NOTREACHED();
+ return "";
+}
+
const char* GetDeviceTypeString(
sync_pb::SyncEnums::DeviceType device_type) {
ASSERT_ENUM_BOUNDS(sync_pb::SyncEnums, DeviceType, TYPE_WIN, TYPE_TABLET);
diff --git a/sync/protocol/proto_enum_conversions.h b/sync/protocol/proto_enum_conversions.h
index 6a6bbdc..55d62a0 100644
--- a/sync/protocol/proto_enum_conversions.h
+++ b/sync/protocol/proto_enum_conversions.h
@@ -56,6 +56,14 @@ SYNC_EXPORT_PRIVATE const char* GetActionString(
SYNC_EXPORT_PRIVATE const char* GetLaunchTypeString(
sync_pb::AppSpecifics::LaunchType launch_type);
+SYNC_EXPORT_PRIVATE const char* GetWalletInfoTypeString(
+ sync_pb::AutofillWalletSpecifics::WalletInfoType wallet_info_type);
+
+SYNC_EXPORT_PRIVATE const char* GetWalletCardStatusString(
+ sync_pb::WalletMaskedCreditCard::WalletCardStatus wallet_card_status);
+
+SYNC_EXPORT_PRIVATE const char* GetWalletCardTypeString(
+ sync_pb::WalletMaskedCreditCard::WalletCardType wallet_card_type);
const char* GetDeviceTypeString(sync_pb::SyncEnums::DeviceType device_type);
diff --git a/sync/protocol/proto_value_conversions.cc b/sync/protocol/proto_value_conversions.cc
index d1786f8..54f0e03 100644
--- a/sync/protocol/proto_value_conversions.cc
+++ b/sync/protocol/proto_value_conversions.cc
@@ -351,6 +351,21 @@ base::DictionaryValue* AutofillProfileSpecificsToValue(
return value;
}
+base::DictionaryValue* AutofillWalletSpecificsToValue(
+ const sync_pb::AutofillWalletSpecifics& proto) {
+ base::DictionaryValue* value = new base::DictionaryValue();
+
+ SET_ENUM(type, GetWalletInfoTypeString);
+ if (proto.type() == sync_pb::AutofillWalletSpecifics::MASKED_CREDIT_CARD) {
+ value->Set("masked_card",
+ WalletMaskedCreditCardToValue(proto.masked_card()));
+ } else if (proto.type() == sync_pb::AutofillWalletSpecifics::POSTAL_ADDRESS) {
+ value->Set("masked_card",
+ WalletPostalAddressToValue(proto.address()));
+ }
+ return value;
+}
+
base::DictionaryValue* MetaInfoToValue(
const sync_pb::MetaInfo& proto) {
base::DictionaryValue* value = new base::DictionaryValue();
@@ -666,6 +681,35 @@ base::DictionaryValue* TypedUrlSpecificsToValue(
return value;
}
+base::DictionaryValue* WalletMaskedCreditCardToValue(
+ const sync_pb::WalletMaskedCreditCard& proto) {
+ base::DictionaryValue* value = new base::DictionaryValue();
+ SET_STR(id);
+ SET_ENUM(status, GetWalletCardStatusString);
+ SET_STR(name_on_card);
+ SET_ENUM(type, GetWalletCardTypeString);
+ SET_STR(last_four);
+ SET_INT32(exp_month);
+ SET_INT32(exp_year);
+ return value;
+}
+
+base::DictionaryValue* WalletPostalAddressToValue(
+ const sync_pb::WalletPostalAddress& proto) {
+ base::DictionaryValue* value = new base::DictionaryValue();
+ SET_STR(company_name);
+ SET_STR_REP(street_address);
+ SET_STR(address_1);
+ SET_STR(address_2);
+ SET_STR(address_3);
+ SET_STR(address_4);
+ SET_STR(postal_code);
+ SET_STR(sorting_code);
+ SET_STR(country_code);
+ SET_STR(language_code);
+ return value;
+}
+
base::DictionaryValue* WifiCredentialSpecificsToValue(
const sync_pb::WifiCredentialSpecifics& proto) {
base::DictionaryValue* value = new base::DictionaryValue();
@@ -685,6 +729,7 @@ base::DictionaryValue* EntitySpecificsToValue(
SET_FIELD(article, ArticleSpecificsToValue);
SET_FIELD(autofill, AutofillSpecificsToValue);
SET_FIELD(autofill_profile, AutofillProfileSpecificsToValue);
+ SET_FIELD(autofill_wallet, AutofillWalletSpecificsToValue);
SET_FIELD(bookmark, BookmarkSpecificsToValue);
SET_FIELD(device_info, DeviceInfoSpecificsToValue);
SET_FIELD(dictionary, DictionarySpecificsToValue);
diff --git a/sync/protocol/proto_value_conversions.h b/sync/protocol/proto_value_conversions.h
index 960ee45..02d7314 100644
--- a/sync/protocol/proto_value_conversions.h
+++ b/sync/protocol/proto_value_conversions.h
@@ -23,6 +23,7 @@ class ArticleSpecifics;
class AttachmentIdProto;
class AutofillProfileSpecifics;
class AutofillSpecifics;
+class AutofillWalletSpecifics;
class BookmarkSpecifics;
class ClientConfigParams;
class ClientToServerMessage;
@@ -71,6 +72,8 @@ class Target;
class ThemeSpecifics;
class TimeRangeDirective;
class TypedUrlSpecifics;
+class WalletMaskedCreditCard;
+class WalletPostalAddress;
class WifiCredentialSpecifics;
} // namespace sync_pb
@@ -163,6 +166,9 @@ SYNC_EXPORT_PRIVATE base::DictionaryValue* AutofillSpecificsToValue(
SYNC_EXPORT_PRIVATE base::DictionaryValue* AutofillProfileSpecificsToValue(
const sync_pb::AutofillProfileSpecifics& autofill_profile_specifics);
+SYNC_EXPORT_PRIVATE base::DictionaryValue* AutofillWalletSpecificsToValue(
+ const sync_pb::AutofillWalletSpecifics& autofill_wallet_specifics);
+
SYNC_EXPORT_PRIVATE base::DictionaryValue* BookmarkSpecificsToValue(
const sync_pb::BookmarkSpecifics& bookmark_specifics);
@@ -239,6 +245,12 @@ SYNC_EXPORT_PRIVATE base::DictionaryValue* ThemeSpecificsToValue(
SYNC_EXPORT_PRIVATE base::DictionaryValue* TypedUrlSpecificsToValue(
const sync_pb::TypedUrlSpecifics& typed_url_specifics);
+SYNC_EXPORT_PRIVATE base::DictionaryValue* WalletMaskedCreditCardToValue(
+ const sync_pb::WalletMaskedCreditCard& wallet_masked_card);
+
+SYNC_EXPORT_PRIVATE base::DictionaryValue* WalletPostalAddressToValue(
+ const sync_pb::WalletPostalAddress& wallet_postal_address);
+
SYNC_EXPORT_PRIVATE base::DictionaryValue* WifiCredentialSpecificsToValue(
const sync_pb::WifiCredentialSpecifics& wifi_credential_specifics);
diff --git a/sync/protocol/proto_value_conversions_unittest.cc b/sync/protocol/proto_value_conversions_unittest.cc
index 698da6b..d52223b 100644
--- a/sync/protocol/proto_value_conversions_unittest.cc
+++ b/sync/protocol/proto_value_conversions_unittest.cc
@@ -57,7 +57,7 @@ TEST_F(ProtoValueConversionsTest, ProtoChangeCheck) {
// If this number changes, that means we added or removed a data
// type. Don't forget to add a unit test for {New
// type}SpecificsToValue below.
- EXPECT_EQ(34, MODEL_TYPE_COUNT);
+ EXPECT_EQ(35, MODEL_TYPE_COUNT);
// We'd also like to check if we changed any field in our messages.
// However, that's hard to do: sizeof could work, but it's
@@ -135,6 +135,10 @@ TEST_F(ProtoValueConversionsTest, AutofillProfileSpecificsToValue) {
TestSpecificsToValue(AutofillProfileSpecificsToValue);
}
+TEST_F(ProtoValueConversionsTest, AutofillWalletSpecificsToValue) {
+ TestSpecificsToValue(AutofillWalletSpecificsToValue);
+}
+
TEST_F(ProtoValueConversionsTest, BookmarkSpecificsToValue) {
TestSpecificsToValue(BookmarkSpecificsToValue);
}
@@ -314,6 +318,8 @@ TEST_F(ProtoValueConversionsTest, EntitySpecificsToValue) {
SET_FIELD(typed_url);
SET_FIELD(wifi_credential);
+ SET_FIELD(autofill_wallet);
+
#undef SET_FIELD
scoped_ptr<base::DictionaryValue> value(EntitySpecificsToValue(specifics));
diff --git a/sync/syncable/model_type.cc b/sync/syncable/model_type.cc
index ced8c3a..bb1f4e5 100644
--- a/sync/syncable/model_type.cc
+++ b/sync/syncable/model_type.cc
@@ -44,7 +44,7 @@ const char* kUserSelectableDataTypeNames[] = {
};
static_assert(
- 34 == MODEL_TYPE_COUNT,
+ 35 == MODEL_TYPE_COUNT,
"update kUserSelectableDataTypeName to match UserSelectableTypes");
void AddDefaultFieldValue(ModelType datatype,
@@ -69,6 +69,9 @@ void AddDefaultFieldValue(ModelType datatype,
case AUTOFILL_PROFILE:
specifics->mutable_autofill_profile();
break;
+ case AUTOFILL_WALLET_DATA:
+ specifics->mutable_autofill_wallet();
+ break;
case THEMES:
specifics->mutable_theme();
break;
@@ -176,6 +179,8 @@ int GetSpecificsFieldNumberFromModelType(ModelType model_type) {
return sync_pb::EntitySpecifics::kAutofillFieldNumber;
case AUTOFILL_PROFILE:
return sync_pb::EntitySpecifics::kAutofillProfileFieldNumber;
+ case AUTOFILL_WALLET_DATA:
+ return sync_pb::EntitySpecifics::kAutofillWalletFieldNumber;
case THEMES:
return sync_pb::EntitySpecifics::kThemeFieldNumber;
case TYPED_URLS:
@@ -284,6 +289,9 @@ ModelType GetModelTypeFromSpecifics(const sync_pb::EntitySpecifics& specifics) {
if (specifics.has_autofill_profile())
return AUTOFILL_PROFILE;
+ if (specifics.has_autofill_wallet())
+ return AUTOFILL_WALLET_DATA;
+
if (specifics.has_theme())
return THEMES;
@@ -444,6 +452,8 @@ ModelTypeSet EncryptableUserTypes() {
// Note however that proxy types map to one or more protocol types, which
// may or may not be encrypted themselves.
encryptable_user_types.RemoveAll(ProxyTypes());
+ // Wallet data is not encrypted since it actually originates on the server.
+ encryptable_user_types.Remove(AUTOFILL_WALLET_DATA);
return encryptable_user_types;
}
@@ -585,6 +595,8 @@ const char* ModelTypeToString(ModelType model_type) {
return "WiFi Credentials";
case PROXY_TABS:
return "Tabs";
+ case AUTOFILL_WALLET_DATA:
+ return "Autofill Wallet";
default:
break;
}
@@ -594,8 +606,10 @@ const char* ModelTypeToString(ModelType model_type) {
// The normal rules about histograms apply here. Always append to the bottom of
// the list, and be careful to not reuse integer values that have already been
-// assigned. Don't forget to update histograms.xml when you make changes to
-// this list.
+// assigned.
+//
+// Don't forget to update the "SyncModelTypes" enum in histograms.xml when you
+// make changes to this list.
int ModelTypeToHistogramInt(ModelType model_type) {
switch (model_type) {
case UNSPECIFIED:
@@ -666,6 +680,8 @@ int ModelTypeToHistogramInt(ModelType model_type) {
return 32;
case SUPERVISED_USER_WHITELISTS:
return 33;
+ case AUTOFILL_WALLET_DATA:
+ return 34;
// Silence a compiler warning.
case MODEL_TYPE_COUNT:
return 0;
@@ -711,6 +727,8 @@ ModelType ModelTypeFromString(const std::string& model_type_string) {
return AUTOFILL;
else if (model_type_string == "Autofill Profiles")
return AUTOFILL_PROFILE;
+ else if (model_type_string == "Autofill Wallet")
+ return AUTOFILL_WALLET_DATA;
else if (model_type_string == "Themes")
return THEMES;
else if (model_type_string == "Typed URLs")
@@ -855,6 +873,8 @@ std::string ModelTypeToRootTag(ModelType type) {
return "google_chrome_app_list";
case AUTOFILL_PROFILE:
return "google_chrome_autofill_profiles";
+ case AUTOFILL_WALLET_DATA:
+ return "google_chrome_autofill_wallet";
case APP_SETTINGS:
return "google_chrome_app_settings";
case EXTENSION_SETTINGS:
@@ -919,6 +939,7 @@ const char kAppListNotificationType[] = "APP_LIST";
const char kSearchEngineNotificationType[] = "SEARCH_ENGINE";
const char kSessionNotificationType[] = "SESSION";
const char kAutofillProfileNotificationType[] = "AUTOFILL_PROFILE";
+const char kAutofillWalletNotificationType[] = "AUTOFILL_WALLET";
const char kAppNotificationNotificationType[] = "APP_NOTIFICATION";
const char kHistoryDeleteDirectiveNotificationType[] =
"HISTORY_DELETE_DIRECTIVE";
@@ -985,6 +1006,9 @@ bool RealModelTypeToNotificationType(ModelType model_type,
case AUTOFILL_PROFILE:
*notification_type = kAutofillProfileNotificationType;
return true;
+ case AUTOFILL_WALLET_DATA:
+ *notification_type = kAutofillWalletNotificationType;
+ return true;
case EXTENSION_SETTINGS:
*notification_type = kExtensionSettingNotificationType;
return true;
@@ -1084,6 +1108,9 @@ bool NotificationTypeToRealModelType(const std::string& notification_type,
} else if (notification_type == kAutofillProfileNotificationType) {
*model_type = AUTOFILL_PROFILE;
return true;
+ } else if (notification_type == kAutofillWalletNotificationType) {
+ *model_type = AUTOFILL_WALLET_DATA;
+ return true;
} else if (notification_type == kAppSettingNotificationType) {
*model_type = APP_SETTINGS;
return true;
diff --git a/sync/syncable/nigori_util.cc b/sync/syncable/nigori_util.cc
index 18b8fce..1eb9227 100644
--- a/sync/syncable/nigori_util.cc
+++ b/sync/syncable/nigori_util.cc
@@ -243,7 +243,7 @@ void UpdateNigoriFromEncryptedTypes(ModelTypeSet encrypted_types,
bool encrypt_everything,
sync_pb::NigoriSpecifics* nigori) {
nigori->set_encrypt_everything(encrypt_everything);
- static_assert(34 == MODEL_TYPE_COUNT, "update encrypted types");
+ static_assert(35 == MODEL_TYPE_COUNT, "update encrypted types");
nigori->set_encrypt_bookmarks(
encrypted_types.Has(BOOKMARKS));
nigori->set_encrypt_preferences(
@@ -279,7 +279,7 @@ ModelTypeSet GetEncryptedTypesFromNigori(
return ModelTypeSet::All();
ModelTypeSet encrypted_types;
- static_assert(34 == MODEL_TYPE_COUNT, "update encrypted types");
+ static_assert(35 == MODEL_TYPE_COUNT, "update encrypted types");
if (nigori.encrypt_bookmarks())
encrypted_types.Put(BOOKMARKS);
if (nigori.encrypt_preferences())
diff --git a/sync/util/data_type_histogram.h b/sync/util/data_type_histogram.h
index 49885a7..2c4ac8e 100644
--- a/sync/util/data_type_histogram.h
+++ b/sync/util/data_type_histogram.h
@@ -51,6 +51,9 @@
case ::syncer::AUTOFILL_PROFILE: \
PER_DATA_TYPE_MACRO("AutofillProfiles"); \
break; \
+ case ::syncer::AUTOFILL_WALLET_DATA: \
+ PER_DATA_TYPE_MACRO("AutofillWallet"); \
+ break; \
case ::syncer::THEMES: \
PER_DATA_TYPE_MACRO("Themes"); \
break; \
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 934a237..1ab21ad 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -58729,6 +58729,7 @@ To add a new entry, add it with any value and run test to compute valid value.
<int value="31" label="Synced Notification App Info"/>
<int value="32" label="Wifi Credentials"/>
<int value="33" label="Managed User Whitelists"/>
+ <int value="34" label="Autofill Wallet"/>
</enum>
<enum name="SyncNigoriMigrationResult" type="int">