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

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

Issue 2507223002: Implement IsReadyToPay handling (Closed)
Patch Set: Rebase 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;
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698