| Index: chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
|
| index 78c296f63daa2a20766aeb7348a3e6b837eb633d..328bb26d15020b5b7a63c7e3cbc5853a86b95ac5 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java
|
| @@ -28,6 +28,7 @@ import org.chromium.base.ThreadUtils;
|
| import org.chromium.chrome.R;
|
| import org.chromium.chrome.browser.ChromeActivity;
|
| import org.chromium.content_public.browser.WebContents;
|
| +import org.chromium.payments.mojom.PaymentCurrencyAmount;
|
| import org.chromium.payments.mojom.PaymentDetailsModifier;
|
| import org.chromium.payments.mojom.PaymentItem;
|
| import org.chromium.payments.mojom.PaymentMethodData;
|
| @@ -44,7 +45,10 @@ import java.util.Set;
|
|
|
| import javax.annotation.Nullable;
|
|
|
| -/** The point of interaction with a locally installed 3rd party native Android payment app. */
|
| +/**
|
| + * The point of interaction with a locally installed 3rd party native Android payment app.
|
| + * https://docs.google.com/document/d/1izV4uC-tiRJG3JLooqY3YRLU22tYOsLTNq0P_InPJeE
|
| + */
|
| public class AndroidPaymentApp
|
| extends PaymentInstrument implements PaymentApp, WindowAndroid.IntentCallback {
|
| /** The action name for the Pay Intent. */
|
| @@ -56,19 +60,34 @@ public class AndroidPaymentApp
|
| /** The maximum number of milliseconds to wait for a connection to READY_TO_PAY service. */
|
| private static final long SERVICE_CONNECTION_TIMEOUT_MS = 1000;
|
|
|
| - private static final String EXTRA_ID = "id";
|
| + // Deprecated parameters sent to the payment app for backward compatibility.
|
| + private static final String EXTRA_DEPRECATED_CERTIFICATE_CHAIN = "certificateChain";
|
| + private static final String EXTRA_DEPRECATED_DATA = "data";
|
| + private static final String EXTRA_DEPRECATED_DATA_MAP = "dataMap";
|
| + private static final String EXTRA_DEPRECATED_DETAILS = "details";
|
| + private static final String EXTRA_DEPRECATED_ID = "id";
|
| + private static final String EXTRA_DEPRECATED_IFRAME_ORIGIN = "iframeOrigin";
|
| + private static final String EXTRA_DEPRECATED_METHOD_NAME = "methodName";
|
| + private static final String EXTRA_DEPRECATED_ORIGIN = "origin";
|
| +
|
| + // Freshest parameters sent to the payment app.
|
| + private static final String EXTRA_CERTIFICATE = "certificate";
|
| private static final String EXTRA_MERCHANT_NAME = "merchantName";
|
| - private static final String EXTRA_METHOD_NAME = "methodName";
|
| + private static final String EXTRA_METHOD_DATA = "methodData";
|
| private static final String EXTRA_METHOD_NAMES = "methodNames";
|
| - private static final String EXTRA_DATA = "data";
|
| - private static final String EXTRA_ORIGIN = "origin";
|
| - private static final String EXTRA_IFRAME_ORIGIN = "iframeOrigin";
|
| - private static final String EXTRA_DATA_MAP = "dataMap";
|
| - private static final String EXTRA_DETAILS = "details";
|
| - private static final String EXTRA_INSTRUMENT_DETAILS = "instrumentDetails";
|
| - private static final String EXTRA_CERTIFICATE_CHAIN = "certificateChain";
|
| - private static final String EXTRA_CERTIFICATE = "certificate";
|
| + private static final String EXTRA_PAYMENT_REQUEST_ID = "paymentRequestId";
|
| + private static final String EXTRA_PAYMENT_REQUEST_ORIGIN = "paymentRequestOrigin";
|
| + private static final String EXTRA_TOP_LEVEL_CERTIFICATE_CHAIN = "topLevelCertificateChain";
|
| + private static final String EXTRA_TOP_LEVEL_ORIGIN = "topLevelOrigin";
|
| + private static final String EXTRA_TOTAL = "total";
|
| +
|
| + // Response from the payment app.
|
| + private static final String EXTRA_DEPRECATED_RESPONSE_INSTRUMENT_DETAILS = "instrumentDetails";
|
| + private static final String EXTRA_RESPONSE_DETAILS = "details";
|
| + private static final String EXTRA_RESPONSE_METHOD_NAME = "methodName";
|
| +
|
| private static final String EMPTY_JSON_DATA = "{}";
|
| +
|
| private final Handler mHandler;
|
| private final WebContents mWebContents;
|
| private final Intent mIsReadyToPayIntent;
|
| @@ -147,8 +166,9 @@ public class AndroidPaymentApp
|
| public void onServiceDisconnected(ComponentName name) {}
|
| };
|
|
|
| - mIsReadyToPayIntent.putExtras(buildExtras(null, null, origin, iframeOrigin,
|
| - certificateChain, methodDataMap, null, null, null));
|
| + mIsReadyToPayIntent.putExtras(buildExtras(null /* id */, null /* merchantName */, origin,
|
| + iframeOrigin, certificateChain, methodDataMap, null /* total */,
|
| + null /* displayItems */, null /* modifiers */));
|
| try {
|
| if (!ContextUtils.getApplicationContext().bindService(
|
| mIsReadyToPayIntent, mServiceConnection, Context.BIND_AUTO_CREATE)) {
|
| @@ -324,35 +344,68 @@ public class AndroidPaymentApp
|
| @Nullable Map<String, PaymentDetailsModifier> modifiers) {
|
| Bundle extras = new Bundle();
|
|
|
| - if (id != null) extras.putString(EXTRA_ID, id);
|
| + if (id != null) extras.putString(EXTRA_PAYMENT_REQUEST_ID, id);
|
| +
|
| if (merchantName != null) extras.putString(EXTRA_MERCHANT_NAME, merchantName);
|
| - extras.putString(EXTRA_ORIGIN, origin);
|
| - extras.putString(EXTRA_IFRAME_ORIGIN, iframeOrigin);
|
|
|
| + extras.putString(EXTRA_TOP_LEVEL_ORIGIN, origin);
|
| +
|
| + extras.putString(EXTRA_PAYMENT_REQUEST_ORIGIN, iframeOrigin);
|
| +
|
| + Parcelable[] serializedCertificateChain = null;
|
| if (certificateChain != null && certificateChain.length > 0) {
|
| + serializedCertificateChain = buildCertificateChain(certificateChain);
|
| extras.putParcelableArray(
|
| - EXTRA_CERTIFICATE_CHAIN, buildCertificateChain(certificateChain));
|
| + EXTRA_TOP_LEVEL_CERTIFICATE_CHAIN, serializedCertificateChain);
|
| }
|
|
|
| - // Deprecated:
|
| - String methodName = methodDataMap.entrySet().iterator().next().getKey();
|
| - extras.putString(EXTRA_METHOD_NAME, methodName);
|
| - PaymentMethodData firstMethodData = methodDataMap.get(methodName);
|
| - extras.putString(EXTRA_DATA,
|
| - firstMethodData == null ? EMPTY_JSON_DATA : firstMethodData.stringifiedData);
|
| -
|
| extras.putStringArrayList(EXTRA_METHOD_NAMES, new ArrayList<>(methodDataMap.keySet()));
|
| +
|
| Bundle methodDataBundle = new Bundle();
|
| for (Map.Entry<String, PaymentMethodData> methodData : methodDataMap.entrySet()) {
|
| methodDataBundle.putString(methodData.getKey(),
|
| methodData.getValue() == null ? EMPTY_JSON_DATA
|
| : methodData.getValue().stringifiedData);
|
| }
|
| - extras.putParcelable(EXTRA_DATA_MAP, methodDataBundle);
|
| + extras.putParcelable(EXTRA_METHOD_DATA, methodDataBundle);
|
| +
|
| + if (total != null) {
|
| + String serializedTotalAmount = serializeTotalAmount(total.amount);
|
| + extras.putString(EXTRA_TOTAL,
|
| + serializedTotalAmount == null ? EMPTY_JSON_DATA : serializedTotalAmount);
|
| + }
|
| +
|
| + return addDeprecatedExtras(id, origin, iframeOrigin, serializedCertificateChain,
|
| + methodDataMap, methodDataBundle, total, displayItems, extras);
|
| + }
|
| +
|
| + private static Bundle addDeprecatedExtras(@Nullable String id, String origin,
|
| + String iframeOrigin, @Nullable Parcelable[] serializedCertificateChain,
|
| + Map<String, PaymentMethodData> methodDataMap, Bundle methodDataBundle,
|
| + @Nullable PaymentItem total, @Nullable List<PaymentItem> displayItems, Bundle extras) {
|
| + if (id != null) extras.putString(EXTRA_DEPRECATED_ID, id);
|
| +
|
| + extras.putString(EXTRA_DEPRECATED_ORIGIN, origin);
|
| +
|
| + extras.putString(EXTRA_DEPRECATED_IFRAME_ORIGIN, iframeOrigin);
|
| +
|
| + if (serializedCertificateChain != null) {
|
| + extras.putParcelableArray(
|
| + EXTRA_DEPRECATED_CERTIFICATE_CHAIN, serializedCertificateChain);
|
| + }
|
| +
|
| + String methodName = methodDataMap.entrySet().iterator().next().getKey();
|
| + extras.putString(EXTRA_DEPRECATED_METHOD_NAME, methodName);
|
| +
|
| + PaymentMethodData firstMethodData = methodDataMap.get(methodName);
|
| + extras.putString(EXTRA_DEPRECATED_DATA,
|
| + firstMethodData == null ? EMPTY_JSON_DATA : firstMethodData.stringifiedData);
|
| +
|
| + extras.putParcelable(EXTRA_DEPRECATED_DATA_MAP, methodDataBundle);
|
|
|
| if (total != null) {
|
| String details = serializeDetails(total, displayItems);
|
| - extras.putString(EXTRA_DETAILS, details == null ? EMPTY_JSON_DATA : details);
|
| + extras.putString(EXTRA_DEPRECATED_DETAILS, details == null ? EMPTY_JSON_DATA : details);
|
| }
|
|
|
| return extras;
|
| @@ -409,6 +462,22 @@ public class AndroidPaymentApp
|
| return stringWriter.toString();
|
| }
|
|
|
| + private static String serializeTotalAmount(PaymentCurrencyAmount totalAmount) {
|
| + StringWriter stringWriter = new StringWriter();
|
| + JsonWriter json = new JsonWriter(stringWriter);
|
| + try {
|
| + // {{{
|
| + json.beginObject();
|
| + json.name("currency").value(totalAmount.currency);
|
| + json.name("value").value(totalAmount.value);
|
| + json.endObject();
|
| + // }}}
|
| + } catch (IOException e) {
|
| + return null;
|
| + }
|
| + return stringWriter.toString();
|
| + }
|
| +
|
| private static void serializePaymentItem(PaymentItem item, JsonWriter json) throws IOException {
|
| // item {{{
|
| json.beginObject();
|
| @@ -432,9 +501,15 @@ public class AndroidPaymentApp
|
| if (data == null || data.getExtras() == null || resultCode != Activity.RESULT_OK) {
|
| mInstrumentDetailsCallback.onInstrumentDetailsError();
|
| } else {
|
| + String details = data.getExtras().getString(EXTRA_RESPONSE_DETAILS);
|
| + if (details == null) {
|
| + details = data.getExtras().getString(EXTRA_DEPRECATED_RESPONSE_INSTRUMENT_DETAILS);
|
| + }
|
| + if (details == null) {
|
| + details = EMPTY_JSON_DATA;
|
| + }
|
| mInstrumentDetailsCallback.onInstrumentDetailsReady(
|
| - data.getExtras().getString(EXTRA_METHOD_NAME),
|
| - data.getExtras().getString(EXTRA_INSTRUMENT_DETAILS));
|
| + data.getExtras().getString(EXTRA_RESPONSE_METHOD_NAME), details);
|
| }
|
| mInstrumentDetailsCallback = null;
|
| }
|
|
|