| OLD | NEW |
| 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.Context; | |
| 8 import android.content.Intent; | 7 import android.content.Intent; |
| 9 import android.content.pm.PackageManager; | |
| 10 import android.content.pm.ResolveInfo; | 8 import android.content.pm.ResolveInfo; |
| 11 import android.graphics.drawable.Drawable; | 9 import android.graphics.drawable.Drawable; |
| 12 import android.net.Uri; | 10 import android.text.TextUtils; |
| 13 import android.util.Pair; | 11 import android.util.Pair; |
| 14 | 12 |
| 15 import org.chromium.base.ContextUtils; | |
| 16 import org.chromium.chrome.browser.ChromeActivity; | |
| 17 import org.chromium.chrome.browser.ChromeFeatureList; | 13 import org.chromium.chrome.browser.ChromeFeatureList; |
| 18 import org.chromium.chrome.browser.UrlConstants; | |
| 19 import org.chromium.chrome.browser.payments.PaymentAppFactory.PaymentAppCreatedC
allback; | 14 import org.chromium.chrome.browser.payments.PaymentAppFactory.PaymentAppCreatedC
allback; |
| 20 import org.chromium.chrome.browser.payments.PaymentAppFactory.PaymentAppFactoryA
ddition; | 15 import org.chromium.chrome.browser.payments.PaymentAppFactory.PaymentAppFactoryA
ddition; |
| 16 import org.chromium.components.payments.PaymentManifestDownloader; |
| 17 import org.chromium.components.payments.PaymentManifestParser; |
| 21 import org.chromium.content_public.browser.WebContents; | 18 import org.chromium.content_public.browser.WebContents; |
| 22 | 19 |
| 23 import java.util.HashMap; | 20 import java.util.HashMap; |
| 24 import java.util.List; | 21 import java.util.List; |
| 25 import java.util.Map; | 22 import java.util.Map; |
| 26 import java.util.Set; | 23 import java.util.Set; |
| 27 | 24 |
| 28 /** Builds instances of payment apps based on installed third party Android paym
ent apps. */ | 25 /** Builds instances of payment apps based on installed third party Android paym
ent apps. */ |
| 29 public class AndroidPaymentAppFactory implements PaymentAppFactoryAddition { | 26 public class AndroidPaymentAppFactory implements PaymentAppFactoryAddition { |
| 30 private static final String ACTION_IS_READY_TO_PAY = | |
| 31 "org.chromium.intent.action.IS_READY_TO_PAY"; | |
| 32 | |
| 33 /** The action name for the Pay Basic-card Intent. */ | |
| 34 private static final String ACTION_PAY_BASIC_CARD = "org.chromium.intent.act
ion.PAY_BASIC_CARD"; | |
| 35 | |
| 36 /** | |
| 37 * The basic-card payment method name used by merchant and defined by W3C: | |
| 38 * https://w3c.github.io/webpayments-methods-card/#method-id | |
| 39 */ | |
| 40 private static final String BASIC_CARD_PAYMENT_METHOD = "basic-card"; | |
| 41 | |
| 42 @Override | 27 @Override |
| 43 public void create(WebContents webContents, Set<String> methods, | 28 public void create( |
| 44 PaymentAppCreatedCallback callback) { | 29 WebContents webContents, Set<String> methods, PaymentAppCreatedCallb
ack callback) { |
| 45 Context context = ChromeActivity.fromWebContents(webContents); | 30 AndroidPaymentAppFinder.find(webContents, methods, |
| 46 if (context == null) { | 31 ChromeFeatureList.isEnabled(ChromeFeatureList.ANDROID_PAYMENT_AP
PS_FILTER), |
| 47 callback.onAllPaymentAppsCreated(); | 32 new PaymentManifestDownloader(webContents), new PaymentManifestP
arser(), |
| 48 return; | 33 new PackageManagerDelegate(), callback); |
| 49 } | |
| 50 | |
| 51 Map<String, AndroidPaymentApp> installedApps = new HashMap<>(); | |
| 52 PackageManager pm = context.getPackageManager(); | |
| 53 Intent payIntent = new Intent(); | |
| 54 | |
| 55 boolean paymentAppsFilterEnabled = | |
| 56 ChromeFeatureList.isEnabled(ChromeFeatureList.ANDROID_PAYMENT_AP
PS_FILTER); | |
| 57 Intent filterIntent = new Intent(AndroidPaymentApp.ACTION_PAY); | |
| 58 | |
| 59 for (String methodName : methods) { | |
| 60 if (methodName.startsWith(UrlConstants.HTTPS_URL_PREFIX)) { | |
| 61 payIntent.setAction(AndroidPaymentApp.ACTION_PAY); | |
| 62 payIntent.setData(Uri.parse(methodName)); | |
| 63 } else if (methodName.equals(BASIC_CARD_PAYMENT_METHOD)) { | |
| 64 payIntent.setAction(ACTION_PAY_BASIC_CARD); | |
| 65 payIntent.setData(null); | |
| 66 } else { | |
| 67 continue; | |
| 68 } | |
| 69 | |
| 70 List<ResolveInfo> matches = pm.queryIntentActivities(payIntent, 0); | |
| 71 for (int i = 0; i < matches.size(); i++) { | |
| 72 ResolveInfo match = matches.get(i); | |
| 73 String packageName = match.activityInfo.packageName; | |
| 74 if (paymentAppsFilterEnabled) { | |
| 75 filterIntent.setPackage(packageName); | |
| 76 if (pm.resolveActivity(filterIntent, 0) == null) continue; | |
| 77 } | |
| 78 // Do not recommend disabled apps. | |
| 79 if (!PaymentPreferencesUtil.isAndroidPaymentAppEnabled(packageNa
me)) continue; | |
| 80 AndroidPaymentApp installedApp = installedApps.get(packageName); | |
| 81 if (installedApp == null) { | |
| 82 CharSequence label = match.loadLabel(pm); | |
| 83 installedApp = | |
| 84 new AndroidPaymentApp(webContents, packageName, matc
h.activityInfo.name, | |
| 85 label == null ? "" : label.toString(), match
.loadIcon(pm)); | |
| 86 callback.onPaymentAppCreated(installedApp); | |
| 87 installedApps.put(packageName, installedApp); | |
| 88 } | |
| 89 installedApp.addMethodName(methodName); | |
| 90 } | |
| 91 } | |
| 92 | |
| 93 List<ResolveInfo> matches = pm.queryIntentServices(new Intent(ACTION_IS_
READY_TO_PAY), 0); | |
| 94 for (int i = 0; i < matches.size(); i++) { | |
| 95 ResolveInfo match = matches.get(i); | |
| 96 String packageName = match.serviceInfo.packageName; | |
| 97 AndroidPaymentApp installedApp = installedApps.get(packageName); | |
| 98 if (installedApp != null) installedApp.setIsReadyToPayAction(match.s
erviceInfo.name); | |
| 99 } | |
| 100 | |
| 101 callback.onAllPaymentAppsCreated(); | |
| 102 } | 34 } |
| 103 | 35 |
| 104 /** | 36 /** |
| 105 * Checks whether there are Android payment apps on device. | 37 * Checks whether there are Android payment apps on device. |
| 106 * | 38 * |
| 107 * @return True if there are Android payment apps on device. | 39 * @return True if there are Android payment apps on device. |
| 108 */ | 40 */ |
| 109 public static boolean hasAndroidPaymentApps() { | 41 public static boolean hasAndroidPaymentApps() { |
| 110 PackageManager pm = ContextUtils.getApplicationContext().getPackageManag
er(); | 42 PackageManagerDelegate packageManagerDelegate = new PackageManagerDelega
te(); |
| 111 // Note that all Android payment apps must support org.chromium.intent.a
ction.PAY action | 43 // Note that all Android payment apps must support org.chromium.intent.a
ction.PAY action |
| 112 // without additional data to be detected. | 44 // without additional data to be detected. |
| 113 Intent payIntent = new Intent(AndroidPaymentApp.ACTION_PAY); | 45 Intent payIntent = new Intent(AndroidPaymentApp.ACTION_PAY); |
| 114 return !pm.queryIntentActivities(payIntent, 0).isEmpty(); | 46 return !packageManagerDelegate.getActivitiesThatCanRespondToIntent(payIn
tent).isEmpty(); |
| 115 } | 47 } |
| 116 | 48 |
| 117 /** | 49 /** |
| 118 * Gets Android payments apps' information on device. | 50 * Gets Android payments apps' information on device. |
| 119 * | 51 * |
| 120 * @return Map of Android payment apps' package names to their information.
Each entry of the | 52 * @return Map of Android payment apps' package names to their information.
Each entry of the |
| 121 * map represents an app and the value stores its name and icon. | 53 * map represents an app and the value stores its name and icon. |
| 122 */ | 54 */ |
| 123 public static Map<String, Pair<String, Drawable>> getAndroidPaymentAppsInfo(
) { | 55 public static Map<String, Pair<String, Drawable>> getAndroidPaymentAppsInfo(
) { |
| 124 Map<String, Pair<String, Drawable>> paymentAppsInfo = new HashMap<>(); | 56 Map<String, Pair<String, Drawable>> paymentAppsInfo = new HashMap<>(); |
| 125 | 57 |
| 126 PackageManager pm = ContextUtils.getApplicationContext().getPackageManag
er(); | 58 PackageManagerDelegate packageManagerDelegate = new PackageManagerDelega
te(); |
| 127 Intent payIntent = new Intent(AndroidPaymentApp.ACTION_PAY); | 59 Intent payIntent = new Intent(AndroidPaymentApp.ACTION_PAY); |
| 128 List<ResolveInfo> matches = pm.queryIntentActivities(payIntent, 0); | 60 List<ResolveInfo> matches = |
| 61 packageManagerDelegate.getActivitiesThatCanRespondToIntent(payIn
tent); |
| 129 if (matches.isEmpty()) return paymentAppsInfo; | 62 if (matches.isEmpty()) return paymentAppsInfo; |
| 130 | 63 |
| 131 for (ResolveInfo match : matches) { | 64 for (ResolveInfo match : matches) { |
| 65 CharSequence label = packageManagerDelegate.getAppLabel(match); |
| 66 if (TextUtils.isEmpty(label)) continue; |
| 132 Pair<String, Drawable> appInfo = | 67 Pair<String, Drawable> appInfo = |
| 133 new Pair<>(match.loadLabel(pm).toString(), match.loadIcon(pm
)); | 68 new Pair<>(label.toString(), packageManagerDelegate.getAppIc
on(match)); |
| 134 paymentAppsInfo.put(match.activityInfo.packageName, appInfo); | 69 paymentAppsInfo.put(match.activityInfo.packageName, appInfo); |
| 135 } | 70 } |
| 136 | 71 |
| 137 return paymentAppsInfo; | 72 return paymentAppsInfo; |
| 138 } | 73 } |
| 139 } | 74 } |
| OLD | NEW |