[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

@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/power_anomaly_app_warning_hint_color"/>
</selector>

View File

@@ -20,6 +20,6 @@
android:viewportWidth="960" android:viewportWidth="960"
android:viewportHeight="960"> android:viewportHeight="960">
<path <path
android:fillColor="@color/color_battery_anomaly_app_warning_selector" android:fillColor="@color/settingslib_colorBackgroundLevel_medium"
android:pathData="M40,840L480,80L920,840L40,840ZM178,760L782,760L480,240L178,760ZM480,720Q497,720 508.5,708.5Q520,697 520,680Q520,663 508.5,651.5Q497,640 480,640Q463,640 451.5,651.5Q440,663 440,680Q440,697 451.5,708.5Q463,720 480,720ZM440,600L520,600L520,400L440,400L440,600ZM480,500L480,500L480,500L480,500Z"/> android:pathData="M40,840L480,80L920,840L40,840ZM178,760L782,760L480,240L178,760ZM480,720Q497,720 508.5,708.5Q520,697 520,680Q520,663 508.5,651.5Q497,640 480,640Q463,640 451.5,651.5Q440,663 440,680Q440,697 451.5,708.5Q463,720 480,720ZM440,600L520,600L520,400L440,400L440,600ZM480,500L480,500L480,500L480,500Z"/>
</vector> </vector>

View File

@@ -55,9 +55,6 @@
<!-- Icon tint color for battery usage system icon --> <!-- Icon tint color for battery usage system icon -->
<color name="battery_usage_system_icon_color">@android:color/white</color> <color name="battery_usage_system_icon_color">@android:color/white</color>
<!-- Power anomaly color for icons, button and text -->
<color name="power_anomaly_app_warning_hint_color">#FDD663</color>
<!-- UDFPS colors --> <!-- UDFPS colors -->
<color name="udfps_enroll_icon">#7DA7F1</color> <color name="udfps_enroll_icon">#7DA7F1</color>
<color name="udfps_moving_target_fill">#475670</color> <color name="udfps_moving_target_fill">#475670</color>

View File

@@ -1459,11 +1459,6 @@
<item>ic_battery_tips_warning_icon</item> <item>ic_battery_tips_warning_icon</item>
</string-array> </string-array>
<string-array name="battery_tips_card_colors" translatable="false">
<item>color_accent_selector</item>
<item>color_battery_anomaly_app_warning_selector</item>
</string-array>
<!-- The following 4 arrays are for power anomaly tips card. Please keep them the same size. --> <!-- The following 4 arrays are for power anomaly tips card. Please keep them the same size. -->
<string-array name="power_anomaly_title_ids" translatable="false"> <string-array name="power_anomaly_title_ids" translatable="false">
<item>battery_tips_settings_summary_brightness</item> <item>battery_tips_settings_summary_brightness</item>

View File

@@ -168,9 +168,6 @@
<!-- Icon tint color for battery usage system icon --> <!-- Icon tint color for battery usage system icon -->
<color name="battery_usage_system_icon_color">?android:attr/textColorPrimary</color> <color name="battery_usage_system_icon_color">?android:attr/textColorPrimary</color>
<!-- Power anomaly color for icons, button -->
<color name="power_anomaly_app_warning_hint_color">#D56E0C</color>
<!-- UDFPS colors --> <!-- UDFPS colors -->
<color name="udfps_enroll_icon">#699FF3</color> <color name="udfps_enroll_icon">#699FF3</color>
<color name="udfps_moving_target_fill">#C2D7F7</color> <color name="udfps_moving_target_fill">#C2D7F7</color>

View File

@@ -21,18 +21,11 @@
android:title="@string/advanced_battery_title" android:title="@string/advanced_battery_title"
settings:keywords="@string/keywords_battery_usage"> settings:keywords="@string/keywords_battery_usage">
<PreferenceCategory <com.android.settingslib.widget.BannerMessagePreference
android:key="battery_tips_category" android:key="battery_tips_card"
android:layout="@layout/preference_category_no_label"
settings:controller= settings:controller=
"com.android.settings.fuelgauge.batteryusage.BatteryTipsController" "com.android.settings.fuelgauge.batteryusage.BatteryTipsController"
settings:isPreferenceVisible="false"> settings:isPreferenceVisible="false" />
<com.android.settings.widget.TipCardPreference
android:key="battery_tips_card"
settings:isPreferenceVisible="false" />
</PreferenceCategory>
<com.android.settings.fuelgauge.batteryusage.BatteryHistoryPreference <com.android.settings.fuelgauge.batteryusage.BatteryHistoryPreference
android:key="battery_chart" android:key="battery_chart"

View File

@@ -17,6 +17,7 @@
package com.android.settings.fuelgauge.batteryusage; package com.android.settings.fuelgauge.batteryusage;
import android.content.Context; import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Bundle; import android.os.Bundle;
import android.provider.Settings; import android.provider.Settings;
import android.text.TextUtils; import android.text.TextUtils;
@@ -28,7 +29,8 @@ import androidx.annotation.Nullable;
import com.android.settings.R; import com.android.settings.R;
import com.android.settings.SettingsActivity; import com.android.settings.SettingsActivity;
import com.android.settings.core.SubSettingLauncher; import com.android.settings.core.SubSettingLauncher;
import com.android.settings.widget.TipCardPreference; import com.android.settingslib.widget.BannerMessagePreference;
import com.android.settingslib.widget.BannerMessagePreference.AttentionLevel;
import java.util.function.Function; import java.util.function.Function;
@@ -37,6 +39,7 @@ class AnomalyEventWrapper {
private final Context mContext; private final Context mContext;
private final PowerAnomalyEvent mPowerAnomalyEvent; private final PowerAnomalyEvent mPowerAnomalyEvent;
private final AttentionLevel mAttentionLevel;
private final int mCardStyleId; private final int mCardStyleId;
private final int mResourceIndex; private final int mResourceIndex;
@@ -51,6 +54,7 @@ class AnomalyEventWrapper {
// Set basic battery tips card info // Set basic battery tips card info
mCardStyleId = mPowerAnomalyEvent.getType().getNumber(); mCardStyleId = mPowerAnomalyEvent.getType().getNumber();
mResourceIndex = mPowerAnomalyEvent.getKey().getNumber(); mResourceIndex = mPowerAnomalyEvent.getKey().getNumber();
mAttentionLevel = mCardStyleId == 0 ? AttentionLevel.NORMAL : AttentionLevel.MEDIUM;
} }
private <T> T getInfo( private <T> T getInfo(
@@ -104,12 +108,14 @@ class AnomalyEventWrapper {
return mPowerAnomalyEvent.hasEventId() ? mPowerAnomalyEvent.getEventId() : null; return mPowerAnomalyEvent.hasEventId() ? mPowerAnomalyEvent.getEventId() : null;
} }
int getIconResId() { Drawable getIconDrawable() {
return getResourceId(R.array.battery_tips_card_icons, mCardStyleId, "drawable"); final int iconResId =
} getResourceId(R.array.battery_tips_card_icons, mCardStyleId, "drawable");
Drawable drawable = mContext.getDrawable(iconResId);
int getColorResId() { if (drawable != null && mAttentionLevel != AttentionLevel.NORMAL) {
return getResourceId(R.array.battery_tips_card_colors, mCardStyleId, "color"); drawable.setTint(mContext.getColor(mAttentionLevel.getButtonBackgroundColorResId()));
}
return drawable;
} }
String getTitleString() { String getTitleString() {
@@ -236,16 +242,16 @@ class AnomalyEventWrapper {
return mHighlightSlotPair; return mHighlightSlotPair;
} }
boolean updateTipsCardPreference(TipCardPreference preference) { boolean updateTipsCardPreference(BannerMessagePreference preference) {
final String titleString = getTitleString(); final String titleString = getTitleString();
if (TextUtils.isEmpty(titleString)) { if (TextUtils.isEmpty(titleString)) {
return false; return false;
} }
preference.setTitle(titleString); preference.setTitle(titleString);
preference.setIconResId(getIconResId()); preference.setIcon(getIconDrawable());
preference.setTintColorResId(getColorResId()); preference.setAttentionLevel(mAttentionLevel);
preference.setPrimaryButtonText(getDismissBtnString()); preference.setNegativeButtonText(getDismissBtnString());
preference.setSecondaryButtonText(getMainBtnString()); preference.setPositiveButtonText(getMainBtnString());
return true; return true;
} }

View File

@@ -377,7 +377,9 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick
mTransomTop = resources.getDimensionPixelSize(R.dimen.chartview_transom_padding_top); mTransomTop = resources.getDimensionPixelSize(R.dimen.chartview_transom_padding_top);
mTransomLineDefaultColor = Utils.getDisabled(mContext, DIVIDER_COLOR); mTransomLineDefaultColor = Utils.getDisabled(mContext, DIVIDER_COLOR);
mTransomLineSelectedColor = mTransomLineSelectedColor =
resources.getColor(R.color.color_battery_anomaly_app_warning_selector); resources.getColor(
com.android.settingslib.widget.preference.banner.R.color
.settingslib_banner_button_background_medium);
final int slotHighlightColor = Utils.getDisabled(mContext, mTransomLineSelectedColor); final int slotHighlightColor = Utils.getDisabled(mContext, mTransomLineSelectedColor);
mTransomIconSize = resources.getDimensionPixelSize(R.dimen.chartview_transom_icon_size); mTransomIconSize = resources.getDimensionPixelSize(R.dimen.chartview_transom_icon_size);
mTransomLinePaint = new Paint(); mTransomLinePaint = new Paint();

View File

@@ -25,15 +25,14 @@ import androidx.preference.PreferenceScreen;
import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting;
import com.android.settings.core.BasePreferenceController; import com.android.settings.core.BasePreferenceController;
import com.android.settings.overlay.FeatureFactory; import com.android.settings.overlay.FeatureFactory;
import com.android.settings.widget.TipCardPreference;
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
import com.android.settingslib.widget.BannerMessagePreference;
/** Controls the update for battery tips card */ /** Controls the update for battery tips card */
public class BatteryTipsController extends BasePreferenceController { public class BatteryTipsController extends BasePreferenceController {
private static final String TAG = "BatteryTipsController"; private static final String TAG = "BatteryTipsController";
private static final String ROOT_PREFERENCE_KEY = "battery_tips_category"; private static final String PREFERENCE_KEY = "battery_tips_card";
private static final String CARD_PREFERENCE_KEY = "battery_tips_card";
@VisibleForTesting static final String ANOMALY_KEY = "anomaly_key"; @VisibleForTesting static final String ANOMALY_KEY = "anomaly_key";
@@ -53,12 +52,12 @@ public class BatteryTipsController extends BasePreferenceController {
@VisibleForTesting OnAnomalyConfirmListener mOnAnomalyConfirmListener; @VisibleForTesting OnAnomalyConfirmListener mOnAnomalyConfirmListener;
@VisibleForTesting OnAnomalyRejectListener mOnAnomalyRejectListener; @VisibleForTesting OnAnomalyRejectListener mOnAnomalyRejectListener;
@VisibleForTesting TipCardPreference mCardPreference; @VisibleForTesting BannerMessagePreference mCardPreference;
@VisibleForTesting AnomalyEventWrapper mAnomalyEventWrapper = null; @VisibleForTesting AnomalyEventWrapper mAnomalyEventWrapper = null;
@VisibleForTesting Boolean mIsAcceptable = false; @VisibleForTesting Boolean mIsAcceptable = false;
public BatteryTipsController(Context context) { public BatteryTipsController(Context context) {
super(context, ROOT_PREFERENCE_KEY); super(context, PREFERENCE_KEY);
final FeatureFactory featureFactory = FeatureFactory.getFeatureFactory(); final FeatureFactory featureFactory = FeatureFactory.getFeatureFactory();
mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider(); mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider();
} }
@@ -71,7 +70,10 @@ public class BatteryTipsController extends BasePreferenceController {
@Override @Override
public void displayPreference(PreferenceScreen screen) { public void displayPreference(PreferenceScreen screen) {
super.displayPreference(screen); super.displayPreference(screen);
mCardPreference = screen.findPreference(CARD_PREFERENCE_KEY); mCardPreference = screen.findPreference(PREFERENCE_KEY);
// Set preference as invisible since there is no default tips.
mCardPreference.setVisible(false);
} }
void setOnAnomalyConfirmListener(OnAnomalyConfirmListener listener) { void setOnAnomalyConfirmListener(OnAnomalyConfirmListener listener) {
@@ -117,20 +119,13 @@ public class BatteryTipsController extends BasePreferenceController {
return; return;
} }
mCardPreference.setPrimaryButtonAction( mCardPreference.setNegativeButtonOnClickListener(
() -> { view -> onBatteryTipsCardDismiss(anomalyKeyNumber));
onBatteryTipsCardDismiss(anomalyKeyNumber); mCardPreference.setPositiveButtonOnClickListener(
return null; view -> onBatteryTipsCardAccept(anomalyKeyNumber));
});
mCardPreference.setSecondaryButtonAction(
() -> {
onBatteryTipsCardAccept(anomalyKeyNumber);
return null;
});
mCardPreference.setPrimaryButtonVisibility(true); mCardPreference.setPositiveButtonVisible(true);
mCardPreference.setSecondaryButtonVisibility(true); mCardPreference.setNegativeButtonVisible(true);
mCardPreference.buildContent();
mCardPreference.setVisible(true); mCardPreference.setVisible(true);
mMetricsFeatureProvider.action( mMetricsFeatureProvider.action(
/* attribution= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL, /* attribution= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL,

View File

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