[Android][Settings] Record usage of autofill options entry point

To check the usage (and in the future compare it with different places),
add a referrer parameter when launching the AutofillOptions screen.

The main entry point is the settings surface and the bucket count
will serve as a regression metric for different locations.
Other planned entry points are:
- deep links (i.e. a link from another App to this setting)
- links from messages (to fix inconsistency device & browser setting)
- potentially entry points from fallback surfaces

The deep link bucket is added but not recorded to satisfy the
argument checks in recording which would crash otherwise.


Bug: 1472225
Change-Id: I442cdff462d102628dd848b623a98a957a8c51fc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4798450
Reviewed-by: Timofey Chudakov <tchudakov@google.com>
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
Commit-Queue: Friedrich Horschig <fhorschig@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1187268}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
index 80af899..ce1b8f6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/settings/MainSettings.java
@@ -20,6 +20,8 @@
 import org.chromium.base.ContextUtils;
 import org.chromium.base.supplier.ObservableSupplier;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.autofill.options.AutofillOptionsFragment;
+import org.chromium.chrome.browser.autofill.options.AutofillOptionsFragment.AutofillOptionsReferrer;
 import org.chromium.chrome.browser.autofill.settings.SettingsLauncherHelper;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.homepage.HomepageManager;
@@ -236,14 +238,6 @@
             removePreferenceIfPresent(PREF_SIGN_IN);
         }
 
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
-                && ChromeFeatureList.isEnabled(
-                        ChromeFeatureList.AUTOFILL_VIRTUAL_VIEW_STRUCTURE_ANDROID)) {
-            addPreferenceIfAbsent(PREF_AUTOFILL_OPTIONS);
-        } else {
-            removePreferenceIfPresent(PREF_AUTOFILL_OPTIONS);
-        }
-
         updateManageSyncPreference();
         updateSearchEnginePreference();
         updateAutofillPreferences();
@@ -326,6 +320,22 @@
     }
 
     private void updateAutofillPreferences() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
+                && ChromeFeatureList.isEnabled(
+                        ChromeFeatureList.AUTOFILL_VIRTUAL_VIEW_STRUCTURE_ANDROID)) {
+            addPreferenceIfAbsent(PREF_AUTOFILL_OPTIONS);
+            Preference preference = findPreference(PREF_AUTOFILL_OPTIONS);
+            preference.setFragment(null);
+            preference.setOnPreferenceClickListener(unused -> {
+                new SettingsLauncherImpl().launchSettingsActivity(getContext(),
+                        AutofillOptionsFragment.class,
+                        AutofillOptionsFragment.createRequiredArgs(
+                                AutofillOptionsReferrer.SETTINGS));
+                return true; // Means event is consumed.
+            });
+        } else {
+            removePreferenceIfPresent(PREF_AUTOFILL_OPTIONS);
+        }
         findPreference(PREF_AUTOFILL_PAYMENTS)
                 .setOnPreferenceClickListener(preference
                         -> SettingsLauncherHelper.showAutofillCreditCardSettings(getActivity()));
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsCoordinator.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsCoordinator.java
index fd4c2b5..426c8ea 100644
--- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsCoordinator.java
+++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsCoordinator.java
@@ -84,7 +84,7 @@
                                         .getBoolean(Pref.AUTOFILL_USING_VIRTUAL_VIEW_STRUCTURE))
                         .with(ON_THIRD_PARTY_TOGGLE_CHANGED, mMediator::onThirdPartyToggleChanged)
                         .build();
-        mMediator.initialize(model);
+        mMediator.initialize(model, mFragment.getReferrer());
 
         PropertyModelChangeProcessor.create(model, mFragment, AutofillOptionsViewBinder::bind);
         return model;
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsFragment.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsFragment.java
index 2bc33c44..74061a53 100644
--- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsFragment.java
+++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsFragment.java
@@ -9,6 +9,7 @@
 import android.view.MenuInflater;
 import android.view.MenuItem;
 
+import androidx.annotation.IntDef;
 import androidx.preference.PreferenceFragmentCompat;
 
 import org.chromium.chrome.browser.autofill.R;
