Merge "Refine metrics log in infrastructure" into rvc-dev
diff --git a/src/com/android/settings/applications/RecentAppsPreferenceController.java b/src/com/android/settings/applications/RecentAppsPreferenceController.java
index 28a88a2..69a68ef 100644
--- a/src/com/android/settings/applications/RecentAppsPreferenceController.java
+++ b/src/com/android/settings/applications/RecentAppsPreferenceController.java
@@ -17,7 +17,6 @@
 package com.android.settings.applications;
 
 import android.app.Application;
-import android.app.settings.SettingsEnums;
 import android.app.usage.UsageStats;
 import android.content.Context;
 import android.icu.text.RelativeDateTimeFormatter;
@@ -98,12 +97,12 @@
                 .setHeaderTitleRes(R.string.recent_app_category_title)
                 .setHeaderDetailsClickListener((View v) -> {
                     mMetricsFeatureProvider.logClickedPreference(mRecentAppsPreference,
-                            SettingsEnums.SETTINGS_APP_NOTIF_CATEGORY);
+                            getMetricsCategory());
                     new SubSettingLauncher(mContext)
                             .setDestination(ManageApplications.class.getName())
                             .setArguments(null /* arguments */)
                             .setTitleRes(R.string.application_info_label)
-                            .setSourceMetricsCategory(SettingsEnums.SETTINGS_APP_NOTIF_CATEGORY)
+                            .setSourceMetricsCategory(getMetricsCategory())
                             .launch();
                 });
     }
@@ -166,11 +165,10 @@
                         RelativeDateTimeFormatter.Style.SHORT))
                 .setOnClickListener(v -> {
                     mMetricsFeatureProvider.logClickedPreference(mRecentAppsPreference,
-                            SettingsEnums.SETTINGS_APP_NOTIF_CATEGORY);
+                            getMetricsCategory());
                     AppInfoBase.startAppInfoFragment(AppInfoDashboardFragment.class,
                             R.string.application_info_label, pkgName, appEntry.info.uid,
-                            mHost, 1001 /*RequestCode*/,
-                            SettingsEnums.SETTINGS_APP_NOTIF_CATEGORY);
+                            mHost, 1001 /*RequestCode*/, getMetricsCategory());
                 })
                 .build();
     }
diff --git a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java
index b5ccd73..d8ec848 100644
--- a/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java
+++ b/src/com/android/settings/applications/specialaccess/deviceadmin/DeviceAdminListPreferenceController.java
@@ -46,7 +46,6 @@
 import androidx.preference.SwitchPreference;
 
 import com.android.settings.core.BasePreferenceController;
