From 9f57691d894fd1f301b1a38cdb083de3b22b2baf Mon Sep 17 00:00:00 2001 From: Zaiyue Xue Date: Sat, 19 Aug 2023 17:30:11 +0800 Subject: [PATCH] Add UI metrics logging for battery tips card. Bug: 291689623 Test: manual Change-Id: I925e4d887c3435239aed0aa0fde7cda2c3a95b3c Merged-In: I925e4d887c3435239aed0aa0fde7cda2c3a95b3c --- .../BatteryTipsCardPreference.java | 29 +++++++++++++++---- .../batteryusage/BatteryTipsController.java | 17 +++++++---- .../BatteryTipsCardPreferenceTest.java | 28 ++++++++++++++---- .../BatteryTipsControllerTest.java | 24 ++++++++++----- .../settings/testutils/BatteryTestUtils.java | 2 ++ 5 files changed, 75 insertions(+), 25 deletions(-) diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java index 5857d628f44..61b3e2f1db3 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java @@ -16,6 +16,7 @@ package com.android.settings.fuelgauge.batteryusage; +import android.app.settings.SettingsEnums; import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; @@ -32,6 +33,7 @@ import com.android.settings.R; import com.android.settings.core.SubSettingLauncher; import com.android.settings.fuelgauge.PowerUsageFeatureProvider; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.google.android.material.button.MaterialButton; @@ -43,6 +45,9 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic private static final String TAG = "BatteryTipsCardPreference"; private final PowerUsageFeatureProvider mPowerUsageFeatureProvider; + private final MetricsFeatureProvider mMetricsFeatureProvider; + + private String mAnomalyEventId; @VisibleForTesting CharSequence mMainButtonLabel; @@ -51,18 +56,26 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic @VisibleForTesting String mDestinationComponentName; @VisibleForTesting - int mSourceMetricsCategory; + Integer mSourceMetricsCategory; public BatteryTipsCardPreference(Context context, AttributeSet attrs) { super(context, attrs); setLayoutResource(R.layout.battery_tips_card); setSelectable(false); - mPowerUsageFeatureProvider = FeatureFactory.getFactory(context) - .getPowerUsageFeatureProvider(context); + final FeatureFactory featureFactory = FeatureFactory.getFactory(context); + mPowerUsageFeatureProvider = featureFactory.getPowerUsageFeatureProvider(context); + mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider(); } /** - * Update the label of main button in tips card. + * Sets the anomaly event id which is used in metrics. + */ + public void setAnomalyEventId(final String anomalyEventId) { + mAnomalyEventId = anomalyEventId; + } + + /** + * Sets the label of main button in tips card. */ public void setMainButtonLabel(CharSequence label) { if (!TextUtils.equals(mMainButtonLabel, label)) { @@ -72,7 +85,7 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic } /** - * Update the label of dismiss button in tips card. + * Sets the label of dismiss button in tips card. */ public void setDismissButtonLabel(CharSequence label) { if (!TextUtils.equals(mDismissButtonLabel, label)) { @@ -82,7 +95,7 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic } /** - * Update the info of target fragment launched by main button. + * Sets the info of target fragment launched by main button. */ public void setMainButtonLauncherInfo(final String destinationClassName, final Integer sourceMetricsCategory) { @@ -102,8 +115,12 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic .setSourceMetricsCategory(mSourceMetricsCategory) .launch(); setVisible(false); + mMetricsFeatureProvider.action( + getContext(), SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, mAnomalyEventId); } else if (viewId == R.id.dismiss_button) { setVisible(false); + mMetricsFeatureProvider.action( + getContext(), SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, mAnomalyEventId); } } diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java index 42604f57b92..09e0c77dcba 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java @@ -16,6 +16,7 @@ package com.android.settings.fuelgauge.batteryusage; +import android.app.settings.SettingsEnums; import android.content.Context; import android.text.TextUtils; @@ -26,6 +27,7 @@ import com.android.settings.R; import com.android.settings.core.BasePreferenceController; import com.android.settings.fuelgauge.PowerUsageFeatureProvider; import com.android.settings.overlay.FeatureFactory; +import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import java.util.function.Function; @@ -36,19 +38,20 @@ public class BatteryTipsController extends BasePreferenceController { private static final String ROOT_PREFERENCE_KEY = "battery_tips_category"; private static final String CARD_PREFERENCE_KEY = "battery_tips_card"; + private final PowerUsageFeatureProvider mPowerUsageFeatureProvider; + private final MetricsFeatureProvider mMetricsFeatureProvider; + @VisibleForTesting BatteryTipsCardPreference mCardPreference; - @VisibleForTesting - PowerUsageFeatureProvider mPowerUsageFeatureProvider; public BatteryTipsController(Context context) { super(context, ROOT_PREFERENCE_KEY); - mPowerUsageFeatureProvider = FeatureFactory.getFactory(context) - .getPowerUsageFeatureProvider(context); + final FeatureFactory featureFactory = FeatureFactory.getFactory(context); + mPowerUsageFeatureProvider = featureFactory.getPowerUsageFeatureProvider(context); + mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider(); } private boolean isTipsCardVisible() { - // TODO: compared with the timestamp of last user dismiss action in sharedPreference. return mPowerUsageFeatureProvider.isBatteryTipsEnabled(); } @@ -131,10 +134,14 @@ public class BatteryTipsController extends BasePreferenceController { WarningItemInfo::getMainButtonSourceMetricsCategory); // Updated card preference and main button fragment launcher + mCardPreference.setAnomalyEventId(powerAnomalyEvent.getEventId()); mCardPreference.setTitle(titleString); mCardPreference.setMainButtonLabel(mainBtnString); mCardPreference.setDismissButtonLabel(dismissBtnString); mCardPreference.setMainButtonLauncherInfo(destinationClassName, sourceMetricsCategory); mCardPreference.setVisible(true); + + mMetricsFeatureProvider.action(mContext, + SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, powerAnomalyEvent.getEventId()); } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java index ed2b31530f0..737717e5bc2 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java @@ -32,8 +32,8 @@ import android.view.View; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.display.AutoBrightnessSettings; -import com.android.settings.fuelgauge.PowerUsageFeatureProvider; import com.android.settings.testutils.BatteryTestUtils; +import com.android.settings.testutils.FakeFeatureFactory; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import org.junit.Before; @@ -49,21 +49,21 @@ import org.robolectric.RuntimeEnvironment; public final class BatteryTipsCardPreferenceTest { private Context mContext; + private FakeFeatureFactory mFeatureFactory; private BatteryTipsCardPreference mBatteryTipsCardPreference; private BatteryTipsController mBatteryTipsController; + @Mock private View mFakeView; - @Mock - private PowerUsageFeatureProvider mPowerUsageFeatureProvider; @Before public void setUp() { MockitoAnnotations.initMocks(this); mContext = spy(RuntimeEnvironment.application); + mFeatureFactory = FakeFeatureFactory.setupForTest(); mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /*attrs=*/ null); mBatteryTipsController = new BatteryTipsController(mContext); mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference; - mBatteryTipsController.mPowerUsageFeatureProvider = mPowerUsageFeatureProvider; } @Test @@ -72,11 +72,11 @@ public final class BatteryTipsCardPreferenceTest { R.layout.battery_tips_card); } @Test - public void onClick_actionBtn_getAdaptiveBrightnessLauncher() { + public void onClick_mainBtn_getAdaptiveBrightnessLauncher() { final ArgumentCaptor captor = ArgumentCaptor.forClass(Intent.class); PowerAnomalyEvent adaptiveBrightnessAnomaly = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent(); - when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); + when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); when(mFakeView.getId()).thenReturn(R.id.main_button); doNothing().when(mContext).startActivity(captor.capture()); @@ -89,5 +89,21 @@ public final class BatteryTipsCardPreferenceTest { .isEqualTo(AutoBrightnessSettings.class.getName()); assertThat(intent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1)) .isEqualTo(SettingsEnums.SETTINGS_AUTO_BRIGHTNESS); + verify(mFeatureFactory.metricsFeatureProvider).action( + mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, "BrightnessAnomaly"); + } + + @Test + public void onClick_dismissBtn_metricsLogged() { + PowerAnomalyEvent screenTimeoutAnomaly = + BatteryTestUtils.createScreenTimeoutAnomalyEvent(); + when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); + when(mFakeView.getId()).thenReturn(R.id.dismiss_button); + + mBatteryTipsController.handleBatteryTipsCardUpdated(screenTimeoutAnomaly); + mBatteryTipsCardPreference.onClick(mFakeView); + + verify(mFeatureFactory.metricsFeatureProvider).action( + mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, "ScreenTimeoutAnomaly"); } } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java index ffb200d03f5..015a295726b 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java @@ -21,12 +21,13 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.app.settings.SettingsEnums; import android.content.Context; import android.content.res.Resources; import android.os.LocaleList; -import com.android.settings.fuelgauge.PowerUsageFeatureProvider; import com.android.settings.testutils.BatteryTestUtils; +import com.android.settings.testutils.FakeFeatureFactory; import org.junit.Before; import org.junit.Test; @@ -43,14 +44,12 @@ import java.util.TimeZone; public final class BatteryTipsControllerTest { private Context mContext; + private FakeFeatureFactory mFeatureFactory; private BatteryTipsController mBatteryTipsController; @Mock private BatteryTipsCardPreference mBatteryTipsCardPreference; - @Mock - private PowerUsageFeatureProvider mPowerUsageFeatureProvider; - @Before public void setUp() { MockitoAnnotations.initMocks(this); @@ -61,9 +60,9 @@ public final class BatteryTipsControllerTest { final Resources resources = spy(mContext.getResources()); resources.getConfiguration().setLocales(new LocaleList(new Locale("en_US"))); doReturn(resources).when(mContext).getResources(); + mFeatureFactory = FakeFeatureFactory.setupForTest(); mBatteryTipsController = new BatteryTipsController(mContext); mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference; - mBatteryTipsController.mPowerUsageFeatureProvider = mPowerUsageFeatureProvider; } @Test @@ -76,10 +75,11 @@ public final class BatteryTipsControllerTest { @Test public void handleBatteryTipsCardUpdated_adaptiveBrightnessAnomaly_showAnomaly() { PowerAnomalyEvent event = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent(); - when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); + when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); mBatteryTipsController.handleBatteryTipsCardUpdated(event); + verify(mBatteryTipsCardPreference).setAnomalyEventId("BrightnessAnomaly"); // Check pre-defined string verify(mBatteryTipsCardPreference).setTitle( "Turn on adaptive brightness to extend battery life"); @@ -90,15 +90,18 @@ public final class BatteryTipsControllerTest { "com.android.settings.display.AutoBrightnessSettings", 1381); verify(mBatteryTipsCardPreference).setVisible(true); + verify(mFeatureFactory.metricsFeatureProvider).action( + mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "BrightnessAnomaly"); } @Test public void handleBatteryTipsCardUpdated_screenTimeoutAnomaly_showAnomaly() { PowerAnomalyEvent event = BatteryTestUtils.createScreenTimeoutAnomalyEvent(); - when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); + when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); mBatteryTipsController.handleBatteryTipsCardUpdated(event); + verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly"); verify(mBatteryTipsCardPreference).setTitle("Reduce screen timeout to extend battery life"); verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings"); verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it"); @@ -106,6 +109,8 @@ public final class BatteryTipsControllerTest { "com.android.settings.display.ScreenTimeoutSettings", 1852); verify(mBatteryTipsCardPreference).setVisible(true); + verify(mFeatureFactory.metricsFeatureProvider).action( + mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "ScreenTimeoutAnomaly"); } @Test public void handleBatteryTipsCardUpdated_screenTimeoutAnomalyHasTitle_showAnomaly() { @@ -117,10 +122,11 @@ public final class BatteryTipsControllerTest { .setTitleString(testTitle) .build()) .build(); - when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); + when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); mBatteryTipsController.handleBatteryTipsCardUpdated(event); + verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly"); verify(mBatteryTipsCardPreference).setTitle(testTitle); verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings"); verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it"); @@ -128,5 +134,7 @@ public final class BatteryTipsControllerTest { "com.android.settings.display.ScreenTimeoutSettings", 1852); verify(mBatteryTipsCardPreference).setVisible(true); + verify(mFeatureFactory.metricsFeatureProvider).action( + mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "ScreenTimeoutAnomaly"); } } diff --git a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java index 77be0388e58..dca15d5d7b3 100644 --- a/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java +++ b/tests/robotests/src/com/android/settings/testutils/BatteryTestUtils.java @@ -211,6 +211,7 @@ public class BatteryTestUtils { /** Create a power anomaly event proto of adaptive brightness. */ public static PowerAnomalyEvent createAdaptiveBrightnessAnomalyEvent() { return PowerAnomalyEvent.newBuilder() + .setEventId("BrightnessAnomaly") .setType(PowerAnomalyType.TYPE_SETTINGS_BANNER) .setKey(PowerAnomalyKey.KEY_BRIGHTNESS) .setWarningBannerInfo(WarningBannerInfo.newBuilder() @@ -223,6 +224,7 @@ public class BatteryTestUtils { /** Create a power anomaly event proto of screen timeout. */ public static PowerAnomalyEvent createScreenTimeoutAnomalyEvent() { return PowerAnomalyEvent.newBuilder() + .setEventId("ScreenTimeoutAnomaly") .setType(PowerAnomalyType.TYPE_SETTINGS_BANNER) .setKey(PowerAnomalyKey.KEY_SCREEN_TIMEOUT) .setWarningBannerInfo(WarningBannerInfo.newBuilder()