summaryrefslogtreecommitdiff
path: root/chromium/components/payments
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-04-05 17:15:33 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-04-11 07:47:18 +0000
commit7324afb043a0b1e623d8e8eb906cdc53bdeb4685 (patch)
treea3fe2d74ea9c9e142c390dac4ca0e219382ace46 /chromium/components/payments
parent6a4cabb866f66d4128a97cdc6d9d08ce074f1247 (diff)
downloadqtwebengine-chromium-7324afb043a0b1e623d8e8eb906cdc53bdeb4685.tar.gz
BASELINE: Update Chromium to 58.0.3029.54
Change-Id: I67f57065a7afdc8e4614adb5c0230281428df4d1 Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Diffstat (limited to 'chromium/components/payments')
-rw-r--r--chromium/components/payments/OWNERS6
-rw-r--r--chromium/components/payments/content/BUILD.gn (renamed from chromium/components/payments/BUILD.gn)54
-rw-r--r--chromium/components/payments/content/DEPS (renamed from chromium/components/payments/DEPS)2
-rw-r--r--chromium/components/payments/content/OWNERS4
-rw-r--r--chromium/components/payments/content/android/BUILD.gn (renamed from chromium/components/payments/android/BUILD.gn)10
-rw-r--r--chromium/components/payments/content/android/DEPS (renamed from chromium/components/payments/android/DEPS)0
-rw-r--r--chromium/components/payments/content/android/currency_formatter_android.cc (renamed from chromium/components/payments/android/currency_formatter_android.cc)19
-rw-r--r--chromium/components/payments/content/android/currency_formatter_android.h (renamed from chromium/components/payments/android/currency_formatter_android.h)10
-rw-r--r--chromium/components/payments/content/android/payment_details_validation_android.cc35
-rw-r--r--chromium/components/payments/content/android/payment_details_validation_android.h12
-rw-r--r--chromium/components/payments/content/payment_app.mojom (renamed from chromium/components/payments/payment_app.mojom)4
-rw-r--r--chromium/components/payments/content/payment_details_validation.cc (renamed from chromium/components/payments/payment_details_validation.cc)16
-rw-r--r--chromium/components/payments/content/payment_details_validation.h (renamed from chromium/components/payments/payment_details_validation.h)8
-rw-r--r--chromium/components/payments/content/payment_request.cc333
-rw-r--r--chromium/components/payments/content/payment_request.h199
-rw-r--r--chromium/components/payments/content/payment_request.mojom (renamed from chromium/components/payments/payment_request.mojom)2
-rw-r--r--chromium/components/payments/content/payment_request_delegate.h (renamed from chromium/components/payments/payment_request_delegate.h)17
-rw-r--r--chromium/components/payments/content/payment_request_dialog.h22
-rw-r--r--chromium/components/payments/content/payment_request_web_contents_manager.cc (renamed from chromium/components/payments/payment_request_web_contents_manager.cc)12
-rw-r--r--chromium/components/payments/content/payment_request_web_contents_manager.h (renamed from chromium/components/payments/payment_request_web_contents_manager.h)12
-rw-r--r--chromium/components/payments/content/payments_validators.cc (renamed from chromium/components/payments/payments_validators.cc)81
-rw-r--r--chromium/components/payments/content/payments_validators.h (renamed from chromium/components/payments/payments_validators.h)28
-rw-r--r--chromium/components/payments/content/payments_validators_test.cc (renamed from chromium/components/payments/payments_validators_test.cc)4
-rw-r--r--chromium/components/payments/core/BUILD.gn39
-rw-r--r--chromium/components/payments/core/DEPS5
-rw-r--r--chromium/components/payments/core/address_normalizer.cc169
-rw-r--r--chromium/components/payments/core/address_normalizer.h94
-rw-r--r--chromium/components/payments/core/address_normalizer_unittest.cc191
-rw-r--r--chromium/components/payments/core/currency_formatter.cc (renamed from chromium/components/payments/currency_formatter.cc)19
-rw-r--r--chromium/components/payments/core/currency_formatter.h (renamed from chromium/components/payments/currency_formatter.h)14
-rw-r--r--chromium/components/payments/core/currency_formatter_unittest.cc (renamed from chromium/components/payments/currency_formatter_unittest.cc)6
-rw-r--r--chromium/components/payments/payment_request.cc110
-rw-r--r--chromium/components/payments/payment_request.h93
33 files changed, 1274 insertions, 356 deletions
diff --git a/chromium/components/payments/OWNERS b/chromium/components/payments/OWNERS
index dc78259ee7a..2ff5e3b38df 100644
--- a/chromium/components/payments/OWNERS
+++ b/chromium/components/payments/OWNERS
@@ -1,6 +1,4 @@
-jdonnelly@chromium.org
-krb@chromium.org
+mathp@chromium.org
rouslan@chromium.org
-per-file *.mojom=set noparent
-per-file *.mojom=file://ipc/SECURITY_OWNERS
+# COMPONENT: UI>Browser>Autofill>Payments
diff --git a/chromium/components/payments/BUILD.gn b/chromium/components/payments/content/BUILD.gn
index 8df0365533d..a6f75fe71c8 100644
--- a/chromium/components/payments/BUILD.gn
+++ b/chromium/components/payments/content/BUILD.gn
@@ -26,33 +26,28 @@ mojom("payment_app") {
]
}
-# TODO(crbug.com/679381): Create a layered component to that we can remove the
-# iOS check here (iOS strict DEPS checker doesn't like the //content dependency
-# below).
-if (!is_ios) {
- static_library("payment_request_impl") {
- sources = [
- "payment_request.cc",
- "payment_request.h",
- "payment_request_delegate.h",
- "payment_request_web_contents_manager.cc",
- "payment_request_web_contents_manager.h",
- ]
+static_library("payment_request_impl") {
+ sources = [
+ "payment_request.cc",
+ "payment_request.h",
+ "payment_request_delegate.h",
+ "payment_request_dialog.h",
+ "payment_request_web_contents_manager.cc",
+ "payment_request_web_contents_manager.h",
+ ]
- deps = [
- ":payment_request",
- ":payment_validation",
- "//components/autofill/core/browser",
- "//content/public/browser",
- "//mojo/public/cpp/bindings",
- ]
- }
+ deps = [
+ ":payment_request",
+ ":payment_validation",
+ "//components/autofill/core/browser",
+ "//components/payments/core",
+ "//content/public/browser",
+ "//mojo/public/cpp/bindings",
+ ]
}
static_library("payment_validation") {
sources = [
- "currency_formatter.cc",
- "currency_formatter.h",
"payment_details_validation.cc",
"payment_details_validation.h",
"payments_validators.cc",
@@ -62,26 +57,31 @@ static_library("payment_validation") {
deps = [
":payment_request",
"//base",
- "//third_party/re2:re2",
- "//url:url",
+ "//components/autofill/core/browser",
+ "//components/payments/core",
+ "//third_party/re2",
+ "//url",
]
public_deps = [
- "//third_party/icu:icu",
+ "//third_party/icu",
+ "//third_party/libaddressinput",
]
}
source_set("unit_tests") {
testonly = true
sources = [
- "currency_formatter_unittest.cc",
"payments_validators_test.cc",
]
deps = [
":payment_validation",
"//base",
+ "//base/test:test_support",
+ "//components/autofill/core/browser",
"//testing/gtest",
- "//third_party/icu:icu",
+ "//third_party/icu",
+ "//third_party/libaddressinput:test_support",
]
}
diff --git a/chromium/components/payments/DEPS b/chromium/components/payments/content/DEPS
index 151fdf5f8b6..ec8a11647d6 100644
--- a/chromium/components/payments/DEPS
+++ b/chromium/components/payments/content/DEPS
@@ -1,8 +1,6 @@
include_rules = [
"+components/autofill",
- # TODO(crbug.com/679381): Move this to components/payments/content.
"+content/public/browser",
-
"+mojo/public/cpp",
"+third_party/re2",
]
diff --git a/chromium/components/payments/content/OWNERS b/chromium/components/payments/content/OWNERS
new file mode 100644
index 00000000000..82559c92e72
--- /dev/null
+++ b/chromium/components/payments/content/OWNERS
@@ -0,0 +1,4 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+# COMPONENT: UI>Browser>Autofill>Payments
diff --git a/chromium/components/payments/android/BUILD.gn b/chromium/components/payments/content/android/BUILD.gn
index a1949e547df..8dafb9b75d6 100644
--- a/chromium/components/payments/android/BUILD.gn
+++ b/chromium/components/payments/content/android/BUILD.gn
@@ -5,17 +5,19 @@
import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
-static_library("payments_jni") {
+static_library("android") {
sources = [
"currency_formatter_android.cc",
"currency_formatter_android.h",
- "payments_jni_registrar.cc",
+ "payment_details_validation_android.cc",
+ "payment_details_validation_android.h",
]
deps = [
":jni_headers",
"//base",
- "//components/payments:payment_request",
- "//components/payments:payment_validation",
+ "//components/payments/content:payment_request",
+ "//components/payments/content:payment_validation",
+ "//components/payments/core",
]
}
diff --git a/chromium/components/payments/android/DEPS b/chromium/components/payments/content/android/DEPS
index c80012b5621..c80012b5621 100644
--- a/chromium/components/payments/android/DEPS
+++ b/chromium/components/payments/content/android/DEPS
diff --git a/chromium/components/payments/android/currency_formatter_android.cc b/chromium/components/payments/content/android/currency_formatter_android.cc
index 00143f3214e..0ea0f912033 100644
--- a/chromium/components/payments/android/currency_formatter_android.cc
+++ b/chromium/components/payments/content/android/currency_formatter_android.cc
@@ -2,18 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/payments/android/currency_formatter_android.h"
+#include "components/payments/content/android/currency_formatter_android.h"
#include "base/android/jni_string.h"
-#include "base/optional.h"
#include "base/strings/string16.h"
-#include "components/payments/currency_formatter.h"
+#include "components/payments/core/currency_formatter.h"
#include "jni/CurrencyFormatter_jni.h"
-using base::android::JavaParamRef;
-using base::android::ConvertJavaStringToUTF8;
-
namespace payments {
+namespace {
+
+using ::base::android::JavaParamRef;
+using ::base::android::ConvertJavaStringToUTF8;
+
+} // namespace
CurrencyFormatterAndroid::CurrencyFormatterAndroid(
JNIEnv* env,
@@ -25,10 +27,7 @@ CurrencyFormatterAndroid::CurrencyFormatterAndroid(
ConvertJavaStringToUTF8(env, currency_system);
currency_formatter_.reset(new CurrencyFormatter(
- ConvertJavaStringToUTF8(env, currency_code),
- currency_system_str.empty()
- ? base::Optional<std::string>()
- : base::Optional<std::string>(currency_system_str),
+ ConvertJavaStringToUTF8(env, currency_code), currency_system_str,
ConvertJavaStringToUTF8(env, locale_name)));
}
diff --git a/chromium/components/payments/android/currency_formatter_android.h b/chromium/components/payments/content/android/currency_formatter_android.h
index f6e6b33e28f..9693c200b83 100644
--- a/chromium/components/payments/android/currency_formatter_android.h
+++ b/chromium/components/payments/content/android/currency_formatter_android.h
@@ -2,17 +2,19 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_PAYMENTS_ANDROID_CURRENCY_FORMATTER_ANDROID_H_
-#define COMPONENTS_PAYMENTS_ANDROID_CURRENCY_FORMATTER_ANDROID_H_
+#ifndef COMPONENTS_PAYMENTS_CONTENT_ANDROID_CURRENCY_FORMATTER_ANDROID_H_
+#define COMPONENTS_PAYMENTS_CONTENT_ANDROID_CURRENCY_FORMATTER_ANDROID_H_
+#include <jni.h>
#include <memory>
#include "base/android/scoped_java_ref.h"
#include "base/macros.h"
-#include "components/payments/currency_formatter.h"
namespace payments {
+class CurrencyFormatter;
+
// Forwarding calls to payments::CurrencyFormatter.
class CurrencyFormatterAndroid {
public:
@@ -48,4 +50,4 @@ class CurrencyFormatterAndroid {
} // namespace payments
-#endif // COMPONENTS_PAYMENTS_ANDROID_CURRENCY_FORMATTER_ANDROID_H_
+#endif // COMPONENTS_PAYMENTS_CONTENT_ANDROID_CURRENCY_FORMATTER_ANDROID_H_
diff --git a/chromium/components/payments/content/android/payment_details_validation_android.cc b/chromium/components/payments/content/android/payment_details_validation_android.cc
new file mode 100644
index 00000000000..072dda083a4
--- /dev/null
+++ b/chromium/components/payments/content/android/payment_details_validation_android.cc
@@ -0,0 +1,35 @@
+// Copyright 2016 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/payments/content/android/payment_details_validation_android.h"
+
+#include <string>
+#include <utility>
+
+#include "components/payments/content/payment_details_validation.h"
+#include "components/payments/content/payment_request.mojom.h"
+#include "jni/PaymentValidator_jni.h"
+
+namespace payments {
+
+jboolean ValidatePaymentDetails(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jclass>& jcaller,
+ const base::android::JavaParamRef<jobject>& buffer) {
+ jbyte* buf_in = static_cast<jbyte*>(env->GetDirectBufferAddress(buffer));
+ jlong buf_size = env->GetDirectBufferCapacity(buffer);
+ std::vector<uint8_t> mojo_buffer(buf_size);
+ memcpy(&mojo_buffer[0], buf_in, buf_size);
+ mojom::PaymentDetailsPtr details;
+ if (!mojom::PaymentDetails::Deserialize(std::move(mojo_buffer), &details))
+ return false;
+ std::string unused_error_message;
+ return payments::validatePaymentDetails(details, &unused_error_message);
+}
+
+} // namespace payments
+
+bool RegisterPaymentValidator(JNIEnv* env) {
+ return payments::RegisterNativesImpl(env);
+}
diff --git a/chromium/components/payments/content/android/payment_details_validation_android.h b/chromium/components/payments/content/android/payment_details_validation_android.h
new file mode 100644
index 00000000000..88367ae1e8e
--- /dev/null
+++ b/chromium/components/payments/content/android/payment_details_validation_android.h
@@ -0,0 +1,12 @@
+// Copyright 2016 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_PAYMENTS_CONTENT_ANDROID_PAYMENT_DETAILS_VALIDATION_ANDROID_H_
+#define COMPONENTS_PAYMENTS_CONTENT_ANDROID_PAYMENT_DETAILS_VALIDATION_ANDROID_H_
+
+#include <jni.h>
+
+bool RegisterPaymentValidator(JNIEnv* env);
+
+#endif // COMPONENTS_PAYMENTS_CONTENT_ANDROID_PAYMENT_DETAILS_VALIDATION_ANDROID_H_
diff --git a/chromium/components/payments/payment_app.mojom b/chromium/components/payments/content/payment_app.mojom
index a3e9715b769..0d9f7c655ad 100644
--- a/chromium/components/payments/payment_app.mojom
+++ b/chromium/components/payments/content/payment_app.mojom
@@ -4,7 +4,7 @@
module payments.mojom;
-import "components/payments/payment_request.mojom";
+import "components/payments/content/payment_request.mojom";
import "url/mojo/url.mojom";
enum PaymentAppManifestError {
@@ -35,7 +35,7 @@ interface PaymentAppManager {
=> (PaymentAppManifest payment_app_manifest, PaymentAppManifestError error);
};
-struct PaymentAppRequestData {
+struct PaymentAppRequest {
url.mojom.Url origin;
array<PaymentMethodData> methodData;
PaymentItem total;
diff --git a/chromium/components/payments/payment_details_validation.cc b/chromium/components/payments/content/payment_details_validation.cc
index 81c42cdbb49..3933c1c3337 100644
--- a/chromium/components/payments/payment_details_validation.cc
+++ b/chromium/components/payments/content/payment_details_validation.cc
@@ -2,14 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/payments/payment_details_validation.h"
+#include "components/payments/content/payment_details_validation.h"
#include <set>
#include <vector>
-#include "components/payments/payment_request.mojom.h"
-#include "components/payments/payments_validators.h"
+#include "components/payments/content/payment_request.mojom.h"
+#include "components/payments/content/payments_validators.h"
+namespace payments {
namespace {
// Validates ShippingOption or PaymentItem, which happen to have identical
@@ -44,16 +45,13 @@ bool validateShippingOptionOrPaymentItem(
return false;
}
- if (item->amount->currency_system.has_value() &&
- item->amount->currency_system.value().empty()) {
+ if (item->amount->currency_system.empty()) {
*error_message = "Currency system can't be empty";
return false;
}
if (!payments::PaymentsValidators::isValidCurrencyCodeFormat(
- item->amount->currency, item->amount->currency_system.has_value()
- ? item->amount->currency_system.value()
- : "",
+ item->amount->currency, item->amount->currency_system,
error_message)) {
return false;
}
@@ -142,8 +140,6 @@ bool validatePaymentDetailsModifiers(
} // namespace
-namespace payments {
-
bool validatePaymentDetails(const mojom::PaymentDetailsPtr& details,
std::string* error_message) {
if (details->total.is_null()) {
diff --git a/chromium/components/payments/payment_details_validation.h b/chromium/components/payments/content/payment_details_validation.h
index 804602c0134..e6230876a1c 100644
--- a/chromium/components/payments/payment_details_validation.h
+++ b/chromium/components/payments/content/payment_details_validation.h
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_PAYMENTS_PAYMENT_DETAILS_VALIDATION_H_
-#define COMPONENTS_PAYMENTS_PAYMENT_DETAILS_VALIDATION_H_
+#ifndef COMPONENTS_PAYMENTS_CONTENT_PAYMENT_DETAILS_VALIDATION_H_
+#define COMPONENTS_PAYMENTS_CONTENT_PAYMENT_DETAILS_VALIDATION_H_
#include <string>
-#include "components/payments/payment_request.mojom.h"
+#include "components/payments/content/payment_request.mojom.h"
namespace payments {
@@ -16,4 +16,4 @@ bool validatePaymentDetails(const mojom::PaymentDetailsPtr& details,
} // namespace payments
-#endif // COMPONENTS_PAYMENTS_PAYMENT_DETAILS_VALIDATION_H_
+#endif // COMPONENTS_PAYMENTS_CONTENT_PAYMENT_DETAILS_VALIDATION_H_
diff --git a/chromium/components/payments/content/payment_request.cc b/chromium/components/payments/content/payment_request.cc
new file mode 100644
index 00000000000..e55e68b272a
--- /dev/null
+++ b/chromium/components/payments/content/payment_request.cc
@@ -0,0 +1,333 @@
+// Copyright 2016 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/payments/content/payment_request.h"
+
+#include <algorithm>
+#include <unordered_map>
+#include <utility>
+
+#include "base/memory/ptr_util.h"
+#include "components/autofill/core/browser/autofill_data_util.h"
+#include "components/autofill/core/browser/field_types.h"
+#include "components/autofill/core/browser/personal_data_manager.h"
+#include "components/payments/content/payment_details_validation.h"
+#include "components/payments/content/payment_request_web_contents_manager.h"
+#include "components/payments/core/currency_formatter.h"
+#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/web_contents.h"
+
+namespace payments {
+
+PaymentRequest::PaymentRequest(
+ content::WebContents* web_contents,
+ std::unique_ptr<PaymentRequestDelegate> delegate,
+ PaymentRequestWebContentsManager* manager,
+ mojo::InterfaceRequest<payments::mojom::PaymentRequest> request)
+ : web_contents_(web_contents),
+ delegate_(std::move(delegate)),
+ manager_(manager),
+ binding_(this, std::move(request)),
+ is_ready_to_pay_(false),
+ selected_shipping_profile_(nullptr),
+ selected_contact_profile_(nullptr),
+ selected_credit_card_(nullptr) {
+ // OnConnectionTerminated will be called when the Mojo pipe is closed. This
+ // will happen as a result of many renderer-side events (both successful and
+ // erroneous in nature).
+ // TODO(crbug.com/683636): Investigate using
+ // set_connection_error_with_reason_handler with Binding::CloseWithReason.
+ binding_.set_connection_error_handler(base::Bind(
+ &PaymentRequest::OnConnectionTerminated, base::Unretained(this)));
+}
+
+PaymentRequest::~PaymentRequest() {}
+
+void PaymentRequest::Init(
+ payments::mojom::PaymentRequestClientPtr client,
+ std::vector<payments::mojom::PaymentMethodDataPtr> method_data,
+ payments::mojom::PaymentDetailsPtr details,
+ payments::mojom::PaymentOptionsPtr options) {
+ DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
+ std::string error;
+ if (!payments::validatePaymentDetails(details, &error)) {
+ LOG(ERROR) << error;
+ OnConnectionTerminated();
+ return;
+ }
+ client_ = std::move(client);
+ details_ = std::move(details);
+ options_ = std::move(options);
+ PopulateValidatedMethodData(method_data);
+ PopulateProfileCache();
+ SetDefaultProfileSelections();
+}
+
+void PaymentRequest::Show() {
+ if (!client_.is_bound() || !binding_.is_bound()) {
+ LOG(ERROR) << "Attempted Show(), but binding(s) missing.";
+ OnConnectionTerminated();
+ return;
+ }
+ delegate_->ShowDialog(this);
+}
+
+void PaymentRequest::Abort() {
+ // The API user has decided to abort. We return a successful abort message to
+ // the renderer, which closes the Mojo message pipe, which triggers
+ // PaymentRequest::OnConnectionTerminated, which destroys this object.
+ if (client_.is_bound())
+ client_->OnAbort(true /* aborted_successfully */);
+}
+
+void PaymentRequest::UserCancelled() {
+ // If |client_| is not bound, then the object is already being destroyed as
+ // a result of a renderer event.
+ if (!client_.is_bound())
+ return;
+
+ // This sends an error to the renderer, which informs the API user.
+ client_->OnError(payments::mojom::PaymentErrorReason::USER_CANCEL);
+
+ // We close all bindings and ask to be destroyed.
+ client_.reset();
+ binding_.Close();
+ manager_->DestroyRequest(this);
+}
+
+void PaymentRequest::OnConnectionTerminated() {
+ // We are here because of a browser-side error, or likely as a result of the
+ // connection_error_handler on |binding_|, which can mean that the renderer
+ // has decided to close the pipe for various reasons (see all uses of
+ // PaymentRequest::clearResolversAndCloseMojoConnection() in Blink). We close
+ // the binding and the dialog, and ask to be deleted.
+ client_.reset();
+ binding_.Close();
+ delegate_->CloseDialog();
+ manager_->DestroyRequest(this);
+}
+
+void PaymentRequest::Pay() {
+ DCHECK(is_ready_to_pay_);
+
+ // TODO(mathp): Return the PaymentResponse to the |client_|.
+ OnConnectionTerminated();
+}
+
+void PaymentRequest::AddObserver(Observer* observer) {
+ CHECK(observer);
+ observers_.AddObserver(observer);
+}
+
+void PaymentRequest::RemoveObserver(Observer* observer) {
+ observers_.RemoveObserver(observer);
+}
+
+CurrencyFormatter* PaymentRequest::GetOrCreateCurrencyFormatter(
+ const std::string& currency_code,
+ const std::string& currency_system,
+ const std::string& locale_name) {
+ if (!currency_formatter_) {
+ currency_formatter_.reset(
+ new CurrencyFormatter(currency_code, currency_system, locale_name));
+ }
+ return currency_formatter_.get();
+}
+
+void PaymentRequest::SetSelectedShippingProfile(
+ autofill::AutofillProfile* profile) {
+ selected_shipping_profile_ = profile;
+ UpdateIsReadyToPayAndNotifyObservers();
+}
+
+void PaymentRequest::SetSelectedContactProfile(
+ autofill::AutofillProfile* profile) {
+ selected_contact_profile_ = profile;
+ UpdateIsReadyToPayAndNotifyObservers();
+}
+
+void PaymentRequest::SetSelectedCreditCard(autofill::CreditCard* card) {
+ selected_credit_card_ = card;
+ UpdateIsReadyToPayAndNotifyObservers();
+}
+
+void PaymentRequest::PopulateProfileCache() {
+ std::vector<autofill::AutofillProfile*> profiles =
+ personal_data_manager()->GetProfilesToSuggest();
+
+ // PaymentRequest may outlive the Profiles returned by the Data Manager.
+ // Thus, we store copies, and return a vector of pointers to these copies
+ // whenever Profiles are requested. The same is true for credit cards.
+ for (size_t i = 0; i < profiles.size(); i++) {
+ profile_cache_.push_back(
+ base::MakeUnique<autofill::AutofillProfile>(*profiles[i]));
+
+ // TODO(tmartino): Implement deduplication rules specific to shipping and
+ // contact profiles.
+ shipping_profiles_.push_back(profile_cache_[i].get());
+ contact_profiles_.push_back(profile_cache_[i].get());
+ }
+
+ const std::vector<autofill::CreditCard*>& cards =
+ personal_data_manager()->GetCreditCardsToSuggest();
+ for (autofill::CreditCard* card : cards) {
+ card_cache_.push_back(base::MakeUnique<autofill::CreditCard>(*card));
+ credit_cards_.push_back(card_cache_.back().get());
+ }
+}
+
+void PaymentRequest::SetDefaultProfileSelections() {
+ if (!shipping_profiles().empty())
+ selected_shipping_profile_ = shipping_profiles()[0];
+
+ if (!contact_profiles().empty())
+ selected_contact_profile_ = contact_profiles()[0];
+
+ // TODO(anthonyvd): Change this code to prioritize server cards and implement
+ // a way to modify this function's return value.
+ const std::vector<autofill::CreditCard*> cards = credit_cards();
+ auto first_complete_card =
+ std::find_if(cards.begin(), cards.end(),
+ [](autofill::CreditCard* card) { return card->IsValid(); });
+
+ selected_credit_card_ =
+ first_complete_card == cards.end() ? nullptr : *first_complete_card;
+
+ UpdateIsReadyToPayAndNotifyObservers();
+}
+
+void PaymentRequest::PopulateValidatedMethodData(
+ const std::vector<payments::mojom::PaymentMethodDataPtr>& method_data) {
+ if (method_data.empty()) {
+ LOG(ERROR) << "Invalid payment methods or data";
+ OnConnectionTerminated();
+ return;
+ }
+
+ // Identifier for the basic card payment method in the PaymentMethodData.
+ const char* const kBasicCardMethodName = "basic-card";
+ std::set<std::string> card_networks{"amex", "diners", "discover",
+ "jcb", "mastercard", "mir",
+ "unionpay", "visa"};
+ for (const payments::mojom::PaymentMethodDataPtr& method_data_entry :
+ method_data) {
+ std::vector<std::string> supported_methods =
+ method_data_entry->supported_methods;
+ if (supported_methods.empty()) {
+ LOG(ERROR) << "Invalid payment methods or data";
+ OnConnectionTerminated();
+ return;
+ }
+
+ for (const std::string& method : supported_methods) {
+ if (method.empty())
+ continue;
+
+ // If a card network is specified right in "supportedMethods", add it.
+ auto card_it = card_networks.find(method);
+ if (card_it != card_networks.end()) {
+ supported_card_networks_.push_back(method);
+ // |method| removed from |card_networks| so that it is not doubly added
+ // to |supported_card_networks_| if "basic-card" is specified with no
+ // supported networks.
+ card_networks.erase(card_it);
+ } else if (method == kBasicCardMethodName) {
+ // For the "basic-card" method, check "supportedNetworks".
+ if (method_data_entry->supported_networks.empty()) {
+ // Empty |supported_networks| means all networks are supported.
+ supported_card_networks_.insert(supported_card_networks_.end(),
+ card_networks.begin(),
+ card_networks.end());
+ // Clear the set so that no further networks are added to
+ // |supported_card_networks_|.
+ card_networks.clear();
+ } else {
+ // The merchant has specified a few basic card supported networks. Use
+ // the mapping to transform to known basic-card types.
+ using ::payments::mojom::BasicCardNetwork;
+ std::unordered_map<BasicCardNetwork, std::string> networks = {
+ {BasicCardNetwork::AMEX, "amex"},
+ {BasicCardNetwork::DINERS, "diners"},
+ {BasicCardNetwork::DISCOVER, "discover"},
+ {BasicCardNetwork::JCB, "jcb"},
+ {BasicCardNetwork::MASTERCARD, "mastercard"},
+ {BasicCardNetwork::MIR, "mir"},
+ {BasicCardNetwork::UNIONPAY, "unionpay"},
+ {BasicCardNetwork::VISA, "visa"}};
+ for (const BasicCardNetwork& supported_network :
+ method_data_entry->supported_networks) {
+ // Make sure that the network was not already added to
+ // |supported_card_networks_|.
+ auto card_it = card_networks.find(networks[supported_network]);
+ if (card_it != card_networks.end()) {
+ supported_card_networks_.push_back(networks[supported_network]);
+ card_networks.erase(card_it);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+void PaymentRequest::UpdateIsReadyToPayAndNotifyObservers() {
+ is_ready_to_pay_ =
+ ArePaymentDetailsSatisfied() && ArePaymentOptionsSatisfied();
+ NotifyOnSelectedInformationChanged();
+}
+
+void PaymentRequest::NotifyOnSelectedInformationChanged() {
+ for (auto& observer : observers_)
+ observer.OnSelectedInformationChanged();
+}
+
+bool PaymentRequest::ArePaymentDetailsSatisfied() {
+ // TODO(mathp): A masked card may not satisfy IsValid().
+ if (selected_credit_card_ == nullptr || !selected_credit_card_->IsValid())
+ return false;
+
+ const std::string basic_card_payment_type =
+ autofill::data_util::GetPaymentRequestData(selected_credit_card_->type())
+ .basic_card_payment_type;
+ return !supported_card_networks_.empty() &&
+ std::find(supported_card_networks_.begin(),
+ supported_card_networks_.end(),
+ basic_card_payment_type) != supported_card_networks_.end();
+}
+
+bool PaymentRequest::ArePaymentOptionsSatisfied() {
+ // TODO(mathp): Have a measure of shipping address completeness.
+ if (request_shipping() && selected_shipping_profile_ == nullptr)
+ return false;
+
+ // TODO(mathp): Make an encompassing class to validate contact info.
+ const std::string& app_locale = delegate_->GetApplicationLocale();
+ if (request_payer_name() &&
+ (selected_contact_profile_ == nullptr ||
+ selected_contact_profile_
+ ->GetInfo(autofill::AutofillType(autofill::NAME_FULL), app_locale)
+ .empty())) {
+ return false;
+ }
+ if (request_payer_email() &&
+ (selected_contact_profile_ == nullptr ||
+ selected_contact_profile_
+ ->GetInfo(autofill::AutofillType(autofill::EMAIL_ADDRESS),
+ app_locale)
+ .empty())) {
+ return false;
+ }
+ if (request_payer_phone() &&
+ (selected_contact_profile_ == nullptr ||
+ selected_contact_profile_
+ ->GetInfo(autofill::AutofillType(autofill::PHONE_HOME_WHOLE_NUMBER),
+ app_locale)
+ .empty())) {
+ return false;
+ }
+
+ return true;
+}
+
+} // namespace payments
diff --git a/chromium/components/payments/content/payment_request.h b/chromium/components/payments/content/payment_request.h
new file mode 100644
index 00000000000..18d3f94229b
--- /dev/null
+++ b/chromium/components/payments/content/payment_request.h
@@ -0,0 +1,199 @@
+// Copyright 2016 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_PAYMENTS_CONTENT_PAYMENT_REQUEST_H_
+#define COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_H_
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "base/observer_list.h"
+#include "components/payments/content/payment_request.mojom.h"
+#include "components/payments/content/payment_request_delegate.h"
+#include "mojo/public/cpp/bindings/binding.h"
+
+namespace autofill {
+class AutofillProfile;
+class CreditCard;
+class PersonalDataManager;
+}
+
+namespace content {
+class WebContents;
+}
+
+namespace payments {
+
+class CurrencyFormatter;
+class PaymentRequestWebContentsManager;
+
+class PaymentRequest : payments::mojom::PaymentRequest {
+ public:
+ class Observer {
+ public:
+ // Called when the information (payment method, address/contact info,
+ // shipping option) changes.
+ virtual void OnSelectedInformationChanged() = 0;
+
+ protected:
+ virtual ~Observer() {}
+ };
+
+ PaymentRequest(
+ content::WebContents* web_contents,
+ std::unique_ptr<PaymentRequestDelegate> delegate,
+ PaymentRequestWebContentsManager* manager,
+ mojo::InterfaceRequest<payments::mojom::PaymentRequest> request);
+ ~PaymentRequest() override;
+
+ // payments::mojom::PaymentRequest "stub"
+ void Init(payments::mojom::PaymentRequestClientPtr client,
+ std::vector<payments::mojom::PaymentMethodDataPtr> method_data,
+ payments::mojom::PaymentDetailsPtr details,
+ payments::mojom::PaymentOptionsPtr options) override;
+ void Show() override;
+ void UpdateWith(payments::mojom::PaymentDetailsPtr details) override {}
+ void Abort() override;
+ void Complete(payments::mojom::PaymentComplete result) override {}
+ void CanMakePayment() override {}
+
+ // Called when the user explicitely cancelled the flow. Will send a message
+ // to the renderer which will indirectly destroy this object (through
+ // OnConnectionTerminated).
+ void UserCancelled();
+
+ // As a result of a browser-side error or renderer-initiated mojo channel
+ // closure (e.g. there was an error on the renderer side, or payment was
+ // successful), this method is called. It is responsible for cleaning up,
+ // such as possibly closing the dialog.
+ void OnConnectionTerminated();
+
+ // Called when the user clicks on the "Pay" button.
+ void Pay();
+
+ void AddObserver(Observer* observer);
+ void RemoveObserver(Observer* observer);
+
+ // Returns the CurrencyFormatter instance for this PaymentRequest.
+ // |locale_name| should be the result of the browser's GetApplicationLocale().
+ // Note: Having multiple currencies per PaymentRequest is not supported; hence
+ // the CurrencyFormatter is cached here.
+ CurrencyFormatter* GetOrCreateCurrencyFormatter(
+ const std::string& currency_code,
+ const std::string& currency_system,
+ const std::string& locale_name);
+
+ // Returns the appropriate Autofill Profiles for this user. On the first
+ // invocation of either getter, the profiles are fetched from the
+ // PersonalDataManager; on subsequent invocations, a cached version is
+ // returned. The profiles returned are owned by the request object.
+ const std::vector<autofill::AutofillProfile*>& shipping_profiles() {
+ return shipping_profiles_;
+ }
+ const std::vector<autofill::AutofillProfile*>& contact_profiles() {
+ return contact_profiles_;
+ }
+ const std::vector<autofill::CreditCard*>& credit_cards() {
+ return credit_cards_;
+ }
+
+ // Gets the Autofill Profile representing the shipping address or contact
+ // information currently selected for this PaymentRequest flow. Can return
+ // null.
+ autofill::AutofillProfile* selected_shipping_profile() const {
+ return selected_shipping_profile_;
+ }
+ autofill::AutofillProfile* selected_contact_profile() const {
+ return selected_contact_profile_;
+ }
+ // Returns the currently selected credit card for this PaymentRequest flow.
+ // It's not guaranteed to be complete. Returns nullptr if there is no selected
+ // card.
+ autofill::CreditCard* selected_credit_card() { return selected_credit_card_; }
+
+ // Sets the |profile| to be the selected one and will update state and notify
+ // observers.
+ void SetSelectedShippingProfile(autofill::AutofillProfile* profile);
+ void SetSelectedContactProfile(autofill::AutofillProfile* profile);
+ void SetSelectedCreditCard(autofill::CreditCard* card);
+
+ autofill::PersonalDataManager* personal_data_manager() {
+ return delegate_->GetPersonalDataManager();
+ }
+
+ payments::mojom::PaymentDetails* details() { return details_.get(); }
+ const std::vector<std::string>& supported_card_networks() {
+ return supported_card_networks_;
+ }
+ content::WebContents* web_contents() { return web_contents_; }
+
+ bool request_shipping() const { return options_->request_shipping; }
+ bool request_payer_name() const { return options_->request_payer_name; }
+ bool request_payer_phone() const { return options_->request_payer_phone; }
+ bool request_payer_email() const { return options_->request_payer_email; }
+
+ bool is_ready_to_pay() { return is_ready_to_pay_; }
+
+ private:
+ // Fetches the Autofill Profiles for this user from the PersonalDataManager,
+ // and stores copies of them, owned by this Request, in profile_cache_.
+ void PopulateProfileCache();
+
+ // Sets the default values for the selected Shipping and Contact profiles, as
+ // well as the selected Credit Card.
+ void SetDefaultProfileSelections();
+
+ // Validates the |method_data| and fills |supported_card_networks_|.
+ void PopulateValidatedMethodData(
+ const std::vector<payments::mojom::PaymentMethodDataPtr>& method_data);
+
+ // Updates |is_ready_to_pay_| with the current state, by validating that all
+ // the required information is available and notify observers.
+ void UpdateIsReadyToPayAndNotifyObservers();
+
+ // Notifies all observers that selected information has changed.
+ void NotifyOnSelectedInformationChanged();
+
+ // Returns whether the selected data satisfies the PaymentDetails requirements
+ // (payment methods).
+ bool ArePaymentDetailsSatisfied();
+ // Returns whether the selected data satisfies the PaymentOptions requirements
+ // (contact info, shipping address).
+ bool ArePaymentOptionsSatisfied();
+
+ content::WebContents* web_contents_;
+ std::unique_ptr<PaymentRequestDelegate> delegate_;
+ // |manager_| owns this PaymentRequest.
+ PaymentRequestWebContentsManager* manager_;
+ mojo::Binding<payments::mojom::PaymentRequest> binding_;
+ payments::mojom::PaymentRequestClientPtr client_;
+ payments::mojom::PaymentDetailsPtr details_;
+ payments::mojom::PaymentOptionsPtr options_;
+ std::unique_ptr<CurrencyFormatter> currency_formatter_;
+ // A set of supported basic card networks.
+ std::vector<std::string> supported_card_networks_;
+ bool is_ready_to_pay_;
+
+ base::ObserverList<Observer> observers_;
+
+ // Profiles may change due to (e.g.) sync events, so profiles are cached after
+ // loading and owned here. They are populated once only, and ordered by
+ // frecency.
+ std::vector<std::unique_ptr<autofill::AutofillProfile>> profile_cache_;
+ std::vector<autofill::AutofillProfile*> shipping_profiles_;
+ std::vector<autofill::AutofillProfile*> contact_profiles_;
+ autofill::AutofillProfile* selected_shipping_profile_;
+ autofill::AutofillProfile* selected_contact_profile_;
+ std::vector<std::unique_ptr<autofill::CreditCard>> card_cache_;
+ std::vector<autofill::CreditCard*> credit_cards_;
+ autofill::CreditCard* selected_credit_card_;
+
+ DISALLOW_COPY_AND_ASSIGN(PaymentRequest);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_H_
diff --git a/chromium/components/payments/payment_request.mojom b/chromium/components/payments/content/payment_request.mojom
index 5b1abcdea23..d8ad5833f48 100644
--- a/chromium/components/payments/payment_request.mojom
+++ b/chromium/components/payments/content/payment_request.mojom
@@ -48,7 +48,7 @@ struct PaymentCurrencyAmount {
// currency identifier belongs to. By default, the value is
// urn:iso:std:iso:4217 indicating that currency is defined by [ISO4217]
// (for example, USD for US Dollars).
- string? currency_system;
+ string currency_system = "urn:iso:std:iso:4217";
};
struct PaymentResponse {
diff --git a/chromium/components/payments/payment_request_delegate.h b/chromium/components/payments/content/payment_request_delegate.h
index 9e666541661..46faaaea93a 100644
--- a/chromium/components/payments/payment_request_delegate.h
+++ b/chromium/components/payments/content/payment_request_delegate.h
@@ -2,8 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_PAYMENTS_PAYMENT_REQUEST_DELEGATE_H_
-#define COMPONENTS_PAYMENTS_PAYMENT_REQUEST_DELEGATE_H_
+#ifndef COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_DELEGATE_H_
+#define COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_DELEGATE_H_
+
+#include <string>
namespace autofill {
class PersonalDataManager;
@@ -18,12 +20,19 @@ class PaymentRequestDelegate {
virtual ~PaymentRequestDelegate() {}
// Shows the Payment Request dialog for the given |request|.
- virtual void ShowPaymentRequestDialog(PaymentRequest* request) = 0;
+ virtual void ShowDialog(PaymentRequest* request) = 0;
+
+ // Closes the same dialog that was opened by this delegate. Must be safe to
+ // call when the dialog is not showing.
+ virtual void CloseDialog() = 0;
// Gets the PersonalDataManager associated with this PaymentRequest flow.
+ // Cannot be null.
virtual autofill::PersonalDataManager* GetPersonalDataManager() = 0;
+
+ virtual const std::string& GetApplicationLocale() const = 0;
};
} // namespace payments
-#endif // COMPONENTS_PAYMENTS_PAYMENT_REQUEST_DELEGATE_H_
+#endif // COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_DELEGATE_H_
diff --git a/chromium/components/payments/content/payment_request_dialog.h b/chromium/components/payments/content/payment_request_dialog.h
new file mode 100644
index 00000000000..5befff8d08f
--- /dev/null
+++ b/chromium/components/payments/content/payment_request_dialog.h
@@ -0,0 +1,22 @@
+// Copyright 2017 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_PAYMENTS_CONTENT_PAYMENT_REQUEST_DIALOG_H_
+#define COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_DIALOG_H_
+
+namespace payments {
+
+// Used to interact with a cross-platform Payment Request dialog.
+class PaymentRequestDialog {
+ public:
+ virtual ~PaymentRequestDialog() {}
+
+ virtual void ShowDialog() = 0;
+
+ virtual void CloseDialog() = 0;
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CONTENT_PAYMENT_REQUEST_DIALOG_H_
diff --git a/chromium/components/payments/payment_request_web_contents_manager.cc b/chromium/components/payments/content/payment_request_web_contents_manager.cc
index ca893723f6f..db68134c47c 100644
--- a/chromium/components/payments/payment_request_web_contents_manager.cc
+++ b/chromium/components/payments/content/payment_request_web_contents_manager.cc
@@ -2,13 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/payments/payment_request_web_contents_manager.h"
+#include "components/payments/content/payment_request_web_contents_manager.h"
-#include <memory>
#include <utility>
#include "base/logging.h"
-#include "components/payments/payment_request_delegate.h"
+#include "base/memory/ptr_util.h"
+#include "components/payments/content/payment_request.h"
+#include "components/payments/content/payment_request_delegate.h"
+#include "content/public/browser/web_contents.h"
DEFINE_WEB_CONTENTS_USER_DATA_KEY(payments::PaymentRequestWebContentsManager);
@@ -29,8 +31,8 @@ void PaymentRequestWebContentsManager::CreatePaymentRequest(
content::WebContents* web_contents,
std::unique_ptr<PaymentRequestDelegate> delegate,
mojo::InterfaceRequest<payments::mojom::PaymentRequest> request) {
- std::unique_ptr<PaymentRequest> new_request(new PaymentRequest(
- web_contents, std::move(delegate), this, std::move(request)));
+ auto new_request = base::MakeUnique<PaymentRequest>(
+ web_contents, std::move(delegate), this, std::move(request));
PaymentRequest* request_ptr = new_request.get();
payment_requests_.insert(std::make_pair(request_ptr, std::move(new_request)));
}
diff --git a/chromium/components/payments/payment_request_web_contents_manager.h b/chromium/components/payments/content/payment_request_web_contents_manager.h
index 42e26f4a9ce..52323140d10 100644
--- a/chromium/components/payments/payment_request_web_contents_manager.h
+++ b/chromium/components/payments/content/payment_request_web_contents_manager.h
@@ -5,15 +5,21 @@
#ifndef COMPONENTS_PAYMENTS_PAYMENT_REQUEST_WEB_CONTENTS_MANAGER_H_
#define COMPONENTS_PAYMENTS_PAYMENT_REQUEST_WEB_CONTENTS_MANAGER_H_
+#include <memory>
#include <unordered_map>
-#include "components/payments/payment_request.h"
-#include "components/payments/payment_request.mojom.h"
+#include "base/macros.h"
+#include "components/payments/content/payment_request.mojom.h"
#include "content/public/browser/web_contents_user_data.h"
#include "mojo/public/cpp/bindings/binding.h"
+namespace content {
+class WebContents;
+}
+
namespace payments {
+class PaymentRequest;
class PaymentRequestDelegate;
// This class owns the PaymentRequest associated with a given WebContents.
@@ -54,6 +60,8 @@ class PaymentRequestWebContentsManager
// the requests themselves call DestroyRequest().
std::unordered_map<PaymentRequest*, std::unique_ptr<PaymentRequest>>
payment_requests_;
+
+ DISALLOW_COPY_AND_ASSIGN(PaymentRequestWebContentsManager);
};
} // namespace payments
diff --git a/chromium/components/payments/payments_validators.cc b/chromium/components/payments/content/payments_validators.cc
index 1d83c237c6e..ed2b448c205 100644
--- a/chromium/components/payments/payments_validators.cc
+++ b/chromium/components/payments/content/payments_validators.cc
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/payments/payments_validators.h"
+#include "components/payments/content/payments_validators.h"
#include "third_party/re2/src/re2/re2.h"
#include "url/gurl.h"
@@ -15,29 +15,29 @@ static const int maximumStringLength = 2048;
bool PaymentsValidators::isValidCurrencyCodeFormat(
const std::string& code,
const std::string& system,
- std::string* optionalErrorMessage) {
+ std::string* optional_error_message) {
if (system == "urn:iso:std:iso:4217") {
if (RE2::FullMatch(code, "[A-Z]{3}"))
return true;
- if (optionalErrorMessage)
- *optionalErrorMessage = "'" + code +
- "' is not a valid ISO 4217 currency code, should "
- "be 3 upper case letters [A-Z]";
+ if (optional_error_message)
+ *optional_error_message =
+ "'" + code +
+ "' is not a valid ISO 4217 currency code, should "
+ "be 3 upper case letters [A-Z]";
return false;
}
if (code.size() > maximumStringLength) {
- if (optionalErrorMessage)
- *optionalErrorMessage =
+ if (optional_error_message)
+ *optional_error_message =
"The currency code should be at most 2048 characters long";
return false;
}
if (!GURL(system).is_valid()) {
- if (optionalErrorMessage)
- *optionalErrorMessage =
- "The system should be a valid URL";
+ if (optional_error_message)
+ *optional_error_message = "The system should be a valid URL";
return false;
}
return true;
@@ -45,74 +45,77 @@ bool PaymentsValidators::isValidCurrencyCodeFormat(
bool PaymentsValidators::isValidAmountFormat(
const std::string& amount,
- std::string* optionalErrorMessage) {
+ std::string* optional_error_message) {
if (RE2::FullMatch(amount, "-?[0-9]+(\\.[0-9]+)?"))
return true;
- if (optionalErrorMessage)
- *optionalErrorMessage = "'" + amount + "' is not a valid amount format";
+ if (optional_error_message)
+ *optional_error_message = "'" + amount + "' is not a valid amount format";
return false;
}
bool PaymentsValidators::isValidCountryCodeFormat(
const std::string& code,
- std::string* optionalErrorMessage) {
+ std::string* optional_error_message) {
if (RE2::FullMatch(code, "[A-Z]{2}"))
return true;
- if (optionalErrorMessage)
- *optionalErrorMessage = "'" + code +
- "' is not a valid CLDR country code, should be 2 "
- "upper case letters [A-Z]";
+ if (optional_error_message)
+ *optional_error_message = "'" + code +
+ "' is not a valid CLDR country code, should be 2 "
+ "upper case letters [A-Z]";
return false;
}
bool PaymentsValidators::isValidLanguageCodeFormat(
const std::string& code,
- std::string* optionalErrorMessage) {
+ std::string* optional_error_message) {
if (RE2::FullMatch(code, "([a-z]{2,3})?"))
return true;
- if (optionalErrorMessage)
- *optionalErrorMessage = "'" + code +
- "' is not a valid BCP-47 language code, should be "
- "2-3 lower case letters [a-z]";
+ if (optional_error_message)
+ *optional_error_message =
+ "'" + code +
+ "' is not a valid BCP-47 language code, should be "
+ "2-3 lower case letters [a-z]";
return false;
}
bool PaymentsValidators::isValidScriptCodeFormat(
const std::string& code,
- std::string* optionalErrorMessage) {
+ std::string* optional_error_message) {
if (RE2::FullMatch(code, "([A-Z][a-z]{3})?"))
return true;
- if (optionalErrorMessage)
- *optionalErrorMessage = "'" + code +
- "' is not a valid ISO 15924 script code, should be "
- "an upper case letter [A-Z] followed by 3 lower "
- "case letters [a-z]";
+ if (optional_error_message)
+ *optional_error_message =
+ "'" + code +
+ "' is not a valid ISO 15924 script code, should be "
+ "an upper case letter [A-Z] followed by 3 lower "
+ "case letters [a-z]";
return false;
}
bool PaymentsValidators::isValidShippingAddress(
const mojom::PaymentAddressPtr& address,
- std::string* optionalErrorMessage) {
- if (!isValidCountryCodeFormat(address->country, optionalErrorMessage))
+ std::string* optional_error_message) {
+ if (!isValidCountryCodeFormat(address->country, optional_error_message))
return false;
- if (!isValidLanguageCodeFormat(address->language_code, optionalErrorMessage))
+ if (!isValidLanguageCodeFormat(address->language_code,
+ optional_error_message))
return false;
- if (!isValidScriptCodeFormat(address->script_code, optionalErrorMessage))
+ if (!isValidScriptCodeFormat(address->script_code, optional_error_message))
return false;
if (address->language_code.empty() && !address->script_code.empty()) {
- if (optionalErrorMessage)
- *optionalErrorMessage =
+ if (optional_error_message)
+ *optional_error_message =
"If language code is empty, then script code should also be empty";
return false;
@@ -123,12 +126,12 @@ bool PaymentsValidators::isValidShippingAddress(
bool PaymentsValidators::isValidErrorMsgFormat(
const std::string& error,
- std::string* optionalErrorMessage) {
+ std::string* optional_error_message) {
if (error.length() <= maximumStringLength)
return true;
- if (optionalErrorMessage)
- *optionalErrorMessage =
+ if (optional_error_message)
+ *optional_error_message =
"Error message should be at most 2048 characters long";
return false;
diff --git a/chromium/components/payments/payments_validators.h b/chromium/components/payments/content/payments_validators.h
index 133eecb7c7e..135074cc1aa 100644
--- a/chromium/components/payments/payments_validators.h
+++ b/chromium/components/payments/content/payments_validators.h
@@ -2,12 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_PAYMENTS_PAYMENTS_VALIDATORS_H_
-#define COMPONENTS_PAYMENTS_PAYMENTS_VALIDATORS_H_
+#ifndef COMPONENTS_PAYMENTS_CONTENT_PAYMENTS_VALIDATORS_H_
+#define COMPONENTS_PAYMENTS_CONTENT_PAYMENTS_VALIDATORS_H_
#include <string>
-#include "components/payments/payment_request.mojom.h"
+#include "base/macros.h"
+#include "components/payments/content/payment_request.mojom.h"
namespace payments {
@@ -22,38 +23,41 @@ class PaymentsValidators {
// false if currency |code| is too long (greater than 2048).
static bool isValidCurrencyCodeFormat(const std::string& code,
const std::string& system,
- std::string* optionalErrorMessage);
+ std::string* optional_error_message);
// Returns true if |amount| is a valid currency code as defined in ISO 20022
// CurrencyAnd30Amount.
static bool isValidAmountFormat(const std::string& amount,
- std::string* optionalErrorMessage);
+ std::string* optional_error_message);
// Returns true if |code| is a valid ISO 3166 country code.
static bool isValidCountryCodeFormat(const std::string& code,
- std::string* optionalErrorMessage);
+ std::string* optional_error_message);
// Returns true if |code| is a valid ISO 639 language code.
static bool isValidLanguageCodeFormat(const std::string& code,
- std::string* optionalErrorMessage);
+ std::string* optional_error_message);
// Returns true if |code| is a valid ISO 15924 script code.
static bool isValidScriptCodeFormat(const std::string& code,
- std::string* optionalErrorMessage);
+ std::string* optional_error_message);
// Returns true if the payment address is valid:
// - Has a valid region code
// - Has a valid language code, if any.
// - Has a valid script code, if any.
// A script code should be present only if language code is present.
- static bool isValidShippingAddress(const mojom::PaymentAddressPtr&,
- std::string* optionalErrorMessage);
+ static bool isValidShippingAddress(const mojom::PaymentAddressPtr& address,
+ std::string* optional_error_message);
// Returns false if |error| is too long (greater than 2048).
static bool isValidErrorMsgFormat(const std::string& code,
- std::string* optionalErrorMessage);
+ std::string* optional_error_message);
+
+ private:
+ DISALLOW_IMPLICIT_CONSTRUCTORS(PaymentsValidators);
};
} // namespace payments
-#endif // COMPONENTS_PAYMENTS_PAYMENTS_VALIDATORS_H_
+#endif // COMPONENTS_PAYMENTS_CONTENT_PAYMENTS_VALIDATORS_H_
diff --git a/chromium/components/payments/payments_validators_test.cc b/chromium/components/payments/content/payments_validators_test.cc
index 16fedd0e811..8214ce148dc 100644
--- a/chromium/components/payments/payments_validators_test.cc
+++ b/chromium/components/payments/content/payments_validators_test.cc
@@ -2,10 +2,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/payments/payments_validators.h"
+#include "components/payments/content/payments_validators.h"
-#include "testing/gtest/include/gtest/gtest.h"
#include <ostream> // NOLINT
+#include "testing/gtest/include/gtest/gtest.h"
namespace payments {
namespace {
diff --git a/chromium/components/payments/core/BUILD.gn b/chromium/components/payments/core/BUILD.gn
new file mode 100644
index 00000000000..e0a51dfc193
--- /dev/null
+++ b/chromium/components/payments/core/BUILD.gn
@@ -0,0 +1,39 @@
+# Copyright 2017 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.
+
+static_library("core") {
+ sources = [
+ "address_normalizer.cc",
+ "address_normalizer.h",
+ "currency_formatter.cc",
+ "currency_formatter.h",
+ ]
+
+ deps = [
+ "//base",
+ "//components/autofill/core/browser",
+ ]
+
+ public_deps = [
+ "//third_party/icu",
+ "//third_party/libaddressinput",
+ ]
+}
+
+source_set("unit_tests") {
+ testonly = true
+ sources = [
+ "address_normalizer_unittest.cc",
+ "currency_formatter_unittest.cc",
+ ]
+
+ deps = [
+ ":core",
+ "//base",
+ "//base/test:test_support",
+ "//components/autofill/core/browser",
+ "//testing/gtest",
+ "//third_party/libaddressinput:test_support",
+ ]
+}
diff --git a/chromium/components/payments/core/DEPS b/chromium/components/payments/core/DEPS
new file mode 100644
index 00000000000..77981288756
--- /dev/null
+++ b/chromium/components/payments/core/DEPS
@@ -0,0 +1,5 @@
+include_rules = [
+ "-content",
+ "+components/autofill/core",
+ "+third_party/libaddressinput",
+]
diff --git a/chromium/components/payments/core/address_normalizer.cc b/chromium/components/payments/core/address_normalizer.cc
new file mode 100644
index 00000000000..3114c5a8922
--- /dev/null
+++ b/chromium/components/payments/core/address_normalizer.cc
@@ -0,0 +1,169 @@
+// Copyright 2017 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/payments/core/address_normalizer.h"
+
+#include <stddef.h>
+#include <utility>
+
+#include "base/bind.h"
+#include "base/bind_helpers.h"
+#include "base/cancelable_callback.h"
+#include "base/location.h"
+#include "base/logging.h"
+#include "base/memory/ptr_util.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/threading/sequenced_task_runner_handle.h"
+#include "base/time/time.h"
+#include "components/autofill/core/browser/address_i18n.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/address_data.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+
+namespace payments {
+namespace {
+
+using ::autofill::AutofillProfile;
+using ::i18n::addressinput::Source;
+using ::i18n::addressinput::Storage;
+
+class AddressNormalizationRequest : public AddressNormalizer::Request {
+ public:
+ // The |delegate| and |address_validator| need to outlive this Request.
+ AddressNormalizationRequest(const AutofillProfile& profile,
+ const std::string& region_code,
+ int timeout_seconds,
+ AddressNormalizer::Delegate* delegate,
+ autofill::AddressValidator* address_validator)
+ : profile_(profile),
+ region_code_(region_code),
+ delegate_(delegate),
+ address_validator_(address_validator),
+ has_responded_(false),
+ on_timeout_(
+ base::Bind(&::payments::AddressNormalizationRequest::OnRulesLoaded,
+ base::Unretained(this),
+ false)) {
+ base::SequencedTaskRunnerHandle::Get()->PostDelayedTask(
+ FROM_HERE, on_timeout_.callback(),
+ base::TimeDelta::FromSeconds(timeout_seconds));
+ }
+
+ ~AddressNormalizationRequest() override {}
+
+ void OnRulesLoaded(bool success) override {
+ on_timeout_.Cancel();
+
+ // Check if the timeout happened before the rules were loaded.
+ if (has_responded_)
+ return;
+ has_responded_ = true;
+
+ if (!success) {
+ delegate_->OnCouldNotNormalize(profile_);
+ return;
+ }
+
+ // The rules should be loaded.
+ DCHECK(address_validator_->AreRulesLoadedForRegion(region_code_));
+
+ // Create the AddressData from the profile.
+ ::i18n::addressinput::AddressData address_data =
+ *autofill::i18n::CreateAddressDataFromAutofillProfile(profile_,
+ region_code_);
+
+ // Normalize the address.
+ if (address_validator_ &&
+ address_validator_->NormalizeAddress(&address_data)) {
+ profile_.SetRawInfo(autofill::ADDRESS_HOME_STATE,
+ base::UTF8ToUTF16(address_data.administrative_area));
+ profile_.SetRawInfo(autofill::ADDRESS_HOME_CITY,
+ base::UTF8ToUTF16(address_data.locality));
+ profile_.SetRawInfo(autofill::ADDRESS_HOME_DEPENDENT_LOCALITY,
+ base::UTF8ToUTF16(address_data.dependent_locality));
+ }
+
+ delegate_->OnAddressNormalized(profile_);
+ }
+
+ private:
+ AutofillProfile profile_;
+ std::string region_code_;
+ AddressNormalizer::Delegate* delegate_;
+ autofill::AddressValidator* address_validator_;
+
+ bool has_responded_;
+ base::CancelableCallback<void()> on_timeout_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddressNormalizationRequest);
+};
+
+} // namespace
+
+AddressNormalizer::AddressNormalizer(std::unique_ptr<Source> source,
+ std::unique_ptr<Storage> storage)
+ : address_validator_(std::move(source), std::move(storage), this) {}
+
+AddressNormalizer::~AddressNormalizer() {}
+
+void AddressNormalizer::LoadRulesForRegion(const std::string& region_code) {
+ address_validator_.LoadRules(region_code);
+}
+
+bool AddressNormalizer::AreRulesLoadedForRegion(
+ const std::string& region_code) {
+ return address_validator_.AreRulesLoadedForRegion(region_code);
+}
+
+void AddressNormalizer::StartAddressNormalization(
+ const AutofillProfile& profile,
+ const std::string& region_code,
+ int timeout_seconds,
+ AddressNormalizer::Delegate* requester) {
+ DCHECK(timeout_seconds >= 0);
+
+ std::unique_ptr<AddressNormalizationRequest> request(
+ base::MakeUnique<AddressNormalizationRequest>(profile, region_code,
+ timeout_seconds, requester,
+ &address_validator_));
+
+ // Check if the rules are already loaded.
+ if (AreRulesLoadedForRegion(region_code)) {
+ request->OnRulesLoaded(true);
+ } else {
+ // Setup the variables so the profile gets normalized when the rules have
+ // finished loading.
+ auto it = pending_normalization_.find(region_code);
+ if (it == pending_normalization_.end()) {
+ // If no entry exists yet, create the entry and assign it to |it|.
+ it = pending_normalization_
+ .insert(std::make_pair(region_code,
+ std::vector<std::unique_ptr<Request>>()))
+ .first;
+ }
+
+ it->second.push_back(std::move(request));
+
+ // Start loading the rules for that region. If the rules were already in the
+ // process of being loaded, this call will do nothing.
+ LoadRulesForRegion(region_code);
+ }
+}
+
+void AddressNormalizer::OnAddressValidationRulesLoaded(
+ const std::string& region_code,
+ bool success) {
+ // Check if an address normalization is pending.
+ auto it = pending_normalization_.find(region_code);
+ if (it != pending_normalization_.end()) {
+ for (size_t i = 0; i < it->second.size(); ++i) {
+ it->second[i]->OnRulesLoaded(success);
+ }
+ pending_normalization_.erase(it);
+ }
+}
+
+} // namespace payments \ No newline at end of file
diff --git a/chromium/components/payments/core/address_normalizer.h b/chromium/components/payments/core/address_normalizer.h
new file mode 100644
index 00000000000..0280d82b1e3
--- /dev/null
+++ b/chromium/components/payments/core/address_normalizer.h
@@ -0,0 +1,94 @@
+// Copyright 2017 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_PAYMENTS_CORE_ADDRESS_NORMALIZER_H_
+#define COMPONENTS_PAYMENTS_CORE_ADDRESS_NORMALIZER_H_
+
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "base/macros.h"
+#include "third_party/libaddressinput/chromium/chrome_address_validator.h"
+
+namespace autofill {
+class AutofillProfile;
+}
+
+namespace i18n {
+namespace libadderssinput {
+class Source;
+class Storage;
+}
+}
+
+namespace payments {
+
+// A class used to normalize addresses.
+class AddressNormalizer : public autofill::LoadRulesListener {
+ public:
+ // The interface for the normalization delegates.
+ class Delegate {
+ public:
+ virtual void OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) = 0;
+
+ virtual void OnCouldNotNormalize(
+ const autofill::AutofillProfile& profile) = 0;
+
+ protected:
+ virtual ~Delegate() {}
+ };
+
+ // The interface for the normalization request.
+ class Request {
+ public:
+ virtual void OnRulesLoaded(bool success) = 0;
+ virtual ~Request() {}
+ };
+
+ AddressNormalizer(std::unique_ptr<i18n::addressinput::Source> source,
+ std::unique_ptr<i18n::addressinput::Storage> storage);
+ ~AddressNormalizer() override;
+
+ // Start loading the validation rules for the specified |region_code|.
+ virtual void LoadRulesForRegion(const std::string& region_code);
+
+ // Returns whether the rules for the specified |region_code| have finished
+ // loading.
+ bool AreRulesLoadedForRegion(const std::string& region_code);
+
+ // Starts the normalization of the |profile| based on the |region_code|. The
+ // normalized profile will be returned to the |requester| possibly
+ // asynchronously. If the normalization is not completed in |timeout_seconds|
+ // the requester will be informed and the request cancelled. This value should
+ // be greater or equal to 0, for which it means that the normalization should
+ // happen synchronously, or not at all if the rules are not already loaded.
+ // Will start loading the rules for the |region_code| if they had not started
+ // loading.
+ void StartAddressNormalization(const autofill::AutofillProfile& profile,
+ const std::string& region_code,
+ int timeout_seconds,
+ Delegate* requester);
+
+ private:
+ // Called when the validation rules for the |region_code| have finished
+ // loading. Implementation of the LoadRulesListener interface.
+ void OnAddressValidationRulesLoaded(const std::string& region_code,
+ bool success) override;
+
+ // Map associating a region code to pending normalizations.
+ std::map<std::string, std::vector<std::unique_ptr<Request>>>
+ pending_normalization_;
+
+ // The address validator used to normalize addresses.
+ autofill::AddressValidator address_validator_;
+
+ DISALLOW_COPY_AND_ASSIGN(AddressNormalizer);
+};
+
+} // namespace payments
+
+#endif // COMPONENTS_PAYMENTS_CORE_ADDRESS_NORMALIZER_H_
diff --git a/chromium/components/payments/core/address_normalizer_unittest.cc b/chromium/components/payments/core/address_normalizer_unittest.cc
new file mode 100644
index 00000000000..0d2f3fae5fc
--- /dev/null
+++ b/chromium/components/payments/core/address_normalizer_unittest.cc
@@ -0,0 +1,191 @@
+// Copyright 2017 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/payments/core/address_normalizer.h"
+
+#include "base/run_loop.h"
+#include "base/strings/utf_string_conversions.h"
+#include "base/test/scoped_task_scheduler.h"
+#include "components/autofill/core/browser/autofill_profile.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/null_storage.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/source.h"
+#include "third_party/libaddressinput/src/cpp/include/libaddressinput/storage.h"
+#include "third_party/libaddressinput/src/cpp/test/testdata_source.h"
+
+namespace payments {
+namespace {
+
+using ::autofill::AutofillProfile;
+using ::i18n::addressinput::NullStorage;
+using ::i18n::addressinput::Source;
+using ::i18n::addressinput::Storage;
+using ::i18n::addressinput::TestdataSource;
+
+// The requester of normalization for this test.
+class NormalizationDelegate : public AddressNormalizer::Delegate {
+ public:
+ NormalizationDelegate()
+ : normalized_called_(false), not_normalized_called_(false) {}
+
+ ~NormalizationDelegate() override {}
+
+ void OnAddressNormalized(
+ const autofill::AutofillProfile& normalized_profile) override {
+ normalized_called_ = true;
+ }
+
+ void OnCouldNotNormalize(const autofill::AutofillProfile& profile) override {
+ not_normalized_called_ = true;
+ }
+
+ bool normalized_called() { return normalized_called_; }
+
+ bool not_normalized_called() { return not_normalized_called_; }
+
+ private:
+ bool normalized_called_;
+ bool not_normalized_called_;
+
+ DISALLOW_COPY_AND_ASSIGN(NormalizationDelegate);
+};
+
+// Used to load region rules for this test.
+class ChromiumTestdataSource : public TestdataSource {
+ public:
+ ChromiumTestdataSource() : TestdataSource(true) {}
+
+ ~ChromiumTestdataSource() override {}
+
+ // For this test, only load the rules for the "US".
+ void Get(const std::string& key, const Callback& data_ready) const override {
+ data_ready(
+ true, key,
+ new std::string("{\"data/US\": "
+ "{\"id\":\"data/US\",\"key\":\"US\",\"name\":\"UNITED "
+ "STATES\",\"lang\":\"en\",\"languages\":\"en\"}}"));
+ }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ChromiumTestdataSource);
+};
+
+// A test subclass of the AddressNormalizer. Used to simulate rules not being
+// loaded.
+class TestAddressNormalizer : public AddressNormalizer {
+ public:
+ TestAddressNormalizer(std::unique_ptr<i18n::addressinput::Source> source,
+ std::unique_ptr<i18n::addressinput::Storage> storage)
+ : AddressNormalizer(std::move(source), std::move(storage)),
+ should_load_rules_(true) {}
+
+ ~TestAddressNormalizer() override {}
+
+ void ShouldLoadRules(bool should_load_rules) {
+ should_load_rules_ = should_load_rules;
+ }
+
+ void LoadRulesForRegion(const std::string& region_code) override {
+ if (should_load_rules_) {
+ AddressNormalizer::LoadRulesForRegion(region_code);
+ }
+ }
+
+ private:
+ bool should_load_rules_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestAddressNormalizer);
+};
+
+} // namespace
+
+class AddressNormalizerTest : public testing::Test {
+ protected:
+ AddressNormalizerTest()
+ : normalizer_(new TestAddressNormalizer(
+ std::unique_ptr<Source>(new ChromiumTestdataSource),
+ std::unique_ptr<Storage>(new NullStorage))) {}
+
+ ~AddressNormalizerTest() override {}
+
+ const std::unique_ptr<TestAddressNormalizer> normalizer_;
+
+ base::test::ScopedTaskScheduler scoped_task_scheduler_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(AddressNormalizerTest);
+};
+
+// Tests that rules are not loaded by default.
+TEST_F(AddressNormalizerTest, AreRulesLoadedForRegion_NotLoaded) {
+ EXPECT_FALSE(normalizer_->AreRulesLoadedForRegion("US"));
+}
+
+// Tests that the rules are loaded correctly.
+TEST_F(AddressNormalizerTest, AreRulesLoadedForRegion_Loaded) {
+ normalizer_->LoadRulesForRegion("US");
+ EXPECT_TRUE(normalizer_->AreRulesLoadedForRegion("US"));
+}
+
+// Tests that if the rules are loaded before the normalization is started, the
+// normalized profile will be returned to the delegate synchronously.
+TEST_F(AddressNormalizerTest, StartNormalization_RulesLoaded) {
+ NormalizationDelegate delegate;
+ AutofillProfile profile;
+
+ // Load the rules.
+ normalizer_->LoadRulesForRegion("US");
+ EXPECT_TRUE(normalizer_->AreRulesLoadedForRegion("US"));
+
+ // Start the normalization.
+ normalizer_->StartAddressNormalization(profile, "US", 0, &delegate);
+
+ // Since the rules are already loaded, the address should be normalized
+ // synchronously.
+ EXPECT_TRUE(delegate.normalized_called());
+ EXPECT_FALSE(delegate.not_normalized_called());
+}
+
+// Tests that if the rules are not loaded before the normalization and cannot be
+// loaded after, the address will not be normalized and the delegate will be
+// notified.
+TEST_F(AddressNormalizerTest, StartNormalization_RulesNotLoaded_WillNotLoad) {
+ NormalizationDelegate delegate;
+ AutofillProfile profile;
+
+ // Make sure the rules will not be loaded in the StartAddressNormalization
+ // call.
+ normalizer_->ShouldLoadRules(false);
+
+ // Start the normalization.
+ normalizer_->StartAddressNormalization(profile, "US", 0, &delegate);
+
+ // Let the timeout execute.
+ base::RunLoop().RunUntilIdle();
+
+ // Since the rules are never loaded and the timeout is 0, the delegate should
+ // get notified that the address could not be normalized.
+ EXPECT_FALSE(delegate.normalized_called());
+ EXPECT_TRUE(delegate.not_normalized_called());
+}
+
+// Tests that if the rules are not loaded before the call to
+// StartAddressNormalization, they will be loaded in the call.
+TEST_F(AddressNormalizerTest, StartNormalization_RulesNotLoaded_WillLoad) {
+ NormalizationDelegate delegate;
+ AutofillProfile profile;
+
+ // Start the normalization.
+ normalizer_->StartAddressNormalization(profile, "US", 0, &delegate);
+
+ // Even if the rules are not loaded before the call to
+ // StartAddressNormalization, they should get loaded in the call. Since our
+ // test source is synchronous, the normalization will happen synchronously
+ // too.
+ EXPECT_TRUE(normalizer_->AreRulesLoadedForRegion("US"));
+ EXPECT_TRUE(delegate.normalized_called());
+ EXPECT_FALSE(delegate.not_normalized_called());
+}
+
+} // namespace payments \ No newline at end of file
diff --git a/chromium/components/payments/currency_formatter.cc b/chromium/components/payments/core/currency_formatter.cc
index d6d4bc04769..4eb4f74ea06 100644
--- a/chromium/components/payments/currency_formatter.cc
+++ b/chromium/components/payments/core/currency_formatter.cc
@@ -2,16 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/payments/currency_formatter.h"
-
-#include <memory>
+#include "components/payments/core/currency_formatter.h"
+#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "third_party/icu/source/common/unicode/stringpiece.h"
#include "third_party/icu/source/common/unicode/uchar.h"
-#include "third_party/icu/source/common/unicode/unistr.h"
#include "third_party/icu/source/common/unicode/utypes.h"
namespace payments {
@@ -36,9 +34,9 @@ const char kEllipsis[] = "\xE2\x80\xA6";
// Returns whether the |currency_code| is valid to be used in ICU.
bool ShouldUseCurrencyCode(const std::string& currency_code,
- const base::Optional<std::string> currency_system) {
- return currency_system.value_or(kIso4217CurrencySystem) ==
- kIso4217CurrencySystem &&
+ const std::string& currency_system) {
+ return (currency_system.empty() ||
+ currency_system == kIso4217CurrencySystem) &&
!currency_code.empty() &&
currency_code.size() <= kMaxCurrencyCodeLength;
}
@@ -52,10 +50,9 @@ std::string FormatCurrencyCode(const std::string& currency_code) {
} // namespace
-CurrencyFormatter::CurrencyFormatter(
- const std::string& currency_code,
- const base::Optional<std::string> currency_system,
- const std::string& locale_name)
+CurrencyFormatter::CurrencyFormatter(const std::string& currency_code,
+ const std::string& currency_system,
+ const std::string& locale_name)
: locale_(locale_name.c_str()),
formatted_currency_code_(FormatCurrencyCode(currency_code)) {
UErrorCode error_code = U_ZERO_ERROR;
diff --git a/chromium/components/payments/currency_formatter.h b/chromium/components/payments/core/currency_formatter.h
index 2794b37dcce..eec9d66bf17 100644
--- a/chromium/components/payments/currency_formatter.h
+++ b/chromium/components/payments/core/currency_formatter.h
@@ -2,16 +2,16 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#ifndef COMPONENTS_PAYMENTS_CURRENCY_FORMATTER_H_
-#define COMPONENTS_PAYMENTS_CURRENCY_FORMATTER_H_
+#ifndef COMPONENTS_PAYMENTS_CORE_CURRENCY_FORMATTER_H_
+#define COMPONENTS_PAYMENTS_CORE_CURRENCY_FORMATTER_H_
#include <memory>
#include <string>
#include "base/macros.h"
-#include "base/optional.h"
#include "base/strings/string16.h"
#include "third_party/icu/source/common/unicode/locid.h"
+#include "third_party/icu/source/common/unicode/unistr.h"
#include "third_party/icu/source/i18n/unicode/numfmt.h"
namespace payments {
@@ -29,7 +29,7 @@ class CurrencyFormatter {
// |currency_system| should have been validated (as part of
// payment_details_validation.h) before this is created.
CurrencyFormatter(const std::string& currency_code,
- const base::Optional<std::string> currency_system,
+ const std::string& currency_system,
const std::string& locale_name);
~CurrencyFormatter();
@@ -43,7 +43,9 @@ class CurrencyFormatter {
// Returns the formatted currency code (<= 6 characters including ellipsis if
// applicable).
- std::string formatted_currency_code() { return formatted_currency_code_; }
+ const std::string& formatted_currency_code() const {
+ return formatted_currency_code_;
+ }
private:
const icu::Locale locale_;
@@ -56,4 +58,4 @@ class CurrencyFormatter {
} // namespace payments
-#endif // COMPONENTS_PAYMENTS_CURRENCY_FORMATTER_H_
+#endif // COMPONENTS_PAYMENTS_CORE_CURRENCY_FORMATTER_H_
diff --git a/chromium/components/payments/currency_formatter_unittest.cc b/chromium/components/payments/core/currency_formatter_unittest.cc
index ad679c62460..e55a2fe29a5 100644
--- a/chromium/components/payments/currency_formatter_unittest.cc
+++ b/chromium/components/payments/core/currency_formatter_unittest.cc
@@ -2,10 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "components/payments/currency_formatter.h"
+#include "components/payments/core/currency_formatter.h"
-#include "base/optional.h"
-#include "base/strings/string16.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -32,7 +30,7 @@ struct TestCase {
const char* const locale_name;
const std::string expected_amount;
const char* const expected_currency_code;
- const base::Optional<std::string> currency_system;
+ const char* const currency_system;
};
class PaymentsCurrencyFormatterTest : public testing::TestWithParam<TestCase> {
diff --git a/chromium/components/payments/payment_request.cc b/chromium/components/payments/payment_request.cc
deleted file mode 100644
index 282b3fa38af..00000000000
--- a/chromium/components/payments/payment_request.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright 2016 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/payments/payment_request.h"
-
-#include "base/memory/ptr_util.h"
-#include "components/autofill/core/browser/personal_data_manager.h"
-#include "components/payments/payment_details_validation.h"
-#include "components/payments/payment_request_delegate.h"
-#include "components/payments/payment_request_web_contents_manager.h"
-#include "content/public/browser/browser_thread.h"
-#include "content/public/browser/web_contents.h"
-
-namespace payments {
-
-PaymentRequest::PaymentRequest(
- content::WebContents* web_contents,
- std::unique_ptr<PaymentRequestDelegate> delegate,
- PaymentRequestWebContentsManager* manager,
- mojo::InterfaceRequest<payments::mojom::PaymentRequest> request)
- : web_contents_(web_contents),
- delegate_(std::move(delegate)),
- manager_(manager),
- binding_(this, std::move(request)) {
- binding_.set_connection_error_handler(
- base::Bind(&PaymentRequest::OnError, base::Unretained(this)));
-}
-
-PaymentRequest::~PaymentRequest() {}
-
-void PaymentRequest::Init(
- payments::mojom::PaymentRequestClientPtr client,
- std::vector<payments::mojom::PaymentMethodDataPtr> methodData,
- payments::mojom::PaymentDetailsPtr details,
- payments::mojom::PaymentOptionsPtr options) {
- DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
- std::string error;
- if (!payments::validatePaymentDetails(details, &error)) {
- LOG(ERROR) << error;
- OnError();
- client_.reset();
- return;
- }
- client_ = std::move(client);
- details_ = std::move(details);
-}
-
-void PaymentRequest::Show() {
- if (!client_.is_bound() || !binding_.is_bound()) {
- OnError();
- return;
- }
- delegate_->ShowPaymentRequestDialog(this);
-}
-
-void PaymentRequest::Cancel() {
- client_->OnError(payments::mojom::PaymentErrorReason::USER_CANCEL);
-}
-
-void PaymentRequest::OnError() {
- binding_.Close();
- manager_->DestroyRequest(this);
-}
-
-CurrencyFormatter* PaymentRequest::GetOrCreateCurrencyFormatter(
- const std::string& currency_code,
- const base::Optional<std::string> currency_system,
- const std::string& locale_name) {
- if (!currency_formatter_) {
- currency_formatter_.reset(
- new CurrencyFormatter(currency_code, currency_system, locale_name));
- }
-
- return currency_formatter_.get();
-}
-
-autofill::AutofillProfile* PaymentRequest::GetCurrentlySelectedProfile() {
- // TODO(tmartino): Implement more sophisticated algorithm for populating
- // this when it starts empty.
- if (!profile_) {
- autofill::PersonalDataManager* data_manager =
- delegate_->GetPersonalDataManager();
- auto profiles = data_manager->GetProfiles();
- if (!profiles.empty())
- profile_ = base::MakeUnique<autofill::AutofillProfile>(*profiles[0]);
- }
- return profile_ ? profile_.get() : nullptr;
-}
-
-autofill::CreditCard* PaymentRequest::GetCurrentlySelectedCreditCard() {
- // TODO(anthonyvd): Change this code to prioritize server cards and implement
- // a way to modify this function's return value.
- autofill::PersonalDataManager* data_manager =
- delegate_->GetPersonalDataManager();
-
- const std::vector<autofill::CreditCard*> cards =
- data_manager->GetCreditCardsToSuggest();
-
- auto first_complete_card = std::find_if(
- cards.begin(),
- cards.end(),
- [] (autofill::CreditCard* card) {
- return card->IsValid();
- });
-
- return first_complete_card == cards.end() ? nullptr : *first_complete_card;
-}
-
-} // namespace payments
diff --git a/chromium/components/payments/payment_request.h b/chromium/components/payments/payment_request.h
deleted file mode 100644
index 6c55cca9ae4..00000000000
--- a/chromium/components/payments/payment_request.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2016 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_PAYMENTS_PAYMENT_REQUEST_H_
-#define COMPONENTS_PAYMENTS_PAYMENT_REQUEST_H_
-
-#include <memory>
-#include <string>
-#include <vector>
-
-#include "components/payments/currency_formatter.h"
-#include "components/payments/payment_request.mojom.h"
-#include "mojo/public/cpp/bindings/binding.h"
-
-namespace autofill {
-class AutofillProfile;
-class CreditCard;
-}
-
-namespace content {
-class WebContents;
-}
-
-namespace payments {
-
-class PaymentRequestDelegate;
-class PaymentRequestWebContentsManager;
-
-class PaymentRequest : payments::mojom::PaymentRequest {
- public:
- PaymentRequest(
- content::WebContents* web_contents,
- std::unique_ptr<PaymentRequestDelegate> delegate,
- PaymentRequestWebContentsManager* manager,
- mojo::InterfaceRequest<payments::mojom::PaymentRequest> request);
- ~PaymentRequest() override;
-
- // payments::mojom::PaymentRequest "stub"
- void Init(payments::mojom::PaymentRequestClientPtr client,
- std::vector<payments::mojom::PaymentMethodDataPtr> methodData,
- payments::mojom::PaymentDetailsPtr details,
- payments::mojom::PaymentOptionsPtr options) override;
- void Show() override;
- void UpdateWith(payments::mojom::PaymentDetailsPtr details) override {}
- void Abort() override {}
- void Complete(payments::mojom::PaymentComplete result) override {}
- void CanMakePayment() override {}
-
- void Cancel();
- void OnError();
-
- // Returns the CurrencyFormatter instance for this PaymentRequest.
- // |locale_name| should be the result of the browser's GetApplicationLocale().
- // Note: Having multiple currencies per PaymentRequest is not supported; hence
- // the CurrencyFormatter is cached here.
- CurrencyFormatter* GetOrCreateCurrencyFormatter(
- const std::string& currency_code,
- const base::Optional<std::string> currency_system,
- const std::string& locale_name);
-
- // Returns the Autofill Profile, representing the shipping address and contact
- // information, currently selected for this PaymentRequest flow. If
- // unpopulated, populates with and returns the 0th profile on record for this
- // user, if it exists; or nullptr otherwise. Profile is owned by the request
- // object, not the caller.
- autofill::AutofillProfile* GetCurrentlySelectedProfile();
-
- // Returns the currently selected credit card for this PaymentRequest flow.
- // It's not guaranteed to be complete. Returns nullptr if there is no selected
- // card.
- autofill::CreditCard* GetCurrentlySelectedCreditCard();
-
- payments::mojom::PaymentDetails* details() { return details_.get(); }
- content::WebContents* web_contents() { return web_contents_; }
-
- private:
- content::WebContents* web_contents_;
- std::unique_ptr<PaymentRequestDelegate> delegate_;
- // |manager_| owns this PaymentRequest.
- PaymentRequestWebContentsManager* manager_;
- mojo::Binding<payments::mojom::PaymentRequest> binding_;
- payments::mojom::PaymentRequestClientPtr client_;
- payments::mojom::PaymentDetailsPtr details_;
- std::unique_ptr<CurrencyFormatter> currency_formatter_;
- std::unique_ptr<autofill::AutofillProfile> profile_;
-
- DISALLOW_COPY_AND_ASSIGN(PaymentRequest);
-};
-
-} // namespace payments
-
-#endif // COMPONENTS_PAYMENTS_PAYMENT_REQUEST_H_