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

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

Issue 2516923002: [Merge M-56] Add canMakeActivePayment() method to web payments. (Closed)
Patch Set: Created 4 years, 1 month 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 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 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.graphics.Bitmap; 8 import android.graphics.Bitmap;
9 import android.os.Handler; 9 import android.os.Handler;
10 import android.support.v4.util.ArrayMap;
10 import android.text.TextUtils; 11 import android.text.TextUtils;
11 12
12 import org.chromium.base.Callback; 13 import org.chromium.base.Callback;
13 import org.chromium.base.Log; 14 import org.chromium.base.Log;
14 import org.chromium.base.VisibleForTesting; 15 import org.chromium.base.VisibleForTesting;
15 import org.chromium.base.metrics.RecordHistogram; 16 import org.chromium.base.metrics.RecordHistogram;
16 import org.chromium.chrome.R; 17 import org.chromium.chrome.R;
17 import org.chromium.chrome.browser.ChromeActivity; 18 import org.chromium.chrome.browser.ChromeActivity;
18 import org.chromium.chrome.browser.ChromeFeatureList; 19 import org.chromium.chrome.browser.ChromeFeatureList;
19 import org.chromium.chrome.browser.autofill.PersonalDataManager; 20 import org.chromium.chrome.browser.autofill.PersonalDataManager;
(...skipping 10 matching lines...) Expand all
30 import org.chromium.chrome.browser.tab.Tab; 31 import org.chromium.chrome.browser.tab.Tab;
31 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; 32 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver;
32 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; 33 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver;
33 import org.chromium.chrome.browser.tabmodel.TabModel; 34 import org.chromium.chrome.browser.tabmodel.TabModel;
34 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; 35 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType;
35 import org.chromium.chrome.browser.tabmodel.TabModelObserver; 36 import org.chromium.chrome.browser.tabmodel.TabModelObserver;
36 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; 37 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver;
37 import org.chromium.components.url_formatter.UrlFormatter; 38 import org.chromium.components.url_formatter.UrlFormatter;
38 import org.chromium.content_public.browser.WebContents; 39 import org.chromium.content_public.browser.WebContents;
39 import org.chromium.mojo.system.MojoException; 40 import org.chromium.mojo.system.MojoException;
41 import org.chromium.payments.mojom.ActivePaymentQueryResult;
40 import org.chromium.payments.mojom.PaymentComplete; 42 import org.chromium.payments.mojom.PaymentComplete;
41 import org.chromium.payments.mojom.PaymentDetails; 43 import org.chromium.payments.mojom.PaymentDetails;
42 import org.chromium.payments.mojom.PaymentErrorReason; 44 import org.chromium.payments.mojom.PaymentErrorReason;
43 import org.chromium.payments.mojom.PaymentItem; 45 import org.chromium.payments.mojom.PaymentItem;
44 import org.chromium.payments.mojom.PaymentMethodData; 46 import org.chromium.payments.mojom.PaymentMethodData;
45 import org.chromium.payments.mojom.PaymentOptions; 47 import org.chromium.payments.mojom.PaymentOptions;
46 import org.chromium.payments.mojom.PaymentRequest; 48 import org.chromium.payments.mojom.PaymentRequest;
47 import org.chromium.payments.mojom.PaymentRequestClient; 49 import org.chromium.payments.mojom.PaymentRequestClient;
48 import org.chromium.payments.mojom.PaymentResponse; 50 import org.chromium.payments.mojom.PaymentResponse;
49 import org.chromium.payments.mojom.PaymentShippingOption; 51 import org.chromium.payments.mojom.PaymentShippingOption;
50 import org.chromium.payments.mojom.PaymentShippingType; 52 import org.chromium.payments.mojom.PaymentShippingType;
51 53
52 import java.util.ArrayList; 54 import java.util.ArrayList;
53 import java.util.Arrays; 55 import java.util.Arrays;
54 import java.util.Collections; 56 import java.util.Collections;
55 import java.util.Comparator; 57 import java.util.Comparator;
56 import java.util.HashMap;
57 import java.util.HashSet; 58 import java.util.HashSet;
58 import java.util.List; 59 import java.util.List;
59 import java.util.Locale; 60 import java.util.Locale;
60 import java.util.Map; 61 import java.util.Map;
61 import java.util.Set; 62 import java.util.Set;
62 63
63 /** 64 /**
64 * Android implementation of the PaymentRequest service defined in 65 * Android implementation of the PaymentRequest service defined in
65 * components/payments/payment_request.mojom. 66 * components/payments/payment_request.mojom.
66 */ 67 */
67 public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie nt, 68 public class PaymentRequestImpl implements PaymentRequest, PaymentRequestUI.Clie nt,
68 PaymentApp.InstrumentsCallback, PaymentInstrument.InstrumentDetailsCallb ack, 69 PaymentApp.InstrumentsCallback, PaymentInstrument.InstrumentDetailsCallb ack,
69 PaymentResponseHelper.PaymentResponseRequesterDelegate { 70 PaymentResponseHelper.PaymentResponseRequesterDelegate {
70 /** 71 /**
71 * Observer to be notified when PaymentRequest UI has been dismissed.
72 */
73 public interface PaymentRequestDismissObserver {
74 /**
75 * Called when PaymentRequest UI has been dismissed.
76 */
77 void onPaymentRequestDismissed();
78 }
79
80 /**
81 * A test-only observer for the PaymentRequest service implementation. 72 * A test-only observer for the PaymentRequest service implementation.
82 */ 73 */
83 public interface PaymentRequestServiceObserverForTest { 74 public interface PaymentRequestServiceObserverForTest {
84 /** 75 /**
85 * Called when an abort request was denied. 76 * Called when an abort request was denied.
86 */ 77 */
87 void onPaymentRequestServiceUnableToAbort(); 78 void onPaymentRequestServiceUnableToAbort();
88 79
89 /** 80 /**
90 * Called when the controller is notified of billing address change, but does not alter the 81 * Called when the controller is notified of billing address change, but does not alter the
91 * editor UI. 82 * editor UI.
92 */ 83 */
93 void onPaymentRequestServiceBillingAddressChangeProcessed(); 84 void onPaymentRequestServiceBillingAddressChangeProcessed();
94 85
95 /** 86 /**
96 * Called when the controller is notified of an expiration month change. 87 * Called when the controller is notified of an expiration month change.
97 */ 88 */
98 void onPaymentRequestServiceExpirationMonthChange(); 89 void onPaymentRequestServiceExpirationMonthChange();
99 90
100 /** 91 /**
101 * Called when a show request failed. This can happen when: 92 * Called when a show request failed. This can happen when:
102 * <ul> 93 * <ul>
103 * <li>The merchant requests only unsupported payment methods.</li> 94 * <li>The merchant requests only unsupported payment methods.</li>
104 * <li>The merchant requests only payment methods that don't have inst ruments and are not 95 * <li>The merchant requests only payment methods that don't have inst ruments and are not
105 * able to add instruments from PaymentRequest UI.</li> 96 * able to add instruments from PaymentRequest UI.</li>
106 * </ul> 97 * </ul>
107 */ 98 */
108 void onPaymentRequestServiceShowFailed(); 99 void onPaymentRequestServiceShowFailed();
100
101 /**
102 * Called when the canMakeActivePayment() request has been responded.
103 */
104 void onPaymentRequestServiceActivePaymentQueryResponded();
109 } 105 }
110 106
111 private static final String TAG = "cr_PaymentRequest"; 107 private static final String TAG = "cr_PaymentRequest";
112 private static final String ANDROID_PAY_METHOD_NAME = "https://android.com/p ay"; 108 private static final String ANDROID_PAY_METHOD_NAME = "https://android.com/p ay";
113 private static final int SUGGESTIONS_LIMIT = 4; 109 private static final int SUGGESTIONS_LIMIT = 4;
114 private static final Comparator<Completable> COMPLETENESS_COMPARATOR = 110 private static final Comparator<Completable> COMPLETENESS_COMPARATOR =
115 new Comparator<Completable>() { 111 new Comparator<Completable>() {
116 @Override 112 @Override
117 public int compare(Completable a, Completable b) { 113 public int compare(Completable a, Completable b) {
118 return (b.isComplete() ? 1 : 0) - (a.isComplete() ? 1 : 0); 114 return (b.isComplete() ? 1 : 0) - (a.isComplete() ? 1 : 0);
119 } 115 }
120 }; 116 };
121 117
118 /** Every origin can call canMakeActivePayment() every 30 minutes. */
119 private static final int CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS = 30 * 60 * 1000;
120
122 private static PaymentRequestServiceObserverForTest sObserverForTest; 121 private static PaymentRequestServiceObserverForTest sObserverForTest;
123 122
123 /** True if show() was called in any PaymentRequestImpl object. */
124 private static boolean sIsShowing;
125
126 /**
127 * In-memory mapping of the origins of websites that have recently called ca nMakeActivePayment()
128 * to the list of the payment methods that were been queried. Used for throt tling the usage of
129 * this call. The user can clear the list by restarting the browser.
130 */
131 private static Map<String, Set<String>> sCanMakeActivePaymentQueries;
132
124 /** Monitors changes in the TabModelSelector. */ 133 /** Monitors changes in the TabModelSelector. */
125 private final TabModelSelectorObserver mSelectorObserver = new EmptyTabModel SelectorObserver() { 134 private final TabModelSelectorObserver mSelectorObserver = new EmptyTabModel SelectorObserver() {
126 @Override 135 @Override
127 public void onTabModelSelected(TabModel newModel, TabModel oldModel) { 136 public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
128 onDismiss(); 137 onDismiss();
129 } 138 }
130 }; 139 };
131 140
132 /** Monitors changes in the current TabModel. */ 141 /** Monitors changes in the current TabModel. */
133 private final TabModelObserver mTabModelObserver = new EmptyTabModelObserver () { 142 private final TabModelObserver mTabModelObserver = new EmptyTabModelObserver () {
134 @Override 143 @Override
135 public void didSelectTab(Tab tab, TabSelectionType type, int lastId) { 144 public void didSelectTab(Tab tab, TabSelectionType type, int lastId) {
136 if (tab == null || tab.getId() != lastId) onDismiss(); 145 if (tab == null || tab.getId() != lastId) onDismiss();
137 } 146 }
138 }; 147 };
139 148
140 private final Handler mHandler = new Handler(); 149 private final Handler mHandler = new Handler();
141 private final ChromeActivity mContext; 150 private final ChromeActivity mContext;
142 private final PaymentRequestDismissObserver mDismissObserver;
143 private final String mMerchantName; 151 private final String mMerchantName;
144 private final String mOrigin; 152 private final String mOrigin;
145 private final List<PaymentApp> mApps; 153 private final List<PaymentApp> mApps;
146 private final AddressEditor mAddressEditor; 154 private final AddressEditor mAddressEditor;
147 private final CardEditor mCardEditor; 155 private final CardEditor mCardEditor;
148 private final PaymentRequestJourneyLogger mJourneyLogger = new PaymentReques tJourneyLogger(); 156 private final PaymentRequestJourneyLogger mJourneyLogger = new PaymentReques tJourneyLogger();
149 157
150 private Bitmap mFavicon; 158 private Bitmap mFavicon;
151 private PaymentRequestClient mClient; 159 private PaymentRequestClient mClient;
152 160
(...skipping 27 matching lines...) Expand all
180 private List<PaymentApp> mPendingApps; 188 private List<PaymentApp> mPendingApps;
181 private List<PaymentInstrument> mPendingInstruments; 189 private List<PaymentInstrument> mPendingInstruments;
182 private List<PaymentInstrument> mPendingAutofillInstruments; 190 private List<PaymentInstrument> mPendingAutofillInstruments;
183 private SectionInformation mPaymentMethodsSection; 191 private SectionInformation mPaymentMethodsSection;
184 private PaymentRequestUI mUI; 192 private PaymentRequestUI mUI;
185 private Callback<PaymentInformation> mPaymentInformationCallback; 193 private Callback<PaymentInformation> mPaymentInformationCallback;
186 private boolean mPaymentAppRunning; 194 private boolean mPaymentAppRunning;
187 private boolean mMerchantSupportsAutofillPaymentInstruments; 195 private boolean mMerchantSupportsAutofillPaymentInstruments;
188 private ContactEditor mContactEditor; 196 private ContactEditor mContactEditor;
189 private boolean mHasRecordedAbortReason; 197 private boolean mHasRecordedAbortReason;
198 private boolean mQueriedCanMakeActivePayment;
190 199
191 /** True if any of the requested payment methods are supported. */ 200 /** True if any of the requested payment methods are supported. */
192 private boolean mArePaymentMethodsSupported; 201 private boolean mArePaymentMethodsSupported;
193 202
194 /** True if show() was called. */
195 private boolean mIsShowing;
196
197 /** The helper to create and fill the response to send to the merchant. */ 203 /** The helper to create and fill the response to send to the merchant. */
198 private PaymentResponseHelper mPaymentResponseHelper; 204 private PaymentResponseHelper mPaymentResponseHelper;
199 205
200 /** 206 /**
201 * Builds the PaymentRequest service implementation. 207 * Builds the PaymentRequest service implementation.
202 * 208 *
203 * @param context The context where PaymentRequest has been invoked. 209 * @param context The context where PaymentRequest has been invoked.
204 * @param webContents The web contents that have invoked the PaymentRequ est API. 210 * @param webContents The web contents that have invoked the PaymentRequ est API.
205 * @param dismissObserver The observer to notify when PaymentRequest UI has been dismissed.
206 */ 211 */
207 public PaymentRequestImpl(Activity context, WebContents webContents, 212 public PaymentRequestImpl(Activity context, WebContents webContents) {
208 PaymentRequestDismissObserver dismissObserver) {
209 assert context != null; 213 assert context != null;
210 assert webContents != null; 214 assert webContents != null;
211 assert dismissObserver != null;
212 215
213 assert context instanceof ChromeActivity; 216 assert context instanceof ChromeActivity;
214 mContext = (ChromeActivity) context; 217 mContext = (ChromeActivity) context;
215 218
216 mDismissObserver = dismissObserver;
217 mMerchantName = webContents.getTitle(); 219 mMerchantName = webContents.getTitle();
218 // The feature is available only in secure context, so it's OK to not sh ow HTTPS. 220 // The feature is available only in secure context, so it's OK to not sh ow HTTPS.
219 mOrigin = UrlFormatter.formatUrlForSecurityDisplay(webContents.getVisibl eUrl(), false); 221 mOrigin = UrlFormatter.formatUrlForSecurityDisplay(
222 webContents.getLastCommittedUrl(), false);
220 223
221 final FaviconHelper faviconHelper = new FaviconHelper(); 224 final FaviconHelper faviconHelper = new FaviconHelper();
222 faviconHelper.getLocalFaviconImageForURL(Profile.getLastUsedProfile(), 225 faviconHelper.getLocalFaviconImageForURL(Profile.getLastUsedProfile(),
223 webContents.getVisibleUrl(), 226 webContents.getVisibleUrl(),
224 mContext.getResources().getDimensionPixelSize(R.dimen.payments_f avicon_size), 227 mContext.getResources().getDimensionPixelSize(R.dimen.payments_f avicon_size),
225 new FaviconHelper.FaviconImageCallback() { 228 new FaviconHelper.FaviconImageCallback() {
226 @Override 229 @Override
227 public void onFaviconAvailable(Bitmap bitmap, String iconUrl ) { 230 public void onFaviconAvailable(Bitmap bitmap, String iconUrl ) {
228 faviconHelper.destroy(); 231 faviconHelper.destroy();
229 if (bitmap == null) return; 232 if (bitmap == null) return;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 398
396 PaymentRequestMetrics.recordRequestedInformationHistogram(requestPayerEm ail, 399 PaymentRequestMetrics.recordRequestedInformationHistogram(requestPayerEm ail,
397 requestPayerPhone, requestShipping, requestPayerName); 400 requestPayerPhone, requestShipping, requestPayerName);
398 } 401 }
399 402
400 /** 403 /**
401 * Called by the merchant website to show the payment request to the user. 404 * Called by the merchant website to show the payment request to the user.
402 */ 405 */
403 @Override 406 @Override
404 public void show() { 407 public void show() {
405 if (mClient == null || mIsShowing) return; 408 if (mClient == null) return;
406 409
407 mIsShowing = true; 410 if (getIsShowing()) {
411 disconnectFromClientWithDebugMessage("A PaymentRequest UI is already showing");
412 recordAbortReasonHistogram(
413 PaymentRequestMetrics.ABORT_REASON_INVALID_DATA_FROM_RENDERE R);
414 return;
415 }
416
417 setIsShowing(true);
408 if (disconnectIfNoPaymentMethodsSupported()) return; 418 if (disconnectIfNoPaymentMethodsSupported()) return;
409 419
410 // Catch any time the user switches tabs. Because the dialog is modal, a user shouldn't be 420 // Catch any time the user switches tabs. Because the dialog is modal, a user shouldn't be
411 // allowed to switch tabs, which can happen if the user receives an exte rnal Intent. 421 // allowed to switch tabs, which can happen if the user receives an exte rnal Intent.
412 mContext.getTabModelSelector().addObserver(mSelectorObserver); 422 mContext.getTabModelSelector().addObserver(mSelectorObserver);
413 mContext.getCurrentTabModel().addObserver(mTabModelObserver); 423 mContext.getCurrentTabModel().addObserver(mTabModelObserver);
414 424
415 mUI.show(); 425 mUI.show();
416 recordSuccessFunnelHistograms("Shown"); 426 recordSuccessFunnelHistograms("Shown");
417 } 427 }
418 428
419 private static Map<String, PaymentMethodData> getValidatedMethodData( 429 private static Map<String, PaymentMethodData> getValidatedMethodData(
420 PaymentMethodData[] methodData, CardEditor paymentMethodsCollector) { 430 PaymentMethodData[] methodData, CardEditor paymentMethodsCollector) {
421 // Payment methodData are required. 431 // Payment methodData are required.
422 if (methodData == null || methodData.length == 0) return null; 432 if (methodData == null || methodData.length == 0) return null;
423 Map<String, PaymentMethodData> result = new HashMap<>(); 433 Map<String, PaymentMethodData> result = new ArrayMap<>();
424 for (int i = 0; i < methodData.length; i++) { 434 for (int i = 0; i < methodData.length; i++) {
425 String[] methods = methodData[i].supportedMethods; 435 String[] methods = methodData[i].supportedMethods;
426 436
427 // Payment methods are required. 437 // Payment methods are required.
428 if (methods == null || methods.length == 0) return null; 438 if (methods == null || methods.length == 0) return null;
429 439
430 for (int j = 0; j < methods.length; j++) { 440 for (int j = 0; j < methods.length; j++) {
431 // Payment methods should be non-empty. 441 // Payment methods should be non-empty.
432 if (TextUtils.isEmpty(methods[j])) return null; 442 if (TextUtils.isEmpty(methods[j])) return null;
433 result.put(methods[j], methodData[i]); 443 result.put(methods[j], methodData[i]);
434 } 444 }
435 445
436 paymentMethodsCollector.addAcceptedPaymentMethodsIfRecognized(method s); 446 paymentMethodsCollector.addAcceptedPaymentMethodsIfRecognized(method s);
437 } 447 }
438 return result; 448 return result;
439 } 449 }
440 450
441 /** Queries the installed payment apps for their instruments that merchant s upports. */ 451 /** Queries the installed payment apps for their instruments that merchant s upports. */
442 private void getMatchingPaymentInstruments() { 452 private void getMatchingPaymentInstruments() {
443 mPendingApps = new ArrayList<>(mApps); 453 mPendingApps = new ArrayList<>(mApps);
444 mPendingInstruments = new ArrayList<>(); 454 mPendingInstruments = new ArrayList<>();
445 mPendingAutofillInstruments = new ArrayList<>(); 455 mPendingAutofillInstruments = new ArrayList<>();
446 456
447 Map<PaymentApp, Map<String, PaymentMethodData>> queryApps = new HashMap< >(); 457 Map<PaymentApp, Map<String, PaymentMethodData>> queryApps = new ArrayMap <>();
448 for (int i = 0; i < mApps.size(); i++) { 458 for (int i = 0; i < mApps.size(); i++) {
449 PaymentApp app = mApps.get(i); 459 PaymentApp app = mApps.get(i);
450 Map<String, PaymentMethodData> appMethods = 460 Map<String, PaymentMethodData> appMethods =
451 filterMerchantMethodData(mMethodData, app.getAppMethodNames( )); 461 filterMerchantMethodData(mMethodData, app.getAppMethodNames( ));
452 if (appMethods == null) { 462 if (appMethods == null) {
453 mPendingApps.remove(app); 463 mPendingApps.remove(app);
454 } else { 464 } else {
455 mArePaymentMethodsSupported = true; 465 mArePaymentMethodsSupported = true;
456 mMerchantSupportsAutofillPaymentInstruments |= app instanceof Au tofillPaymentApp; 466 mMerchantSupportsAutofillPaymentInstruments |= app instanceof Au tofillPaymentApp;
457 queryApps.put(app, appMethods); 467 queryApps.put(app, appMethods);
458 } 468 }
459 } 469 }
460 470
461 // Query instruments after mMerchantSupportsAutofillPaymentInstruments h as been initialized, 471 // Query instruments after mMerchantSupportsAutofillPaymentInstruments h as been initialized,
462 // so a fast response from a non-autofill payment app at the front of th e app list does not 472 // so a fast response from a non-autofill payment app at the front of th e app list does not
463 // cause NOT_SUPPORTED payment rejection. 473 // cause NOT_SUPPORTED payment rejection.
464 for (Map.Entry<PaymentApp, Map<String, PaymentMethodData>> q : queryApps .entrySet()) { 474 for (Map.Entry<PaymentApp, Map<String, PaymentMethodData>> q : queryApps .entrySet()) {
465 q.getKey().getInstruments(q.getValue(), this); 475 q.getKey().getInstruments(q.getValue(), this);
466 } 476 }
467 } 477 }
468 478
469 /** Filter out merchant method data that's not relevant to a payment app. Ca n return null. */ 479 /** Filter out merchant method data that's not relevant to a payment app. Ca n return null. */
470 private static Map<String, PaymentMethodData> filterMerchantMethodData( 480 private static Map<String, PaymentMethodData> filterMerchantMethodData(
471 Map<String, PaymentMethodData> merchantMethodData, Set<String> appMe thods) { 481 Map<String, PaymentMethodData> merchantMethodData, Set<String> appMe thods) {
472 Map<String, PaymentMethodData> result = null; 482 Map<String, PaymentMethodData> result = null;
473 for (String method : appMethods) { 483 for (String method : appMethods) {
474 if (merchantMethodData.containsKey(method)) { 484 if (merchantMethodData.containsKey(method)) {
475 if (result == null) result = new HashMap<>(); 485 if (result == null) result = new ArrayMap<>();
476 result.put(method, merchantMethodData.get(method)); 486 result.put(method, merchantMethodData.get(method));
477 } 487 }
478 } 488 }
479 return result; 489 return result;
480 } 490 }
481 491
482 /** 492 /**
483 * Called by merchant to update the shipping options and line items after th e user has selected 493 * Called by merchant to update the shipping options and line items after th e user has selected
484 * their shipping address or shipping option. 494 * their shipping address or shipping option.
485 */ 495 */
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 * Called when the merchant website has processed the payment. 918 * Called when the merchant website has processed the payment.
909 */ 919 */
910 @Override 920 @Override
911 public void complete(int result) { 921 public void complete(int result) {
912 if (mClient == null) return; 922 if (mClient == null) return;
913 recordSuccessFunnelHistograms("Completed"); 923 recordSuccessFunnelHistograms("Completed");
914 closeUI(PaymentComplete.FAIL != result); 924 closeUI(PaymentComplete.FAIL != result);
915 } 925 }
916 926
917 /** 927 /**
928 * Called by the merchant website to check if the user has complete payment instruments.
929 */
930 @Override
931 public void canMakeActivePayment() {
932 if (mClient == null) return;
933
934 if (sCanMakeActivePaymentQueries == null) sCanMakeActivePaymentQueries = new ArrayMap<>();
935
936 if (sCanMakeActivePaymentQueries.containsKey(mOrigin)) {
937 if (!mMethodData.keySet().equals(sCanMakeActivePaymentQueries.get(mO rigin))) {
938 mClient.onCanMakeActivePayment(ActivePaymentQueryResult.QUERY_QU OTA_EXCEEDED);
939 if (sObserverForTest != null) {
940 sObserverForTest.onPaymentRequestServiceActivePaymentQueryRe sponded();
941 }
942 return;
943 }
944 } else {
945 sCanMakeActivePaymentQueries.put(mOrigin, mMethodData.keySet());
946 mHandler.postDelayed(new Runnable() {
947 @Override
948 public void run() {
949 sCanMakeActivePaymentQueries.remove(mOrigin);
950 }
951 }, CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS);
952 }
953
954 if (!mPendingApps.isEmpty() || !mPendingInstruments.isEmpty()) {
955 mQueriedCanMakeActivePayment = true;
956 } else {
957 mClient.onCanMakeActivePayment(mPaymentMethodsSection == null
958 || mPaymentMethodsSection.getSelectedItem() == null
959 ? ActivePaymentQueryResult.CANNOT_MAKE_ACTIVE_PAYMEN T
960 : ActivePaymentQueryResult.CAN_MAKE_ACTIVE_PAYMENT);
961 if (sObserverForTest != null) {
962 sObserverForTest.onPaymentRequestServiceActivePaymentQueryRespon ded();
963 }
964 }
965 }
966
967 /**
918 * Called when the renderer closes the Mojo connection. 968 * Called when the renderer closes the Mojo connection.
919 */ 969 */
920 @Override 970 @Override
921 public void close() { 971 public void close() {
922 if (mClient == null) return; 972 if (mClient == null) return;
923 closeClient(); 973 closeClient();
924 closeUI(true); 974 closeUI(true);
925 recordAbortReasonHistogram(PaymentRequestMetrics.ABORT_REASON_MOJO_RENDE RER_CLOSING); 975 recordAbortReasonHistogram(PaymentRequestMetrics.ABORT_REASON_MOJO_RENDE RER_CLOSING);
926 } 976 }
927 977
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 // Pre-select the first instrument on the list, if it is complete. 1044 // Pre-select the first instrument on the list, if it is complete.
995 int selection = SectionInformation.NO_SELECTION; 1045 int selection = SectionInformation.NO_SELECTION;
996 if (!mPendingInstruments.isEmpty()) { 1046 if (!mPendingInstruments.isEmpty()) {
997 PaymentInstrument first = mPendingInstruments.get(0); 1047 PaymentInstrument first = mPendingInstruments.get(0);
998 if (!(first instanceof AutofillPaymentInstrument) 1048 if (!(first instanceof AutofillPaymentInstrument)
999 || ((AutofillPaymentInstrument) first).isComplete()) { 1049 || ((AutofillPaymentInstrument) first).isComplete()) {
1000 selection = 0; 1050 selection = 0;
1001 } 1051 }
1002 } 1052 }
1003 1053
1054 if (mQueriedCanMakeActivePayment) {
1055 mQueriedCanMakeActivePayment = false;
1056 mClient.onCanMakeActivePayment(selection == 0
1057 ? ActivePaymentQueryResult.CAN_MAKE_ACTIVE_PAYMENT
1058 : ActivePaymentQueryResult.CANNOT_MAKE_ACTIVE_PAYMEN T);
1059 if (sObserverForTest != null) {
1060 sObserverForTest.onPaymentRequestServiceActivePaymentQueryRespon ded();
1061 }
1062 }
1063
1004 // The list of payment instruments is ready to display. 1064 // The list of payment instruments is ready to display.
1005 mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYPE_PA YMENT_METHODS, 1065 mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYPE_PA YMENT_METHODS,
1006 selection, mPendingInstruments); 1066 selection, mPendingInstruments);
1007 1067
1008 mPendingInstruments.clear(); 1068 mPendingInstruments.clear();
1009 1069
1010 // UI has requested the full list of payment instruments. Provide it now . 1070 // UI has requested the full list of payment instruments. Provide it now .
1011 if (mPaymentInformationCallback != null) providePaymentInformation(); 1071 if (mPaymentInformationCallback != null) providePaymentInformation();
1012 } 1072 }
1013 1073
1014 /** 1074 /**
1015 * If no payment methods are supported, disconnect from the client and retur n true. 1075 * If no payment methods are supported, disconnect from the client and retur n true.
1016 * 1076 *
1017 * @return True if no payment methods are supported 1077 * @return True if no payment methods are supported
1018 */ 1078 */
1019 private boolean disconnectIfNoPaymentMethodsSupported() { 1079 private boolean disconnectIfNoPaymentMethodsSupported() {
1020 boolean waitingForPaymentApps = !mPendingApps.isEmpty() || !mPendingInst ruments.isEmpty(); 1080 boolean waitingForPaymentApps = !mPendingApps.isEmpty() || !mPendingInst ruments.isEmpty();
1021 boolean foundPaymentMethods = 1081 boolean foundPaymentMethods =
1022 mPaymentMethodsSection != null && !mPaymentMethodsSection.isEmpt y(); 1082 mPaymentMethodsSection != null && !mPaymentMethodsSection.isEmpt y();
1023 boolean userCanAddCreditCard = mMerchantSupportsAutofillPaymentInstrumen ts 1083 boolean userCanAddCreditCard = mMerchantSupportsAutofillPaymentInstrumen ts
1024 && !ChromeFeatureList.isEnabled(ChromeFeatureList.NO_CREDIT_CARD _ABORT); 1084 && !ChromeFeatureList.isEnabled(ChromeFeatureList.NO_CREDIT_CARD _ABORT);
1025 1085
1026 if (!mArePaymentMethodsSupported 1086 if (!mArePaymentMethodsSupported
1027 || (mIsShowing && !waitingForPaymentApps && !foundPaymentMethods 1087 || (getIsShowing() && !waitingForPaymentApps && !foundPaymentMet hods
1028 && !userCanAddCreditCard)) { 1088 && !userCanAddCreditCard)) {
1029 // All payment apps have responded, but none of them have instrument s. It's possible to 1089 // All payment apps have responded, but none of them have instrument s. It's possible to
1030 // add credit cards, but the merchant does not support them either. The payment request 1090 // add credit cards, but the merchant does not support them either. The payment request
1031 // must be rejected. 1091 // must be rejected.
1032 disconnectFromClientWithDebugMessage("Requested payment methods have no instruments", 1092 disconnectFromClientWithDebugMessage("Requested payment methods have no instruments",
1033 PaymentErrorReason.NOT_SUPPORTED); 1093 PaymentErrorReason.NOT_SUPPORTED);
1034 recordAbortReasonHistogram(mArePaymentMethodsSupported 1094 recordAbortReasonHistogram(mArePaymentMethodsSupported
1035 ? PaymentRequestMetrics.ABORT_REASON_NO_MATCHING_PAY MENT_METHOD 1095 ? PaymentRequestMetrics.ABORT_REASON_NO_MATCHING_PAY MENT_METHOD
1036 : PaymentRequestMetrics.ABORT_REASON_NO_SUPPORTED_PA YMENT_METHOD); 1096 : PaymentRequestMetrics.ABORT_REASON_NO_SUPPORTED_PA YMENT_METHOD);
1037 if (sObserverForTest != null) sObserverForTest.onPaymentRequestServi ceShowFailed(); 1097 if (sObserverForTest != null) sObserverForTest.onPaymentRequestServi ceShowFailed();
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1134 mPaymentMethodsSection = null; 1194 mPaymentMethodsSection = null;
1135 } 1195 }
1136 1196
1137 mContext.getTabModelSelector().removeObserver(mSelectorObserver); 1197 mContext.getTabModelSelector().removeObserver(mSelectorObserver);
1138 mContext.getCurrentTabModel().removeObserver(mTabModelObserver); 1198 mContext.getCurrentTabModel().removeObserver(mTabModelObserver);
1139 } 1199 }
1140 1200
1141 private void closeClient() { 1201 private void closeClient() {
1142 if (mClient != null) mClient.close(); 1202 if (mClient != null) mClient.close();
1143 mClient = null; 1203 mClient = null;
1144 mDismissObserver.onPaymentRequestDismissed(); 1204 setIsShowing(false);
1205 }
1206
1207 private static boolean getIsShowing() {
1208 return sIsShowing;
1209 }
1210
1211 private static void setIsShowing(boolean isShowing) {
1212 sIsShowing = isShowing;
1145 } 1213 }
1146 1214
1147 @VisibleForTesting 1215 @VisibleForTesting
1148 public static void setObserverForTest(PaymentRequestServiceObserverForTest o bserverForTest) { 1216 public static void setObserverForTest(PaymentRequestServiceObserverForTest o bserverForTest) {
1149 sObserverForTest = observerForTest; 1217 sObserverForTest = observerForTest;
1150 } 1218 }
1151 1219
1152 /** 1220 /**
1153 * Records specific histograms related to the different steps of a successfu l checkout. 1221 * Records specific histograms related to the different steps of a successfu l checkout.
1154 */ 1222 */
(...skipping 19 matching lines...) Expand all
1174 "PaymentRequest.CheckoutFunnel.Aborted", abortReason, 1242 "PaymentRequest.CheckoutFunnel.Aborted", abortReason,
1175 PaymentRequestMetrics.ABORT_REASON_MAX); 1243 PaymentRequestMetrics.ABORT_REASON_MAX);
1176 1244
1177 if (abortReason == PaymentRequestMetrics.ABORT_REASON_ABORTED_BY_USER) { 1245 if (abortReason == PaymentRequestMetrics.ABORT_REASON_ABORTED_BY_USER) {
1178 mJourneyLogger.recordJourneyStatsHistograms("UserAborted"); 1246 mJourneyLogger.recordJourneyStatsHistograms("UserAborted");
1179 } else { 1247 } else {
1180 mJourneyLogger.recordJourneyStatsHistograms("OtherAborted"); 1248 mJourneyLogger.recordJourneyStatsHistograms("OtherAborted");
1181 } 1249 }
1182 } 1250 }
1183 } 1251 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698