| 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.components.payments; |
| 6 | 6 |
| 7 import org.chromium.base.metrics.RecordHistogram; | 7 import org.chromium.base.annotations.JNINamespace; |
| 8 | 8 |
| 9 /** | 9 /** |
| 10 * A class used to record journey metrics for the Payment Request feature. | 10 * A class used to record journey metrics for the Payment Request feature. |
| 11 */ | 11 */ |
| 12 public class PaymentRequestJourneyLogger { | 12 @JNINamespace("payments") |
| 13 public class JourneyLogger { |
| 14 // Note: The constants should always be in sync with those in the |
| 15 // components/payments/core/journey_logger.h file. |
| 13 // The index of the different sections of a Payment Request. Used to record
journey stats. | 16 // The index of the different sections of a Payment Request. Used to record
journey stats. |
| 14 public static final int SECTION_CONTACT_INFO = 0; | 17 public static final int SECTION_CONTACT_INFO = 0; |
| 15 public static final int SECTION_CREDIT_CARDS = 1; | 18 public static final int SECTION_CREDIT_CARDS = 1; |
| 16 public static final int SECTION_SHIPPING_ADDRESS = 2; | 19 public static final int SECTION_SHIPPING_ADDRESS = 2; |
| 17 public static final int SECTION_MAX = 3; | 20 public static final int SECTION_MAX = 3; |
| 18 | 21 |
| 19 // For the CanMakePayment histograms. | 22 // For the CanMakePayment histograms. |
| 20 public static final int CAN_MAKE_PAYMENT_USED = 0; | 23 public static final int CAN_MAKE_PAYMENT_USED = 0; |
| 21 public static final int CAN_MAKE_PAYMENT_NOT_USED = 1; | 24 public static final int CAN_MAKE_PAYMENT_NOT_USED = 1; |
| 22 public static final int CAN_MAKE_PAYMENT_USE_MAX = 2; | 25 public static final int CAN_MAKE_PAYMENT_USE_MAX = 2; |
| 23 | 26 |
| 24 // Used to log different parameters' effect on whether the transaction was c
ompleted. | 27 // Used to log different parameters' effect on whether the transaction was c
ompleted. |
| 25 public static final int COMPLETION_STATUS_COMPLETED = 0; | 28 public static final int COMPLETION_STATUS_COMPLETED = 0; |
| 26 public static final int COMPLETION_STATUS_ABORTED = 1; | 29 public static final int COMPLETION_STATUS_USER_ABORTED = 1; |
| 27 public static final int COMPLETION_STATUS_MAX = 2; | 30 public static final int COMPLETION_STATUS_OTHER_ABORTED = 2; |
| 31 public static final int COMPLETION_STATUS_MAX = 3; |
| 28 | 32 |
| 29 // Used to mesure the impact of the CanMakePayment return value on whether t
he Payment Request | 33 // Used to mesure the impact of the CanMakePayment return value on whether t
he Payment Request |
| 30 // is shown to the user. | 34 // is shown to the user. |
| 31 public static final int CMP_SHOW_COULD_NOT_MAKE_PAYMENT_AND_DID_NOT_SHOW = 0
; | 35 public static final int CMP_SHOW_COULD_NOT_MAKE_PAYMENT_AND_DID_NOT_SHOW = 0
; |
| 32 public static final int CMP_SHOW_DID_SHOW = 1 << 0; | 36 public static final int CMP_SHOW_DID_SHOW = 1 << 0; |
| 33 public static final int CMP_SHOW_COULD_MAKE_PAYMENT = 1 << 1; | 37 public static final int CMP_SHOW_COULD_MAKE_PAYMENT = 1 << 1; |
| 34 public static final int CMP_SHOW_MAX = 4; | 38 public static final int CMP_SHOW_MAX = 4; |
| 35 | 39 |
| 36 // The minimum expected value of CustomCountHistograms is always set to 1. I
t is still possible | 40 // The minimum expected value of CustomCountHistograms is always set to 1. I
t is still possible |
| 37 // to log the value 0 to that type of histogram. | 41 // to log the value 0 to that type of histogram. |
| 38 private static final int MIN_EXPECTED_SAMPLE = 1; | 42 private static final int MIN_EXPECTED_SAMPLE = 1; |
| 39 private static final int MAX_EXPECTED_SAMPLE = 49; | 43 private static final int MAX_EXPECTED_SAMPLE = 49; |
| 40 private static final int NUMBER_BUCKETS = 50; | 44 private static final int NUMBER_BUCKETS = 50; |
| 41 | 45 |
| 42 private static class SectionStats { | 46 /** |
| 43 private int mNumberSuggestionsShown; | 47 * Pointer to the native implementation. |
| 44 private int mNumberSelectionChanges; | 48 */ |
| 45 private int mNumberSelectionEdits; | 49 private long mJourneyLoggerAndroid; |
| 46 private int mNumberSelectionAdds; | 50 |
| 47 private boolean mIsRequested; | 51 public JourneyLogger() { |
| 52 // Note that this pointer could leak the native object. The called must
call destroy() to |
| 53 // ensure that the native object is destroyed. |
| 54 mJourneyLoggerAndroid = nativeInitJourneyLoggerAndroid(); |
| 48 } | 55 } |
| 49 | 56 |
| 50 private SectionStats[] mSections; | 57 /** Will destroy the native object. This class shouldn't be used afterwards.
*/ |
| 51 | 58 public void destroy() { |
| 52 private boolean mWasCanMakePaymentUsed; | 59 if (mJourneyLoggerAndroid != 0) { |
| 53 private boolean mCouldMakePayment; | 60 nativeDestroy(mJourneyLoggerAndroid); |
| 54 private boolean mWasShowCalled; | 61 mJourneyLoggerAndroid = 0; |
| 55 | |
| 56 public PaymentRequestJourneyLogger() { | |
| 57 mSections = new SectionStats[SECTION_MAX]; | |
| 58 for (int i = 0; i < mSections.length; ++i) { | |
| 59 mSections[i] = new SectionStats(); | |
| 60 } | 62 } |
| 61 } | 63 } |
| 62 | 64 |
| 63 /** | 65 /** |
| 64 * Sets the number of suggestions shown for the specified section. | 66 * Sets the number of suggestions shown for the specified section. |
| 65 * | 67 * |
| 66 * @param section The section for which to log. | 68 * @param section The section for which to log. |
| 67 * @param number The number of suggestions. | 69 * @param number The number of suggestions. |
| 68 */ | 70 */ |
| 69 public void setNumberOfSuggestionsShown(int section, int number) { | 71 public void setNumberOfSuggestionsShown(int section, int number) { |
| 70 assert section < SECTION_MAX; | 72 assert section < SECTION_MAX; |
| 71 mSections[section].mNumberSuggestionsShown = number; | 73 nativeSetNumberOfSuggestionsShown(mJourneyLoggerAndroid, section, number
); |
| 72 mSections[section].mIsRequested = true; | |
| 73 } | 74 } |
| 74 | 75 |
| 75 /** | 76 /** |
| 76 * Increments the number of selection changes for the specified section. | 77 * Increments the number of selection changes for the specified section. |
| 77 * | 78 * |
| 78 * @param section The section for which to log. | 79 * @param section The section for which to log. |
| 79 */ | 80 */ |
| 80 public void incrementSelectionChanges(int section) { | 81 public void incrementSelectionChanges(int section) { |
| 81 assert section < SECTION_MAX; | 82 assert section < SECTION_MAX; |
| 82 mSections[section].mNumberSelectionChanges++; | 83 nativeIncrementSelectionChanges(mJourneyLoggerAndroid, section); |
| 83 } | 84 } |
| 84 | 85 |
| 85 /** | 86 /** |
| 86 * Increments the number of selection edits for the specified section. | 87 * Increments the number of selection edits for the specified section. |
| 87 * | 88 * |
| 88 * @param section The section for which to log. | 89 * @param section The section for which to log. |
| 89 */ | 90 */ |
| 90 public void incrementSelectionEdits(int section) { | 91 public void incrementSelectionEdits(int section) { |
| 91 assert section < SECTION_MAX; | 92 assert section < SECTION_MAX; |
| 92 mSections[section].mNumberSelectionEdits++; | 93 nativeIncrementSelectionEdits(mJourneyLoggerAndroid, section); |
| 93 } | 94 } |
| 94 | 95 |
| 95 /** | 96 /** |
| 96 * Increments the number of selection adds for the specified section. | 97 * Increments the number of selection adds for the specified section. |
| 97 * | 98 * |
| 98 * @param section The section for which to log. | 99 * @param section The section for which to log. |
| 99 */ | 100 */ |
| 100 public void incrementSelectionAdds(int section) { | 101 public void incrementSelectionAdds(int section) { |
| 101 assert section < SECTION_MAX; | 102 assert section < SECTION_MAX; |
| 102 mSections[section].mNumberSelectionAdds++; | 103 nativeIncrementSelectionAdds(mJourneyLoggerAndroid, section); |
| 103 } | 104 } |
| 104 | 105 |
| 105 /** | 106 /** |
| 106 * Records the fact that the merchant called CanMakePayment and records it's
return value. | 107 * Records the fact that the merchant called CanMakePayment and records it's
return value. |
| 107 * | 108 * |
| 108 * @param value The return value of the CanMakePayment call. | 109 * @param value The return value of the CanMakePayment call. |
| 109 */ | 110 */ |
| 110 public void setCanMakePaymentValue(boolean value) { | 111 public void setCanMakePaymentValue(boolean value) { |
| 111 mWasCanMakePaymentUsed = true; | 112 nativeSetCanMakePaymentValue(mJourneyLoggerAndroid, value); |
| 112 mCouldMakePayment |= value; | |
| 113 } | 113 } |
| 114 | 114 |
| 115 /** | 115 /** |
| 116 * Records the fact that the Payment Request was shown to the user. | 116 * Records the fact that the Payment Request was shown to the user. |
| 117 */ | 117 */ |
| 118 public void setShowCalled() { | 118 public void setShowCalled() { |
| 119 mWasShowCalled = true; | 119 nativeSetShowCalled(mJourneyLoggerAndroid); |
| 120 } | 120 } |
| 121 | 121 |
| 122 /* | 122 /* |
| 123 * Records the histograms for all the sections that were requested by the me
rchant and for the | 123 * Records the histograms for all the sections that were requested by the me
rchant and for the |
| 124 * usage of the CanMakePayment method and its effect on the transaction. Thi
s method should be | 124 * usage of the CanMakePayment method and its effect on the transaction. Thi
s method should be |
| 125 * called when the payment request has either been completed or aborted. | 125 * called when the payment request has either been completed or aborted. |
| 126 * | 126 * |
| 127 * @param submissionType A string indicating the way the payment request was
concluded. | 127 * @param submissionType An int indicating the way the payment request was c
oncluded. |
| 128 */ | 128 */ |
| 129 public void recordJourneyStatsHistograms(String submissionType) { | 129 public void recordJourneyStatsHistograms(int completionStatus) { |
| 130 recordSectionSpecificStats(submissionType); | 130 nativeRecordJourneyStatsHistograms(mJourneyLoggerAndroid, completionStat
us); |
| 131 | |
| 132 // Record the CanMakePayment metrics based on whether the transaction wa
s completed or | |
| 133 // aborted by the user (UserAborted) or otherwise (OtherAborted). | |
| 134 recordCanMakePaymentStats(submissionType.contains("Abort") ? COMPLETION_
STATUS_ABORTED | |
| 135 : COMPLETION_
STATUS_COMPLETED); | |
| 136 } | 131 } |
| 137 | 132 |
| 138 /** | 133 private native long nativeInitJourneyLoggerAndroid(); |
| 139 * Records the histograms for all the sections that were requested by the me
rchant. | 134 private native void nativeDestroy(long nativeJourneyLoggerAndroid); |
| 140 * | 135 private native void nativeSetNumberOfSuggestionsShown( |
| 141 * @param submissionType A string indicating the way the payment request was
concluded. | 136 long nativeJourneyLoggerAndroid, int section, int number); |
| 142 */ | 137 private native void nativeIncrementSelectionChanges( |
| 143 private void recordSectionSpecificStats(String submissionType) { | 138 long nativeJourneyLoggerAndroid, int section); |
| 144 // Record whether the user had suggestions for each requested informatio
n. | 139 private native void nativeIncrementSelectionEdits(long nativeJourneyLoggerAn
droid, int section); |
| 145 boolean userHadAllRequestedInformation = true; | 140 private native void nativeIncrementSelectionAdds(long nativeJourneyLoggerAnd
roid, int section); |
| 146 | 141 private native void nativeSetCanMakePaymentValue( |
| 147 for (int i = 0; i < mSections.length; ++i) { | 142 long nativeJourneyLoggerAndroid, boolean value); |
| 148 String nameSuffix = ""; | 143 private native void nativeSetShowCalled(long nativeJourneyLoggerAndroid); |
| 149 switch (i) { | 144 private native void nativeRecordJourneyStatsHistograms( |
| 150 case SECTION_SHIPPING_ADDRESS: | 145 long nativeJourneyLoggerAndroid, int completionStatus); |
| 151 nameSuffix = "ShippingAddress." + submissionType; | |
| 152 break; | |
| 153 case SECTION_CONTACT_INFO: | |
| 154 nameSuffix = "ContactInfo." + submissionType; | |
| 155 break; | |
| 156 case SECTION_CREDIT_CARDS: | |
| 157 nameSuffix = "CreditCards." + submissionType; | |
| 158 break; | |
| 159 default: | |
| 160 break; | |
| 161 } | |
| 162 | |
| 163 assert !nameSuffix.isEmpty(); | |
| 164 | |
| 165 // Only log the metrics for a section if it was requested by the mer
chant. | |
| 166 if (mSections[i].mIsRequested) { | |
| 167 RecordHistogram.recordCustomCountHistogram( | |
| 168 "PaymentRequest.NumberOfSelectionAdds." + nameSuffix, | |
| 169 Math.min(mSections[i].mNumberSelectionAdds, MAX_EXPECTED
_SAMPLE), | |
| 170 MIN_EXPECTED_SAMPLE, MAX_EXPECTED_SAMPLE, NUMBER_BUCKETS
); | |
| 171 RecordHistogram.recordCustomCountHistogram( | |
| 172 "PaymentRequest.NumberOfSelectionChanges." + nameSuffix, | |
| 173 Math.min(mSections[i].mNumberSelectionChanges, MAX_EXPEC
TED_SAMPLE), | |
| 174 MIN_EXPECTED_SAMPLE, MAX_EXPECTED_SAMPLE, NUMBER_BUCKETS
); | |
| 175 RecordHistogram.recordCustomCountHistogram( | |
| 176 "PaymentRequest.NumberOfSelectionEdits." + nameSuffix, | |
| 177 Math.min(mSections[i].mNumberSelectionEdits, MAX_EXPECTE
D_SAMPLE), | |
| 178 MIN_EXPECTED_SAMPLE, MAX_EXPECTED_SAMPLE, NUMBER_BUCKETS
); | |
| 179 RecordHistogram.recordCustomCountHistogram( | |
| 180 "PaymentRequest.NumberOfSuggestionsShown." + nameSuffix, | |
| 181 Math.min(mSections[i].mNumberSuggestionsShown, MAX_EXPEC
TED_SAMPLE), | |
| 182 MIN_EXPECTED_SAMPLE, MAX_EXPECTED_SAMPLE, NUMBER_BUCKETS
); | |
| 183 | |
| 184 if (mSections[i].mNumberSuggestionsShown == 0) { | |
| 185 userHadAllRequestedInformation = false; | |
| 186 } | |
| 187 } | |
| 188 } | |
| 189 | |
| 190 // Record metrics about completion based on whether the user had suggest
ions for each | |
| 191 // requested information. | |
| 192 int completionStatus = submissionType.contains("Abort") ? COMPLETION_STA
TUS_ABORTED | |
| 193 : COMPLETION_STA
TUS_COMPLETED; | |
| 194 if (userHadAllRequestedInformation) { | |
| 195 RecordHistogram.recordEnumeratedHistogram( | |
| 196 "PaymentRequest.UserHadSuggestionsForEverything.EffectOnComp
letion", | |
| 197 completionStatus, COMPLETION_STATUS_MAX); | |
| 198 } else { | |
| 199 RecordHistogram.recordEnumeratedHistogram( | |
| 200 "PaymentRequest.UserDidNotHaveSuggestionsForEverything.Effec
tOnCompletion", | |
| 201 completionStatus, COMPLETION_STATUS_MAX); | |
| 202 } | |
| 203 } | |
| 204 | |
| 205 /** | |
| 206 * Records the metrics related the the CanMakePayment method. | |
| 207 * | |
| 208 * @param completionStatus Whether the transaction was completed or aborted. | |
| 209 */ | |
| 210 private void recordCanMakePaymentStats(int completionStatus) { | |
| 211 // Record CanMakePayment usage. | |
| 212 RecordHistogram.recordEnumeratedHistogram("PaymentRequest.CanMakePayment
.Usage", | |
| 213 mWasCanMakePaymentUsed ? CAN_MAKE_PAYMENT_USED : CAN_MAKE_PAYMEN
T_NOT_USED, | |
| 214 CAN_MAKE_PAYMENT_USE_MAX); | |
| 215 | |
| 216 recordCanMakePaymentEffectOnShow(); | |
| 217 recordCanMakePaymentEffectOnCompletion(completionStatus); | |
| 218 } | |
| 219 | |
| 220 /** | |
| 221 * Records CanMakePayment's return value effect on whether the Payment Reque
st was shown or not. | |
| 222 */ | |
| 223 private void recordCanMakePaymentEffectOnShow() { | |
| 224 if (!mWasCanMakePaymentUsed) return; | |
| 225 | |
| 226 int effectOnShow = 0; | |
| 227 if (mWasShowCalled) effectOnShow |= CMP_SHOW_DID_SHOW; | |
| 228 if (mCouldMakePayment) effectOnShow |= CMP_SHOW_COULD_MAKE_PAYMENT; | |
| 229 | |
| 230 RecordHistogram.recordEnumeratedHistogram( | |
| 231 "PaymentRequest.CanMakePayment.Used.EffetOnShow", effectOnShow,
CMP_SHOW_MAX); | |
| 232 } | |
| 233 | |
| 234 /** | |
| 235 * Records the completion status depending on the the usage and return value
of the | |
| 236 * CanMakePaymentMethod. | |
| 237 * | |
| 238 * @param completionStatus Whether the transaction was completed or aborted. | |
| 239 */ | |
| 240 private void recordCanMakePaymentEffectOnCompletion(int completionStatus) { | |
| 241 if (!mWasShowCalled) return; | |
| 242 | |
| 243 String histogramName = "PaymentRequest.CanMakePayment."; | |
| 244 | |
| 245 if (!mWasCanMakePaymentUsed) { | |
| 246 histogramName += "NotUsed.WithShowEffectOnCompletion"; | |
| 247 } else if (mCouldMakePayment) { | |
| 248 histogramName += "Used.TrueWithShowEffectOnCompletion"; | |
| 249 } else { | |
| 250 histogramName += "Used.FalseWithShowEffectOnCompletion"; | |
| 251 } | |
| 252 | |
| 253 RecordHistogram.recordEnumeratedHistogram( | |
| 254 histogramName, completionStatus, COMPLETION_STATUS_MAX); | |
| 255 } | |
| 256 } | 146 } |
| OLD | NEW |