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; |
13 import android.os.BadParcelableException; | |
10 import android.os.Bundle; | 14 import android.os.Bundle; |
11 import android.os.Handler; | 15 import android.os.Handler; |
16 import android.os.IBinder; | |
17 import android.os.NetworkOnMainThreadException; | |
18 import android.os.RemoteException; | |
12 import android.util.JsonWriter; | 19 import android.util.JsonWriter; |
13 | 20 |
21 import org.chromium.IsReadyToPayService; | |
22 import org.chromium.IsReadyToPayServiceCallback; | |
14 import org.chromium.chrome.R; | 23 import org.chromium.chrome.R; |
15 import org.chromium.content.browser.ContentViewCore; | 24 import org.chromium.content.browser.ContentViewCore; |
16 import org.chromium.content_public.browser.WebContents; | 25 import org.chromium.content_public.browser.WebContents; |
17 import org.chromium.payments.mojom.PaymentItem; | 26 import org.chromium.payments.mojom.PaymentItem; |
18 import org.chromium.payments.mojom.PaymentMethodData; | 27 import org.chromium.payments.mojom.PaymentMethodData; |
19 import org.chromium.ui.base.WindowAndroid; | 28 import org.chromium.ui.base.WindowAndroid; |
20 | 29 |
21 import java.io.IOException; | 30 import java.io.IOException; |
22 import java.io.StringWriter; | 31 import java.io.StringWriter; |
23 import java.util.ArrayList; | 32 import java.util.ArrayList; |
(...skipping 11 matching lines...) Expand all Loading... | |
35 | 44 |
36 private static final String EXTRA_METHOD_NAME = "methodName"; | 45 private static final String EXTRA_METHOD_NAME = "methodName"; |
37 private static final String EXTRA_DATA = "data"; | 46 private static final String EXTRA_DATA = "data"; |
38 private static final String EXTRA_ORIGIN = "origin"; | 47 private static final String EXTRA_ORIGIN = "origin"; |
39 private static final String EXTRA_DETAILS = "details"; | 48 private static final String EXTRA_DETAILS = "details"; |
40 private static final String EXTRA_INSTRUMENT_DETAILS = "instrumentDetails"; | 49 private static final String EXTRA_INSTRUMENT_DETAILS = "instrumentDetails"; |
41 private static final String EMPTY_JSON_DATA = "{}"; | 50 private static final String EMPTY_JSON_DATA = "{}"; |
42 | 51 |
43 private final Handler mHandler; | 52 private final Handler mHandler; |
44 private final WebContents mWebContents; | 53 private final WebContents mWebContents; |
54 private final Intent mIsReadyToPayIntent; | |
45 private final Intent mPayIntent; | 55 private final Intent mPayIntent; |
46 private final Set<String> mMethodNames; | 56 private final Set<String> mMethodNames; |
47 private String mIsReadyToPayService; | 57 private IsReadyToPayService mIsReadyToPayService; |
58 private InstrumentsCallback mInstrumentsCallback; | |
48 private InstrumentDetailsCallback mInstrumentDetailsCallback; | 59 private InstrumentDetailsCallback mInstrumentDetailsCallback; |
49 | 60 |
61 private final ServiceConnection mServiceConnection = new ServiceConnection() { | |
please use gerrit instead
2017/01/13 20:54:46
Please group all "private final" variables togethe
| |
62 @Override | |
63 public void onServiceConnected(ComponentName name, IBinder service) { | |
64 mIsReadyToPayService = IsReadyToPayService.Stub.asInterface(service) ; | |
65 if (mIsReadyToPayService == null) { | |
66 sendInstrumentsReady(null); | |
67 } else { | |
68 sendIsReadyToPay(); | |
please use gerrit instead
2017/01/13 20:54:46
These send* can get confusing. sendInstrumentsRead
| |
69 } | |
70 } | |
71 | |
72 @Override | |
73 public void onServiceDisconnected(ComponentName name) { | |
74 sendInstrumentsReady(null); | |
75 } | |
76 }; | |
50 /** | 77 /** |
51 * Builds the point of interaction with a locally installed 3rd party native Android payment | 78 * Builds the point of interaction with a locally installed 3rd party native Android payment |
52 * app. | 79 * app. |
53 * | 80 * |
54 * @param webContents The web contents. | 81 * @param webContents The web contents. |
55 * @param packageName The name of the package of the payment app. | 82 * @param packageName The name of the package of the payment app. |
56 * @param activity The name of the payment activity in the payment app. | 83 * @param activity The name of the payment activity in the payment app. |
57 * @param label The UI label to use for the payment app. | 84 * @param label The UI label to use for the payment app. |
58 * @param icon The icon to use in UI for the payment app. | 85 * @param icon The icon to use in UI for the payment app. |
59 */ | 86 */ |
60 public AndroidPaymentApp(WebContents webContents, String packageName, String activity, | 87 public AndroidPaymentApp(WebContents webContents, String packageName, String activity, |
61 String label, Drawable icon) { | 88 String label, Drawable icon) { |
62 super(packageName, label, null, icon); | 89 super(packageName, label, null, icon); |
63 mHandler = new Handler(); | 90 mHandler = new Handler(); |
64 mWebContents = webContents; | 91 mWebContents = webContents; |
65 mPayIntent = new Intent(); | 92 mPayIntent = new Intent(); |
93 mIsReadyToPayIntent = new Intent(); | |
94 mIsReadyToPayIntent.setPackage(packageName); | |
66 mPayIntent.setClassName(packageName, activity); | 95 mPayIntent.setClassName(packageName, activity); |
67 mPayIntent.setAction(ACTION_PAY); | 96 mPayIntent.setAction(ACTION_PAY); |
68 mMethodNames = new HashSet<>(); | 97 mMethodNames = new HashSet<>(); |
69 } | 98 } |
70 | 99 |
71 /** @param methodName A payment method that this app supports, e.g., "https: //bobpay.com". */ | 100 /** @param methodName A payment method that this app supports, e.g., "https: //bobpay.com". */ |
72 public void addMethodName(String methodName) { | 101 public void addMethodName(String methodName) { |
73 mMethodNames.add(methodName); | 102 mMethodNames.add(methodName); |
74 } | 103 } |
75 | 104 |
76 /** @param service The name of the "is ready to pay" service in the payment app. */ | 105 /** @param className The class name of the "is ready to pay" service in the payment app. */ |
77 public void setIsReadyToPayService(String service) { | 106 public void setIsReadyToPayAction(String className) { |
78 mIsReadyToPayService = service; | 107 mIsReadyToPayIntent.setClassName(mIsReadyToPayIntent.getPackage(), class Name); |
79 } | 108 } |
80 | 109 |
81 @Override | 110 @Override |
82 public void getInstruments(Map<String, PaymentMethodData> methodData, String origin, | 111 public void getInstruments(final Map<String, PaymentMethodData> methodData, final String origin, |
please use gerrit instead
2017/01/13 20:54:46
No need for these three "final" keywords, because
| |
83 final InstrumentsCallback callback) { | 112 final InstrumentsCallback callback) { |
84 mHandler.post(new Runnable() { | 113 mInstrumentsCallback = callback; |
85 @Override | 114 if (mIsReadyToPayIntent.getComponent() != null) { |
please use gerrit instead
2017/01/13 20:54:46
When you find an IS_READY_TO_PAY service, you call
| |
86 public void run() { | 115 isReadyToPay(origin, methodData.get(mMethodNames.iterator().next())) ; |
87 List<PaymentInstrument> instruments = new ArrayList<>(); | 116 } else { |
88 instruments.add(AndroidPaymentApp.this); | 117 mHandler.post(new Runnable() { |
89 callback.onInstrumentsReady(AndroidPaymentApp.this, instruments) ; | 118 @Override |
90 } | 119 public void run() { |
91 }); | 120 sendInstrumentsReady(AndroidPaymentApp.this); |
121 } | |
122 }); | |
123 } | |
92 } | 124 } |
93 | 125 |
94 @Override | 126 @Override |
95 public boolean supportsMethodsAndData(Map<String, PaymentMethodData> methods AndData) { | 127 public boolean supportsMethodsAndData(Map<String, PaymentMethodData> methods AndData) { |
96 assert methodsAndData != null; | 128 assert methodsAndData != null; |
97 Set<String> methodNames = new HashSet<>(methodsAndData.keySet()); | 129 Set<String> methodNames = new HashSet<>(methodsAndData.keySet()); |
98 methodNames.retainAll(getAppMethodNames()); | 130 methodNames.retainAll(getAppMethodNames()); |
99 return !methodNames.isEmpty(); | 131 return !methodNames.isEmpty(); |
100 } | 132 } |
101 | 133 |
134 private void sendInstrumentsReady(PaymentInstrument instrument) { | |
135 List<PaymentInstrument> instruments = null; | |
136 if (instrument != null) { | |
137 instruments = new ArrayList<>(); | |
138 instruments.add(instrument); | |
139 } | |
140 mInstrumentsCallback.onInstrumentsReady(this, instruments); | |
141 } | |
142 | |
143 private void isReadyToPay(String origin, PaymentMethodData data) { | |
please use gerrit instead
2017/01/13 20:54:46
You can combine this function with getIntsruments(
| |
144 Bundle extras = new Bundle(); | |
145 extras.putString(EXTRA_METHOD_NAME, mMethodNames.iterator().next()); | |
146 extras.putString(EXTRA_ORIGIN, origin); | |
147 extras.putString(EXTRA_DATA, data == null ? EMPTY_JSON_DATA : data.strin gifiedData); | |
148 mIsReadyToPayIntent.putExtras(extras); | |
149 | |
150 if (mIsReadyToPayService != null) { | |
151 sendIsReadyToPay(); | |
152 } else { | |
153 ContentViewCore contentView = ContentViewCore.fromWebContents(mWebCo ntents); | |
154 if (contentView == null) { | |
155 notifyError(); | |
156 return; | |
157 } | |
158 | |
159 WindowAndroid window = contentView.getWindowAndroid(); | |
160 if (window == null) { | |
161 notifyError(); | |
162 return; | |
163 } | |
164 | |
165 try { | |
166 window.getApplicationContext().bindService( | |
167 mIsReadyToPayIntent, mServiceConnection, Context.BIND_AU TO_CREATE); | |
168 } catch (SecurityException e) { | |
169 sendInstrumentsReady(null); | |
170 } | |
171 } | |
172 } | |
173 | |
174 private void sendIsReadyToPay() { | |
175 assert mIsReadyToPayService != null; | |
176 IsReadyToPayServiceCallback.Stub callback = new IsReadyToPayServiceCallb ack.Stub() { | |
177 @Override | |
178 public void handleIsReadyToPay(boolean isReadyToPay) throws RemoteEx ception { | |
179 if (isReadyToPay) { | |
180 sendInstrumentsReady(AndroidPaymentApp.this); | |
181 } else { | |
182 sendInstrumentsReady(null); | |
183 } | |
184 } | |
185 }; | |
186 try { | |
187 mIsReadyToPayService.isReadyToPay(callback); | |
188 } catch (RemoteException | SecurityException | BadParcelableException | |
189 | IllegalArgumentException | NullPointerException | IllegalState Exception | |
190 | NetworkOnMainThreadException | UnsupportedOperationException e ) { | |
please use gerrit instead
2017/01/13 20:54:46
At this point I think it's OK to use Throwable.
rwlbuis
2017/01/13 22:12:25
Do you mean instead of last two or everyhing? Is t
please use gerrit instead
2017/01/16 17:41:18
Instead of everything. It's to make the code more
rwlbuis
2017/01/17 20:00:35
Done.
| |
191 /** The exceptions above are not caught in the remote Service but pa ssed on to the | |
please use gerrit instead
2017/01/13 20:54:46
"The exceptions above" --> "Many undocumented exce
| |
192 Service caller, see writeException in Parcel.java. */ | |
193 sendInstrumentsReady(null); | |
194 } | |
195 } | |
196 | |
102 @Override | 197 @Override |
103 public String getAppIdentifier() { | 198 public String getAppIdentifier() { |
104 return getIdentifier(); | 199 return getIdentifier(); |
105 } | 200 } |
106 | 201 |
107 @Override | 202 @Override |
108 public Set<String> getAppMethodNames() { | 203 public Set<String> getAppMethodNames() { |
109 return Collections.unmodifiableSet(mMethodNames); | 204 return Collections.unmodifiableSet(mMethodNames); |
110 } | 205 } |
111 | 206 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
217 mInstrumentDetailsCallback.onInstrumentDetailsReady( | 312 mInstrumentDetailsCallback.onInstrumentDetailsReady( |
218 data.getExtras().getString(EXTRA_METHOD_NAME), | 313 data.getExtras().getString(EXTRA_METHOD_NAME), |
219 data.getExtras().getString(EXTRA_INSTRUMENT_DETAILS)); | 314 data.getExtras().getString(EXTRA_INSTRUMENT_DETAILS)); |
220 } | 315 } |
221 mInstrumentDetailsCallback = null; | 316 mInstrumentDetailsCallback = null; |
222 } | 317 } |
223 | 318 |
224 @Override | 319 @Override |
225 public void dismissInstrument() {} | 320 public void dismissInstrument() {} |
226 } | 321 } |
OLD | NEW |