| OLD | NEW |
| 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 21 matching lines...) Expand all Loading... |
| 32 import org.chromium.chrome.browser.tab.Tab; | 32 import org.chromium.chrome.browser.tab.Tab; |
| 33 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; | 33 import org.chromium.chrome.browser.tabmodel.EmptyTabModelObserver; |
| 34 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; | 34 import org.chromium.chrome.browser.tabmodel.EmptyTabModelSelectorObserver; |
| 35 import org.chromium.chrome.browser.tabmodel.TabModel; | 35 import org.chromium.chrome.browser.tabmodel.TabModel; |
| 36 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; | 36 import org.chromium.chrome.browser.tabmodel.TabModel.TabSelectionType; |
| 37 import org.chromium.chrome.browser.tabmodel.TabModelObserver; | 37 import org.chromium.chrome.browser.tabmodel.TabModelObserver; |
| 38 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; | 38 import org.chromium.chrome.browser.tabmodel.TabModelSelectorObserver; |
| 39 import org.chromium.components.url_formatter.UrlFormatter; | 39 import org.chromium.components.url_formatter.UrlFormatter; |
| 40 import org.chromium.content_public.browser.WebContents; | 40 import org.chromium.content_public.browser.WebContents; |
| 41 import org.chromium.mojo.system.MojoException; | 41 import org.chromium.mojo.system.MojoException; |
| 42 import org.chromium.payments.mojom.ActivePaymentQueryResult; | 42 import org.chromium.payments.mojom.CanMakePaymentQueryResult; |
| 43 import org.chromium.payments.mojom.PaymentComplete; | 43 import org.chromium.payments.mojom.PaymentComplete; |
| 44 import org.chromium.payments.mojom.PaymentDetails; | 44 import org.chromium.payments.mojom.PaymentDetails; |
| 45 import org.chromium.payments.mojom.PaymentErrorReason; | 45 import org.chromium.payments.mojom.PaymentErrorReason; |
| 46 import org.chromium.payments.mojom.PaymentItem; | 46 import org.chromium.payments.mojom.PaymentItem; |
| 47 import org.chromium.payments.mojom.PaymentMethodData; | 47 import org.chromium.payments.mojom.PaymentMethodData; |
| 48 import org.chromium.payments.mojom.PaymentOptions; | 48 import org.chromium.payments.mojom.PaymentOptions; |
| 49 import org.chromium.payments.mojom.PaymentRequest; | 49 import org.chromium.payments.mojom.PaymentRequest; |
| 50 import org.chromium.payments.mojom.PaymentRequestClient; | 50 import org.chromium.payments.mojom.PaymentRequestClient; |
| 51 import org.chromium.payments.mojom.PaymentResponse; | 51 import org.chromium.payments.mojom.PaymentResponse; |
| 52 import org.chromium.payments.mojom.PaymentShippingOption; | 52 import org.chromium.payments.mojom.PaymentShippingOption; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 * Called when a show request failed. This can happen when: | 94 * Called when a show request failed. This can happen when: |
| 95 * <ul> | 95 * <ul> |
| 96 * <li>The merchant requests only unsupported payment methods.</li> | 96 * <li>The merchant requests only unsupported payment methods.</li> |
| 97 * <li>The merchant requests only payment methods that don't have inst
ruments and are not | 97 * <li>The merchant requests only payment methods that don't have inst
ruments and are not |
| 98 * able to add instruments from PaymentRequest UI.</li> | 98 * able to add instruments from PaymentRequest UI.</li> |
| 99 * </ul> | 99 * </ul> |
| 100 */ | 100 */ |
| 101 void onPaymentRequestServiceShowFailed(); | 101 void onPaymentRequestServiceShowFailed(); |
| 102 | 102 |
| 103 /** | 103 /** |
| 104 * Called when the canMakeActivePayment() request has been responded. | 104 * Called when the canMakePayment() request has been responded. |
| 105 */ | 105 */ |
| 106 void onPaymentRequestServiceActivePaymentQueryResponded(); | 106 void onPaymentRequestServiceCanMakePaymentQueryResponded(); |
| 107 } | 107 } |
| 108 | 108 |
| 109 /** The object to keep track of cached payment query results. */ | 109 /** The object to keep track of cached payment query results. */ |
| 110 private static class ActivePaymentQuery { | 110 private static class CanMakePaymentQuery { |
| 111 private final Set<PaymentRequestImpl> mObservers = new HashSet<>(); | 111 private final Set<PaymentRequestImpl> mObservers = new HashSet<>(); |
| 112 private final Set<String> mMethods; | 112 private final Set<String> mMethods; |
| 113 private Boolean mResponse; | 113 private Boolean mResponse; |
| 114 | 114 |
| 115 /** | 115 /** |
| 116 * Keeps track of an active payment query. | 116 * Keeps track of a payment query. |
| 117 * | 117 * |
| 118 * @param methods The payment methods that are being queried. | 118 * @param methods The payment methods that are being queried. |
| 119 */ | 119 */ |
| 120 public ActivePaymentQuery(Set<String> methods) { | 120 public CanMakePaymentQuery(Set<String> methods) { |
| 121 assert methods != null; | 121 assert methods != null; |
| 122 mMethods = methods; | 122 mMethods = methods; |
| 123 } | 123 } |
| 124 | 124 |
| 125 /** | 125 /** |
| 126 * Checks whether the given payment methods matches the previously queri
ed payment methods. | 126 * Checks whether the given payment methods matches the previously queri
ed payment methods. |
| 127 * | 127 * |
| 128 * @param methods The payment methods that are being queried. | 128 * @param methods The payment methods that are being queried. |
| 129 * @return True if the given methods match the previously queried paymen
t methods. | 129 * @return True if the given methods match the previously queried paymen
t methods. |
| 130 */ | 130 */ |
| 131 public boolean matchesPaymentMethods(Set<String> methods) { | 131 public boolean matchesPaymentMethods(Set<String> methods) { |
| 132 return mMethods.equals(methods); | 132 return mMethods.equals(methods); |
| 133 } | 133 } |
| 134 | 134 |
| 135 /** @return Whether active payment can be made, or null if response is n
ot known yet. */ | 135 /** @return Whether payment can be made, or null if response is not know
n yet. */ |
| 136 public Boolean getPreviousResponse() { | 136 public Boolean getPreviousResponse() { |
| 137 return mResponse; | 137 return mResponse; |
| 138 } | 138 } |
| 139 | 139 |
| 140 /** @param response Whether active payment can be made. */ | 140 /** @param response Whether payment can be made. */ |
| 141 public void setResponse(boolean response) { | 141 public void setResponse(boolean response) { |
| 142 if (mResponse == null) mResponse = response; | 142 if (mResponse == null) mResponse = response; |
| 143 for (PaymentRequestImpl observer : mObservers) { | 143 for (PaymentRequestImpl observer : mObservers) { |
| 144 observer.respondActivePaymentQuery(mResponse.booleanValue()); | 144 observer.respondCanMakePaymentQuery(mResponse.booleanValue()); |
| 145 } | 145 } |
| 146 mObservers.clear(); | 146 mObservers.clear(); |
| 147 } | 147 } |
| 148 | 148 |
| 149 /** @param observer The observer to notify when the query response is kn
own. */ | 149 /** @param observer The observer to notify when the query response is kn
own. */ |
| 150 public void addObserver(PaymentRequestImpl observer) { | 150 public void addObserver(PaymentRequestImpl observer) { |
| 151 mObservers.add(observer); | 151 mObservers.add(observer); |
| 152 } | 152 } |
| 153 }; | 153 }; |
| 154 | 154 |
| 155 private static final String TAG = "cr_PaymentRequest"; | 155 private static final String TAG = "cr_PaymentRequest"; |
| 156 private static final String ANDROID_PAY_METHOD_NAME = "https://android.com/p
ay"; | 156 private static final String ANDROID_PAY_METHOD_NAME = "https://android.com/p
ay"; |
| 157 private static final int SUGGESTIONS_LIMIT = 4; | 157 private static final int SUGGESTIONS_LIMIT = 4; |
| 158 private static final Comparator<Completable> COMPLETENESS_COMPARATOR = | 158 private static final Comparator<Completable> COMPLETENESS_COMPARATOR = |
| 159 new Comparator<Completable>() { | 159 new Comparator<Completable>() { |
| 160 @Override | 160 @Override |
| 161 public int compare(Completable a, Completable b) { | 161 public int compare(Completable a, Completable b) { |
| 162 return (b.isComplete() ? 1 : 0) - (a.isComplete() ? 1 : 0); | 162 return (b.isComplete() ? 1 : 0) - (a.isComplete() ? 1 : 0); |
| 163 } | 163 } |
| 164 }; | 164 }; |
| 165 | 165 |
| 166 /** Every origin can call canMakeActivePayment() every 30 minutes. */ | 166 /** Every origin can call canMakePayment() every 30 minutes. */ |
| 167 private static final int CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS = 30 * 60 *
1000; | 167 private static final int CAN_MAKE_PAYMENT_QUERY_PERIOD_MS = 30 * 60 * 1000; |
| 168 | 168 |
| 169 private static PaymentRequestServiceObserverForTest sObserverForTest; | 169 private static PaymentRequestServiceObserverForTest sObserverForTest; |
| 170 | 170 |
| 171 /** True if show() was called in any PaymentRequestImpl object. */ | 171 /** True if show() was called in any PaymentRequestImpl object. */ |
| 172 private static boolean sIsShowing; | 172 private static boolean sIsShowing; |
| 173 | 173 |
| 174 /** | 174 /** |
| 175 * In-memory mapping of the origins of websites that have recently called ca
nMakeActivePayment() | 175 * In-memory mapping of the origins of websites that have recently called ca
nMakePayment() |
| 176 * to the list of the payment methods that were been queried. Used for throt
tling the usage of | 176 * to the list of the payment methods that were been queried. Used for throt
tling the usage of |
| 177 * this call. The mapping is shared among all instances of PaymentRequestImp
l in the browser | 177 * this call. The mapping is shared among all instances of PaymentRequestImp
l in the browser |
| 178 * process on UI thread. The user can reset the throttling mechanism by rest
arting the browser. | 178 * process on UI thread. The user can reset the throttling mechanism by rest
arting the browser. |
| 179 */ | 179 */ |
| 180 private static Map<String, ActivePaymentQuery> sCanMakeActivePaymentQueries; | 180 private static Map<String, CanMakePaymentQuery> sCanMakePaymentQueries; |
| 181 | 181 |
| 182 /** Monitors changes in the TabModelSelector. */ | 182 /** Monitors changes in the TabModelSelector. */ |
| 183 private final TabModelSelectorObserver mSelectorObserver = new EmptyTabModel
SelectorObserver() { | 183 private final TabModelSelectorObserver mSelectorObserver = new EmptyTabModel
SelectorObserver() { |
| 184 @Override | 184 @Override |
| 185 public void onTabModelSelected(TabModel newModel, TabModel oldModel) { | 185 public void onTabModelSelected(TabModel newModel, TabModel oldModel) { |
| 186 onDismiss(); | 186 onDismiss(); |
| 187 } | 187 } |
| 188 }; | 188 }; |
| 189 | 189 |
| 190 /** Monitors changes in the current TabModel. */ | 190 /** Monitors changes in the current TabModel. */ |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 private List<PaymentApp> mPendingApps; | 243 private List<PaymentApp> mPendingApps; |
| 244 private List<PaymentInstrument> mPendingInstruments; | 244 private List<PaymentInstrument> mPendingInstruments; |
| 245 private List<PaymentInstrument> mPendingAutofillInstruments; | 245 private List<PaymentInstrument> mPendingAutofillInstruments; |
| 246 private SectionInformation mPaymentMethodsSection; | 246 private SectionInformation mPaymentMethodsSection; |
| 247 private PaymentRequestUI mUI; | 247 private PaymentRequestUI mUI; |
| 248 private Callback<PaymentInformation> mPaymentInformationCallback; | 248 private Callback<PaymentInformation> mPaymentInformationCallback; |
| 249 private boolean mPaymentAppRunning; | 249 private boolean mPaymentAppRunning; |
| 250 private boolean mMerchantSupportsAutofillPaymentInstruments; | 250 private boolean mMerchantSupportsAutofillPaymentInstruments; |
| 251 private ContactEditor mContactEditor; | 251 private ContactEditor mContactEditor; |
| 252 private boolean mHasRecordedAbortReason; | 252 private boolean mHasRecordedAbortReason; |
| 253 private boolean mQueriedCanMakeActivePayment; | 253 private boolean mQueriedCanMakePayment; |
| 254 private CurrencyStringFormatter mFormatter; | 254 private CurrencyStringFormatter mFormatter; |
| 255 | 255 |
| 256 /** True if any of the requested payment methods are supported. */ | 256 /** True if any of the requested payment methods are supported. */ |
| 257 private boolean mArePaymentMethodsSupported; | 257 private boolean mArePaymentMethodsSupported; |
| 258 | 258 |
| 259 /** The helper to create and fill the response to send to the merchant. */ | 259 /** The helper to create and fill the response to send to the merchant. */ |
| 260 private PaymentResponseHelper mPaymentResponseHelper; | 260 private PaymentResponseHelper mPaymentResponseHelper; |
| 261 | 261 |
| 262 /** | 262 /** |
| 263 * Builds the PaymentRequest service implementation. | 263 * Builds the PaymentRequest service implementation. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 292 } | 292 } |
| 293 mUI.setTitleBitmap(bitmap); | 293 mUI.setTitleBitmap(bitmap); |
| 294 } | 294 } |
| 295 }); | 295 }); |
| 296 | 296 |
| 297 mApps = PaymentAppFactory.create(mContext, webContents); | 297 mApps = PaymentAppFactory.create(mContext, webContents); |
| 298 | 298 |
| 299 mAddressEditor = new AddressEditor(); | 299 mAddressEditor = new AddressEditor(); |
| 300 mCardEditor = new CardEditor(webContents, mAddressEditor, sObserverForTe
st); | 300 mCardEditor = new CardEditor(webContents, mAddressEditor, sObserverForTe
st); |
| 301 | 301 |
| 302 if (sCanMakeActivePaymentQueries == null) sCanMakeActivePaymentQueries =
new ArrayMap<>(); | 302 if (sCanMakePaymentQueries == null) sCanMakePaymentQueries = new ArrayMa
p<>(); |
| 303 | 303 |
| 304 recordSuccessFunnelHistograms("Initiated"); | 304 recordSuccessFunnelHistograms("Initiated"); |
| 305 } | 305 } |
| 306 | 306 |
| 307 /** | 307 /** |
| 308 * Called by the merchant website to initialize the payment request data. | 308 * Called by the merchant website to initialize the payment request data. |
| 309 */ | 309 */ |
| 310 @Override | 310 @Override |
| 311 public void init(PaymentRequestClient client, PaymentMethodData[] methodData
, | 311 public void init(PaymentRequestClient client, PaymentMethodData[] methodData
, |
| 312 PaymentDetails details, PaymentOptions options) { | 312 PaymentDetails details, PaymentOptions options) { |
| (...skipping 722 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1035 public void complete(int result) { | 1035 public void complete(int result) { |
| 1036 if (mClient == null) return; | 1036 if (mClient == null) return; |
| 1037 recordSuccessFunnelHistograms("Completed"); | 1037 recordSuccessFunnelHistograms("Completed"); |
| 1038 closeUI(PaymentComplete.FAIL != result); | 1038 closeUI(PaymentComplete.FAIL != result); |
| 1039 } | 1039 } |
| 1040 | 1040 |
| 1041 /** | 1041 /** |
| 1042 * Called by the merchant website to check if the user has complete payment
instruments. | 1042 * Called by the merchant website to check if the user has complete payment
instruments. |
| 1043 */ | 1043 */ |
| 1044 @Override | 1044 @Override |
| 1045 public void canMakeActivePayment() { | 1045 public void canMakePayment() { |
| 1046 if (mClient == null) return; | 1046 if (mClient == null) return; |
| 1047 | 1047 |
| 1048 ActivePaymentQuery query = sCanMakeActivePaymentQueries.get(mOrigin); | 1048 CanMakePaymentQuery query = sCanMakePaymentQueries.get(mOrigin); |
| 1049 if (query == null) { | 1049 if (query == null) { |
| 1050 query = new ActivePaymentQuery(mMethodData.keySet()); | 1050 query = new CanMakePaymentQuery(mMethodData.keySet()); |
| 1051 sCanMakeActivePaymentQueries.put(mOrigin, query); | 1051 sCanMakePaymentQueries.put(mOrigin, query); |
| 1052 mHandler.postDelayed(new Runnable() { | 1052 mHandler.postDelayed(new Runnable() { |
| 1053 @Override | 1053 @Override |
| 1054 public void run() { | 1054 public void run() { |
| 1055 sCanMakeActivePaymentQueries.remove(mOrigin); | 1055 sCanMakePaymentQueries.remove(mOrigin); |
| 1056 } | 1056 } |
| 1057 }, CAN_MAKE_ACTIVE_PAYMENT_QUERY_PERIOD_MS); | 1057 }, CAN_MAKE_PAYMENT_QUERY_PERIOD_MS); |
| 1058 } | 1058 } |
| 1059 | 1059 |
| 1060 if (!query.matchesPaymentMethods(mMethodData.keySet())) { | 1060 if (!query.matchesPaymentMethods(mMethodData.keySet())) { |
| 1061 mClient.onCanMakeActivePayment(ActivePaymentQueryResult.QUERY_QUOTA_
EXCEEDED); | 1061 mClient.onCanMakePayment(CanMakePaymentQueryResult.QUERY_QUOTA_EXCEE
DED); |
| 1062 if (sObserverForTest != null) { | 1062 if (sObserverForTest != null) { |
| 1063 sObserverForTest.onPaymentRequestServiceActivePaymentQueryRespon
ded(); | 1063 sObserverForTest.onPaymentRequestServiceCanMakePaymentQueryRespo
nded(); |
| 1064 } | 1064 } |
| 1065 return; | 1065 return; |
| 1066 } | 1066 } |
| 1067 | 1067 |
| 1068 if (query.getPreviousResponse() != null) { | 1068 if (query.getPreviousResponse() != null) { |
| 1069 respondActivePaymentQuery(query.getPreviousResponse().booleanValue()
); | 1069 respondCanMakePaymentQuery(query.getPreviousResponse().booleanValue(
)); |
| 1070 return; | 1070 return; |
| 1071 } | 1071 } |
| 1072 | 1072 |
| 1073 query.addObserver(this); | 1073 query.addObserver(this); |
| 1074 if (mPendingApps.isEmpty() && mPendingInstruments.isEmpty()) { | 1074 if (mPendingApps.isEmpty() && mPendingInstruments.isEmpty()) { |
| 1075 query.setResponse(mPaymentMethodsSection != null | 1075 query.setResponse(mPaymentMethodsSection != null |
| 1076 && mPaymentMethodsSection.getSelectedItem() != null); | 1076 && mPaymentMethodsSection.getSelectedItem() != null); |
| 1077 } | 1077 } |
| 1078 } | 1078 } |
| 1079 | 1079 |
| 1080 private void respondActivePaymentQuery(boolean response) { | 1080 private void respondCanMakePaymentQuery(boolean response) { |
| 1081 mClient.onCanMakeActivePayment(response | 1081 mClient.onCanMakePayment(response |
| 1082 ? ActivePaymentQueryResult.CAN_MAKE_ACTIVE_PAYMENT | 1082 ? CanMakePaymentQueryResult.CAN_MAKE_PAYMENT |
| 1083 : ActivePaymentQueryResult.CANNOT_MAKE_ACTIVE_PAYMENT); | 1083 : CanMakePaymentQueryResult.CANNOT_MAKE_PAYMENT); |
| 1084 if (sObserverForTest != null) { | 1084 if (sObserverForTest != null) { |
| 1085 sObserverForTest.onPaymentRequestServiceActivePaymentQueryResponded(
); | 1085 sObserverForTest.onPaymentRequestServiceCanMakePaymentQueryResponded
(); |
| 1086 } | 1086 } |
| 1087 } | 1087 } |
| 1088 | 1088 |
| 1089 /** | 1089 /** |
| 1090 * Called when the renderer closes the Mojo connection. | 1090 * Called when the renderer closes the Mojo connection. |
| 1091 */ | 1091 */ |
| 1092 @Override | 1092 @Override |
| 1093 public void close() { | 1093 public void close() { |
| 1094 if (mClient == null) return; | 1094 if (mClient == null) return; |
| 1095 closeClient(); | 1095 closeClient(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1167 // Pre-select the first instrument on the list, if it is complete. | 1167 // Pre-select the first instrument on the list, if it is complete. |
| 1168 int selection = SectionInformation.NO_SELECTION; | 1168 int selection = SectionInformation.NO_SELECTION; |
| 1169 if (!mPendingInstruments.isEmpty()) { | 1169 if (!mPendingInstruments.isEmpty()) { |
| 1170 PaymentInstrument first = mPendingInstruments.get(0); | 1170 PaymentInstrument first = mPendingInstruments.get(0); |
| 1171 if (!(first instanceof AutofillPaymentInstrument) | 1171 if (!(first instanceof AutofillPaymentInstrument) |
| 1172 || ((AutofillPaymentInstrument) first).isComplete()) { | 1172 || ((AutofillPaymentInstrument) first).isComplete()) { |
| 1173 selection = 0; | 1173 selection = 0; |
| 1174 } | 1174 } |
| 1175 } | 1175 } |
| 1176 | 1176 |
| 1177 ActivePaymentQuery query = sCanMakeActivePaymentQueries.get(mOrigin); | 1177 CanMakePaymentQuery query = sCanMakePaymentQueries.get(mOrigin); |
| 1178 if (query != null) query.setResponse(selection == 0); | 1178 if (query != null) query.setResponse(selection == 0); |
| 1179 | 1179 |
| 1180 // The list of payment instruments is ready to display. | 1180 // The list of payment instruments is ready to display. |
| 1181 mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYPE_PA
YMENT_METHODS, | 1181 mPaymentMethodsSection = new SectionInformation(PaymentRequestUI.TYPE_PA
YMENT_METHODS, |
| 1182 selection, mPendingInstruments); | 1182 selection, mPendingInstruments); |
| 1183 | 1183 |
| 1184 mPendingInstruments.clear(); | 1184 mPendingInstruments.clear(); |
| 1185 | 1185 |
| 1186 updateInstrumentModifiedTotals(); | 1186 updateInstrumentModifiedTotals(); |
| 1187 | 1187 |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1381 "PaymentRequest.CheckoutFunnel.Aborted", abortReason, | 1381 "PaymentRequest.CheckoutFunnel.Aborted", abortReason, |
| 1382 PaymentRequestMetrics.ABORT_REASON_MAX); | 1382 PaymentRequestMetrics.ABORT_REASON_MAX); |
| 1383 | 1383 |
| 1384 if (abortReason == PaymentRequestMetrics.ABORT_REASON_ABORTED_BY_USER) { | 1384 if (abortReason == PaymentRequestMetrics.ABORT_REASON_ABORTED_BY_USER) { |
| 1385 mJourneyLogger.recordJourneyStatsHistograms("UserAborted"); | 1385 mJourneyLogger.recordJourneyStatsHistograms("UserAborted"); |
| 1386 } else { | 1386 } else { |
| 1387 mJourneyLogger.recordJourneyStatsHistograms("OtherAborted"); | 1387 mJourneyLogger.recordJourneyStatsHistograms("OtherAborted"); |
| 1388 } | 1388 } |
| 1389 } | 1389 } |
| 1390 } | 1390 } |
| OLD | NEW |