diff --git a/res/color/color_battery_anomaly_app_warning_selector.xml b/res/color/color_battery_anomaly_app_warning_selector.xml deleted file mode 100644 index 4ad78e6784e..00000000000 --- a/res/color/color_battery_anomaly_app_warning_selector.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - diff --git a/res/drawable/ic_battery_tips_warning_icon.xml b/res/drawable/ic_battery_tips_warning_icon.xml index 0dcfa6d3bd3..1555930bca3 100644 --- a/res/drawable/ic_battery_tips_warning_icon.xml +++ b/res/drawable/ic_battery_tips_warning_icon.xml @@ -20,6 +20,6 @@ android:viewportWidth="960" android:viewportHeight="960"> \ No newline at end of file diff --git a/res/values-night/colors.xml b/res/values-night/colors.xml index c767f04a831..212f1a6e2ea 100644 --- a/res/values-night/colors.xml +++ b/res/values-night/colors.xml @@ -55,9 +55,6 @@ @android:color/white - - #FDD663 - #7DA7F1 #475670 diff --git a/res/values/arrays.xml b/res/values/arrays.xml index 5de62226d14..e653c63a507 100644 --- a/res/values/arrays.xml +++ b/res/values/arrays.xml @@ -1459,11 +1459,6 @@ ic_battery_tips_warning_icon - - color_accent_selector - color_battery_anomaly_app_warning_selector - - battery_tips_settings_summary_brightness diff --git a/res/values/colors.xml b/res/values/colors.xml index 0160ec52e35..9a27f97a776 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -168,9 +168,6 @@ ?android:attr/textColorPrimary - - #D56E0C - #699FF3 #C2D7F7 diff --git a/res/xml/power_usage_advanced.xml b/res/xml/power_usage_advanced.xml index 3258b7b9ca2..cc37625fa3d 100644 --- a/res/xml/power_usage_advanced.xml +++ b/res/xml/power_usage_advanced.xml @@ -21,18 +21,11 @@ android:title="@string/advanced_battery_title" settings:keywords="@string/keywords_battery_usage"> - - - - - + settings:isPreferenceVisible="false" /> T getInfo( @@ -104,12 +108,14 @@ class AnomalyEventWrapper { return mPowerAnomalyEvent.hasEventId() ? mPowerAnomalyEvent.getEventId() : null; } - int getIconResId() { - return getResourceId(R.array.battery_tips_card_icons, mCardStyleId, "drawable"); - } - - int getColorResId() { - return getResourceId(R.array.battery_tips_card_colors, mCardStyleId, "color"); + Drawable getIconDrawable() { + final int iconResId = + getResourceId(R.array.battery_tips_card_icons, mCardStyleId, "drawable"); + Drawable drawable = mContext.getDrawable(iconResId); + if (drawable != null && mAttentionLevel != AttentionLevel.NORMAL) { + drawable.setTint(mContext.getColor(mAttentionLevel.getButtonBackgroundColorResId())); + } + return drawable; } String getTitleString() { @@ -236,16 +242,16 @@ class AnomalyEventWrapper { return mHighlightSlotPair; } - boolean updateTipsCardPreference(TipCardPreference preference) { + boolean updateTipsCardPreference(BannerMessagePreference preference) { final String titleString = getTitleString(); if (TextUtils.isEmpty(titleString)) { return false; } preference.setTitle(titleString); - preference.setIconResId(getIconResId()); - preference.setTintColorResId(getColorResId()); - preference.setPrimaryButtonText(getDismissBtnString()); - preference.setSecondaryButtonText(getMainBtnString()); + preference.setIcon(getIconDrawable()); + preference.setAttentionLevel(mAttentionLevel); + preference.setNegativeButtonText(getDismissBtnString()); + preference.setPositiveButtonText(getMainBtnString()); return true; } diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java index 88f99c3beaf..eafccdb124e 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryChartView.java @@ -377,7 +377,9 @@ public class BatteryChartView extends AppCompatImageView implements View.OnClick mTransomTop = resources.getDimensionPixelSize(R.dimen.chartview_transom_padding_top); mTransomLineDefaultColor = Utils.getDisabled(mContext, DIVIDER_COLOR); 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); mTransomIconSize = resources.getDimensionPixelSize(R.dimen.chartview_transom_icon_size); mTransomLinePaint = new Paint(); diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java index 405b78651a5..705ec6ad505 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java @@ -25,15 +25,14 @@ import androidx.preference.PreferenceScreen; import com.android.internal.annotations.VisibleForTesting; import com.android.settings.core.BasePreferenceController; import com.android.settings.overlay.FeatureFactory; -import com.android.settings.widget.TipCardPreference; import com.android.settingslib.core.instrumentation.MetricsFeatureProvider; +import com.android.settingslib.widget.BannerMessagePreference; /** Controls the update for battery tips card */ public class BatteryTipsController extends BasePreferenceController { private static final String TAG = "BatteryTipsController"; - private static final String ROOT_PREFERENCE_KEY = "battery_tips_category"; - private static final String CARD_PREFERENCE_KEY = "battery_tips_card"; + private static final String PREFERENCE_KEY = "battery_tips_card"; @VisibleForTesting static final String ANOMALY_KEY = "anomaly_key"; @@ -53,12 +52,12 @@ public class BatteryTipsController extends BasePreferenceController { @VisibleForTesting OnAnomalyConfirmListener mOnAnomalyConfirmListener; @VisibleForTesting OnAnomalyRejectListener mOnAnomalyRejectListener; - @VisibleForTesting TipCardPreference mCardPreference; + @VisibleForTesting BannerMessagePreference mCardPreference; @VisibleForTesting AnomalyEventWrapper mAnomalyEventWrapper = null; @VisibleForTesting Boolean mIsAcceptable = false; public BatteryTipsController(Context context) { - super(context, ROOT_PREFERENCE_KEY); + super(context, PREFERENCE_KEY); final FeatureFactory featureFactory = FeatureFactory.getFeatureFactory(); mMetricsFeatureProvider = featureFactory.getMetricsFeatureProvider(); } @@ -71,7 +70,10 @@ public class BatteryTipsController extends BasePreferenceController { @Override public void displayPreference(PreferenceScreen 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) { @@ -117,20 +119,13 @@ public class BatteryTipsController extends BasePreferenceController { return; } - mCardPreference.setPrimaryButtonAction( - () -> { - onBatteryTipsCardDismiss(anomalyKeyNumber); - return null; - }); - mCardPreference.setSecondaryButtonAction( - () -> { - onBatteryTipsCardAccept(anomalyKeyNumber); - return null; - }); + mCardPreference.setNegativeButtonOnClickListener( + view -> onBatteryTipsCardDismiss(anomalyKeyNumber)); + mCardPreference.setPositiveButtonOnClickListener( + view -> onBatteryTipsCardAccept(anomalyKeyNumber)); - mCardPreference.setPrimaryButtonVisibility(true); - mCardPreference.setSecondaryButtonVisibility(true); - mCardPreference.buildContent(); + mCardPreference.setPositiveButtonVisible(true); + mCardPreference.setNegativeButtonVisible(true); mCardPreference.setVisible(true); mMetricsFeatureProvider.action( /* attribution= */ SettingsEnums.FUELGAUGE_BATTERY_HISTORY_DETAIL, 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 6c29036b086..d5613952edb 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsControllerTest.java @@ -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; + } + } }