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 |