From 059f9dc48371aa7f62dd76a53a0fc6dcd4711e2d Mon Sep 17 00:00:00 2001 From: gogerald Date: Tue, 29 Aug 2017 15:25:10 +0000 Subject: [PATCH] [Payments] Delegate PaymentRequest.abort to web payment handler Spec change: https://github.com/w3c/payment-handler/pull/207 Bug: 736745 Change-Id: Ifb78aa332080044180e2e836ac0709ba3f727567 Reviewed-on: https://chromium-review.googlesource.com/636504 Reviewed-by: Rouslan Solomakhin Commit-Queue: Ganggui Tang Cr-Commit-Position: refs/heads/master@{#498114} --- .../browser/payments/PaymentInstrument.java | 25 ++++++++++++++++ .../browser/payments/PaymentRequestImpl.java | 29 +++++++++++++------ .../payments/ServiceWorkerPaymentApp.java | 5 ++++ .../ServiceWorkerPaymentAppBridge.java | 26 +++++++++++++++++ .../service_worker_payment_app_bridge.cc | 24 +++++++++++++++ 5 files changed, 100 insertions(+), 9 deletions(-) diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentInstrument.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentInstrument.java index df6d3546d97b4..b2b1d9762d283 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentInstrument.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentInstrument.java @@ -6,6 +6,7 @@ import android.graphics.drawable.Drawable; +import org.chromium.base.ThreadUtils; import org.chromium.chrome.browser.payments.ui.PaymentOption; import org.chromium.payments.mojom.PaymentDetailsModifier; import org.chromium.payments.mojom.PaymentItem; @@ -46,6 +47,16 @@ public interface InstrumentDetailsCallback { void onInstrumentDetailsError(); } + /** The interface for the requester to abort payment. */ + public interface AbortCallback { + /** + * Called after aborting payment is finished. + * + * @param abortSucceeded Indicates whether abort is succeed. + */ + void onInstrumentAbortResult(boolean abortSucceeded); + } + protected PaymentInstrument(String id, String label, String sublabel, Drawable icon) { super(id, label, sublabel, icon); } @@ -143,6 +154,20 @@ public abstract void invokePaymentApp(String id, String merchantName, String ori List displayItems, Map modifiers, InstrumentDetailsCallback callback); + /** + * Abort invocation of the payment app. + * + * @param callback The callback to return abort result. + */ + public void abortPaymentApp(AbortCallback callback) { + ThreadUtils.postOnUiThread(new Runnable() { + @Override + public void run() { + callback.onInstrumentAbortResult(false); + } + }); + } + /** * Cleans up any resources held by the payment instrument. For example, closes server * connections. diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java index e3e28f3c0956e..05dc34373574f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java @@ -87,12 +87,12 @@ * Android implementation of the PaymentRequest service defined in * components/payments/content/payment_request.mojom. */ -public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Client, - PaymentApp.InstrumentsCallback, - PaymentInstrument.InstrumentDetailsCallback, - PaymentAppFactory.PaymentAppCreatedCallback, - PaymentResponseHelper.PaymentResponseRequesterDelegate, - FocusChangedObserver, NormalizedAddressRequestDelegate { +public class PaymentRequestImpl + implements PaymentRequest, PaymentRequestUI.Client, PaymentApp.InstrumentsCallback, + PaymentInstrument.AbortCallback, PaymentInstrument.InstrumentDetailsCallback, + PaymentAppFactory.PaymentAppCreatedCallback, + PaymentResponseHelper.PaymentResponseRequesterDelegate, FocusChangedObserver, + NormalizedAddressRequestDelegate { /** * A test-only observer for the PaymentRequest service implementation. */ @@ -1426,13 +1426,24 @@ private void disconnectFromClientWithDebugMessage(String debugMessage, int reaso @Override public void abort() { if (mClient == null) return; - mClient.onAbort(!mPaymentAppRunning); + if (mPaymentAppRunning) { - if (sObserverForTest != null) sObserverForTest.onPaymentRequestServiceUnableToAbort(); - } else { + ((PaymentInstrument) mPaymentMethodsSection.getSelectedItem()).abortPaymentApp(this); + return; + } + onInstrumentAbortResult(true); + } + + /** Called by the payment app in response to an abort request. */ + @Override + public void onInstrumentAbortResult(boolean abortSucceeded) { + mClient.onAbort(abortSucceeded); + if (abortSucceeded) { closeClient(); closeUI(true); mJourneyLogger.setAborted(AbortReason.ABORTED_BY_MERCHANT); + } else { + if (sObserverForTest != null) sObserverForTest.onPaymentRequestServiceUnableToAbort(); } } diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentApp.java index 2a23b11f4317a..a13e09f251793 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentApp.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentApp.java @@ -125,6 +125,11 @@ public void invokePaymentApp(String id, String merchantName, String origin, Stri new HashSet<>(modifiers.values()), callback); } + @Override + public void abortPaymentApp(AbortCallback callback) { + ServiceWorkerPaymentAppBridge.abortPaymentApp(mWebContents, mRegistrationId, callback); + } + @Override public void dismissInstrument() {} diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java index 02293cfde43d3..c6ec3f9bf0f0f 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ServiceWorkerPaymentAppBridge.java @@ -63,6 +63,18 @@ public static void invokePaymentApp(WebContents webContents, long registrationId modifiers.toArray(new PaymentDetailsModifier[0]), callback); } + /** + * Abort invocation of the payment app. + * + * @param webContents The web contents that invoked PaymentRequest. + * @param registrationId The service worker registration ID of the Payment App. + * @param callback Called after abort invoke payment app is finished running. + */ + public static void abortPaymentApp(WebContents webContents, long registrationId, + PaymentInstrument.AbortCallback callback) { + nativeAbortPaymentApp(webContents, registrationId, callback); + } + @CalledByNative private static String[] getSupportedMethodsFromMethodData(PaymentMethodData data) { return data.supportedMethods; @@ -140,6 +152,12 @@ private static void onPaymentAppInvoked( } } + @CalledByNative + private static void onPaymentAppAborted(Object callback, boolean result) { + assert callback instanceof PaymentInstrument.AbortCallback; + ((PaymentInstrument.AbortCallback) callback).onInstrumentAbortResult(result); + } + /* * TODO(tommyt): crbug.com/505554. Change the |callback| parameter below to * be of type PaymentInstrument.InstrumentDetailsCallback, once this JNI bug @@ -156,4 +174,12 @@ private static native void nativeInvokePaymentApp(WebContents webContents, long String topLevelOrigin, String paymentRequestOrigin, String paymentRequestId, PaymentMethodData[] methodData, PaymentItem total, PaymentDetailsModifier[] modifiers, Object callback); + + /* + * TODO(tommyt): crbug.com/505554. Change the |callback| parameter below to + * be of type PaymentInstrument.InstrumentDetailsCallback, once this JNI bug + * has been resolved. + */ + private static native void nativeAbortPaymentApp( + WebContents webContents, long registrationId, Object callback); } diff --git a/chrome/browser/android/payments/service_worker_payment_app_bridge.cc b/chrome/browser/android/payments/service_worker_payment_app_bridge.cc index 50c9860cef46f..d9ff094adaaf4 100644 --- a/chrome/browser/android/payments/service_worker_payment_app_bridge.cc +++ b/chrome/browser/android/payments/service_worker_payment_app_bridge.cc @@ -85,6 +85,15 @@ void OnPaymentAppInvoked( ConvertUTF8ToJavaString(env, handler_response->stringified_details)); } +void OnPaymentAppAborted(const JavaRef& jweb_contents, + const JavaRef& jcallback, + bool result) { + JNIEnv* env = AttachCurrentThread(); + + Java_ServiceWorkerPaymentAppBridge_onPaymentAppAborted(env, jcallback, + result); +} + } // namespace static void GetAllPaymentApps(JNIEnv* env, @@ -202,3 +211,18 @@ static void InvokePaymentApp( ScopedJavaGlobalRef(env, jweb_contents), ScopedJavaGlobalRef(env, jcallback))); } + +static void AbortPaymentApp(JNIEnv* env, + const JavaParamRef& jcaller, + const JavaParamRef& jweb_contents, + jlong registration_id, + const JavaParamRef& jcallback) { + content::WebContents* web_contents = + content::WebContents::FromJavaWebContents(jweb_contents); + + content::PaymentAppProvider::GetInstance()->AbortPayment( + web_contents->GetBrowserContext(), registration_id, + base::BindOnce(&OnPaymentAppAborted, + ScopedJavaGlobalRef(env, jweb_contents), + ScopedJavaGlobalRef(env, jcallback))); +}