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.app.Activity; | 7 import android.app.Activity; |
8 import android.content.ComponentName; | |
9 import android.content.Context; | |
8 import android.content.Intent; | 10 import android.content.Intent; |
11 import android.content.ServiceConnection; | |
9 import android.graphics.drawable.Drawable; | 12 import android.graphics.drawable.Drawable; |
10 import android.os.Bundle; | 13 import android.os.Bundle; |
11 import android.os.Handler; | 14 import android.os.Handler; |
15 import android.os.IBinder; | |
16 import android.os.RemoteException; | |
12 import android.util.JsonWriter; | 17 import android.util.JsonWriter; |
13 | 18 |
19 import org.chromium.IsReadyToPayService; | |
20 import org.chromium.IsReadyToPayServiceCallback; | |
14 import org.chromium.chrome.R; | 21 import org.chromium.chrome.R; |
15 import org.chromium.content.browser.ContentViewCore; | 22 import org.chromium.content.browser.ContentViewCore; |
16 import org.chromium.content_public.browser.WebContents; | 23 import org.chromium.content_public.browser.WebContents; |
24 | |
please use gerrit instead
2017/01/09 19:02:14
No need for newline here.
rwlbuis
2017/01/10 16:40:00
Done.
| |
17 import org.chromium.payments.mojom.PaymentItem; | 25 import org.chromium.payments.mojom.PaymentItem; |
18 import org.chromium.payments.mojom.PaymentMethodData; | 26 import org.chromium.payments.mojom.PaymentMethodData; |
19 import org.chromium.ui.base.WindowAndroid; | 27 import org.chromium.ui.base.WindowAndroid; |
20 | 28 |
21 import java.io.IOException; | 29 import java.io.IOException; |
22 import java.io.StringWriter; | 30 import java.io.StringWriter; |
23 import java.util.ArrayList; | 31 import java.util.ArrayList; |
24 import java.util.Collections; | 32 import java.util.Collections; |
25 import java.util.HashSet; | 33 import java.util.HashSet; |
26 import java.util.List; | 34 import java.util.List; |
27 import java.util.Map; | 35 import java.util.Map; |
28 import java.util.Set; | 36 import java.util.Set; |
29 | 37 |
30 /** The point of interaction with a locally installed 3rd party native Android p ayment app. */ | 38 /** The point of interaction with a locally installed 3rd party native Android p ayment app. */ |
31 public class AndroidPaymentApp extends PaymentInstrument implements PaymentApp, | 39 public class AndroidPaymentApp extends PaymentInstrument implements PaymentApp, |
32 WindowAndroid.IntentCallback { | 40 WindowAndroid.IntentCallback { |
33 private static final String EXTRA_METHOD_NAME = "methodName"; | 41 private static final String EXTRA_METHOD_NAME = "methodName"; |
34 private static final String EXTRA_DATA = "data"; | 42 private static final String EXTRA_DATA = "data"; |
35 private static final String EXTRA_ORIGIN = "origin"; | 43 private static final String EXTRA_ORIGIN = "origin"; |
36 private static final String EXTRA_DETAILS = "details"; | 44 private static final String EXTRA_DETAILS = "details"; |
37 private static final String EXTRA_INSTRUMENT_DETAILS = "instrumentDetails"; | 45 private static final String EXTRA_INSTRUMENT_DETAILS = "instrumentDetails"; |
46 private static final String READY_TO_PAY = "readyToPay"; | |
please use gerrit instead
2017/01/09 19:02:14
Unused.
rwlbuis
2017/01/10 16:40:00
Done.
| |
38 private static final String EMPTY_JSON_DATA = "{}"; | 47 private static final String EMPTY_JSON_DATA = "{}"; |
39 | 48 |
40 private final Handler mHandler; | 49 private final Handler mHandler; |
41 private final WebContents mWebContents; | 50 private final WebContents mWebContents; |
51 private final Intent mIsReadyToPayIntent; | |
42 private final Intent mPayIntent; | 52 private final Intent mPayIntent; |
43 private final Set<String> mMethodNames; | 53 private final Set<String> mMethodNames; |
44 private String mIsReadyToPayService; | 54 private IsReadyToPayService mIsReadyToPayService; |
55 private InstrumentsCallback mInstrumentsCallback; | |
45 private InstrumentDetailsCallback mInstrumentDetailsCallback; | 56 private InstrumentDetailsCallback mInstrumentDetailsCallback; |
46 | 57 |
47 /** | 58 /** |
48 * Builds the point of interaction with a locally installed 3rd party native Android payment | 59 * Builds the point of interaction with a locally installed 3rd party native Android payment |
49 * app. | 60 * app. |
50 * | 61 * |
51 * @param webContents The web contents. | 62 * @param webContents The web contents. |
52 * @param packageName The name of the package of the payment app. | 63 * @param packageName The name of the package of the payment app. |
53 * @param activity The name of the payment activity in the payment app. | 64 * @param activity The name of the payment activity in the payment app. |
54 * @param label The UI label to use for the payment app. | 65 * @param label The UI label to use for the payment app. |
55 * @param icon The icon to use in UI for the payment app. | 66 * @param icon The icon to use in UI for the payment app. |
56 */ | 67 */ |
57 public AndroidPaymentApp(WebContents webContents, String packageName, String activity, | 68 public AndroidPaymentApp(WebContents webContents, String packageName, String activity, |
58 String label, Drawable icon) { | 69 String label, Drawable icon) { |
59 super(packageName, label, null, icon); | 70 super(packageName, label, null, icon); |
60 mHandler = new Handler(); | 71 mHandler = new Handler(); |
61 mWebContents = webContents; | 72 mWebContents = webContents; |
62 mPayIntent = new Intent(); | 73 mPayIntent = new Intent(); |
74 mIsReadyToPayIntent = new Intent(); | |
75 mIsReadyToPayIntent.setPackage(packageName); | |
63 mPayIntent.setClassName(packageName, activity); | 76 mPayIntent.setClassName(packageName, activity); |
64 mMethodNames = new HashSet<>(); | 77 mMethodNames = new HashSet<>(); |
65 } | 78 } |
66 | 79 |
67 /** @param methodName A payment method that this app supports, e.g., "https: //bobpay.com". */ | 80 /** @param methodName A payment method that this app supports, e.g., "https: //bobpay.com". */ |
68 public void addMethodName(String methodName) { | 81 public void addMethodName(String methodName) { |
69 mMethodNames.add(methodName); | 82 mMethodNames.add(methodName); |
70 } | 83 } |
71 | 84 |
72 /** @param service The name of the "is ready to pay" service in the payment app. */ | 85 /** @param service The name of the "is ready to pay" service in the payment app. */ |
please use gerrit instead
2017/01/09 19:02:14
Update JavaDoc.
rwlbuis
2017/01/10 16:40:00
Done.
| |
73 public void setIsReadyToPayService(String service) { | 86 public void setIsReadyToPayAction(String className) { |
74 mIsReadyToPayService = service; | 87 mIsReadyToPayIntent.setClassName(mIsReadyToPayIntent.getPackage(), class Name); |
75 } | 88 } |
76 | 89 |
77 @Override | 90 @Override |
78 public void getInstruments(Map<String, PaymentMethodData> methodData, String origin, | 91 public void getInstruments(final Map<String, PaymentMethodData> methodData, final String origin, |
79 final InstrumentsCallback callback) { | 92 final InstrumentsCallback callback) { |
93 mInstrumentsCallback = callback; | |
80 mHandler.post(new Runnable() { | 94 mHandler.post(new Runnable() { |
please use gerrit instead
2017/01/09 19:02:14
Use the handler only to make sendInstrumentsReady(
rwlbuis
2017/01/10 16:40:00
Done.
please use gerrit instead
2017/01/10 16:49:22
You seem to have forgotten to update the code.
rwlbuis
2017/01/10 19:31:05
Oops! Done.
| |
81 @Override | 95 @Override |
82 public void run() { | 96 public void run() { |
83 List<PaymentInstrument> instruments = new ArrayList<>(); | 97 if (mIsReadyToPayIntent.getComponent() != null) { |
84 instruments.add(AndroidPaymentApp.this); | 98 isReadyToPay(origin, methodData.get(mMethodNames.iterator(). next())); |
85 callback.onInstrumentsReady(AndroidPaymentApp.this, instruments) ; | 99 } else { |
100 sendInstrumentsReady(AndroidPaymentApp.this); | |
101 } | |
86 } | 102 } |
87 }); | 103 }); |
88 } | 104 } |
89 | 105 |
90 @Override | 106 @Override |
91 public boolean supportsMethodsAndData(Map<String, PaymentMethodData> methods AndData) { | 107 public boolean supportsMethodsAndData(Map<String, PaymentMethodData> methods AndData) { |
92 assert methodsAndData != null; | 108 assert methodsAndData != null; |
93 Set<String> methodNames = new HashSet<>(methodsAndData.keySet()); | 109 Set<String> methodNames = new HashSet<>(methodsAndData.keySet()); |
94 methodNames.retainAll(getAppMethodNames()); | 110 methodNames.retainAll(getAppMethodNames()); |
95 return !methodNames.isEmpty(); | 111 return !methodNames.isEmpty(); |
96 } | 112 } |
97 | 113 |
114 private void sendInstrumentsReady(PaymentInstrument instrument) { | |
115 List<PaymentInstrument> instruments = null; | |
116 if (instrument != null) { | |
117 instruments = new ArrayList<>(); | |
118 instruments.add(instrument); | |
119 } | |
120 mInstrumentsCallback.onInstrumentsReady(AndroidPaymentApp.this, instrume nts); | |
please use gerrit instead
2017/01/09 19:02:14
|this| is sufficient here, because you're not in a
rwlbuis
2017/01/10 16:40:00
Done.
| |
121 } | |
122 | |
123 private void isReadyToPay(String origin, PaymentMethodData data) { | |
124 Bundle extras = new Bundle(); | |
125 extras.putString(EXTRA_METHOD_NAME, mMethodNames.iterator().next()); | |
126 extras.putString(EXTRA_ORIGIN, origin); | |
127 extras.putString(EXTRA_DATA, data == null ? EMPTY_JSON_DATA : data.strin gifiedData); | |
128 mIsReadyToPayIntent.putExtras(extras); | |
129 | |
130 if (mIsReadyToPayService != null) { | |
131 sendIsReadyToPay(); | |
132 } else { | |
133 try { | |
134 ContentViewCore contentView = ContentViewCore.fromWebContents(mW ebContents); | |
135 if (contentView == null) { | |
136 notifyError(); | |
137 return; | |
138 } | |
139 | |
140 WindowAndroid window = contentView.getWindowAndroid(); | |
141 if (window == null) { | |
142 notifyError(); | |
143 return; | |
144 } | |
145 | |
146 window.getApplicationContext().bindService( | |
147 mIsReadyToPayIntent, mServiceConnection, Context.BIND_AU TO_CREATE); | |
148 } catch (SecurityException e) { | |
please use gerrit instead
2017/01/09 19:02:14
Only bindService() can throw a SecurityException.
rwlbuis
2017/01/10 16:40:00
Done.
| |
149 sendInstrumentsReady(null); | |
150 } | |
151 } | |
152 } | |
153 | |
154 private final ServiceConnection mServiceConnection = new ServiceConnection() { | |
please use gerrit instead
2017/01/09 19:02:14
Variables should be above methods.
rwlbuis
2017/01/10 16:40:00
Done.
| |
155 @Override | |
156 public void onServiceConnected(ComponentName name, IBinder service) { | |
157 mIsReadyToPayService = IsReadyToPayService.Stub.asInterface(service) ; | |
158 if (mIsReadyToPayService == null) { | |
159 sendInstrumentsReady(null); | |
160 } else { | |
161 sendIsReadyToPay(); | |
162 } | |
163 } | |
164 | |
165 @Override | |
166 public void onServiceDisconnected(ComponentName name) { | |
167 sendInstrumentsReady(null); | |
168 } | |
169 }; | |
170 private void sendIsReadyToPay() { | |
171 assert mIsReadyToPayService != null; | |
172 final IsReadyToPayServiceCallback.Stub callback = new IsReadyToPayServic eCallback.Stub() { | |
please use gerrit instead
2017/01/09 19:02:14
The "final" keyword seems unnecessary.
rwlbuis
2017/01/10 16:40:00
Done.
| |
173 @Override | |
174 public void handleIsReadyToPay(boolean isReadyToPay) throws RemoteEx ception { | |
175 if (isReadyToPay) { | |
176 sendInstrumentsReady(AndroidPaymentApp.this); | |
177 } else { | |
178 sendInstrumentsReady(null); | |
179 } | |
180 } | |
181 }; | |
182 try { | |
183 mIsReadyToPayService.isReadyToPay(callback); | |
184 } catch (Exception e) { | |
please use gerrit instead
2017/01/09 19:02:14
We prefer explicit exception types.
rwlbuis
2017/01/10 16:40:00
This is actually an important part of this patch.
please use gerrit instead
2017/01/10 16:49:22
Please make sure in your patch that the payment ap
rwlbuis
2017/01/10 19:31:05
For reference I found a description of the excepti
| |
185 sendInstrumentsReady(null); | |
186 } | |
187 } | |
188 | |
98 @Override | 189 @Override |
99 public String getAppIdentifier() { | 190 public String getAppIdentifier() { |
100 return getIdentifier(); | 191 return getIdentifier(); |
101 } | 192 } |
102 | 193 |
103 @Override | 194 @Override |
104 public Set<String> getAppMethodNames() { | 195 public Set<String> getAppMethodNames() { |
105 return Collections.unmodifiableSet(mMethodNames); | 196 return Collections.unmodifiableSet(mMethodNames); |
106 } | 197 } |
107 | 198 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
213 mInstrumentDetailsCallback.onInstrumentDetailsReady( | 304 mInstrumentDetailsCallback.onInstrumentDetailsReady( |
214 data.getExtras().getString(EXTRA_METHOD_NAME), | 305 data.getExtras().getString(EXTRA_METHOD_NAME), |
215 data.getExtras().getString(EXTRA_INSTRUMENT_DETAILS)); | 306 data.getExtras().getString(EXTRA_INSTRUMENT_DETAILS)); |
216 } | 307 } |
217 mInstrumentDetailsCallback = null; | 308 mInstrumentDetailsCallback = null; |
218 } | 309 } |
219 | 310 |
220 @Override | 311 @Override |
221 public void dismissInstrument() {} | 312 public void dismissInstrument() {} |
222 } | 313 } |
OLD | NEW |