-import com.android.settings.dashboard.DashboardFragment;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
@@ -202,8 +201,7 @@
         pref.setSummary(item.getDescription());
         pref.setEnabled(item.isEnabled());
         pref.setOnPreferenceClickListener(preference -> {
-            mMetricsFeatureProvider.logClickedPreference(preference,
-                    preference.getExtras().getInt(DashboardFragment.CATEGORY));
+            mMetricsFeatureProvider.logClickedPreference(preference, getMetricsCategory());
             final UserHandle user = item.getUser();
             mContext.startActivityAsUser(item.getLaunchIntent(mContext), user);
             return true;
diff --git a/src/com/android/settings/core/BasePreferenceController.java b/src/com/android/settings/core/BasePreferenceController.java
index 1985a99..c90fe48 100644
--- a/src/com/android/settings/core/BasePreferenceController.java
+++ b/src/com/android/settings/core/BasePreferenceController.java
@@ -124,6 +124,7 @@
     private boolean mIsForWork;
     @Nullable
     private UserHandle mWorkProfileUser;
+    private int mMetricsCategory;
 
     /**
      * Instantiate a controller as specified controller type and user-defined key.
@@ -398,12 +399,28 @@
      * This won't block UI thread however has similar side effect. Please use it if you
      * want to avoid janky animation(i.e. new preference is added in the middle of page).
      *
-     * This music be used in {@link BasePreferenceController}
+     * This must be used in {@link BasePreferenceController}
      */
     public interface UiBlocker {
     }
 
     /**
+     * Set the metrics category of the parent fragment.
+     *
+     * Called by DashboardFragment#onAttach
+     */
+    public void setMetricsCategory(int metricsCategory) {
+        mMetricsCategory = metricsCategory;
+    }
+
+    /**
+     * @return the metrics category of the parent fragment.
+     */
+    protected int getMetricsCategory() {
+        return mMetricsCategory;
+    }
+
+    /**
      * @return Non-{@code null} {@link UserHandle} when a work profile is enabled.
      * Otherwise {@code null}.
      */
diff --git a/src/com/android/settings/core/TogglePreferenceController.java b/src/com/android/settings/core/TogglePreferenceController.java
index 7abe6e0..5a2a8b7 100644
--- a/src/com/android/settings/core/TogglePreferenceController.java
+++ b/src/com/android/settings/core/TogglePreferenceController.java
@@ -18,8 +18,10 @@
 import androidx.preference.Preference;
 import androidx.preference.TwoStatePreference;
 
+import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.slices.SliceData;
 import com.android.settings.widget.MasterSwitchPreference;
+import com.android.settings.widget.TwoStateButtonPreference;
 
 /**
  * Abstract class that consolidates logic for updating toggle controllers.
@@ -54,6 +56,8 @@
             ((TwoStatePreference) preference).setChecked(isChecked());
         } else if (preference instanceof MasterSwitchPreference) {
             ((MasterSwitchPreference) preference).setChecked(isChecked());
+        } else if (preference instanceof TwoStateButtonPreference) {
+            ((TwoStateButtonPreference) preference).setChecked(isChecked());
         } else {
             refreshSummary(preference);
         }
@@ -61,6 +65,12 @@
 
     @Override
     public final boolean onPreferenceChange(Preference preference, Object newValue) {
+        // TwoStatePreference is a regular preference and can be handled by DashboardFragment
+        if (preference instanceof MasterSwitchPreference
+                || preference instanceof TwoStateButtonPreference) {
+            FeatureFactory.getFactory(mContext).getMetricsFeatureProvider()
+                    .logClickedPreference(preference, getMetricsCategory());
+        }
         return setChecked((boolean) newValue);
     }
 
diff --git a/src/com/android/settings/dashboard/DashboardFragment.java b/src/com/android/settings/dashboard/DashboardFragment.java
index d121195..c70d841 100644
--- a/src/com/android/settings/dashboard/DashboardFragment.java
+++ b/src/com/android/settings/dashboard/DashboardFragment.java
@@ -113,6 +113,14 @@
             }
         });
 
+        // Set metrics category for BasePreferenceController.
+        final int metricCategory = getMetricsCategory();
+        mControllers.forEach(controller -> {
+            if (controller instanceof BasePreferenceController) {
+                ((BasePreferenceController) controller).setMetricsCategory(metricCategory);
+            }
+        });
+
         mPlaceholderPreferenceController =
                 new DashboardTilePlaceholderPreferenceController(context);
         mControllers.add(mPlaceholderPreferenceController);
diff --git a/src/com/android/settings/display/DarkUIPreferenceController.java b/src/com/android/settings/display/DarkUIPreferenceController.java
index c2da56a..98d9a69 100644
--- a/src/com/android/settings/display/DarkUIPreferenceController.java
+++ b/src/com/android/settings/display/DarkUIPreferenceController.java
@@ -17,7 +17,6 @@
 package com.android.settings.display;
 
 import android.app.UiModeManager;
-import android.app.settings.SettingsEnums;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -33,8 +32,6 @@
 
 import com.android.settings.R;
 import com.android.settings.core.TogglePreferenceController;
-import com.android.settings.overlay.FeatureFactory;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -49,7 +46,6 @@
     @VisibleForTesting
     Preference mPreference;
 
-    private final MetricsFeatureProvider mMetricsFeatureProvider;
     private UiModeManager mUiModeManager;
     private PowerManager mPowerManager;
     private Context mContext;
@@ -68,7 +64,6 @@
         mContext = context;
         mUiModeManager = context.getSystemService(UiModeManager.class);
         mPowerManager = context.getSystemService(PowerManager.class);
-        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
     }
 
     @Override
@@ -91,7 +86,6 @@
 
     @Override
     public boolean setChecked(boolean isChecked) {
-        mMetricsFeatureProvider.logClickedPreference(mPreference, SettingsEnums.DISPLAY);
         final boolean dialogSeen =
                 Settings.Secure.getInt(mContext.getContentResolver(),
                         Settings.Secure.DARK_MODE_DIALOG_SEEN, 0) == DIALOG_SEEN;
diff --git a/src/com/android/settings/display/NightDisplayActivationPreferenceController.java b/src/com/android/settings/display/NightDisplayActivationPreferenceController.java
index f68df50..4b1e295 100644
--- a/src/com/android/settings/display/NightDisplayActivationPreferenceController.java
+++ b/src/com/android/settings/display/NightDisplayActivationPreferenceController.java
@@ -16,7 +16,6 @@
 
 package com.android.settings.display;
 
-import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.hardware.display.ColorDisplayManager;
 import android.text.TextUtils;
@@ -50,8 +49,7 @@
         @Override
         public void onClick(View v) {
             mButtonTriggered = true;
-            mMetricsFeatureProvider.logClickedPreference(mPreference,
-                    SettingsEnums.NIGHT_DISPLAY_SETTINGS);
+            mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory());
             mColorDisplayManager.setNightDisplayActivated(
                     !mColorDisplayManager.isNightDisplayActivated());
             updateStateInternal();
diff --git a/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java b/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java
index 622f2e2..74b029f 100644
--- a/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java
+++ b/src/com/android/settings/display/darkmode/DarkModeActivationPreferenceController.java
@@ -16,7 +16,6 @@
 package com.android.settings.display.darkmode;
 
 import android.app.UiModeManager;
-import android.app.settings.SettingsEnums;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.os.PowerManager;
@@ -136,8 +135,7 @@
     private final View.OnClickListener mListener = new View.OnClickListener() {
         @Override
         public void onClick(View v) {
-            mMetricsFeatureProvider.logClickedPreference(mPreference,
-                    SettingsEnums.DARK_UI_SETTINGS);
+            mMetricsFeatureProvider.logClickedPreference(mPreference, getMetricsCategory());
             final boolean active = (mContext.getResources().getConfiguration().uiMode
                     & Configuration.UI_MODE_NIGHT_YES) != 0;
             mUiModeManager.setNightModeActivated(!active);
diff --git a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java
index fff6523..a089abc 100644
--- a/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batterysaver/BatterySaverButtonPreferenceController.java
@@ -16,21 +16,17 @@
 
 package com.android.settings.fuelgauge.batterysaver;
 
-import android.app.settings.SettingsEnums;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.net.Uri;
 import android.os.PowerManager;
 import android.provider.SettingsSlicesContract;
 
-import androidx.preference.Preference;
 import androidx.preference.PreferenceScreen;
 
 import com.android.settings.core.TogglePreferenceController;
 import com.android.settings.fuelgauge.BatterySaverReceiver;
-import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.widget.TwoStateButtonPreference;
-import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
 import com.android.settingslib.core.lifecycle.LifecycleObserver;
 import com.android.settingslib.core.lifecycle.events.OnStart;
 import com.android.settingslib.core.lifecycle.events.OnStop;
@@ -45,13 +41,11 @@
 
     private final BatterySaverReceiver mBatterySaverReceiver;
     private final PowerManager mPowerManager;
-    private final MetricsFeatureProvider mMetricsFeatureProvider;
 
     private TwoStateButtonPreference mPreference;
 
     public BatterySaverButtonPreferenceController(Context context, String key) {
         super(context, key);
-        mMetricsFeatureProvider = FeatureFactory.getFactory(context).getMetricsFeatureProvider();
         mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
         mBatterySaverReceiver = new BatterySaverReceiver(context);
         mBatterySaverReceiver.setBatterySaverListener(this);
@@ -100,22 +94,12 @@
 
     @Override
     public boolean setChecked(boolean stateOn) {
-        mMetricsFeatureProvider.logClickedPreference(mPreference,
-                SettingsEnums.FUELGAUGE_BATTERY_SAVER);
         // This screen already shows a warning, so we don't need another warning.
         return BatterySaverUtils.setPowerSaveMode(mContext, stateOn,
                 false /* needFirstTimeWarning */);
     }
 
     @Override
-    public void updateState(Preference preference) {
-        super.updateState(preference);
-        if (mPreference != null) {
-            mPreference.setChecked(isChecked());
-        }
-    }
-
-    @Override
     public void onPowerSaveModeChanged() {
         final boolean isChecked = isChecked();
         if (mPreference != null && mPreference.isChecked() != isChecked) {
diff --git a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java
index fc18f60..0707c2c 100644
--- a/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/core/BasePreferenceControllerTest.java
@@ -28,6 +28,7 @@
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
+import android.app.settings.SettingsEnums;
 import android.content.Context;
 
 import androidx.preference.Preference;
@@ -205,6 +206,15 @@
         assertThat(keys).isEmpty();
     }
 
+    @Test
+    public void getMetricsCategory_metricsCategoryIsSet_shouldReturnTheSameCategory() {
+        mPreferenceController.setMetricsCategory(SettingsEnums.DISPLAY);
+
+        final int category = mPreferenceController.getMetricsCategory();
+
+        assertThat(category).isEqualTo(SettingsEnums.DISPLAY);
+    }
+
     private class FakeBasePreferenceController extends BasePreferenceController {
 
         private int mAvailable;