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

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentAppFinder.java

Issue 2793573002: [Payments] Use <meta-data> tag instead of intent filter data to detect supported payment methods. (Closed)
Patch Set: Created 3 years, 8 months 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 unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.payments; 5 package org.chromium.chrome.browser.payments;
6 6
7 import android.content.Intent; 7 import android.content.Intent;
8 import android.content.pm.ResolveInfo; 8 import android.content.pm.ResolveInfo;
9 import android.net.Uri;
10 import android.text.TextUtils; 9 import android.text.TextUtils;
11 10
12 import org.chromium.base.Log; 11 import org.chromium.base.Log;
13 import org.chromium.chrome.browser.ChromeActivity; 12 import org.chromium.chrome.browser.ChromeActivity;
14 import org.chromium.chrome.browser.UrlConstants; 13 import org.chromium.chrome.browser.UrlConstants;
15 import org.chromium.chrome.browser.payments.PaymentAppFactory.PaymentAppCreatedC allback; 14 import org.chromium.chrome.browser.payments.PaymentAppFactory.PaymentAppCreatedC allback;
16 import org.chromium.chrome.browser.payments.PaymentManifestVerifier.ManifestVeri fyCallback; 15 import org.chromium.chrome.browser.payments.PaymentManifestVerifier.ManifestVeri fyCallback;
17 import org.chromium.components.payments.PaymentManifestDownloader; 16 import org.chromium.components.payments.PaymentManifestDownloader;
18 import org.chromium.components.payments.PaymentManifestParser; 17 import org.chromium.components.payments.PaymentManifestParser;
19 import org.chromium.content_public.browser.WebContents; 18 import org.chromium.content_public.browser.WebContents;
(...skipping 14 matching lines...) Expand all
34 * is a URI that starts with "https://". The "basic-card" payment method is an e xception: it's a 33 * is a URI that starts with "https://". The "basic-card" payment method is an e xception: it's a
35 * common payment method that does not have a manifest and can be used by any pa yment app. 34 * common payment method that does not have a manifest and can be used by any pa yment app.
36 */ 35 */
37 public class AndroidPaymentAppFinder implements ManifestVerifyCallback { 36 public class AndroidPaymentAppFinder implements ManifestVerifyCallback {
38 private static final String TAG = "cr_PaymentAppFinder"; 37 private static final String TAG = "cr_PaymentAppFinder";
39 38
40 /** The name of the intent for the service to check whether an app is ready to pay. */ 39 /** The name of the intent for the service to check whether an app is ready to pay. */
41 /* package */ static final String ACTION_IS_READY_TO_PAY = 40 /* package */ static final String ACTION_IS_READY_TO_PAY =
42 "org.chromium.intent.action.IS_READY_TO_PAY"; 41 "org.chromium.intent.action.IS_READY_TO_PAY";
43 42
44 /** The name of the intent for the action of paying using "basic-card" metho d. */
45 /* package */ static final String ACTION_PAY_BASIC_CARD =
46 "org.chromium.intent.action.PAY_BASIC_CARD";
47
48 /** 43 /**
49 * The basic-card payment method name used by merchant and defined by W3C: 44 * The basic-card payment method name used by merchant and defined by W3C:
50 * https://w3c.github.io/webpayments-methods-card/#method-id 45 * https://w3c.github.io/webpayments-methods-card/#method-id
51 */ 46 */
52 /* package */ static final String BASIC_CARD_PAYMENT_METHOD = "basic-card"; 47 /* package */ static final String BASIC_CARD_PAYMENT_METHOD = "basic-card";
53 48
49 /**
50 * Meta data name of an app's supported payment method names.
51 */
52 static final String META_DATA_NAME_OF_PAYMENT_METHOD_NAMES =
53 "org.chromium.payment_method_names";
54
55 /**
56 * Meta data name of an app's supported default payment method name.
57 */
58 static final String META_DATA_NAME_OF_DEFAULT_PAYMENT_METHOD_NAME =
59 "org.chromum.default_payment_method_name";
60
54 /** The maximum number of payment method manifests to download. */ 61 /** The maximum number of payment method manifests to download. */
55 private static final int MAX_NUMBER_OF_MANIFESTS = 10; 62 private static final int MAX_NUMBER_OF_MANIFESTS = 10;
56 63
57 private final WebContents mWebContents; 64 private final WebContents mWebContents;
58 private final boolean mQueryBasicCard; 65 private final boolean mQueryBasicCard;
59 private final Set<URI> mPaymentMethods; 66 private final Set<URI> mPaymentMethods;
60 private final PaymentManifestDownloader mDownloader; 67 private final PaymentManifestDownloader mDownloader;
61 private final PaymentManifestParser mParser; 68 private final PaymentManifestParser mParser;
62 private final PackageManagerDelegate mPackageManagerDelegate; 69 private final PackageManagerDelegate mPackageManagerDelegate;
63 private final PaymentAppCreatedCallback mCallback; 70 private final PaymentAppCreatedCallback mCallback;
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 mPendingApps = new HashMap<>(); 151 mPendingApps = new HashMap<>();
145 mResult = new HashMap<>(); 152 mResult = new HashMap<>();
146 ChromeActivity activity = ChromeActivity.fromWebContents(mWebContents); 153 ChromeActivity activity = ChromeActivity.fromWebContents(mWebContents);
147 mIsIncognito = activity != null && activity.getCurrentTabModel() != null 154 mIsIncognito = activity != null && activity.getCurrentTabModel() != null
148 && activity.getCurrentTabModel().isIncognito(); 155 && activity.getCurrentTabModel().isIncognito();
149 mRequireShowInSettings = requireShowInSettings; 156 mRequireShowInSettings = requireShowInSettings;
150 mSettingsLookup = new Intent(AndroidPaymentApp.ACTION_PAY); 157 mSettingsLookup = new Intent(AndroidPaymentApp.ACTION_PAY);
151 } 158 }
152 159
153 private void findAndroidPaymentApps() { 160 private void findAndroidPaymentApps() {
161 Intent payIntent = new Intent(AndroidPaymentApp.ACTION_PAY);
162 List<ResolveInfo> apps =
163 mPackageManagerDelegate.getActivitiesThatCanRespondToIntent(payI ntent);
164 if (apps.isEmpty()) {
165 onSearchFinished();
166 return;
167 }
168
169 List<String[]> appSupportedMethods = new ArrayList<String[]>();
170 for (int i = 0; i < apps.size(); i++) {
171 appSupportedMethods.add(mPackageManagerDelegate.getStringArrayMetaDa ta(
172 apps.get(i).activityInfo.packageName, META_DATA_NAME_OF_PAYM ENT_METHOD_NAMES));
173 }
174
175 List<String> appSupportedDefaultMethods = new ArrayList<String>();
176 for (int i = 0; i < apps.size(); i++) {
177 appSupportedDefaultMethods.add(
178 mPackageManagerDelegate.getStringMetaData(apps.get(i).activi tyInfo.packageName,
179 META_DATA_NAME_OF_DEFAULT_PAYMENT_METHOD_NAME));
180 }
181
154 List<PaymentManifestVerifier> verifiers = new ArrayList<>(); 182 List<PaymentManifestVerifier> verifiers = new ArrayList<>();
155 if (!mPaymentMethods.isEmpty()) { 183 if (!mPaymentMethods.isEmpty()) {
please use gerrit instead 2017/03/31 15:47:08 This check seems redundant now. Let's remove it.
gogerald1 2017/03/31 16:18:43 Why? mPaymentMethods is merchant queried methods w
please use gerrit instead 2017/03/31 16:26:30 It's redundant because the for loop on the next li
gogerald1 2017/03/31 16:28:54 yes, my bad, updated in the new patch
156 Intent payIntent = new Intent(AndroidPaymentApp.ACTION_PAY);
157 for (URI methodName : mPaymentMethods) { 184 for (URI methodName : mPaymentMethods) {
158 payIntent.setData(Uri.parse(methodName.toString())); 185 List<ResolveInfo> supportedApps = findOutAppsSupportTheGivenPaym entMethod(apps,
159 List<ResolveInfo> apps = 186 appSupportedMethods, appSupportedDefaultMethods, methodN ame.toString());
160 mPackageManagerDelegate.getActivitiesThatCanRespondToInt ent(payIntent); 187 if (supportedApps.isEmpty()) continue;
161 if (apps.isEmpty()) continue;
162 188
163 // Start the parser utility process as soon as possible, once we know that a 189 // Start the parser utility process as soon as possible, once we know that a
164 // manifest file needs to be parsed. The startup can take up to 2 seconds. 190 // manifest file needs to be parsed. The startup can take up to 2 seconds.
165 if (!mParser.isUtilityProcessRunning()) mParser.startUtilityProc ess(); 191 if (!mParser.isUtilityProcessRunning()) mParser.startUtilityProc ess();
166 192
167 verifiers.add(new PaymentManifestVerifier(methodName, apps, mDow nloader, mParser, 193 verifiers.add(new PaymentManifestVerifier(methodName, supportedA pps, mDownloader,
168 mPackageManagerDelegate, this /* callback */)); 194 mParser, mPackageManagerDelegate, this /* callback */));
169 mPendingApps.put(methodName, new HashSet<>(apps)); 195 mPendingApps.put(methodName, new HashSet<>(supportedApps));
196
170 if (verifiers.size() == MAX_NUMBER_OF_MANIFESTS) { 197 if (verifiers.size() == MAX_NUMBER_OF_MANIFESTS) {
171 Log.d(TAG, "Reached maximum number of allowed payment app ma nifests."); 198 Log.d(TAG, "Reached maximum number of allowed payment app ma nifests.");
172 break; 199 break;
173 } 200 }
174 } 201 }
175 } 202 }
176 203
177 if (mQueryBasicCard) { 204 if (mQueryBasicCard) {
178 Intent basicCardPayIntent = new Intent(ACTION_PAY_BASIC_CARD); 205 List<ResolveInfo> supportedApps = findOutAppsSupportTheGivenPaymentM ethod(apps,
179 List<ResolveInfo> apps = 206 appSupportedMethods, appSupportedDefaultMethods, BASIC_CARD_ PAYMENT_METHOD);
180 mPackageManagerDelegate.getActivitiesThatCanRespondToIntent( basicCardPayIntent); 207 for (int i = 0; i < supportedApps.size(); i++) {
181 for (int i = 0; i < apps.size(); i++) {
182 // Chrome does not verify app manifests for "basic-card" support . 208 // Chrome does not verify app manifests for "basic-card" support .
183 onValidPaymentApp(BASIC_CARD_PAYMENT_METHOD, apps.get(i)); 209 onValidPaymentApp(BASIC_CARD_PAYMENT_METHOD, supportedApps.get(i ));
184 } 210 }
185 } 211 }
186 212
187 if (verifiers.isEmpty()) { 213 if (verifiers.isEmpty()) {
188 onSearchFinished(); 214 onSearchFinished();
189 return; 215 return;
190 } 216 }
191 217
192 for (int i = 0; i < verifiers.size(); i++) { 218 for (int i = 0; i < verifiers.size(); i++) {
193 verifiers.get(i).verify(); 219 verifiers.get(i).verify();
194 } 220 }
195 } 221 }
196 222
223 private List<ResolveInfo> findOutAppsSupportTheGivenPaymentMethod(List<Resol veInfo> apps,
please use gerrit instead 2017/03/31 15:47:08 static?
please use gerrit instead 2017/03/31 15:47:08 filterAppsByMethodName().
gogerald1 2017/03/31 16:18:43 Done.
gogerald1 2017/03/31 16:18:43 Done.
224 List<String[]> appsMethods, List<String> appsDefaultMethods, String targetMethodName) {
please use gerrit instead 2017/03/31 15:47:08 Let's pass URI data type in as many places as poss
gogerald1 2017/03/31 16:18:43 Looks not good since this interface is also used f
225 assert apps.size() == appsMethods.size();
226 assert apps.size() == appsDefaultMethods.size();
227
228 // Note that apps, appsMethods and appsDefaultMethods must have the same size. And the
229 // information at the same index must correspond to the same app.
230 List<ResolveInfo> supportedApps = new ArrayList<ResolveInfo>();
231 for (int i = 0; i < apps.size(); i++) {
232 if (targetMethodName.equalsIgnoreCase(appsDefaultMethods.get(i))) {
please use gerrit instead 2017/03/31 15:47:08 Don't ignore case. Let's be strict.
gogerald1 2017/03/31 16:18:43 Done. I am worried that the merchant might use upp
please use gerrit instead 2017/03/31 16:26:30 We prohibit variations in the spec as much as poss
233 supportedApps.add(apps.get(i));
234 continue;
235 }
236
237 String[] methods = appsMethods.get(i);
238 if (methods == null) continue;
239 for (int j = 0; j < methods.length; j++) {
240 if (targetMethodName.equalsIgnoreCase(methods[j])) {
241 supportedApps.add(apps.get(i));
242 break;
243 }
244 }
245 }
246 return supportedApps;
247 }
248
197 @Override 249 @Override
198 public void onValidPaymentApp(URI methodName, ResolveInfo resolveInfo) { 250 public void onValidPaymentApp(URI methodName, ResolveInfo resolveInfo) {
199 onValidPaymentApp(methodName.toString(), resolveInfo); 251 onValidPaymentApp(methodName.toString(), resolveInfo);
200 removePendingApp(methodName, resolveInfo); 252 removePendingApp(methodName, resolveInfo);
201 } 253 }
202 254
203 /** Same as above, but also works for non-URI method names, e.g., "basic-car d". */ 255 /** Same as above, but also works for non-URI method names, e.g., "basic-car d". */
204 private void onValidPaymentApp(String methodName, ResolveInfo resolveInfo) { 256 private void onValidPaymentApp(String methodName, ResolveInfo resolveInfo) {
205 String packageName = resolveInfo.activityInfo.packageName; 257 String packageName = resolveInfo.activityInfo.packageName;
206 AndroidPaymentApp app = mResult.get(packageName); 258 AndroidPaymentApp app = mResult.get(packageName);
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 } 315 }
264 } 316 }
265 317
266 for (Map.Entry<String, AndroidPaymentApp> entry : mResult.entrySet()) { 318 for (Map.Entry<String, AndroidPaymentApp> entry : mResult.entrySet()) {
267 mCallback.onPaymentAppCreated(entry.getValue()); 319 mCallback.onPaymentAppCreated(entry.getValue());
268 } 320 }
269 321
270 mCallback.onAllPaymentAppsCreated(); 322 mCallback.onAllPaymentAppsCreated();
271 } 323 }
272 } 324 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698