@@ -17,15 +18,43 @@
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.chrome.browser.settings.ProfileDependentSetting;
 import org.chromium.components.browser_ui.settings.SettingsUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 /**
  * Autofill options fragment, which allows the user to configure autofill.
  */
 public class AutofillOptionsFragment extends PreferenceFragmentCompat
         implements FragmentHelpAndFeedbackLauncher, ProfileDependentSetting {
+    // Key for the argument with which the AutofillOptions fragment will be launched. The value for
+    // this argument is part of the AutofillOptionsReferrer enum containing all entry points.
+    public static final String AUTOFILL_OPTIONS_REFERRER = "autofill-options-referrer";
     public static final String PREF_AUTOFILL_THIRD_PARTY_FILLING = "autofill_third_party_filling";
 
     private Profile mProfile;
     private HelpAndFeedbackLauncher mHelpAndFeedbackLauncher;
+    private @AutofillOptionsReferrer int mReferrer;
+
+    // Represents different referrers when navigating to the Autofill Options page.
+    //
+    // These values are persisted to logs. Entries should not be renumbered and
+    // numeric values should never be reused.
+    //
+    // Needs to stay in sync with AutofillOptionsReferrer in enums.xml.
+    @IntDef({AutofillOptionsReferrer.SETTINGS, AutofillOptionsReferrer.DEEP_LINK_TO_SETTINGS,
+            AutofillOptionsReferrer.COUNT})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AutofillOptionsReferrer {
+        /**
+         * Corresponds to the Settings page.
+         */
+        int SETTINGS = 0;
+        /**
+         * Corresponds to an external link opening Chrome.
+         */
+        int DEEP_LINK_TO_SETTINGS = 1;
+        int COUNT = 2;
+    }
 
     /**
      * This default constructor is required to instantiate the fragment.
@@ -47,6 +76,12 @@
     }
 
     @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mReferrer = getReferrerFromInstanceStateOrLaunchBundle(savedInstanceState);
+    }
+
+    @Override
     public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
         menu.clear();
         MenuItem help =
@@ -83,4 +118,33 @@
     public void setProfile(Profile profile) {
         mProfile = profile;
     }
+
+    public static Bundle createRequiredArgs(@AutofillOptionsReferrer int referrer) {
+        Bundle requiredArgs = new Bundle();
+        requiredArgs.putInt(AUTOFILL_OPTIONS_REFERRER, referrer);
+        return requiredArgs;
+    }
+
+    @AutofillOptionsReferrer
+    int getReferrer() {
+        return mReferrer;
+    }
+
+    @Override
+    public void onSaveInstanceState(Bundle outState) {
+        super.onSaveInstanceState(outState);
+        outState.putInt(AUTOFILL_OPTIONS_REFERRER, mReferrer);
+    }
+
+    private @AutofillOptionsReferrer int getReferrerFromInstanceStateOrLaunchBundle(
+            Bundle savedInstanceState) {
+        if (savedInstanceState != null
+                && savedInstanceState.containsKey(AUTOFILL_OPTIONS_REFERRER)) {
+            return savedInstanceState.getInt(AUTOFILL_OPTIONS_REFERRER);
+        }
+        Bundle extras = getArguments();
+        assert extras.containsKey(AUTOFILL_OPTIONS_REFERRER)
+            : "AutofillOptionsFragment must be launched with a autofill-options-referrer fragment!";
+        return extras.getInt(AUTOFILL_OPTIONS_REFERRER);
+    }
 }
diff --git a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsMediator.java b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsMediator.java
index debd190..0231011 100644
--- a/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsMediator.java
+++ b/chrome/browser/autofill/android/java/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsMediator.java
@@ -9,6 +9,7 @@
 import androidx.annotation.VisibleForTesting;
 
 import org.chromium.base.metrics.RecordHistogram;
+import org.chromium.chrome.browser.autofill.options.AutofillOptionsFragment.AutofillOptionsReferrer;
 import org.chromium.chrome.browser.preferences.Pref;
 import org.chromium.chrome.browser.profiles.Profile;
 import org.chromium.components.prefs.PrefService;
@@ -23,6 +24,8 @@
     @VisibleForTesting
     static final String HISTOGRAM_USE_THIRD_PARTY_FILLING =
             "Autofill.Settings.ToggleUseThirdPartyFilling";
+    @VisibleForTesting
+    static final String HISTOGRAM_REFERRER = "Autofill.Settings.AutofillOptionsReferrerAndroid";
     private final Profile mProfile;
     private PropertyModel mModel;
 
@@ -30,8 +33,10 @@
         mProfile = profile;
     }
 
-    void initialize(PropertyModel model) {
+    void initialize(PropertyModel model, @AutofillOptionsReferrer int referrer) {
         mModel = model;
+        RecordHistogram.recordEnumeratedHistogram(
+                HISTOGRAM_REFERRER, referrer, AutofillOptionsReferrer.COUNT);
     }
 
     boolean isInitialized() {
diff --git a/chrome/browser/autofill/android/junit/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsTest.java b/chrome/browser/autofill/android/junit/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsTest.java
index ddc4abd8..8659916 100644
--- a/chrome/browser/autofill/android/junit/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsTest.java
+++ b/chrome/browser/autofill/android/junit/src/org/chromium/chrome/browser/autofill/options/AutofillOptionsTest.java
@@ -15,7 +15,6 @@
 import static org.chromium.chrome.browser.autofill.options.AutofillOptionsProperties.ON_THIRD_PARTY_TOGGLE_CHANGED;
 import static org.chromium.chrome.browser.autofill.options.AutofillOptionsProperties.THIRD_PARTY_AUTOFILL_ENABLED;
 
-import android.os.Bundle;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
@@ -40,6 +39,7 @@
 import org.chromium.base.test.util.HistogramWatcher;
 import org.chromium.base.test.util.JniMocker;
 import org.chromium.chrome.R;
+import org.chromium.chrome.browser.autofill.options.AutofillOptionsFragment.AutofillOptionsReferrer;
 import org.chromium.chrome.browser.feedback.HelpAndFeedbackLauncher;
 import org.chromium.chrome.browser.flags.ChromeFeatureList;
 import org.chromium.chrome.browser.preferences.Pref;
@@ -86,8 +86,9 @@
         mJniMocker.mock(UserPrefsJni.TEST_HOOKS, mMockUserPrefsJni);
         doReturn(mPrefs).when(mMockUserPrefsJni).get(mProfile);
 
-        mScenario = FragmentScenario.launchInContainer(
-                AutofillOptionsFragment.class, Bundle.EMPTY, R.style.Theme_MaterialComponents);
+        mScenario = FragmentScenario.launchInContainer(AutofillOptionsFragment.class,
+                AutofillOptionsFragment.createRequiredArgs(AutofillOptionsReferrer.SETTINGS),
+                R.style.Theme_MaterialComponents);
         mScenario.onFragment(fragment -> {
             mFragment = (AutofillOptionsFragment) fragment; // Valid until scenario is recreated.
             mFragment.setProfile(mProfile);
@@ -217,6 +218,18 @@
                 .show(mFragment.getActivity(), getString(R.string.help_context_autofill), null);
     }
 
+    @Test
+    @SmallTest
+    public void passedReferrerRecordedInHistogram() {
+        HistogramWatcher histogramWatcher = HistogramWatcher.newSingleRecordWatcher(
+                AutofillOptionsMediator.HISTOGRAM_REFERRER, AutofillOptionsReferrer.SETTINGS);
+
+        // Component initialization triggers the recording.
+        AutofillOptionsCoordinator.createFor(mFragment);
+
+        histogramWatcher.assertExpected();
+    }
+
     private String getString(@StringRes int stringId) {
         return mFragment.getResources().getString(stringId);
     }
diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml
index 5a8073d..18669cd 100644
--- a/tools/metrics/histograms/enums.xml
+++ b/tools/metrics/histograms/enums.xml
@@ -7615,6 +7615,11 @@
   <int value="2" label="User did not interact with the infobar"/>
 </enum>
 
+<enum name="AutofillOptionsReferrer">
+  <int value="0" label="User entered the autofill options via main settings."/>
+  <int value="1" label="User entered the autofill options via deep link."/>
+</enum>
+
 <enum name="AutofillOtpAuthEvent">
   <int value="0" label="Unknown result"/>
   <int value="1" label="OTP auth succeeded"/>
diff --git a/tools/metrics/histograms/metadata/autofill/histograms.xml b/tools/metrics/histograms/metadata/autofill/histograms.xml
index 96817138..646afe3 100644
--- a/tools/metrics/histograms/metadata/autofill/histograms.xml
+++ b/tools/metrics/histograms/metadata/autofill/histograms.xml
@@ -4209,6 +4209,16 @@
   </summary>
 </histogram>
 
+<histogram name="Autofill.Settings.AutofillOptionsReferrerAndroid"
+    enum="AutofillOptionsReferrer" expires_after="2024-01-30">
+  <owner>fhorschig@chromium.org</owner>
+  <owner>chrome-autofill-alerts@google.com</owner>
+  <summary>
+    Records which entry point opened the Autofill Options screen. Recorded on
+    Android.
+  </summary>
+</histogram>
+
 <histogram name="Autofill.Settings.ToggleUseThirdPartyFilling" enum="Boolean"
     expires_after="2024-01-30">
   <owner>fhorschig@chromium.org</owner>