Commit 78d60d3d authored by rob.buis's avatar rob.buis Committed by Commit bot

Introduce method data map in getInstrument

Payments apps can support multiple methods, and each method can
have associated data, so instead of passing on method associated
data as JSON string, pass a method -> method specific data map.

This CL also renames some methods to make it clear if we are dealing
with the PaymentApp or PaymentInstrument.

BUG=587995

Review-Url: https://codereview.chromium.org/2434333005
Cr-Commit-Position: refs/heads/master@{#427068}
parent 51e9b147
......@@ -18,6 +18,7 @@ import org.chromium.content_public.browser.WebContents;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
......@@ -39,7 +40,8 @@ public class AutofillPaymentApp implements PaymentApp {
}
@Override
public void getInstruments(JSONObject unusedDetails, final InstrumentsCallback callback) {
public void getInstruments(
Map<String, JSONObject> unusedMethodData, final InstrumentsCallback callback) {
PersonalDataManager pdm = PersonalDataManager.getInstance();
List<CreditCard> cards = pdm.getCreditCardsToSuggest();
final List<PaymentInstrument> instruments = new ArrayList<>(cards.size());
......@@ -61,7 +63,7 @@ public class AutofillPaymentApp implements PaymentApp {
}
@Override
public Set<String> getSupportedMethodNames() {
public Set<String> getAppMethodNames() {
// https://w3c.github.io/webpayments-methods-card/#method-id
// The spec also includes more detailed card types, e.g., "visa/credit" and "visa/debit".
// Autofill does not distinguish between these types of cards, so they are not in the list
......@@ -84,7 +86,7 @@ public class AutofillPaymentApp implements PaymentApp {
}
@Override
public String getIdentifier() {
public String getAppIdentifier() {
return "Chrome_Autofill_Payment_App";
}
}
......@@ -34,7 +34,7 @@ public class AutofillPaymentInstrument
private CreditCard mCard;
private boolean mIsComplete;
@Nullable private AutofillProfile mBillingAddress;
@Nullable private DetailsCallback mCallback;
@Nullable private InstrumentDetailsCallback mCallback;
/**
* Builds a payment instrument for the given credit card.
......@@ -59,13 +59,14 @@ public class AutofillPaymentInstrument
}
@Override
public String getMethodName() {
public String getInstrumentMethodName() {
return mCard.getBasicCardPaymentType();
}
@Override
public void getDetails(String unusedMerchantName, String unusedOrigin, PaymentItem unusedTotal,
List<PaymentItem> unusedCart, JSONObject unusedDetails, DetailsCallback callback) {
public void getInstrumentDetails(String unusedMerchantName, String unusedOrigin,
PaymentItem unusedTotal, List<PaymentItem> unusedCart, JSONObject unusedDetails,
InstrumentDetailsCallback callback) {
assert mIsComplete;
assert mCallback == null;
mCallback = callback;
......@@ -132,7 +133,7 @@ public class AutofillPaymentInstrument
}
@Override
public void dismiss() {}
public void dismissInstrument() {}
/** @return Whether the card is complete and ready to be sent to the merchant as-is. */
public boolean isComplete() {
......
......@@ -7,6 +7,7 @@ package org.chromium.chrome.browser.payments;
import org.json.JSONObject;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
......@@ -32,11 +33,12 @@ public interface PaymentApp {
* cards for the current profile. Can return null or empty list, e.g., if user has no locally
* stored credit cards.
*
* @param details The payment-method specific data, e.g., whether the app should be invoked in
* test or production mode, merchant identifier, or a public key.
* @param callback The object that will receive the list of instruments.
* @param methodData The map from methods to method specific data. The data contains such
* information as whether the app should be invoked in test or production
* mode, merchant identifier, or a public key.
* @param callback The object that will receive the list of instruments.
*/
void getInstruments(JSONObject details, InstrumentsCallback callback);
void getInstruments(Map<String, JSONObject> methodData, InstrumentsCallback callback);
/**
* Returns a list of all payment method names that this app supports. For example, ["visa",
......@@ -45,7 +47,7 @@ public interface PaymentApp {
*
* @return The list of all payment method names that this app supports.
*/
Set<String> getSupportedMethodNames();
Set<String> getAppMethodNames();
/**
* Returns the identifier for this payment app to be saved in user preferences. For example,
......@@ -53,5 +55,5 @@ public interface PaymentApp {
*
* @return The identifier for this payment app.
*/
String getIdentifier();
String getAppIdentifier();
}
......@@ -48,6 +48,7 @@ public class PaymentAppFactory {
/**
* Builds instances of payment apps.
*
* @param context The context.
* @param webContents The web contents where PaymentRequest was invoked.
*/
public static List<PaymentApp> create(Context context, WebContents webContents) {
......
......@@ -20,7 +20,7 @@ public abstract class PaymentInstrument extends PaymentOption {
/**
* The interface for the requester of instrument details.
*/
public interface DetailsCallback {
public interface InstrumentDetailsCallback {
/**
* Called after retrieving instrument details.
*
......@@ -40,12 +40,12 @@ public abstract class PaymentInstrument extends PaymentOption {
}
/**
* Returns the method name for this instrument, e.g., "visa" or "mastercard" in basic card
* payments: https://w3c.github.io/browser-payment-api/specs/basic-card-payment.html#method-id
* Returns a method name for this instrument, e.g., "visa" or "mastercard" in basic card
* payments: https://w3c.github.io/webpayments-methods-card/#method-id
*
* @return The method name for this instrument.
* @return The method names for this instrument.
*/
public abstract String getMethodName();
public abstract String getInstrumentMethodName();
/**
* Asynchronously retrieves the instrument details and invokes the callback with the result.
......@@ -58,12 +58,12 @@ public abstract class PaymentInstrument extends PaymentOption {
* in test or production key, a merchant identifier, or a public key.
* @param callback The object that will receive the instrument details.
*/
public abstract void getDetails(String merchantName, String origin, PaymentItem total,
List<PaymentItem> cart, JSONObject details, DetailsCallback callback);
public abstract void getInstrumentDetails(String merchantName, String origin, PaymentItem total,
List<PaymentItem> cart, JSONObject details, InstrumentDetailsCallback callback);
/**
* Cleans up any resources held by the payment instrument. For example, closes server
* connections.
*/
public abstract void dismiss();
public abstract void dismissInstrument();
}
......@@ -69,7 +69,7 @@ import java.util.Set;
* third_party/WebKit/public/platform/modules/payments/payment_request.mojom.
*/
public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Client,
PaymentApp.InstrumentsCallback, PaymentInstrument.DetailsCallback,
PaymentApp.InstrumentsCallback, PaymentInstrument.InstrumentDetailsCallback,
NormalizedAddressRequestDelegate {
/**
* Observer to be notified when PaymentRequest UI has been dismissed.
......@@ -457,28 +457,41 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
mPendingInstruments = new ArrayList<>();
mPendingAutofillInstruments = new ArrayList<>();
Map<PaymentApp, JSONObject> queryApps = new HashMap<>();
Map<PaymentApp, Map<String, JSONObject>> queryApps = new HashMap<>();
for (int i = 0; i < mApps.size(); i++) {
PaymentApp app = mApps.get(i);
Set<String> appMethods = app.getSupportedMethodNames();
appMethods.retainAll(mMethodData.keySet());
if (appMethods.isEmpty()) {
Map<String, JSONObject> appMethods =
filterMerchantMethodData(mMethodData, app.getAppMethodNames());
if (appMethods == null) {
mPendingApps.remove(app);
} else {
mArePaymentMethodsSupported = true;
mMerchantSupportsAutofillPaymentInstruments |= app instanceof AutofillPaymentApp;
queryApps.put(app, mMethodData.get(appMethods.iterator().next()));
queryApps.put(app, appMethods);
}
}
// Query instruments after mMerchantSupportsAutofillPaymentInstruments has been initialized,
// so a fast response from a non-autofill payment app at the front of the app list does not
// cause NOT_SUPPORTED payment rejection.
for (Map.Entry<PaymentApp, JSONObject> q : queryApps.entrySet()) {
for (Map.Entry<PaymentApp, Map<String, JSONObject>> q : queryApps.entrySet()) {
q.getKey().getInstruments(q.getValue(), this);
}
}
/** Filter out merchant method data that's not relevant to a payment app. Can return null. */
private static Map<String, JSONObject> filterMerchantMethodData(
Map<String, JSONObject> merchantMethodData, Set<String> appMethods) {
Map<String, JSONObject> result = null;
for (String method : appMethods) {
if (merchantMethodData.containsKey(method)) {
if (result == null) result = new HashMap<>();
result.put(method, merchantMethodData.get(method));
}
}
return result;
}
/**
* Called by merchant to update the shipping options and line items after the user has selected
* their shipping address or shipping option.
......@@ -880,8 +893,8 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
assert selectedPaymentMethod instanceof PaymentInstrument;
PaymentInstrument instrument = (PaymentInstrument) selectedPaymentMethod;
mPaymentAppRunning = true;
instrument.getDetails(mMerchantName, mOrigin, mRawTotal, mRawLineItems,
mMethodData.get(instrument.getMethodName()), this);
instrument.getInstrumentDetails(mMerchantName, mOrigin, mRawTotal, mRawLineItems,
mMethodData.get(instrument.getInstrumentMethodName()), this);
recordSuccessFunnelHistograms("PayClicked");
return !(instrument instanceof AutofillPaymentInstrument);
}
......@@ -965,10 +978,10 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
if (instruments != null) {
for (int i = 0; i < instruments.size(); i++) {
PaymentInstrument instrument = instruments.get(i);
if (mMethodData.containsKey(instrument.getMethodName())) {
if (mMethodData.containsKey(instrument.getInstrumentMethodName())) {
addPendingInstrument(instrument);
} else {
instrument.dismiss();
instrument.dismissInstrument();
}
}
}
......@@ -1226,7 +1239,7 @@ public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie
for (int i = 0; i < mPaymentMethodsSection.getSize(); i++) {
PaymentOption option = mPaymentMethodsSection.getItem(i);
assert option instanceof PaymentInstrument;
((PaymentInstrument) option).dismiss();
((PaymentInstrument) option).dismissInstrument();
}
mPaymentMethodsSection = null;
}
......
......@@ -40,6 +40,7 @@ import org.chromium.payments.mojom.PaymentItem;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
......@@ -677,7 +678,7 @@ abstract class PaymentRequestTestBase extends ChromeActivityTestCaseBase<ChromeT
@Override
public void getInstruments(
JSONObject details, final InstrumentsCallback instrumentsCallback) {
Map<String, JSONObject> methodData, final InstrumentsCallback instrumentsCallback) {
mCallback = instrumentsCallback;
respond();
}
......@@ -702,14 +703,14 @@ abstract class PaymentRequestTestBase extends ChromeActivityTestCaseBase<ChromeT
}
@Override
public Set<String> getSupportedMethodNames() {
public Set<String> getAppMethodNames() {
Set<String> methodNames = new HashSet<>();
methodNames.add(mMethodName);
return methodNames;
}
@Override
public String getIdentifier() {
public String getAppIdentifier() {
return mMethodName;
}
}
......@@ -724,18 +725,19 @@ abstract class PaymentRequestTestBase extends ChromeActivityTestCaseBase<ChromeT
}
@Override
public String getMethodName() {
public String getInstrumentMethodName() {
return mMethodName;
}
@Override
public void getDetails(String merchantName, String origin, PaymentItem total,
List<PaymentItem> cart, JSONObject details, DetailsCallback detailsCallback) {
public void getInstrumentDetails(String merchantName, String origin, PaymentItem total,
List<PaymentItem> cart, JSONObject details,
InstrumentDetailsCallback detailsCallback) {
detailsCallback.onInstrumentDetailsReady(
mMethodName, "{\"transaction\": 1337}");
}
@Override
public void dismiss() {}
public void dismissInstrument() {}
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment