From 3911a4b59e7c773bf4522e31db3d75519d6cf038 Mon Sep 17 00:00:00 2001 From: Vishwas Uppoor Date: Fri, 18 Mar 2022 17:05:58 +0000 Subject: [PATCH] [VCN][M2] Metrics for Clank This CL adds VCN metrics for Clank: 1. Enrollment / unenrollment metrics from Clank settings page. 2. Infobar metrics via the native controller. (cherry picked from commit a5aa93abc8bad750f9f495f76581f489c929718c) Bug: 1302747 Change-Id: I43d83a274d7ad362b2b5f2e0bf6d0b100ebb3c06 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3497535 Reviewed-by: Siyu An Reviewed-by: Siddharth Shah Reviewed-by: Ioana Pandele Reviewed-by: Mohamed Amir Yosef Reviewed-by: Jared Saul Commit-Queue: Vishwas Uppoor Cr-Original-Commit-Position: refs/heads/main@{#981328} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3531468 Reviewed-by: Krishna Govind Commit-Queue: Krishna Govind Owners-Override: Krishna Govind Cr-Commit-Position: refs/branch-heads/4896@{#677} Cr-Branched-From: 1f63ff4bc27570761b35ffbc7f938f6586f7bee8-refs/heads/main@{#972766} --- .../browser/autofill/AutofillUiUtils.java | 31 +++++-- .../settings/AutofillServerCardEditor.java | 17 +++- .../AutofillVirtualCardEnrollmentDialog.java | 30 +++++- ...AutofillVirtualCardUnenrollmentDialog.java | 15 ++- .../AutofillServerCardEditorTest.java | 93 ++++++++++++++++++- ...card_enrollment_infobar_delegate_mobile.cc | 16 +++- ..._card_enrollment_infobar_delegate_mobile.h | 6 ++ tools/metrics/histograms/enums.xml | 6 ++ .../metadata/autofill/histograms.xml | 61 +++++++++++- 9 files changed, 251 insertions(+), 24 deletions(-) diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java index 6c89a45cc18af..c8903d6178b10 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/AutofillUiUtils.java @@ -32,9 +32,9 @@ import androidx.core.widget.TextViewCompat; import org.chromium.base.ApiCompatibilityUtils; +import org.chromium.base.Callback; import org.chromium.base.ContextUtils; import org.chromium.chrome.R; -import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncherImpl; import org.chromium.chrome.browser.profiles.Profile; import org.chromium.ui.text.NoUnderlineClickableSpan; @@ -77,6 +77,18 @@ public interface OffsetProvider { int NONE = 7; } + // Constants used to log UMA "enum" histograms about the type of links clicked in mobile virtual + // card dialogs. Entries should not be renumbered and numeric values should never be reused. + @IntDef({VirtualCardDialogLink.EDUCATION_TEXT, VirtualCardDialogLink.GOOGLE_LEGAL_MESSAGE, + VirtualCardDialogLink.ISSUER_LEGAL_MESSAGE, VirtualCardDialogLink.NUM_ENTRIES}) + @Retention(RetentionPolicy.SOURCE) + public @interface VirtualCardDialogLink { + int EDUCATION_TEXT = 0; + int GOOGLE_LEGAL_MESSAGE = 1; + int ISSUER_LEGAL_MESSAGE = 2; + int NUM_ENTRIES = 3; + } + /** * Launches the Autofill help page on top of the current @{link android.app.Activity} and * current @{link Profile}. @@ -389,16 +401,17 @@ public static void inlineTitleStringWithLogo( * * @param context The context used for fetching the required resources. * @param legalMessageLines The list of LegalMessageLines to be represented as a string. + * @param onClickCallback The callback for the link clicks. * @return A {@link SpannableStringBuilder} that can directly be set on a TextView. */ - public static SpannableStringBuilder getSpannableStringForLegalMessageLines( - Context context, LinkedList legalMessageLines) { + public static SpannableStringBuilder getSpannableStringForLegalMessageLines(Context context, + LinkedList legalMessageLines, Callback onClickCallback) { SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(); for (LegalMessageLine line : legalMessageLines) { SpannableString text = new SpannableString(line.text); for (final LegalMessageLine.Link link : line.links) { text.setSpan(new NoUnderlineClickableSpan(context.getResources(), - (view) -> CustomTabActivity.showInfoPage(context, link.url)), + view -> onClickCallback.onResult(link.url)), link.start, link.end, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); } spannableStringBuilder.append(text); @@ -408,19 +421,19 @@ public static SpannableStringBuilder getSpannableStringForLegalMessageLines( /** * Returns a {@link SpannableString} containing a {@link NoUnderlineClickableSpan} for the text - * contained within the tags and defaults to opening a the provided url in a - * custom tab. + * contained within the tags . * @param context The context required to fetch the resources. * @param stringResourceId The resource id of the string on which the clickable span should be * applied. * @param url The url that should be opened when the clickable span is clicked. + * @param onClickCallback The callback for the link clicks. * @return {@link SpannableString} that can be directly set on the TextView. */ public static SpannableString getSpannableStringWithClickableSpansToOpenLinksInCustomTabs( - Context context, int stringResourceId, String url) { + Context context, int stringResourceId, String url, Callback onClickCallback) { return SpanApplier.applySpans(context.getString(stringResourceId), new SpanApplier.SpanInfo("", "", - new NoUnderlineClickableSpan(context.getResources(), - (view) -> CustomTabActivity.showInfoPage(context, url)))); + new NoUnderlineClickableSpan( + context.getResources(), view -> onClickCallback.onResult(url)))); } } diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillServerCardEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillServerCardEditor.java index 721ea460f35f9..0ae0f906112ad 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillServerCardEditor.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillServerCardEditor.java @@ -16,6 +16,7 @@ import androidx.annotation.Nullable; import org.chromium.base.annotations.UsedByReflection; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeStringConstants; import org.chromium.chrome.browser.autofill.PersonalDataManager; @@ -63,10 +64,14 @@ public View onCreateView( ((TextView) v.findViewById(R.id.title)).setText(mCard.getObfuscatedNumber()); ((TextView) v.findViewById(R.id.summary)) .setText(mCard.getFormattedExpirationDate(getActivity())); - v.findViewById(R.id.edit_server_card) - .setOnClickListener(view - -> CustomTabActivity.showInfoPage(getActivity(), - ChromeStringConstants.AUTOFILL_MANAGE_WALLET_CARD_URL)); + v.findViewById(R.id.edit_server_card).setOnClickListener(view -> { + RecordHistogram.recordBooleanHistogram(showVirtualCardEnrollmentButton() + ? "Autofill.SettingsPage.ButtonClicked.VirtualCard.EditCard" + : "Autofill.SettingsPage.ButtonClicked.ServerCard.EditCard", + true); + CustomTabActivity.showInfoPage( + getActivity(), ChromeStringConstants.AUTOFILL_MANAGE_WALLET_CARD_URL); + }); final LinearLayout virtualCardContainerLayout = (LinearLayout) v.findViewById(R.id.virtual_card_ui); @@ -81,6 +86,10 @@ public View onCreateView( : "mDelegate must be initialized before making (un)enrolment calls."; final ModalDialogManager modalDialogManager = new ModalDialogManager( new AppModalPresenter(getActivity()), ModalDialogType.APP); + RecordHistogram.recordBooleanHistogram(mVirtualCardEnrollmentButtonShowsUnenroll + ? "Autofill.SettingsPage.ButtonClicked.VirtualCard.VirtualCardUnenroll" + : "Autofill.SettingsPage.ButtonClicked.VirtualCard.VirtualCardEnroll", + true); if (!mVirtualCardEnrollmentButtonShowsUnenroll) { mDelegate.offerVirtualCardEnrollment(mCard.getInstrumentId(), result -> showVirtualCardEnrollmentDialog(result, modalDialogManager)); diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialog.java index 90bca74deb5f0..c9f86eed5c660 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardEnrollmentDialog.java @@ -12,9 +12,12 @@ import android.widget.TextView; import org.chromium.base.Callback; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeStringConstants; import org.chromium.chrome.browser.autofill.AutofillUiUtils; +import org.chromium.chrome.browser.autofill.AutofillUiUtils.VirtualCardDialogLink; +import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogProperties; @@ -23,6 +26,9 @@ /** Dialog shown to the user to enroll a credit card into the virtual card feature. */ public class AutofillVirtualCardEnrollmentDialog { + private static final String LINK_CLICK_HISTOGRAM = + "Autofill.VirtualCard.SettingsPageEnrollment.LinkClicked"; + private final Context mContext; private final ModalDialogManager mModalDialogManager; private final VirtualCardEnrollmentFields mVirtualCardEnrollmentFields; @@ -52,6 +58,9 @@ public void show() { mContext.getString(R.string.no_thanks)); dialogModel.with(ModalDialogProperties.CONTROLLER, new SimpleModalDialogController(mModalDialogManager, (action) -> { + RecordHistogram.recordBooleanHistogram( + "Autofill.VirtualCard.SettingsPageEnrollment", + action == DialogDismissalCause.POSITIVE_BUTTON_CLICKED); mResultHandler.onResult(action == DialogDismissalCause.POSITIVE_BUTTON_CLICKED); })); mModalDialogManager.showDialog(dialogModel.build(), ModalDialogManager.ModalDialogType.APP); @@ -71,19 +80,34 @@ private View getCustomViewForModalDialog() { virtualCardEducationTextView.setText( AutofillUiUtils.getSpannableStringWithClickableSpansToOpenLinksInCustomTabs( mContext, R.string.autofill_virtual_card_enrollment_dialog_education_text, - ChromeStringConstants.AUTOFILL_VIRTUAL_CARD_ENROLLMENT_SUPPORT_URL)); + ChromeStringConstants.AUTOFILL_VIRTUAL_CARD_ENROLLMENT_SUPPORT_URL, url -> { + RecordHistogram.recordEnumeratedHistogram(LINK_CLICK_HISTOGRAM, + VirtualCardDialogLink.EDUCATION_TEXT, + VirtualCardDialogLink.NUM_ENTRIES); + CustomTabActivity.showInfoPage(mContext, url); + })); virtualCardEducationTextView.setMovementMethod(LinkMovementMethod.getInstance()); TextView googleLegalMessageTextView = (TextView) customView.findViewById(R.id.google_legal_message); googleLegalMessageTextView.setText(AutofillUiUtils.getSpannableStringForLegalMessageLines( - mContext, mVirtualCardEnrollmentFields.getGoogleLegalMessages())); + mContext, mVirtualCardEnrollmentFields.getGoogleLegalMessages(), url -> { + RecordHistogram.recordEnumeratedHistogram(LINK_CLICK_HISTOGRAM, + VirtualCardDialogLink.GOOGLE_LEGAL_MESSAGE, + VirtualCardDialogLink.NUM_ENTRIES); + CustomTabActivity.showInfoPage(mContext, url); + })); googleLegalMessageTextView.setMovementMethod(LinkMovementMethod.getInstance()); TextView issuerLegalMessageTextView = (TextView) customView.findViewById(R.id.issuer_legal_message); issuerLegalMessageTextView.setText(AutofillUiUtils.getSpannableStringForLegalMessageLines( - mContext, mVirtualCardEnrollmentFields.getIssuerLegalMessages())); + mContext, mVirtualCardEnrollmentFields.getIssuerLegalMessages(), url -> { + RecordHistogram.recordEnumeratedHistogram(LINK_CLICK_HISTOGRAM, + VirtualCardDialogLink.ISSUER_LEGAL_MESSAGE, + VirtualCardDialogLink.NUM_ENTRIES); + CustomTabActivity.showInfoPage(mContext, url); + })); issuerLegalMessageTextView.setMovementMethod(LinkMovementMethod.getInstance()); ((TextView) customView.findViewById(R.id.credit_card_identifier)) diff --git a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialog.java b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialog.java index 5e073a984bf67..f49ada41e4a2b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialog.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/autofill/settings/AutofillVirtualCardUnenrollmentDialog.java @@ -7,9 +7,12 @@ import android.content.Context; import org.chromium.base.Callback; +import org.chromium.base.metrics.RecordHistogram; import org.chromium.chrome.R; import org.chromium.chrome.browser.ChromeStringConstants; import org.chromium.chrome.browser.autofill.AutofillUiUtils; +import org.chromium.chrome.browser.autofill.AutofillUiUtils.VirtualCardDialogLink; +import org.chromium.chrome.browser.customtabs.CustomTabActivity; import org.chromium.ui.modaldialog.DialogDismissalCause; import org.chromium.ui.modaldialog.ModalDialogManager; import org.chromium.ui.modaldialog.ModalDialogProperties; @@ -37,6 +40,9 @@ public AutofillVirtualCardUnenrollmentDialog(Context context, public void show() { SimpleModalDialogController modalDialogController = new SimpleModalDialogController(mModalDialogManager, result -> { + RecordHistogram.recordBooleanHistogram( + "Autofill.VirtualCard.SettingsPageUnenrollment", + result == DialogDismissalCause.POSITIVE_BUTTON_CLICKED); mResultHandler.onResult(result == DialogDismissalCause.POSITIVE_BUTTON_CLICKED); }); PropertyModel.Builder builder = @@ -50,7 +56,14 @@ public void show() { mContext, R.string.autofill_credit_card_editor_virtual_card_unenroll_dialog_message, ChromeStringConstants - .AUTOFILL_VIRTUAL_CARD_ENROLLMENT_SUPPORT_URL)) + .AUTOFILL_VIRTUAL_CARD_ENROLLMENT_SUPPORT_URL, + url -> { + RecordHistogram.recordEnumeratedHistogram( + "Autofill.VirtualCard.SettingsPageUnenrollment.LinkClicked", + VirtualCardDialogLink.EDUCATION_TEXT, + VirtualCardDialogLink.NUM_ENTRIES); + CustomTabActivity.showInfoPage(mContext, url); + })) .with(ModalDialogProperties.POSITIVE_BUTTON_TEXT, mContext.getString( R.string.autofill_credit_card_editor_virtual_card_unenroll_dialog_positive_button_label)) diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillServerCardEditorTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillServerCardEditorTest.java index 431e04493b006..e964bccadd295 100644 --- a/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillServerCardEditorTest.java +++ b/chrome/android/javatests/src/org/chromium/chrome/browser/autofill/settings/AutofillServerCardEditorTest.java @@ -23,12 +23,22 @@ import android.graphics.Bitmap; import android.os.Bundle; import android.support.test.runner.lifecycle.Stage; - +import android.text.Spanned; +import android.text.style.ClickableSpan; +import android.view.View; +import android.widget.TextView; + +import androidx.test.espresso.Espresso; +import androidx.test.espresso.NoMatchingViewException; +import androidx.test.espresso.UiController; +import androidx.test.espresso.ViewAction; import androidx.test.espresso.matcher.ViewMatchers.Visibility; import androidx.test.filters.MediumTest; +import org.hamcrest.Matcher; import org.hamcrest.Matchers; import org.junit.After; +import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; @@ -41,11 +51,13 @@ import org.mockito.junit.MockitoRule; import org.chromium.base.Callback; +import org.chromium.base.test.metrics.HistogramTestRule; import org.chromium.base.test.util.ApplicationTestUtils; import org.chromium.base.test.util.Batch; import org.chromium.base.test.util.JniMocker; import org.chromium.chrome.R; import org.chromium.chrome.browser.autofill.AutofillTestHelper; +import org.chromium.chrome.browser.autofill.AutofillUiUtils.VirtualCardDialogLink; import org.chromium.chrome.browser.autofill.LegalMessageLine; import org.chromium.chrome.browser.autofill.PersonalDataManager.CreditCard; import org.chromium.chrome.browser.flags.ChromeFeatureList; @@ -76,6 +88,8 @@ public class AutofillServerCardEditorTest { @Rule public final SettingsActivityTestRule mSettingsActivityTestRule = new SettingsActivityTestRule<>(AutofillServerCardEditor.class); + @Rule + public HistogramTestRule mHistogramTester = new HistogramTestRule(); private static final long NATIVE_AUTOFILL_PAYMENTS_METHODS_DELEGATE = 100L; @@ -213,6 +227,12 @@ public void virtualCardUnenrolledAndEligible_virtualCardAddButtonClicked_enrollA // Press the Add button. onView(withId(R.id.virtual_card_enrollment_button)).perform(click()); + // Verify that enrollment button click is recorded. + Assert.assertEquals(1, + mHistogramTester.getHistogramValueCount( + "Autofill.SettingsPage.ButtonClicked.VirtualCard.VirtualCardEnroll", + /* true */ 1)); + // Verify that the Virtual Card enrollment button still shows "Add" and that the button is // disabled. onView(withId(R.id.virtual_card_enrollment_button)) @@ -243,9 +263,26 @@ public void virtualCardUnenrolledAndEligible_virtualCardAddButtonClicked_enrollA // Verify that the dialog was displayed. onView(withId(R.id.dialog_title)).check(matches(isDisplayed())); + // Click on the education link. + onView(withId(R.id.virtual_card_education)).perform(clickLink()); + + // Verify that education text link click is recorded. + Assert.assertEquals(1, + mHistogramTester.getHistogramValueCount( + "Autofill.VirtualCard.SettingsPageEnrollment.LinkClicked", + VirtualCardDialogLink.EDUCATION_TEXT)); + + // Go back to the settings page. + Espresso.pressBack(); + // Click positive button on enrollment dialog. onView(withId(R.id.positive_button)).perform(click()); + // Verify that enrollment dialog acceptance is recorded. + Assert.assertEquals(1, + mHistogramTester.getHistogramValueCount( + "Autofill.VirtualCard.SettingsPageEnrollment", /* true */ 1)); + // Verify that the Virtual Card enrollment button shows "Remove" and that the button is // enabled. onView(withId(R.id.virtual_card_enrollment_button)) @@ -309,6 +346,11 @@ public void virtualCardUnenrolledAndEligible_virtualCardAddButtonClicked_enrollR // Click negative button on enrollment dialog. onView(withId(R.id.negative_button)).perform(click()); + // Verify that enrollment dialog rejection is recorded. + Assert.assertEquals(1, + mHistogramTester.getHistogramValueCount( + "Autofill.VirtualCard.SettingsPageEnrollment", /* false */ 0)); + // Verify that the Virtual Card enrollment button still shows "Add" and that the button is // now enabled. onView(withId(R.id.virtual_card_enrollment_button)) @@ -361,12 +403,25 @@ public void virtualCardEnrolled_virtualCardRemoveButtonClicked_unenrollCancelled // Press the Remove button. onView(withId(R.id.virtual_card_enrollment_button)).perform(click()); + + // Verify that unenrollment button click is recorded. + Assert.assertEquals(1, + mHistogramTester.getHistogramValueCount( + "Autofill.SettingsPage.ButtonClicked.VirtualCard.VirtualCardUnenroll", + /* true */ 1)); + // Verify that the unenroll dialog is shown. onView(withText(R.string.autofill_credit_card_editor_virtual_card_unenroll_dialog_title)) .check(matches(isDisplayed())); // Click the Cancel button. onView(withText(android.R.string.cancel)).perform(click()); + + // Verify that unenrollment dialog rejection is recorded. + Assert.assertEquals(1, + mHistogramTester.getHistogramValueCount( + "Autofill.VirtualCard.SettingsPageUnenrollment", /* false */ 0)); + // Verify that the button label has not changed from "Remove". onView(withId(R.id.virtual_card_enrollment_button)) .check(matches(withText(R.string.remove))); @@ -401,6 +456,12 @@ public void virtualCardEnrolled_virtualCardRemoveButtonClicked_unenrollAccepted( onView(withText( R.string.autofill_credit_card_editor_virtual_card_unenroll_dialog_positive_button_label)) .perform(click()); + + // Verify that unenrollment dialog acceptance is recorded. + Assert.assertEquals(1, + mHistogramTester.getHistogramValueCount( + "Autofill.VirtualCard.SettingsPageUnenrollment", /* true */ 1)); + // Verify that the Virtual Card enrollment button now shows "Add". onView(withId(R.id.virtual_card_enrollment_button)).check(matches(withText(R.string.add))); // Verify that the native unenroll method was called with the correct parameters. @@ -438,4 +499,34 @@ private Bundle fragmentArgs(String guid) { args.putString(AutofillEditorBase.AUTOFILL_GUID, guid); return args; } + + private ViewAction clickLink() { + return new ViewAction() { + @Override + public Matcher getConstraints() { + return Matchers.instanceOf(TextView.class); + } + + @Override + public String getDescription() { + return "Clicks on the only link in the view."; + } + + @Override + public void perform(UiController uiController, View view) { + TextView textView = (TextView) view; + Spanned spannedString = (Spanned) textView.getText(); + ClickableSpan[] spans = + spannedString.getSpans(0, spannedString.length(), ClickableSpan.class); + if (spans.length == 0) { + throw new NoMatchingViewException.Builder() + .includeViewHierarchy(true) + .withRootView(textView) + .build(); + } + Assert.assertEquals("There should be only one clickable link", 1, spans.length); + spans[0].onClick(view); + } + }; + } } diff --git a/components/autofill/core/browser/payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.cc b/components/autofill/core/browser/payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.cc index 86174da13bfa5..d3ae8f30ef239 100644 --- a/components/autofill/core/browser/payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.cc +++ b/components/autofill/core/browser/payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.cc @@ -21,7 +21,10 @@ AutofillVirtualCardEnrollmentInfoBarDelegateMobile:: virtual_card_enroll_bubble_controller) {} AutofillVirtualCardEnrollmentInfoBarDelegateMobile:: - ~AutofillVirtualCardEnrollmentInfoBarDelegateMobile() = default; + ~AutofillVirtualCardEnrollmentInfoBarDelegateMobile() { + if (!had_user_interaction_) + OnInfobarClosed(PaymentsBubbleClosedReason::kNotInteracted); +} // static AutofillVirtualCardEnrollmentInfoBarDelegateMobile* @@ -113,17 +116,28 @@ AutofillVirtualCardEnrollmentInfoBarDelegateMobile::GetButtonLabel( } void AutofillVirtualCardEnrollmentInfoBarDelegateMobile::InfoBarDismissed() { + OnInfobarClosed(PaymentsBubbleClosedReason::kClosed); virtual_card_enroll_bubble_controller_->OnDeclineButton(); } bool AutofillVirtualCardEnrollmentInfoBarDelegateMobile::Cancel() { + OnInfobarClosed(PaymentsBubbleClosedReason::kClosed); virtual_card_enroll_bubble_controller_->OnDeclineButton(); return true; } bool AutofillVirtualCardEnrollmentInfoBarDelegateMobile::Accept() { + OnInfobarClosed(PaymentsBubbleClosedReason::kAccepted); virtual_card_enroll_bubble_controller_->OnAcceptButton(); return true; } +void AutofillVirtualCardEnrollmentInfoBarDelegateMobile::OnInfobarClosed( + PaymentsBubbleClosedReason closed_reason) { + DCHECK(!had_user_interaction_); + + virtual_card_enroll_bubble_controller_->OnBubbleClosed(closed_reason); + had_user_interaction_ = true; +} + } // namespace autofill diff --git a/components/autofill/core/browser/payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.h b/components/autofill/core/browser/payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.h index 3ba47778ae246..df05618abbb78 100644 --- a/components/autofill/core/browser/payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.h +++ b/components/autofill/core/browser/payments/autofill_virtual_card_enrollment_infobar_delegate_mobile.h @@ -70,9 +70,15 @@ class AutofillVirtualCardEnrollmentInfoBarDelegateMobile bool Accept() override; private: + // Logs metrics via the native controller. + void OnInfobarClosed(PaymentsBubbleClosedReason closed_reason); + // Pointer to the native controller. raw_ptr virtual_card_enroll_bubble_controller_; + + // Did the user ever explicitly accept or dismiss this infobar? + bool had_user_interaction_ = false; }; } // namespace autofill diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 8cb77e91f80d8..2ba4590553eb6 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml @@ -7543,6 +7543,12 @@ others/histograms.xml --> + + + + + + diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml index 9e09afa04651e..5c1e29eace00e 100644 --- a/tools/metrics/histograms/metadata/autofill/histograms.xml +++ b/tools/metrics/histograms/metadata/autofill/histograms.xml @@ -79,9 +79,9 @@ chromium-metrics-reviews@google.com. - - - + + + @@ -101,6 +101,13 @@ chromium-metrics-reviews@google.com. summary="Progress dialog for the VCN Card Unmask Flow"/> + + + + + @@ -2707,6 +2714,23 @@ chromium-metrics-reviews@google.com. + + vishwasuppoor@chromium.org + siashah@chromium.org + payments-autofill-team@google.com + + Emits true whenever {Button} is clicked in the mobile {CardType} edit page. + Never emits false. + + + + + + + + + siashah@chromium.org @@ -3351,9 +3375,34 @@ chromium-metrics-reviews@google.com. + + vishwasuppoor@chromium.org + siashah@chromium.org + payments-autofill-team@google.com + + Emits true when a user accepts {Dialog} in the mobile virtual card edit + page. Emits false if the user declines. + + + + + + vishwasuppoor@chromium.org + siashah@chromium.org + payments-autofill-team@google.com + + Records which link is clicked whenever a user clicks on links in {Dialog} in + the mobile virtual card edit page. The links are the education text link, + Google legal message link, and issuer legal message link. + + + + + enum="AutofillVirtualCardEnrollBubbleResult" expires_after="2023-04-01"> alexandertekle@google.com siyua@chromium.org payments-autofill-team@google.com @@ -3367,13 +3416,15 @@ chromium-metrics-reviews@google.com. + enum="BooleanPreviouslyShown" expires_after="2023-04-01"> alexandertekle@google.com siyua@chromium.org payments-autofill-team@google.com Records the reason for starting the virtual card enroll bubble for flows that start from {EnrollmentSource}. Recorded when the bubble is shown. + Records false the first time the bubble is shown, true for subsequent bubble + shows.