Commit 097e31e7 authored by Sahel Sharify's avatar Sahel Sharify Committed by Commit Bot

[Payments][Android] Fix supported_delegation plumbing for native apps.

Without this fix the following warning appears while reading the
supported delegation meta data:
W Bundle  : Key org.chromium.payment_supported_delegations expected
String[] but value was a java.lang.Integer.  The default value <null>
was returned.

The fix is tested with a demo native payment app.

Bug: 1026667
Change-Id: Ifcc372bfb035766b4ea874bba59692cb9999c5d9
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2218752
Commit-Queue: Sahel Sharify <sahel@chromium.org>
Reviewed-by: default avatarRouslan Solomakhin <rouslan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#772712}
parent 97099b53
...@@ -464,14 +464,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback { ...@@ -464,14 +464,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
*/ */
private Set<String> getSupportedPaymentMethods(ActivityInfo activityInfo) { private Set<String> getSupportedPaymentMethods(ActivityInfo activityInfo) {
Set<String> result = new HashSet<>(); Set<String> result = new HashSet<>();
if (activityInfo.metaData == null) return result;
int resId = activityInfo.metaData.getInt(META_DATA_NAME_OF_PAYMENT_METHOD_NAMES);
if (resId == 0) return result;
String[] nonDefaultPaymentMethodNames = String[] nonDefaultPaymentMethodNames =
mPackageManagerDelegate.getStringArrayResourceForApplication( getStringArrayMetaData(activityInfo, META_DATA_NAME_OF_PAYMENT_METHOD_NAMES);
activityInfo.applicationInfo, resId);
if (nonDefaultPaymentMethodNames == null) return result; if (nonDefaultPaymentMethodNames == null) return result;
// Normalize methods that look like URLs in the same way they will be normalized in // Normalize methods that look like URLs in the same way they will be normalized in
...@@ -485,6 +479,23 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback { ...@@ -485,6 +479,23 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
return result; return result;
} }
/**
* Queries the Android app metadata for a string array.
* @param activityInfo The application information to query.
* @param metaDataName The name of the string array meta data to be retrieved.
* @return The string array.
*/
@Nullable
private String[] getStringArrayMetaData(ActivityInfo activityInfo, String metaDataName) {
if (activityInfo.metaData == null) return null;
int resId = activityInfo.metaData.getInt(metaDataName);
if (resId == 0) return null;
return mPackageManagerDelegate.getStringArrayResourceForApplication(
activityInfo.applicationInfo, resId);
}
@Override @Override
public void onValidDefaultPaymentApp(GURL methodName, ResolveInfo resolveInfo) { public void onValidDefaultPaymentApp(GURL methodName, ResolveInfo resolveInfo) {
getOrCreateVerifiedPaymentMethod(methodName).defaultApplications.add(resolveInfo); getOrCreateVerifiedPaymentMethod(methodName).defaultApplications.add(resolveInfo);
...@@ -646,10 +657,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback { ...@@ -646,10 +657,8 @@ public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
} }
private SupportedDelegations getAppsSupportedDelegations(ActivityInfo activityInfo) { private SupportedDelegations getAppsSupportedDelegations(ActivityInfo activityInfo) {
if (activityInfo.metaData == null) return new SupportedDelegations();
String[] supportedDelegationNames = String[] supportedDelegationNames =
activityInfo.metaData.getStringArray(META_DATA_NAME_OF_SUPPORTED_DELEGATIONS); getStringArrayMetaData(activityInfo, META_DATA_NAME_OF_SUPPORTED_DELEGATIONS);
return SupportedDelegations.createFromStringArray(supportedDelegationNames); return SupportedDelegations.createFromStringArray(supportedDelegationNames);
} }
......
...@@ -19,19 +19,22 @@ import androidx.annotation.Nullable; ...@@ -19,19 +19,22 @@ import androidx.annotation.Nullable;
import org.chromium.components.payments.PackageManagerDelegate; import org.chromium.components.payments.PackageManagerDelegate;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
/** Simulates a package manager in memory. */ /** Simulates a package manager in memory. */
class MockPackageManagerDelegate extends PackageManagerDelegate { class MockPackageManagerDelegate extends PackageManagerDelegate {
private static final int STRING_ARRAY_RESOURCE_ID = 1; private static final int PAYMENT_METHOD_NAMES_STRING_ARRAY_RESOURCE_ID = 1;
private static final int SUPPORTED_DELEGATIONS_STRING_ARRAY_RESOURCE_ID = 2;
private static final int RESOURCES_SIZE = 2;
private final List<ResolveInfo> mActivities = new ArrayList<>(); private final List<ResolveInfo> mActivities = new ArrayList<>();
private final Map<String, PackageInfo> mPackages = new HashMap<>(); private final Map<String, PackageInfo> mPackages = new HashMap<>();
private final Map<ResolveInfo, CharSequence> mLabels = new HashMap<>(); private final Map<ResolveInfo, CharSequence> mLabels = new HashMap<>();
private final List<ResolveInfo> mServices = new ArrayList<>(); private final List<ResolveInfo> mServices = new ArrayList<>();
private final Map<ApplicationInfo, String[]> mResources = new HashMap<>(); private final Map<ApplicationInfo, List<String[]>> mResources = new HashMap<>();
/** /**
* Simulates an installed payment app with no supported delegations. * Simulates an installed payment app with no supported delegations.
...@@ -57,9 +60,10 @@ class MockPackageManagerDelegate extends PackageManagerDelegate { ...@@ -57,9 +60,10 @@ class MockPackageManagerDelegate extends PackageManagerDelegate {
* @param label The user visible name of the app. * @param label The user visible name of the app.
* @param packageName The identifying package name. * @param packageName The identifying package name.
* @param defaultPaymentMethodName The name of the default payment method name for this app. If * @param defaultPaymentMethodName The name of the default payment method name for this app. If
* null, then this app will not have metadata. If empty, then the default payment method * empty, then the default payment method name will not be set.
* name will not be set. * @param supportedDelegations The delegations that the app can support. If both
* @param supportedDelegations The delegations that the app can support. * supportedDelegations and defaultPaymentMethodName null, then this app will not have
* metadata.
* @param signature The signature of the app. The SHA256 hash of this signature is called * @param signature The signature of the app. The SHA256 hash of this signature is called
* "fingerprint" and should be present in the app's web app manifest. If null, then this * "fingerprint" and should be present in the app's web app manifest. If null, then this
* app will not have package info. If empty, then this app will not have any signatures. * app will not have package info. If empty, then this app will not have any signatures.
...@@ -79,9 +83,12 @@ class MockPackageManagerDelegate extends PackageManagerDelegate { ...@@ -79,9 +83,12 @@ class MockPackageManagerDelegate extends PackageManagerDelegate {
defaultPaymentMethodName); defaultPaymentMethodName);
} }
if (supportedDelegations != null && supportedDelegations.length > 0) { if (supportedDelegations != null && supportedDelegations.length > 0) {
metaData.putStringArray( metaData.putInt(AndroidPaymentAppFinder.META_DATA_NAME_OF_SUPPORTED_DELEGATIONS,
AndroidPaymentAppFinder.META_DATA_NAME_OF_SUPPORTED_DELEGATIONS, SUPPORTED_DELEGATIONS_STRING_ARRAY_RESOURCE_ID);
supportedDelegations); List<String[]> resources = Arrays.asList(new String[RESOURCES_SIZE][]);
resources.set(
SUPPORTED_DELEGATIONS_STRING_ARRAY_RESOURCE_ID - 1, supportedDelegations);
mResources.put(paymentApp.activityInfo.applicationInfo, resources);
} }
paymentApp.activityInfo.metaData = metaData; paymentApp.activityInfo.metaData = metaData;
} }
...@@ -127,8 +134,16 @@ class MockPackageManagerDelegate extends PackageManagerDelegate { ...@@ -127,8 +134,16 @@ class MockPackageManagerDelegate extends PackageManagerDelegate {
if (paymentApp.activityInfo.packageName.equals(packageName)) { if (paymentApp.activityInfo.packageName.equals(packageName)) {
paymentApp.activityInfo.metaData.putInt( paymentApp.activityInfo.metaData.putInt(
AndroidPaymentAppFinder.META_DATA_NAME_OF_PAYMENT_METHOD_NAMES, AndroidPaymentAppFinder.META_DATA_NAME_OF_PAYMENT_METHOD_NAMES,
STRING_ARRAY_RESOURCE_ID); PAYMENT_METHOD_NAMES_STRING_ARRAY_RESOURCE_ID);
mResources.put(paymentApp.activityInfo.applicationInfo, metadata); List<String[]> resources;
if (mResources.containsKey(paymentApp.activityInfo.applicationInfo)) {
resources = mResources.get(paymentApp.activityInfo.applicationInfo);
mResources.remove(paymentApp.activityInfo.applicationInfo);
} else {
resources = Arrays.asList(new String[RESOURCES_SIZE][]);
}
resources.set(PAYMENT_METHOD_NAMES_STRING_ARRAY_RESOURCE_ID - 1, metadata);
mResources.put(paymentApp.activityInfo.applicationInfo, resources);
return; return;
} }
} }
...@@ -176,7 +191,7 @@ class MockPackageManagerDelegate extends PackageManagerDelegate { ...@@ -176,7 +191,7 @@ class MockPackageManagerDelegate extends PackageManagerDelegate {
@Nullable @Nullable
public String[] getStringArrayResourceForApplication( public String[] getStringArrayResourceForApplication(
ApplicationInfo applicationInfo, int resourceId) { ApplicationInfo applicationInfo, int resourceId) {
assert STRING_ARRAY_RESOURCE_ID == resourceId; assert resourceId > 0 && resourceId <= RESOURCES_SIZE;
return mResources.get(applicationInfo); return mResources.get(applicationInfo).get(resourceId - 1);
} }
} }
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