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

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

Issue 2524613004: [Merge M-56] Return cached query result for canMakeActivePayment. (Closed)
Patch Set: Created 4 years 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.support.v4.util.ArrayMap;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 * </ul> 97 * </ul>
98 */ 98 */
99 void onPaymentRequestServiceShowFailed(); 99 void onPaymentRequestServiceShowFailed();
100 100
101 /** 101 /**
102 * Called when the canMakeActivePayment() request has been responded. 102 * Called when the canMakeActivePayment() request has been responded.
103 */ 103 */
104 void onPaymentRequestServiceActivePaymentQueryResponded(); 104 void onPaymentRequestServiceActivePaymentQueryResponded();
105 } 105 }
106 106
107 /** The object to keep track of cached payment query results. */
108 private static class ActivePaymentQuery {
109 private final Set<PaymentRequestImpl> mObservers = new HashSet<>();
110 private final Set<String> mMethods;
111 private Boolean mResponse;
112
113 /**
114 * Keeps track of an active payment query.
115 *
116 * @param methods The payment methods that are being queried.
117 */
118 public ActivePaymentQuery(Set<String> methods) {
119 assert methods != null;
120 mMethods = methods;
121 }
122
123 /**
124 * Checks whether the given payment methods matches the previously queri ed payment methods.
125 *
126 * @param methods The payment methods that are being queried.
127 * @return True if the given methods match the previously queried paymen t methods.
128 */
129 public boolean matchesPaymentMethods(Set<String> methods) {
130 return mMethods.equals(methods);
131 }
132
133 /** @return Whether active payment can be made, or null if response is n ot known yet. */
134 public Boolean getPreviousResponse() {
135 return mResponse;
136 }
137
138 /** @param response Whether active payment can be made. */
139 public void setResponse(boolean response) {
140 if (mResponse == null) mResponse = response;
141 for (PaymentRequestImpl observer : mObservers) {
142 observer.respondActivePaymentQuery(mResponse.booleanValue());
143 }
144 mObservers.clear();
145 }
146
147 /** @param observer The observer to notify when the query response is kn own. */
148 public void addObserver(PaymentRequestImpl observer) {
149 mObservers.add(observer);
150 }
151 };
152
107 private static final String TAG = "cr_PaymentRequest"; 153 private static final String TAG = "cr_PaymentRequest";
108 private static final String ANDROID_PAY_METHOD_NAME = "https://android.com/p ay"; 154 private static final String ANDROID_PAY_METHOD_NAME = "https://android.com/p ay";
109 private static final int SUGGESTIONS_LIMIT = 4; 155 private static final int SUGGESTIONS_LIMIT = 4;
110 private static final Comparator<Completable> COMPLETENESS_COMPARATOR = 156 private static final Comparator<Completable> COMPLETENESS_COMPARATOR =
111 new Comparator<Completable>() { 157 new Comparator<Completable>() {
112 @Override 158 @Override
113 public int compare(Completable a, Completable b) { 159 public int compare(Completable a, Completable b) {
114 return (b.isComplete() ? 1 : 0) - (a.isComplete() ? 1 : 0); 160 return (b.isComplete() ? 1 : 0) - (a.isComplete() ? 1 : 0);
115 } 161 }
116 }; 162 };
117 163
118 /** Every origin can call canMakeActivePayment() every 30 minutes. */ 164 /** Every origin can call canMakeActivePayment() every 30 minutes. */
119 private static final int CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS = 30 * 60 * 1000; 165 private static final int CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS = 30 * 60 * 1000;
120 166
121 private static PaymentRequestServiceObserverForTest sObserverForTest; 167 private static PaymentRequestServiceObserverForTest sObserverForTest;
122 168
123 /** True if show() was called in any PaymentRequestImpl object. */ 169 /** True if show() was called in any PaymentRequestImpl object. */
124 private static boolean sIsShowing; 170 private static boolean sIsShowing;
125 171
126 /** 172 /**
127 * In-memory mapping of the origins of websites that have recently called ca nMakeActivePayment() 173 * 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 174 * 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. 175 * this call. The mapping is shared among all instances of PaymentRequestImp l in the browser
176 * process on UI thread. The user can reset the throttling mechanism by rest arting the browser.
130 */ 177 */
131 private static Map<String, Set<String>> sCanMakeActivePaymentQueries; 178 private static Map<String, ActivePaymentQuery> sCanMakeActivePaymentQueries;
132 179
133 /** Monitors changes in the TabModelSelector. */ 180 /** Monitors changes in the TabModelSelector. */
134 private final TabModelSelectorObserver mSelectorObserver = new EmptyTabModel SelectorObserver() { 181 private final TabModelSelectorObserver mSelectorObserver = new EmptyTabModel SelectorObserver() {
135 @Override 182 @Override
136 public void onTabModelSelected(TabModel newModel, TabModel oldModel) { 183 public void onTabModelSelected(TabModel newModel, TabModel oldModel) {
137 onDismiss(); 184 onDismiss();
138 } 185 }
139 }; 186 };
140 187
141 /** Monitors changes in the current TabModel. */ 188 /** Monitors changes in the current TabModel. */
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
236 } 283 }
237 mUI.setTitleBitmap(bitmap); 284 mUI.setTitleBitmap(bitmap);
238 } 285 }
239 }); 286 });
240 287
241 mApps = PaymentAppFactory.create(mContext, webContents); 288 mApps = PaymentAppFactory.create(mContext, webContents);
242 289
243 mAddressEditor = new AddressEditor(); 290 mAddressEditor = new AddressEditor();
244 mCardEditor = new CardEditor(webContents, mAddressEditor, sObserverForTe st); 291 mCardEditor = new CardEditor(webContents, mAddressEditor, sObserverForTe st);
245 292
293 if (sCanMakeActivePaymentQueries == null) sCanMakeActivePaymentQueries = new ArrayMap<>();
294
246 recordSuccessFunnelHistograms("Initiated"); 295 recordSuccessFunnelHistograms("Initiated");
247 } 296 }
248 297
249 /** 298 /**
250 * Called by the merchant website to initialize the payment request data. 299 * Called by the merchant website to initialize the payment request data.
251 */ 300 */
252 @Override 301 @Override
253 public void init(PaymentRequestClient client, PaymentMethodData[] methodData , 302 public void init(PaymentRequestClient client, PaymentMethodData[] methodData ,
254 PaymentDetails details, PaymentOptions options) { 303 PaymentDetails details, PaymentOptions options) {
255 if (mClient != null || client == null) return; 304 if (mClient != null || client == null) return;
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after
924 closeUI(PaymentComplete.FAIL != result); 973 closeUI(PaymentComplete.FAIL != result);
925 } 974 }
926 975
927 /** 976 /**
928 * Called by the merchant website to check if the user has complete payment instruments. 977 * Called by the merchant website to check if the user has complete payment instruments.
929 */ 978 */
930 @Override 979 @Override
931 public void canMakeActivePayment() { 980 public void canMakeActivePayment() {
932 if (mClient == null) return; 981 if (mClient == null) return;
933 982
934 if (sCanMakeActivePaymentQueries == null) sCanMakeActivePaymentQueries = new ArrayMap<>(); 983 ActivePaymentQuery query = sCanMakeActivePaymentQueries.get(mOrigin);
935 984 if (query == null) {
936 if (sCanMakeActivePaymentQueries.containsKey(mOrigin)) { 985 query = new ActivePaymentQuery(mMethodData.keySet());
937 if (!mMethodData.keySet().equals(sCanMakeActivePaymentQueries.get(mO rigin))) { 986 sCanMakeActivePaymentQueries.put(mOrigin, query);
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() { 987 mHandler.postDelayed(new Runnable() {
947 @Override 988 @Override
948 public void run() { 989 public void run() {
949 sCanMakeActivePaymentQueries.remove(mOrigin); 990 sCanMakeActivePaymentQueries.remove(mOrigin);
950 } 991 }
951 }, CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS); 992 }, CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS);
952 } 993 }
953 994
954 if (!mPendingApps.isEmpty() || !mPendingInstruments.isEmpty()) { 995 if (!query.matchesPaymentMethods(mMethodData.keySet())) {
955 mQueriedCanMakeActivePayment = true; 996 mClient.onCanMakeActivePayment(ActivePaymentQueryResult.QUERY_QUOTA_ EXCEEDED);
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) { 997 if (sObserverForTest != null) {
962 sObserverForTest.onPaymentRequestServiceActivePaymentQueryRespon ded(); 998 sObserverForTest.onPaymentRequestServiceActivePaymentQueryRespon ded();
963 } 999 }
1000 return;
1001 }
1002
1003 if (query.getPreviousResponse() != null) {
1004 respondActivePaymentQuery(query.getPreviousResponse().booleanValue() );
1005 return;
1006 }
1007
1008 query.addObserver(this);
1009 if (mPendingApps.isEmpty() && mPendingInstruments.isEmpty()) {
1010 query.setResponse(mPaymentMethodsSection != null
1011 && mPaymentMethodsSection.getSelectedItem() != null);
964 } 1012 }
965 } 1013 }
966 1014
1015 private void respondActivePaymentQuery(boolean response) {
1016 mClient.onCanMakeActivePayment(response
1017 ? ActivePaymentQueryResult.CAN_MAKE_ACTIVE_PAYMENT
1018 : ActivePaymentQueryResult.CANNOT_MAKE_ACTIVE_PAYMENT);
1019 if (sObserverForTest != null) {
1020 sObserverForTest.onPaymentRequestServiceActivePaymentQueryResponded( );
1021 }
1022 }
1023
967 /** 1024 /**
968 * Called when the renderer closes the Mojo connection. 1025 * Called when the renderer closes the Mojo connection.
969 */ 1026 */
970 @Override 1027 @Override
971 public void close() { 1028 public void close() {
972 if (mClient == null) return; 1029 if (mClient == null) return;
973 closeClient(); 1030 closeClient();
974 closeUI(true); 1031 closeUI(true);
975 recordAbortReasonHistogram(PaymentRequestMetrics.ABORT_REASON_MOJO_RENDE RER_CLOSING); 1032 recordAbortReasonHistogram(PaymentRequestMetrics.ABORT_REASON_MOJO_RENDE RER_CLOSING);
976 } 1033 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 // > Complete autofill instruments. 1089 // > Complete autofill instruments.
1033 // > Incomplete autofill instruments. 1090 // > Incomplete autofill instruments.
1034 Collections.sort(mPendingAutofillInstruments, COMPLETENESS_COMPARATOR); 1091 Collections.sort(mPendingAutofillInstruments, COMPLETENESS_COMPARATOR);
1035 mPendingInstruments.addAll(mPendingAutofillInstruments); 1092 mPendingInstruments.addAll(mPendingAutofillInstruments);
1036 1093
1037 // Log the number of suggested credit cards. 1094 // Log the number of suggested credit cards.
1038 mJourneyLogger.setNumberOfSuggestionsShown(PaymentRequestJourneyLogger.S ECTION_CREDIT_CARDS, 1095 mJourneyLogger.setNumberOfSuggestionsShown(PaymentRequestJourneyLogger.S ECTION_CREDIT_CARDS,
1039 mPendingAutofillInstruments.size()); 1096 mPendingAutofillInstruments.size());
1040 1097
1041 mPendingAutofillInstruments.clear(); 1098 mPendingAutofillInstruments.clear();
1042 mPendingAutofillInstruments = null;
1043 1099
1044 // Pre-select the first instrument on the list, if it is complete. 1100 // Pre-select the first instrument on the list, if it is complete.
1045 int selection = SectionInformation.NO_SELECTION; 1101 int selection = SectionInformation.NO_SELECTION;
1046 if (!mPendingInstruments.isEmpty()) { 1102 if (!mPendingInstruments.isEmpty()) {
1047 PaymentInstrument first = mPendingInstruments.get(0); 1103 PaymentInstrument first = mPendingInstruments.get(0);
1048 if (!(first instanceof AutofillPaymentInstrument) 1104 if (!(first instanceof AutofillPaymentInstrument)
1049 || ((AutofillPaymentInstrument) first).isComplete()) { 1105 || ((AutofillPaymentInstrument) first).isComplete()) {
1050 selection = 0; 1106 selection = 0;
1051 } 1107 }
1052 } 1108 }
1053 1109
1054 if (mQueriedCanMakeActivePayment) { 1110 ActivePaymentQuery query = sCanMakeActivePaymentQueries.get(mOrigin);
1055 mQueriedCanMakeActivePayment = false; 1111 if (query != null) query.setResponse(selection == 0);
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 1112
1064 // The list of payment instruments is ready to display. 1113 // The list of payment instruments is ready to display.
1065 mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYPE_PA YMENT_METHODS, 1114 mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYPE_PA YMENT_METHODS,
1066 selection, mPendingInstruments); 1115 selection, mPendingInstruments);
1067 1116
1068 mPendingInstruments.clear(); 1117 mPendingInstruments.clear();
1069 1118
1070 // UI has requested the full list of payment instruments. Provide it now . 1119 // UI has requested the full list of payment instruments. Provide it now .
1071 if (mPaymentInformationCallback != null) providePaymentInformation(); 1120 if (mPaymentInformationCallback != null) providePaymentInformation();
1072 } 1121 }
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
1242 "PaymentRequest.CheckoutFunnel.Aborted", abortReason, 1291 "PaymentRequest.CheckoutFunnel.Aborted", abortReason,
1243 PaymentRequestMetrics.ABORT_REASON_MAX); 1292 PaymentRequestMetrics.ABORT_REASON_MAX);
1244 1293
1245 if (abortReason == PaymentRequestMetrics.ABORT_REASON_ABORTED_BY_USER) { 1294 if (abortReason == PaymentRequestMetrics.ABORT_REASON_ABORTED_BY_USER) {
1246 mJourneyLogger.recordJourneyStatsHistograms("UserAborted"); 1295 mJourneyLogger.recordJourneyStatsHistograms("UserAborted");
1247 } else { 1296 } else {
1248 mJourneyLogger.recordJourneyStatsHistograms("OtherAborted"); 1297 mJourneyLogger.recordJourneyStatsHistograms("OtherAborted");
1249 } 1298 }
1250 } 1299 }
1251 } 1300 }
OLDNEW
« no previous file with comments | « no previous file | chrome/android/javatests/src/org/chromium/chrome/browser/payments/PaymentRequestPaymentAppActivePaymentQueryTest.java » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698