Chromium Code Reviews| 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 |