Add UI metrics logging for battery tips card.

Bug: 291689623
Test: manual
Change-Id: I925e4d887c3435239aed0aa0fde7cda2c3a95b3c
This commit is contained in:
Zaiyue Xue
2023-08-19 17:30:11 +08:00
parent a796508aa2
commit f838f5d5fa
5 changed files with 75 additions and 25 deletions

View File

@@ -16,6 +16,7 @@
package com.android.settings.fuelgauge.batteryusage; package com.android.settings.fuelgauge.batteryusage;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.AttributeSet; import android.util.AttributeSet;
@@ -32,6 +33,7 @@ import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.SubSettingLauncher;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider; import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.google.android.material.button.MaterialButton; 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 static final String TAG = "BatteryTipsCardPreference";
private final PowerUsageFeatureProvider mPowerUsageFeatureProvider; private final PowerUsageFeatureProvider mPowerUsageFeatureProvider;
private final MetricsFeatureProvider mMetricsFeatureProvider;
private String mAnomalyEventId;
@VisibleForTesting @VisibleForTesting
CharSequence mMainButtonLabel; CharSequence mMainButtonLabel;
@@ -51,18 +56,26 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
@VisibleForTesting @VisibleForTesting
String mDestinationComponentName; String mDestinationComponentName;
@VisibleForTesting @VisibleForTesting
int mSourceMetricsCategory; Integer mSourceMetricsCategory;
public BatteryTipsCardPreference(Context context, AttributeSet attrs) { public BatteryTipsCardPreference(Context context, AttributeSet attrs) {
super(context, attrs); super(context, attrs);
setLayoutResource(R.layout.battery_tips_card); setLayoutResource(R.layout.battery_tips_card);
setSelectable(false); setSelectable(false);
mPowerUsageFeatureProvider = FeatureFactory.getFeatureFactory() final FeatureFactory featureFactory = FeatureFactory.getFeatureFactory();
.getPowerUsageFeatureProvider(); mPowerUsageFeatureProvider = featureFactory.getPowerUsageFeatureProvider();
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) { public void setMainButtonLabel(CharSequence label) {
if (!TextUtils.equals(mMainButtonLabel, 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) { public void setDismissButtonLabel(CharSequence label) {
if (!TextUtils.equals(mDismissButtonLabel, 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, public void setMainButtonLauncherInfo(final String destinationClassName,
final Integer sourceMetricsCategory) { final Integer sourceMetricsCategory) {
@@ -102,8 +115,12 @@ public class BatteryTipsCardPreference extends Preference implements View.OnClic
.setSourceMetricsCategory(mSourceMetricsCategory) .setSourceMetricsCategory(mSourceMetricsCategory)
.launch(); .launch();
setVisible(false); setVisible(false);
mMetricsFeatureProvider.action(
getContext(), SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, mAnomalyEventId);
} else if (viewId == R.id.dismiss_button) { } else if (viewId == R.id.dismiss_button) {
setVisible(false); setVisible(false);
mMetricsFeatureProvider.action(
getContext(), SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, mAnomalyEventId);
} }
} }

View File

@@ -16,6 +16,7 @@
package com.android.settings.fuelgauge.batteryusage; package com.android.settings.fuelgauge.batteryusage;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.text.TextUtils; import android.text.TextUtils;
@@ -26,6 +27,7 @@ import com.android.settings.R;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider; import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import java.util.function.Function; 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 ROOT_PREFERENCE_KEY = "battery_tips_category";
private static final String CARD_PREFERENCE_KEY = "battery_tips_card"; private static final String CARD_PREFERENCE_KEY = "battery_tips_card";
private final PowerUsageFeatureProvider mPowerUsageFeatureProvider;
private final MetricsFeatureProvider mMetricsFeatureProvider;
@VisibleForTesting @VisibleForTesting
BatteryTipsCardPreference mCardPreference; BatteryTipsCardPreference mCardPreference;
@VisibleForTesting
PowerUsageFeatureProvider mPowerUsageFeatureProvider;
public BatteryTipsController(Context context) { public BatteryTipsController(Context context) {
super(context, ROOT_PREFERENCE_KEY); super(context, ROOT_PREFERENCE_KEY);
mPowerUsageFeatureProvider = FeatureFactory.getFeatureFactory() final FeatureFactory featureFactory = FeatureFactory.getFeatureFactory();
.getPowerUsageFeatureProvider(); mPowerUsageFeatureProvider = featureFactory.getPowerUsageFeatureProvider();
mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
} }
private boolean isTipsCardVisible() { private boolean isTipsCardVisible() {
// TODO: compared with the timestamp of last user dismiss action in sharedPreference.
return mPowerUsageFeatureProvider.isBatteryTipsEnabled(); return mPowerUsageFeatureProvider.isBatteryTipsEnabled();
} }
@@ -131,10 +134,14 @@ public class BatteryTipsController extends BasePreferenceController {
WarningItemInfo::getMainButtonSourceMetricsCategory); WarningItemInfo::getMainButtonSourceMetricsCategory);
// Updated card preference and main button fragment launcher // Updated card preference and main button fragment launcher
mCardPreference.setAnomalyEventId(powerAnomalyEvent.getEventId());
mCardPreference.setTitle(titleString); mCardPreference.setTitle(titleString);
mCardPreference.setMainButtonLabel(mainBtnString); mCardPreference.setMainButtonLabel(mainBtnString);
mCardPreference.setDismissButtonLabel(dismissBtnString); mCardPreference.setDismissButtonLabel(dismissBtnString);
mCardPreference.setMainButtonLauncherInfo(destinationClassName, sourceMetricsCategory); mCardPreference.setMainButtonLauncherInfo(destinationClassName, sourceMetricsCategory);
mCardPreference.setVisible(true); mCardPreference.setVisible(true);
mMetricsFeatureProvider.action(mContext,
SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, powerAnomalyEvent.getEventId());
} }
} }

