Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3181)

Unified Diff: chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java

Issue 2467393002: Add canMakeActivePayment() method to web payments. (Closed)
Patch Set: ArrayMap and rebase Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/android/java/src/org/chromium/chrome/browser/payments/PaymentRequestImpl.java
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 5069a737c5cfe6cd6329fad4052970fb026eb6e7..089092dea65180e8f3b95373cba1757b1a64f8b4 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
@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.payments;
import android.app.Activity;
import android.graphics.Bitmap;
import android.os.Handler;
+import android.support.v4.util.ArrayMap;
import android.text.TextUtils;
import org.json.JSONException;
@@ -41,6 +42,7 @@ import org.chromium.components.safejson.JsonSanitizer;
import org.chromium.components.url_formatter.UrlFormatter;
import org.chromium.content_public.browser.WebContents;
import org.chromium.mojo.system.MojoException;
+import org.chromium.payments.mojom.ActivePaymentQueryResult;
import org.chromium.payments.mojom.PaymentComplete;
import org.chromium.payments.mojom.PaymentDetails;
import org.chromium.payments.mojom.PaymentErrorReason;
@@ -58,7 +60,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
-import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
@@ -73,9 +74,14 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
PaymentApp.InstrumentsCallback, PaymentInstrument.InstrumentDetailsCallback,
PaymentResponseHelper.PaymentResponseRequesterDelegate {
/**
- * Observer to be notified when PaymentRequest UI has been dismissed.
+ * Observer to be notified when PaymentRequest UI has been displayed or dismissed.
*/
- public interface PaymentRequestDismissObserver {
+ public interface PaymentRequestDisplayObserver {
+ /**
+ * Called when PaymentRequest UI has been displayed.
+ */
+ void onPaymentRequestDisplayed();
+
/**
* Called when PaymentRequest UI has been dismissed.
*/
@@ -111,6 +117,11 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
* </ul>
*/
void onPaymentRequestServiceShowFailed();
+
+ /**
+ * Called when the canMakeActivePayment() request has been responded.
+ */
+ void onPaymentRequestServiceActivePaymentQueryResponded();
}
private static final String TAG = "cr_PaymentRequest";
@@ -124,8 +135,18 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
}
};
+ /** Every origin can call canMakeActivePayment() every 30 minutes. */
+ private static final int CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS = 30 * 60 * 1000;
+
private static PaymentRequestServiceObserverForTest sObserverForTest;
+ /**
+ * In-memory mapping of the origins of websites that have recently called canMakeActivePayment()
+ * to the list of the payment methods that were been queried. Used for throttling the usage of
+ * this call. The user can clear the list by restarting the browser.
+ */
+ private static Map<String, Set<String>> sCanMakeActivePaymentQueries;
+
/** Monitors changes in the TabModelSelector. */
private final TabModelSelectorObserver mSelectorObserver = new EmptyTabModelSelectorObserver() {
@Override
@@ -144,7 +165,7 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
private final Handler mHandler = new Handler();
private final ChromeActivity mContext;
- private final PaymentRequestDismissObserver mDismissObserver;
+ private final PaymentRequestDisplayObserver mDisplayObserver;
private final String mMerchantName;
private final String mOrigin;
private final List<PaymentApp> mApps;
@@ -192,6 +213,7 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
private boolean mMerchantSupportsAutofillPaymentInstruments;
private ContactEditor mContactEditor;
private boolean mHasRecordedAbortReason;
+ private boolean mQueriedCanMakeActivePayment;
/** True if any of the requested payment methods are supported. */
private boolean mArePaymentMethodsSupported;
@@ -207,18 +229,19 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
*
* @param context The context where PaymentRequest has been invoked.
* @param webContents The web contents that have invoked the PaymentRequest API.
- * @param dismissObserver The observer to notify when PaymentRequest UI has been dismissed.
+ * @param displayObserver The observer to notify when PaymentRequest UI has been displayed or
+ * dismissed.
*/
public PaymentRequestImpl(Activity context, WebContents webContents,
- PaymentRequestDismissObserver dismissObserver) {
+ PaymentRequestDisplayObserver displayObserver) {
assert context != null;
assert webContents != null;
- assert dismissObserver != null;
+ assert displayObserver != null;
assert context instanceof ChromeActivity;
mContext = (ChromeActivity) context;
- mDismissObserver = dismissObserver;
+ mDisplayObserver = displayObserver;
mMerchantName = webContents.getTitle();
// The feature is available only in secure context, so it's OK to not show HTTPS.
mOrigin = UrlFormatter.formatUrlForSecurityDisplay(webContents.getVisibleUrl(), false);
@@ -419,13 +442,15 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
mUI.show();
recordSuccessFunnelHistograms("Shown");
+
+ mDisplayObserver.onPaymentRequestDisplayed();
}
private static Map<String, JSONObject> getValidatedMethodData(
PaymentMethodData[] methodData, CardEditor paymentMethodsCollector) {
// Payment methodData are required.
if (methodData == null || methodData.length == 0) return null;
- Map<String, JSONObject> result = new HashMap<>();
+ Map<String, JSONObject> result = new ArrayMap<>();
for (int i = 0; i < methodData.length; i++) {
JSONObject data = null;
if (!TextUtils.isEmpty(methodData[i].stringifiedData)) {
@@ -464,7 +489,7 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
mPendingInstruments = new ArrayList<>();
mPendingAutofillInstruments = new ArrayList<>();
- Map<PaymentApp, Map<String, JSONObject>> queryApps = new HashMap<>();
+ Map<PaymentApp, Map<String, JSONObject>> queryApps = new ArrayMap<>();
for (int i = 0; i < mApps.size(); i++) {
PaymentApp app = mApps.get(i);
Map<String, JSONObject> appMethods =
@@ -492,7 +517,7 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
Map<String, JSONObject> result = null;
for (String method : appMethods) {
if (merchantMethodData.containsKey(method)) {
- if (result == null) result = new HashMap<>();
+ if (result == null) result = new ArrayMap<>();
result.put(method, merchantMethodData.get(method));
}
}
@@ -907,6 +932,47 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
}
/**
+ * Called by the merchant website to check if the user has complete payment instruments.
+ */
+ @Override
+ public void canMakeActivePayment() {
+ if (mClient == null) return;
+
+ if (sCanMakeActivePaymentQueries == null) sCanMakeActivePaymentQueries = new ArrayMap<>();
+
+ if (sCanMakeActivePaymentQueries.containsKey(mOrigin)) {
+ if (!mMethodData.keySet().equals(sCanMakeActivePaymentQueries.get(mOrigin))) {
+ mClient.onCanMakeActivePayment(ActivePaymentQueryResult.QUERY_QUOTA_EXCEEDED);
+ if (sObserverForTest != null) {
+ sObserverForTest.onPaymentRequestServiceActivePaymentQueryResponded();
+ }
+ return;
+ }
+ } else {
+ sCanMakeActivePaymentQueries.put(mOrigin, mMethodData.keySet());
+ }
+
+ mHandler.postDelayed(new Runnable() {
Ian Wen 2016/11/10 23:50:15 I think we should move the postDelayed() to the el
please use gerrit instead 2016/11/11 22:22:25 Done.
+ @Override
+ public void run() {
+ sCanMakeActivePaymentQueries.remove(mOrigin);
+ }
+ }, CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS);
+
+ if (!mPendingApps.isEmpty() || !mPendingInstruments.isEmpty()) {
+ mQueriedCanMakeActivePayment = true;
+ } else {
+ mClient.onCanMakeActivePayment(mPaymentMethodsSection == null
+ || mPaymentMethodsSection.getSelectedItem() == null
+ ? ActivePaymentQueryResult.CANNOT_MAKE_ACTIVE_PAYMENT
+ : ActivePaymentQueryResult.CAN_MAKE_ACTIVE_PAYMENT);
+ if (sObserverForTest != null) {
+ sObserverForTest.onPaymentRequestServiceActivePaymentQueryResponded();
+ }
+ }
+ }
+
+ /**
* Called when the renderer closes the Mojo connection.
*/
@Override
@@ -993,6 +1059,16 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
}
}
+ if (mQueriedCanMakeActivePayment) {
+ mQueriedCanMakeActivePayment = false;
+ mClient.onCanMakeActivePayment(selection == 0
+ ? ActivePaymentQueryResult.CAN_MAKE_ACTIVE_PAYMENT
+ : ActivePaymentQueryResult.CANNOT_MAKE_ACTIVE_PAYMENT);
+ if (sObserverForTest != null) {
+ sObserverForTest.onPaymentRequestServiceActivePaymentQueryResponded();
+ }
+ }
+
// The list of payment instruments is ready to display.
mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYPE_PAYMENT_METHODS,
selection, mPendingInstruments);
@@ -1133,7 +1209,7 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
private void closeClient() {
if (mClient != null) mClient.close();
mClient = null;
- mDismissObserver.onPaymentRequestDismissed();
+ mDisplayObserver.onPaymentRequestDismissed();
}
@VisibleForTesting

Powered by Google App Engine
This is Rietveld 408576698