OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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; | 7 import android.content.Context; |
| 8 import android.content.Intent; |
| 9 import android.content.pm.PackageManager; |
| 10 import android.content.pm.ResolveInfo; |
| 11 import android.net.Uri; |
8 | 12 |
9 import org.chromium.base.VisibleForTesting; | 13 import org.chromium.base.VisibleForTesting; |
| 14 import org.chromium.chrome.browser.ChromeFeatureList; |
| 15 import org.chromium.content.browser.ContentViewCore; |
10 import org.chromium.content_public.browser.WebContents; | 16 import org.chromium.content_public.browser.WebContents; |
| 17 import org.chromium.ui.base.WindowAndroid; |
11 | 18 |
12 import java.util.ArrayList; | 19 import java.util.ArrayList; |
| 20 import java.util.Collection; |
| 21 import java.util.HashMap; |
13 import java.util.List; | 22 import java.util.List; |
| 23 import java.util.Map; |
| 24 import java.util.Set; |
14 | 25 |
15 /** | 26 /** |
16 * Builds instances of payment apps. | 27 * Builds instances of payment apps. |
17 */ | 28 */ |
18 public class PaymentAppFactory { | 29 public class PaymentAppFactory { |
| 30 private static final String PAY_INTENT_ACTION = "org.chromium.intent.action.
PAY"; |
| 31 private static final String IS_READY_TO_PAY_INTENT_ACTION = |
| 32 "org.chromium.intent.action.IS_READY_TO_PAY"; |
| 33 private static final String METHOD_PREFIX = "https://"; |
| 34 |
19 /** | 35 /** |
20 * Can be used to build additional types of payment apps without Chrome know
ing about their | 36 * Can be used to build additional types of payment apps without Chrome know
ing about their |
21 * types. | 37 * types. |
22 */ | 38 */ |
23 private static PaymentAppFactoryAddition sAdditionalFactory; | 39 private static PaymentAppFactoryAddition sAdditionalFactory; |
24 | 40 |
25 /** | 41 /** |
26 * The interface for additional payment app factories. | 42 * The interface for additional payment app factories. |
27 */ | 43 */ |
28 public interface PaymentAppFactoryAddition { | 44 public interface PaymentAppFactoryAddition { |
29 /** | 45 /** |
30 * Builds instances of payment apps. | 46 * Builds instances of payment apps. |
31 * | 47 * |
32 * @param context The application context. | 48 * @param context The application context. |
33 * @param webContents The web contents that invoked PaymentRequest. | 49 * @param webContents The web contents that invoked PaymentRequest. |
34 */ | 50 */ |
35 List<PaymentApp> create(Context context, WebContents webContents); | 51 List<PaymentApp> create(Context context, WebContents webContents); |
36 } | 52 } |
37 | 53 |
38 /** | 54 /** |
| 55 */ |
| 56 public interface PaymentAppsCallback { |
| 57 void onPaymentAppsReady(List<PaymentApp> apps); |
| 58 } |
| 59 |
| 60 /** |
39 * Sets the additional factory that can build instances of payment apps. | 61 * Sets the additional factory that can build instances of payment apps. |
40 * | 62 * |
41 * @param additionalFactory Can build instances of payment apps. | 63 * @param additionalFactory Can build instances of payment apps. |
42 */ | 64 */ |
43 @VisibleForTesting | 65 @VisibleForTesting |
44 public static void setAdditionalFactory(PaymentAppFactoryAddition additional
Factory) { | 66 public static void setAdditionalFactory(PaymentAppFactoryAddition additional
Factory) { |
45 sAdditionalFactory = additionalFactory; | 67 sAdditionalFactory = additionalFactory; |
46 } | 68 } |
47 | 69 |
48 /** | 70 /** |
49 * Builds instances of payment apps. | 71 * Builds instances of payment apps. |
50 * | 72 * |
51 * @param context The context. | 73 * @param context The context. |
52 * @param webContents The web contents where PaymentRequest was invoked. | 74 * @param webContents The web contents where PaymentRequest was invoked. |
| 75 * @param methods The methods that merchant supports. |
| 76 * @param callback The callback to notify of payment apps. |
53 */ | 77 */ |
54 public static List<PaymentApp> create(Context context, WebContents webConten
ts) { | 78 public static void create(Context context, WebContents webContents, |
55 List<PaymentApp> result = new ArrayList<>(2); | 79 Set<String> methods, final PaymentAppsCallback callback) { |
| 80 final List<PaymentApp> result = new ArrayList<>(); |
56 result.add(new AutofillPaymentApp(context, webContents)); | 81 result.add(new AutofillPaymentApp(context, webContents)); |
57 if (sAdditionalFactory != null) { | 82 if (sAdditionalFactory != null) result.addAll( |
58 result.addAll( | 83 sAdditionalFactory.create(context, webContents)); |
59 sAdditionalFactory.create(context, webContents)); | 84 if (ChromeFeatureList.isEnabled(ChromeFeatureList.ANDROID_PAY_INTEGRATIO
N_V1)) { |
| 85 result.addAll(getInstalledApps(context, |
| 86 ContentViewCore.fromWebContents(webContents).getWindowAndroi
d(), methods)); |
60 } | 87 } |
61 return result; | 88 new android.os.Handler().post(new Runnable() { |
| 89 @Override |
| 90 public void run() { |
| 91 callback.onPaymentAppsReady(result); |
| 92 } |
| 93 }); |
| 94 } |
| 95 |
| 96 private static Collection<? extends PaymentApp> getInstalledApps( |
| 97 Context context, WindowAndroid window, Set<String> methods) { |
| 98 // Check cache of payment method specs. |
| 99 |
| 100 Map<String, AndroidPaymentApp> installedApps = new HashMap<>(); |
| 101 PackageManager pm = context.getPackageManager(); |
| 102 Intent payIntent = new Intent(PAY_INTENT_ACTION); |
| 103 for (String methodName : methods) { |
| 104 if (methodName.startsWith(METHOD_PREFIX)) { |
| 105 payIntent.setData(Uri.parse(methodName)); |
| 106 List<ResolveInfo> matches = pm.queryIntentActivities(payIntent,
0); |
| 107 for (int i = 0; i < matches.size(); i++) { |
| 108 ResolveInfo match = matches.get(i); |
| 109 String packageName = match.activityInfo.packageName; |
| 110 AndroidPaymentApp installedApp = installedApps.get(packageNa
me); |
| 111 if (installedApp == null) { |
| 112 CharSequence label = match.loadLabel(pm); |
| 113 installedApp = |
| 114 new AndroidPaymentApp(window, packageName, match
.activityInfo.name, |
| 115 label == null ? "" : label.toString(), m
atch.loadIcon(pm)); |
| 116 installedApps.put(packageName, installedApp); |
| 117 } |
| 118 installedApp.addMethodName(methodName); |
| 119 } |
| 120 } |
| 121 } |
| 122 |
| 123 List<ResolveInfo> matches = |
| 124 pm.queryIntentServices(new Intent(IS_READY_TO_PAY_INTENT_ACTION)
, 0); |
| 125 for (int i = 0; i < matches.size(); i++) { |
| 126 ResolveInfo match = matches.get(i); |
| 127 String packageName = match.serviceInfo.packageName; |
| 128 AndroidPaymentApp installedApp = installedApps.get(packageName); |
| 129 if (installedApp != null) installedApp.setIsReadyToPayAction(match.s
erviceInfo.name); |
| 130 } |
| 131 |
| 132 // Update the cache of payment method specs. |
| 133 |
| 134 return installedApps.values(); |
62 } | 135 } |
63 } | 136 } |
OLD | NEW |