View File

@@ -32,8 +32,8 @@ import android.view.View;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.display.AutoBrightnessSettings; import com.android.settings.display.AutoBrightnessSettings;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.testutils.BatteryTestUtils; import com.android.settings.testutils.BatteryTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import org.junit.Before; import org.junit.Before;
@@ -49,21 +49,21 @@ import org.robolectric.RuntimeEnvironment;
public final class BatteryTipsCardPreferenceTest { public final class BatteryTipsCardPreferenceTest {
private Context mContext; private Context mContext;
private FakeFeatureFactory mFeatureFactory;
private BatteryTipsCardPreference mBatteryTipsCardPreference; private BatteryTipsCardPreference mBatteryTipsCardPreference;
private BatteryTipsController mBatteryTipsController; private BatteryTipsController mBatteryTipsController;
@Mock @Mock
private View mFakeView; private View mFakeView;
@Mock
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
mContext = spy(RuntimeEnvironment.application); mContext = spy(RuntimeEnvironment.application);
mFeatureFactory = FakeFeatureFactory.setupForTest();
mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /*attrs=*/ null); mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /*attrs=*/ null);
mBatteryTipsController = new BatteryTipsController(mContext); mBatteryTipsController = new BatteryTipsController(mContext);
mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference; mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference;
mBatteryTipsController.mPowerUsageFeatureProvider = mPowerUsageFeatureProvider;
} }
@Test @Test
@@ -72,11 +72,11 @@ public final class BatteryTipsCardPreferenceTest {
R.layout.battery_tips_card); R.layout.battery_tips_card);
} }
@Test @Test
public void onClick_actionBtn_getAdaptiveBrightnessLauncher() { public void onClick_mainBtn_getAdaptiveBrightnessLauncher() {
final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class); final ArgumentCaptor<Intent> captor = ArgumentCaptor.forClass(Intent.class);
PowerAnomalyEvent adaptiveBrightnessAnomaly = PowerAnomalyEvent adaptiveBrightnessAnomaly =
BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent(); BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
when(mFakeView.getId()).thenReturn(R.id.main_button); when(mFakeView.getId()).thenReturn(R.id.main_button);
doNothing().when(mContext).startActivity(captor.capture()); doNothing().when(mContext).startActivity(captor.capture());
@@ -89,5 +89,21 @@ public final class BatteryTipsCardPreferenceTest {
.isEqualTo(AutoBrightnessSettings.class.getName()); .isEqualTo(AutoBrightnessSettings.class.getName());
assertThat(intent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1)) assertThat(intent.getIntExtra(MetricsFeatureProvider.EXTRA_SOURCE_METRICS_CATEGORY, -1))
.isEqualTo(SettingsEnums.SETTINGS_AUTO_BRIGHTNESS); .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");
} }
} }

