Index: chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java |
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java |
index 50f0757202f797f8b91bccf9094a33d0ea883b29..7a9000f3164c463193fae6b0dc8feb39e73aa5ff 100644 |
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java |
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java |
@@ -33,13 +33,17 @@ import javax.annotation.Nullable; |
/** |
* Finds installed native Android payment apps and verifies their signatures according to the |
- * payment method manifests. The manifests are located based on the payment method name, which |
- * is a URI that starts with "https://". The "basic-card" payment method is an exception: it's a |
- * common payment method that does not have a manifest and can be used by any payment app. |
+ * payment method manifests. The manifests are located based on the payment method name, which is a |
+ * URI that starts with "https://". The W3C-published non-URI payment method names are exceptions: |
+ * these are common payment method names that do not have a manifest and can be used by any payment |
+ * app. |
*/ |
public class AndroidPaymentAppFinder implements ManifestVerifyCallback { |
private static final String TAG = "cr_PaymentAppFinder"; |
+ /** The maximum number of payment method manifests to download. */ |
+ private static final int MAX_NUMBER_OF_MANIFESTS = 10; |
+ |
/** The name of the intent for the service to check whether an app is ready to pay. */ |
/* package */ static final String ACTION_IS_READY_TO_PAY = |
"org.chromium.intent.action.IS_READY_TO_PAY"; |
@@ -53,21 +57,18 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback { |
/** |
* Meta data name of an app's supported payment method names. |
*/ |
- static final String META_DATA_NAME_OF_PAYMENT_METHOD_NAMES = |
+ /* package */ static final String META_DATA_NAME_OF_PAYMENT_METHOD_NAMES = |
"org.chromium.payment_method_names"; |
/** |
* Meta data name of an app's supported default payment method name. |
*/ |
- static final String META_DATA_NAME_OF_DEFAULT_PAYMENT_METHOD_NAME = |
+ /* package */ static final String META_DATA_NAME_OF_DEFAULT_PAYMENT_METHOD_NAME = |
"org.chromium.default_payment_method_name"; |
- /** The maximum number of payment method manifests to download. */ |
- private static final int MAX_NUMBER_OF_MANIFESTS = 10; |
- |
private final WebContents mWebContents; |
- private final boolean mQueryBasicCard; |
- private final Set<URI> mPaymentMethods; |
+ private final Set<String> mNonUriPaymentMethods; |
+ private final Set<URI> mUriPaymentMethods; |
private final PaymentManifestDownloader mDownloader; |
private final PaymentManifestParser mParser; |
private final PackageManagerDelegate mPackageManagerDelegate; |
@@ -77,7 +78,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback { |
/** |
* A map of payment method names to the list of (yet) unverified Android apps that claim to |
* handle these methods. Example payment method names in this data structure: |
- * "https://bobpay.com", "https://android.com/pay". Basic card is excluded. |
+ * "https://bobpay.com", "https://android.com/pay". Items in the supportedNonUriPaymentMethods |
+ * are excluded. |
*/ |
private final Map<URI, Set<ResolveInfo>> mPendingApps; |
@@ -109,25 +111,31 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback { |
PaymentManifestDownloader downloader, PaymentManifestParser parser, |
PackageManagerDelegate packageManagerDelegate, PaymentAppCreatedCallback callback) { |
mWebContents = webContents; |
- mQueryBasicCard = methods.contains(BASIC_CARD_PAYMENT_METHOD); |
- mPaymentMethods = new HashSet<>(); |
- for (String method : methods) { |
- assert !TextUtils.isEmpty(method); |
- if (!method.startsWith(UrlConstants.HTTPS_URL_PREFIX)) continue; |
+ // For non-URI payment method names, only names published by W3C should be supported. |
+ Set<String> supportedNonUriPaymentMethods = new HashSet<>(); |
+ supportedNonUriPaymentMethods.add(BASIC_CARD_PAYMENT_METHOD); |
- URI uri; |
- try { |
- // Don't use java.net.URL, because it performs a synchronous DNS lookup in |
- // the constructor. |
- uri = new URI(method); |
- } catch (URISyntaxException e) { |
- continue; |
- } |
+ mNonUriPaymentMethods = new HashSet<>(); |
+ mUriPaymentMethods = new HashSet<>(); |
+ for (String method : methods) { |
+ assert !TextUtils.isEmpty(method); |
+ if (supportedNonUriPaymentMethods.contains(method)) { |
+ mNonUriPaymentMethods.add(method); |
+ } else if (method.startsWith(UrlConstants.HTTPS_URL_PREFIX)) { |
+ URI uri; |
+ try { |
+ // Don't use java.net.URL, because it performs a synchronous DNS lookup in |
+ // the constructor. |
+ uri = new URI(method); |
+ } catch (URISyntaxException e) { |
+ continue; |
+ } |
- if (uri.isAbsolute()) { |
- assert UrlConstants.HTTPS_SCHEME.equals(uri.getScheme()); |
- mPaymentMethods.add(uri); |
+ if (uri.isAbsolute()) { |
+ assert UrlConstants.HTTPS_SCHEME.equals(uri.getScheme()); |
+ mUriPaymentMethods.add(uri); |
+ } |
} |
} |
@@ -151,29 +159,24 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback { |
return; |
} |
- List<String[]> appSupportedMethods = new ArrayList<String[]>(); |
+ List<Set<String>> appSupportedMethods = new ArrayList<>(); |
for (int i = 0; i < apps.size(); i++) { |
appSupportedMethods.add(getPaymentMethodNames(apps.get(i).activityInfo)); |
} |
- List<String> appSupportedDefaultMethods = new ArrayList<String>(); |
- for (int i = 0; i < apps.size(); i++) { |
- appSupportedDefaultMethods.add(getDefaultPaymentMethodName(apps.get(i).activityInfo)); |
- } |
- |
List<PaymentManifestVerifier> verifiers = new ArrayList<>(); |
- for (URI methodName : mPaymentMethods) { |
- List<ResolveInfo> supportedApps = filterAppsByMethodName( |
- apps, appSupportedMethods, appSupportedDefaultMethods, methodName.toString()); |
+ for (URI uriMethodName : mUriPaymentMethods) { |
+ List<ResolveInfo> supportedApps = |
+ filterAppsByMethodName(apps, appSupportedMethods, uriMethodName.toString()); |
if (supportedApps.isEmpty()) continue; |
// Start the parser utility process as soon as possible, once we know that a |
// manifest file needs to be parsed. The startup can take up to 2 seconds. |
if (!mParser.isUtilityProcessRunning()) mParser.startUtilityProcess(); |
- verifiers.add(new PaymentManifestVerifier(methodName, supportedApps, mDownloader, |
+ verifiers.add(new PaymentManifestVerifier(uriMethodName, supportedApps, mDownloader, |
mParser, mPackageManagerDelegate, this /* callback */)); |
- mPendingApps.put(methodName, new HashSet<>(supportedApps)); |
+ mPendingApps.put(uriMethodName, new HashSet<>(supportedApps)); |
if (verifiers.size() == MAX_NUMBER_OF_MANIFESTS) { |
Log.d(TAG, "Reached maximum number of allowed payment app manifests."); |
@@ -181,12 +184,12 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback { |
} |
} |
- if (mQueryBasicCard) { |
- List<ResolveInfo> supportedApps = filterAppsByMethodName(apps, appSupportedMethods, |
- appSupportedDefaultMethods, BASIC_CARD_PAYMENT_METHOD); |
+ for (String nonUriMethodName : mNonUriPaymentMethods) { |
+ List<ResolveInfo> supportedApps = |
+ filterAppsByMethodName(apps, appSupportedMethods, nonUriMethodName); |
for (int i = 0; i < supportedApps.size(); i++) { |
- // Chrome does not verify app manifests for "basic-card" support. |
- onValidPaymentApp(BASIC_CARD_PAYMENT_METHOD, supportedApps.get(i)); |
+ // Chrome does not verify app manifests for non-URI payment method support. |
+ onValidPaymentApp(nonUriMethodName, supportedApps.get(i)); |
} |
} |
@@ -201,47 +204,43 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback { |
} |
@Nullable |
- private String[] getPaymentMethodNames(ActivityInfo activityInfo) { |
- if (activityInfo.metaData == null) return null; |
+ private Set<String> getPaymentMethodNames(ActivityInfo activityInfo) { |
+ Set<String> result = new HashSet<>(); |
+ if (activityInfo.metaData == null) return result; |
+ |
+ String defaultMethodName = |
+ activityInfo.metaData.getString(META_DATA_NAME_OF_DEFAULT_PAYMENT_METHOD_NAME); |
+ if (!TextUtils.isEmpty(defaultMethodName)) result.add(defaultMethodName); |
int resId = activityInfo.metaData.getInt(META_DATA_NAME_OF_PAYMENT_METHOD_NAMES); |
- if (resId == 0) return null; |
+ if (resId == 0) return result; |
Resources resources = |
mPackageManagerDelegate.getResourcesForApplication(activityInfo.applicationInfo); |
- if (resources == null) return null; |
- return resources.getStringArray(resId); |
- } |
+ if (resources == null) return result; |
- @Nullable |
- private String getDefaultPaymentMethodName(ActivityInfo activityInfo) { |
- if (activityInfo.metaData == null) return null; |
+ String[] methodNames = resources.getStringArray(resId); |
+ if (methodNames == null) return result; |
+ |
+ for (int i = 0; i < methodNames.length; i++) { |
+ result.add(methodNames[i]); |
+ } |
- return activityInfo.metaData.getString(META_DATA_NAME_OF_DEFAULT_PAYMENT_METHOD_NAME); |
+ return result; |
} |
- private static List<ResolveInfo> filterAppsByMethodName(List<ResolveInfo> apps, |
- List<String[]> appsMethods, List<String> appsDefaultMethods, String targetMethodName) { |
- assert apps.size() == appsMethods.size(); |
- assert apps.size() == appsDefaultMethods.size(); |
+ private static List<ResolveInfo> filterAppsByMethodName( |
+ List<ResolveInfo> apps, List<Set<String>> methodNames, String targetMethodName) { |
+ assert apps.size() == methodNames.size(); |
- // Note that apps, appsMethods and appsDefaultMethods must have the same size. And the |
- // information at the same index must correspond to the same app. |
- List<ResolveInfo> supportedApps = new ArrayList<ResolveInfo>(); |
+ // Note that apps and methodNames must have the same size. The information at the same |
+ // index must correspond to the same app. |
+ List<ResolveInfo> supportedApps = new ArrayList<>(); |
for (int i = 0; i < apps.size(); i++) { |
- if (targetMethodName.equals(appsDefaultMethods.get(i))) { |
+ if (methodNames.get(i).contains(targetMethodName)) { |
supportedApps.add(apps.get(i)); |
continue; |
} |
- |
- String[] methods = appsMethods.get(i); |
- if (methods == null) continue; |
- for (int j = 0; j < methods.length; j++) { |
- if (targetMethodName.equals(methods[j])) { |
- supportedApps.add(apps.get(i)); |
- break; |
- } |
- } |
} |
return supportedApps; |
} |