[Expressive Battery] Migrate tips card in battery usage to banner message

- Update card preference: Update icon hint color by banner attention level
- Remove redundant color token: Use the existing Material yellow as a warning color

Bug: 349652542
Test: atest BatteryTipsControllerTest
Flag: com.android.settingslib.widget.theme.flags.is_expressive_design_enabled
Change-Id: I35730eb4716e9dbd712c22db63490e8bc06fc482
This commit is contained in:
mxyyiyi
2025-02-18 14:00:55 +08:00
parent 5703095c5c
commit 9ba79d8b02
10 changed files with 134 additions and 111 deletions

View File

@@ -19,6 +19,8 @@ package com.android.settings.fuelgauge.batteryusage;
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
@@ -29,30 +31,41 @@ import static org.mockito.Mockito.when;
import android.app.settings.SettingsEnums;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.LocaleList;
import android.view.View;
import com.android.settings.R;
import com.android.settings.testutils.BatteryTestUtils;
import com.android.settings.testutils.FakeFeatureFactory;
import com.android.settings.widget.TipCardPreference;
import com.android.settingslib.widget.BannerMessagePreference;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;
import org.robolectric.shadow.api.Shadow;
import java.util.Locale;
import java.util.TimeZone;
@RunWith(RobolectricTestRunner.class)
@Config(shadows = BatteryTipsControllerTest.ShadowBannerMessagePreference.class)
public final class BatteryTipsControllerTest {
private Context mContext;
private FakeFeatureFactory mFeatureFactory;
private BatteryTipsController mBatteryTipsController;
private TipCardPreference mCardPreference;
private BannerMessagePreference mCardPreference;
@Mock Drawable mIconDrawable;
@Mock View mView;
@Before
public void setUp() {
@@ -61,12 +74,13 @@ public final class BatteryTipsControllerTest {
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
mContext = spy(RuntimeEnvironment.application);
DatabaseUtils.removeDismissedPowerAnomalyKeys(mContext);
final Resources resources = spy(mContext.getResources());
resources.getConfiguration().setLocales(new LocaleList(new Locale("en_US")));
doReturn(resources).when(mContext).getResources();
mFeatureFactory = FakeFeatureFactory.setupForTest();
mBatteryTipsController = spy(new BatteryTipsController(mContext));
mCardPreference = new TipCardPreference(mContext);
mCardPreference = spy(new BannerMessagePreference(mContext));
mBatteryTipsController.mCardPreference = mCardPreference;
}
@@ -84,18 +98,16 @@ public final class BatteryTipsControllerTest {
new AnomalyEventWrapper(
mContext,
BatteryTestUtils.createAdaptiveBrightnessAnomalyEvent(true)));
when(anomalyEventWrapper.getIconDrawable()).thenReturn(mIconDrawable);
when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
mBatteryTipsController.handleBatteryTipsCardUpdated(anomalyEventWrapper, false);
assertThat(mCardPreference.getTitle())
.isEqualTo("Turn on adaptive brightness to extend battery life");
assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo("Got it");
assertThat(mCardPreference.getSecondaryButtonText()).isEqualTo("View Settings");
assertThat(mCardPreference.getIconResId()).isEqualTo(R.drawable.ic_battery_tips_lightbulb);
assertThat(mCardPreference.getTintColorResId()).isEqualTo(R.color.color_accent_selector);
assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
assertThat(mCardPreference.getSecondaryButtonVisibility()).isTrue();
assertCardPreference(
"Turn on adaptive brightness to extend battery life",
"View Settings",
"Got it",
BannerMessagePreference.AttentionLevel.NORMAL);
assertCardButtonActionAndMetrics(anomalyEventWrapper);
}
@@ -105,18 +117,16 @@ public final class BatteryTipsControllerTest {
spy(
new AnomalyEventWrapper(
mContext, BatteryTestUtils.createScreenTimeoutAnomalyEvent(true)));
when(anomalyEventWrapper.getIconDrawable()).thenReturn(mIconDrawable);
when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
mBatteryTipsController.handleBatteryTipsCardUpdated(anomalyEventWrapper, false);
assertThat(mCardPreference.getTitle())
.isEqualTo("Reduce screen timeout to extend battery life");
assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo("Got it");
assertThat(mCardPreference.getSecondaryButtonText()).isEqualTo("View Settings");
assertThat(mCardPreference.getIconResId()).isEqualTo(R.drawable.ic_battery_tips_lightbulb);
assertThat(mCardPreference.getTintColorResId()).isEqualTo(R.color.color_accent_selector);
assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
assertThat(mCardPreference.getSecondaryButtonVisibility()).isTrue();
assertCardPreference(
"Reduce screen timeout to extend battery life",
"View Settings",
"Got it",
BannerMessagePreference.AttentionLevel.NORMAL);
assertCardButtonActionAndMetrics(anomalyEventWrapper);
}
@@ -133,17 +143,16 @@ public final class BatteryTipsControllerTest {
.build();
AnomalyEventWrapper anomalyEventWrapper =
spy(new AnomalyEventWrapper(mContext, anomalyEvent));
when(anomalyEventWrapper.getIconDrawable()).thenReturn(mIconDrawable);
when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
mBatteryTipsController.handleBatteryTipsCardUpdated(anomalyEventWrapper, false);
assertThat(mCardPreference.getTitle()).isEqualTo(testTitle);
assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo("Got it");
assertThat(mCardPreference.getSecondaryButtonText()).isEqualTo("View Settings");
assertThat(mCardPreference.getIconResId()).isEqualTo(R.drawable.ic_battery_tips_lightbulb);
assertThat(mCardPreference.getTintColorResId()).isEqualTo(R.color.color_accent_selector);
assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
assertThat(mCardPreference.getSecondaryButtonVisibility()).isTrue();
assertCardPreference(
testTitle,
"View Settings",
"Got it",
BannerMessagePreference.AttentionLevel.NORMAL);
assertCardButtonActionAndMetrics(anomalyEventWrapper);
}
@@ -151,6 +160,7 @@ public final class BatteryTipsControllerTest {
public void handleBatteryTipsCardUpdated_appAnomaly_showAnomaly() {
AnomalyEventWrapper anomalyEventWrapper =
spy(new AnomalyEventWrapper(mContext, BatteryTestUtils.createAppAnomalyEvent()));
when(anomalyEventWrapper.getIconDrawable()).thenReturn(mIconDrawable);
when(mFeatureFactory.powerUsageFeatureProvider.isBatteryTipsEnabled()).thenReturn(true);
anomalyEventWrapper.setRelatedBatteryDiffEntry(
@@ -159,29 +169,41 @@ public final class BatteryTipsControllerTest {
() -> mBatteryTipsController.acceptTipsCard());
mBatteryTipsController.handleBatteryTipsCardUpdated(anomalyEventWrapper, true);
assertThat(mCardPreference.getTitle()).isEqualTo("Chrome used more battery than usual");
assertThat(mCardPreference.getPrimaryButtonText()).isEqualTo("Got it");
assertThat(mCardPreference.getSecondaryButtonText()).isEqualTo("Check");
assertThat(mCardPreference.getIconResId())
.isEqualTo(R.drawable.ic_battery_tips_warning_icon);
assertThat(mCardPreference.getTintColorResId())
.isEqualTo(R.color.color_battery_anomaly_app_warning_selector);
assertThat(mCardPreference.getPrimaryButtonVisibility()).isTrue();
assertThat(mCardPreference.getSecondaryButtonVisibility()).isTrue();
assertThat(mCardPreference.isVisible()).isTrue();
assertCardPreference(
"Chrome used more battery than usual",
"Check",
"Got it",
BannerMessagePreference.AttentionLevel.MEDIUM);
assertCardButtonActionAndMetrics(anomalyEventWrapper);
}
private void assertCardPreference(
final String title,
final String positiveBtnText,
final String negativeBtnText,
BannerMessagePreference.AttentionLevel attentionLevel) {
verify(mCardPreference).setTitle(eq(title));
verify(mCardPreference).setPositiveButtonText(eq(positiveBtnText));
verify(mCardPreference).setNegativeButtonText(eq(negativeBtnText));
verify(mCardPreference).setIcon(mIconDrawable);
verify(mCardPreference).setAttentionLevel(attentionLevel);
verify(mCardPreference).setPositiveButtonVisible(true);
verify(mCardPreference).setNegativeButtonVisible(true);
assertThat(mCardPreference.isVisible()).isTrue();
}
private void assertCardButtonActionAndMetrics(final AnomalyEventWrapper anomalyEventWrapper) {
when(anomalyEventWrapper.updateSystemSettingsIfAvailable()).thenReturn(true);
final int powerAnomalyKeyNumber = anomalyEventWrapper.getAnomalyKeyNumber();
assertCardMetrics(SettingsEnums.ACTION_BATTERY_TIPS_CARD_SHOW, powerAnomalyKeyNumber);
assertThat(mCardPreference.isVisible()).isTrue();
final ShadowBannerMessagePreference shadowPreference = Shadow.extract(mCardPreference);
// Check accept button action
mCardPreference.setVisible(true);
mCardPreference.getSecondaryButtonAction().invoke();
clearInvocations(mFeatureFactory.metricsFeatureProvider);
shadowPreference.getPositiveButtonOnClickListener().onClick(mView);
assertCardMetrics(SettingsEnums.ACTION_BATTERY_TIPS_CARD_ACCEPT, powerAnomalyKeyNumber);
assertThat(mCardPreference.isVisible()).isFalse();
final boolean isAppAnomalyCard = powerAnomalyKeyNumber > 1;
@@ -190,7 +212,8 @@ public final class BatteryTipsControllerTest {
// Check reject button action
mCardPreference.setVisible(true);
mCardPreference.getPrimaryButtonAction().invoke();
clearInvocations(mFeatureFactory.metricsFeatureProvider);
shadowPreference.getNegativeButtonOnClickListener().onClick(mView);
assertCardMetrics(SettingsEnums.ACTION_BATTERY_TIPS_CARD_DISMISS, powerAnomalyKeyNumber);
assertThat(mCardPreference.isVisible()).isFalse();
}
@@ -204,4 +227,37 @@ public final class BatteryTipsControllerTest {
BatteryTipsController.ANOMALY_KEY,
powerAnomalyKeyNumber);
}
@Implements(BannerMessagePreference.class)
public static class ShadowBannerMessagePreference {
@RealObject protected BannerMessagePreference mRealBannerMessagePreference;
private View.OnClickListener mPositiveButtonOnClickListener;
private View.OnClickListener mNegativeButtonOnClickListener;
/** Shadow implementation of setPositiveButtonOnClickListener */
@Implementation
public BannerMessagePreference setPositiveButtonOnClickListener(
View.OnClickListener listener) {
mPositiveButtonOnClickListener = listener;
return mRealBannerMessagePreference;
}
/** Shadow implementation of setNegativeButtonOnClickListener */
@Implementation
public BannerMessagePreference setNegativeButtonOnClickListener(
View.OnClickListener listener) {
mNegativeButtonOnClickListener = listener;
return mRealBannerMessagePreference;
}
View.OnClickListener getPositiveButtonOnClickListener() {
return mPositiveButtonOnClickListener;
}
View.OnClickListener getNegativeButtonOnClickListener() {
return mNegativeButtonOnClickListener;
}
}
}