View File

@@ -21,12 +21,13 @@ import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.settings.SettingsEnums;
import android.content.Context; import android.content.Context;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.LocaleList; import android.os.LocaleList;
import com.android.settings.fuelgauge.PowerUsageFeatureProvider;
import com.android.settings.testutils.BatteryTestUtils; import com.android.settings.testutils.BatteryTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;
import org.junit.Before; import org.junit.Before;
import org.junit.Test; import org.junit.Test;
@@ -43,14 +44,12 @@ import java.util.TimeZone;
public final class BatteryTipsControllerTest { public final class BatteryTipsControllerTest {
private Context mContext; private Context mContext;
private FakeFeatureFactory mFeatureFactory;
private BatteryTipsController mBatteryTipsController; private BatteryTipsController mBatteryTipsController;
@Mock @Mock
private BatteryTipsCardPreference mBatteryTipsCardPreference; private BatteryTipsCardPreference mBatteryTipsCardPreference;
@Mock
private PowerUsageFeatureProvider mPowerUsageFeatureProvider;
@Before @Before
public void setUp() { public void setUp() {
MockitoAnnotations.initMocks(this); MockitoAnnotations.initMocks(this);
@@ -61,9 +60,9 @@ public final class BatteryTipsControllerTest {
final Resources resources = spy(mContext.getResources()); final Resources resources = spy(mContext.getResources());
resources.getConfiguration().setLocales(new LocaleList(new Locale("en_US"))); resources.getConfiguration().setLocales(new LocaleList(new Locale("en_US")));
doReturn(resources).when(mContext).getResources(); doReturn(resources).when(mContext).getResources();
mFeatureFactory = FakeFeatureFactory.setupForTest();
mBatteryTipsController = new BatteryTipsController(mContext); mBatteryTipsController = new BatteryTipsController(mContext);
mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference; mBatteryTipsController.mCardPreference = mBatteryTipsCardPreference;
mBatteryTipsController.mPowerUsageFeatureProvider = mPowerUsageFeatureProvider;
} }
@Test @Test
@@ -76,10 +75,11 @@ public final class BatteryTipsControllerTest {
@Test @Test
public void handleBatteryTipsCardUpdated_adaptiveBrightnessAnomaly_showAnomaly() { public void handleBatteryTipsCardUpdated_adaptiveBrightnessAnomaly_showAnomaly() {
PowerAnomalyEvent event = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent(); PowerAnomalyEvent event = BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent();
when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
mBatteryTipsController.handleBatteryTipsCardUpdated(event); mBatteryTipsController.handleBatteryTipsCardUpdated(event);
verify(mBatteryTipsCardPreference).setAnomalyEventId("BrightnessAnomaly");
// Check pre-defined string // Check pre-defined string
verify(mBatteryTipsCardPreference).setTitle( verify(mBatteryTipsCardPreference).setTitle(
"Turn on adaptive brightness to extend battery life"); "Turn on adaptive brightness to extend battery life");
@@ -90,15 +90,18 @@ public final class BatteryTipsControllerTest {
"com.android.settings.display.AutoBrightnessSettings", "com.android.settings.display.AutoBrightnessSettings",
1381); 1381);
verify(mBatteryTipsCardPreference).setVisible(true); verify(mBatteryTipsCardPreference).setVisible(true);
verify(mFeatureFactory.metricsFeatureProvider).action(
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "BrightnessAnomaly");
} }
@Test @Test
public void handleBatteryTipsCardUpdated_screenTimeoutAnomaly_showAnomaly() { public void handleBatteryTipsCardUpdated_screenTimeoutAnomaly_showAnomaly() {
PowerAnomalyEvent event = BatteryTestUtils.createScreenTimeoutAnomalyEvent(); PowerAnomalyEvent event = BatteryTestUtils.createScreenTimeoutAnomalyEvent();
when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
mBatteryTipsController.handleBatteryTipsCardUpdated(event); mBatteryTipsController.handleBatteryTipsCardUpdated(event);
verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly");
verify(mBatteryTipsCardPreference).setTitle("Reduce screen timeout to extend battery life"); verify(mBatteryTipsCardPreference).setTitle("Reduce screen timeout to extend battery life");
verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings"); verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it"); verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
@@ -106,6 +109,8 @@ public final class BatteryTipsControllerTest {
"com.android.settings.display.ScreenTimeoutSettings", "com.android.settings.display.ScreenTimeoutSettings",
1852); 1852);
verify(mBatteryTipsCardPreference).setVisible(true); verify(mBatteryTipsCardPreference).setVisible(true);
verify(mFeatureFactory.metricsFeatureProvider).action(
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "ScreenTimeoutAnomaly");
} }
@Test @Test
public void handleBatteryTipsCardUpdated_screenTimeoutAnomalyHasTitle_showAnomaly() { public void handleBatteryTipsCardUpdated_screenTimeoutAnomalyHasTitle_showAnomaly() {
@@ -117,10 +122,11 @@ public final class BatteryTipsControllerTest {
.setTitleString(testTitle) .setTitleString(testTitle)
.build()) .build())
.build(); .build();
when(mPowerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true); when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
mBatteryTipsController.handleBatteryTipsCardUpdated(event); mBatteryTipsController.handleBatteryTipsCardUpdated(event);
verify(mBatteryTipsCardPreference).setAnomalyEventId("ScreenTimeoutAnomaly");
verify(mBatteryTipsCardPreference).setTitle(testTitle); verify(mBatteryTipsCardPreference).setTitle(testTitle);
verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings"); verify(mBatteryTipsCardPreference).setMainButtonLabel("View Settings");
verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it"); verify(mBatteryTipsCardPreference).setDismissButtonLabel("Got it");
@@ -128,5 +134,7 @@ public final class BatteryTipsControllerTest {
"com.android.settings.display.ScreenTimeoutSettings", "com.android.settings.display.ScreenTimeoutSettings",
1852); 1852);
verify(mBatteryTipsCardPreference).setVisible(true); verify(mBatteryTipsCardPreference).setVisible(true);
verify(mFeatureFactory.metricsFeatureProvider).action(
mContext, SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, "ScreenTimeoutAnomaly");
} }
} }

