Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(322)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/payments/AndroidPaymentApp.java

Issue 2507223002: Implement IsReadyToPay handling (Closed)
Patch Set: Add separate exceptions + comment Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698