View File

@@ -211,6 +211,7 @@ public class BatteryTestUtils {
/** Create a power anomaly event proto of adaptive brightness. */ /** Create a power anomaly event proto of adaptive brightness. */
public static PowerAnomalyEvent createAdaptiveBrightnessAnomalyEvent() { public static PowerAnomalyEvent createAdaptiveBrightnessAnomalyEvent() {
return PowerAnomalyEvent.newBuilder() return PowerAnomalyEvent.newBuilder()
.setEventId("BrightnessAnomaly")
.setType(PowerAnomalyType.TYPE_SETTINGS_BANNER) .setType(PowerAnomalyType.TYPE_SETTINGS_BANNER)
.setKey(PowerAnomalyKey.KEY_BRIGHTNESS) .setKey(PowerAnomalyKey.KEY_BRIGHTNESS)
.setWarningBannerInfo(WarningBannerInfo.newBuilder() .setWarningBannerInfo(WarningBannerInfo.newBuilder()
@@ -223,6 +224,7 @@ public class BatteryTestUtils {
/** Create a power anomaly event proto of screen timeout. */ /** Create a power anomaly event proto of screen timeout. */
public static PowerAnomalyEvent createScreenTimeoutAnomalyEvent() { public static PowerAnomalyEvent createScreenTimeoutAnomalyEvent() {
return PowerAnomalyEvent.newBuilder() return PowerAnomalyEvent.newBuilder()
.setEventId("ScreenTimeoutAnomaly")
.setType(PowerAnomalyType.TYPE_SETTINGS_BANNER) .setType(PowerAnomalyType.TYPE_SETTINGS_BANNER)
.setKey(PowerAnomalyKey.KEY_SCREEN_TIMEOUT) .setKey(PowerAnomalyKey.KEY_SCREEN_TIMEOUT)
.setWarningBannerInfo(WarningBannerInfo.newBuilder() .setWarningBannerInfo(WarningBannerInfo.newBuilder()