From c4ac74872b0585826f44f875ac58fd39161e60e9 Mon Sep 17 00:00:00 2001 From: mxyyiyi Date: Wed, 19 Jul 2023 13:28:52 +0800 Subject: [PATCH] Implement the battery tips cards.(1/2) Bug: 291689623 Test: Manual (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:3ff665bd3292986030fdd8a3689b35bbf6f5a615) Change-Id: I4443cdb21b3ba30900fc2f6fcc21c4c56dc1293f --- res/drawable/battery_tips_all_rounded_bg.xml | 22 +++ .../battery_tips_half_rounded_bottom_bg.xml | 27 ++++ .../battery_tips_half_rounded_top_bg.xml | 27 ++++ res/drawable/ic_battery_tips_close.xml | 25 ++++ res/drawable/ic_battery_tips_close_icon.xml | 32 +++++ res/drawable/ic_battery_tips_lightbulb.xml | 25 ++++ res/drawable/ic_battery_tips_thumb_down.xml | 25 ++++ res/drawable/ic_battery_tips_thumb_up.xml | 25 ++++ res/layout/battery_tips_card.xml | 125 ++++++++++++++++++ res/values/dimens.xml | 4 + res/values/strings.xml | 18 +++ res/xml/power_usage_advanced.xml | 12 ++ .../fuelgauge/PowerUsageFeatureProvider.java | 10 ++ .../PowerUsageFeatureProviderImpl.java | 10 ++ .../BatteryChartPreferenceController.java | 23 ++++ .../BatteryTipsCardPreference.java | 99 ++++++++++++++ .../batteryusage/BatteryTipsController.java | 77 +++++++++++ .../batteryusage/PowerUsageAdvanced.java | 12 ++ .../PowerUsageFeatureProviderImplTest.java | 9 ++ .../BatteryTipsCardPreferenceTest.java | 50 +++++++ 20 files changed, 657 insertions(+) create mode 100644 res/drawable/battery_tips_all_rounded_bg.xml create mode 100644 res/drawable/battery_tips_half_rounded_bottom_bg.xml create mode 100644 res/drawable/battery_tips_half_rounded_top_bg.xml create mode 100644 res/drawable/ic_battery_tips_close.xml create mode 100644 res/drawable/ic_battery_tips_close_icon.xml create mode 100644 res/drawable/ic_battery_tips_lightbulb.xml create mode 100644 res/drawable/ic_battery_tips_thumb_down.xml create mode 100644 res/drawable/ic_battery_tips_thumb_up.xml create mode 100644 res/layout/battery_tips_card.xml create mode 100644 src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java create mode 100644 src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java diff --git a/res/drawable/battery_tips_all_rounded_bg.xml b/res/drawable/battery_tips_all_rounded_bg.xml new file mode 100644 index 00000000000..4f61f544074 --- /dev/null +++ b/res/drawable/battery_tips_all_rounded_bg.xml @@ -0,0 +1,22 @@ + + + + + + + \ No newline at end of file diff --git a/res/drawable/battery_tips_half_rounded_bottom_bg.xml b/res/drawable/battery_tips_half_rounded_bottom_bg.xml new file mode 100644 index 00000000000..7766de63400 --- /dev/null +++ b/res/drawable/battery_tips_half_rounded_bottom_bg.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/res/drawable/battery_tips_half_rounded_top_bg.xml b/res/drawable/battery_tips_half_rounded_top_bg.xml new file mode 100644 index 00000000000..aba1a4fb329 --- /dev/null +++ b/res/drawable/battery_tips_half_rounded_top_bg.xml @@ -0,0 +1,27 @@ + + + + + + + \ No newline at end of file diff --git a/res/drawable/ic_battery_tips_close.xml b/res/drawable/ic_battery_tips_close.xml new file mode 100644 index 00000000000..7ef571b52f9 --- /dev/null +++ b/res/drawable/ic_battery_tips_close.xml @@ -0,0 +1,25 @@ + + + + + diff --git a/res/drawable/ic_battery_tips_close_icon.xml b/res/drawable/ic_battery_tips_close_icon.xml new file mode 100644 index 00000000000..b7664740450 --- /dev/null +++ b/res/drawable/ic_battery_tips_close_icon.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/res/drawable/ic_battery_tips_lightbulb.xml b/res/drawable/ic_battery_tips_lightbulb.xml new file mode 100644 index 00000000000..f1449f9bb5b --- /dev/null +++ b/res/drawable/ic_battery_tips_lightbulb.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/res/drawable/ic_battery_tips_thumb_down.xml b/res/drawable/ic_battery_tips_thumb_down.xml new file mode 100644 index 00000000000..cd7656b220f --- /dev/null +++ b/res/drawable/ic_battery_tips_thumb_down.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/res/drawable/ic_battery_tips_thumb_up.xml b/res/drawable/ic_battery_tips_thumb_up.xml new file mode 100644 index 00000000000..b1d4cb66c70 --- /dev/null +++ b/res/drawable/ic_battery_tips_thumb_up.xml @@ -0,0 +1,25 @@ + + + + + \ No newline at end of file diff --git a/res/layout/battery_tips_card.xml b/res/layout/battery_tips_card.xml new file mode 100644 index 00000000000..d2edb51c0ab --- /dev/null +++ b/res/layout/battery_tips_card.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index a7a124a32c5..e272c15109b 100755 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -373,6 +373,10 @@ 1dp 2dp + + 4dp + 24dp + 174dp 28dp diff --git a/res/values/strings.xml b/res/values/strings.xml index 840cef422f2..08632498e69 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -9686,6 +9686,24 @@ Set battery usage for apps + + Optimize + + + Is this message helpful? + + + Turn on adaptive brightness to extend battery life + + + It will help reduce your daily battery drain by 10% + + + Reduce screen timeout to extend battery life + + + It will help reduce your daily battery drain by 10% + Unrestricted diff --git a/res/xml/power_usage_advanced.xml b/res/xml/power_usage_advanced.xml index 2a1a23c78fe..c1294535a74 100644 --- a/res/xml/power_usage_advanced.xml +++ b/res/xml/power_usage_advanced.xml @@ -21,6 +21,18 @@ android:title="@string/advanced_battery_title" settings:keywords="@string/keywords_battery_usage"> + + + + + + mHourlyViewModels; private OnBatteryUsageUpdatedListener mOnBatteryUsageUpdatedListener; private OnScreenOnTimeUpdatedListener mOnScreenOnTimeUpdatedListener; + private OnBatteryTipsUpdatedListener mOnBatteryTipsUpdatedListener; private final SettingsActivity mActivity; private final MetricsFeatureProvider mMetricsFeatureProvider; @@ -209,6 +224,10 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll mOnScreenOnTimeUpdatedListener = listener; } + void setOnBatteryTipsUpdatedListener(OnBatteryTipsUpdatedListener listener) { + mOnBatteryTipsUpdatedListener = listener; + } + void setBatteryHistoryMap( final Map> batteryHistoryMap) { Log.d(TAG, "setBatteryHistoryMap() " + (batteryHistoryMap == null ? "null" @@ -344,6 +363,10 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll } mOnBatteryUsageUpdatedListener.onBatteryUsageUpdated( slotUsageData, getSlotInformation(), isBatteryUsageMapNullOrEmpty()); + + if (mOnBatteryTipsUpdatedListener != null) { + mOnBatteryTipsUpdatedListener.onBatteryTipsUpdated(null, null); + } } return true; } diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java new file mode 100644 index 00000000000..89e2ce937a5 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreference.java @@ -0,0 +1,99 @@ +/* + * 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. + */ + +package com.android.settings.fuelgauge.batteryusage; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.widget.ImageButton; +import android.widget.TextView; + +import androidx.preference.Preference; +import androidx.preference.PreferenceViewHolder; + +import com.android.settings.R; +import com.android.settings.fuelgauge.PowerUsageFeatureProvider; +import com.android.settings.overlay.FeatureFactory; + +import com.google.android.material.button.MaterialButton; + +/** + * A preference for displaying the battery tips card view. + */ +public class BatteryTipsCardPreference extends Preference implements View.OnClickListener { + + private static final String TAG = "BatteryTipsCardPreference"; + + private final PowerUsageFeatureProvider mPowerUsageFeatureProvider; + + private MaterialButton mActionButton; + private ImageButton mDismissButton; + private ImageButton mThumbUpButton; + private ImageButton mThumbDownButton; + private CharSequence mTitle; + private CharSequence mSummary; + + public BatteryTipsCardPreference(Context context, AttributeSet attrs) { + super(context, attrs); + setLayoutResource(R.layout.battery_tips_card); + setSelectable(false); + mPowerUsageFeatureProvider = FeatureFactory.getFeatureFactory() + .getPowerUsageFeatureProvider(); + } + + @Override + public void setTitle(CharSequence title) { + mTitle = title; + notifyChanged(); + } + + @Override + public void setSummary(CharSequence summary) { + mSummary = summary; + notifyChanged(); + } + + @Override + public void onClick(View view) { + // TODO: replace with the settings anomaly obtained from detectSettingsAnomaly(); + } + + @Override + public void onBindViewHolder(PreferenceViewHolder view) { + super.onBindViewHolder(view); + + ((TextView) view.findViewById(R.id.title)).setText(mTitle); + ((TextView) view.findViewById(R.id.summary)).setText(mSummary); + + mActionButton = (MaterialButton) view.findViewById(R.id.action_button); + mActionButton.setOnClickListener(this); + mDismissButton = (ImageButton) view.findViewById(R.id.dismiss_button); + mDismissButton.setOnClickListener(this); + + if (!mPowerUsageFeatureProvider.isBatteryTipsFeedbackEnabled()) { + return; + } + view.findViewById(R.id.tips_card) + .setBackgroundResource(R.drawable.battery_tips_half_rounded_top_bg); + view.findViewById(R.id.feedback_card).setVisibility(View.VISIBLE); + + mThumbUpButton = (ImageButton) view.findViewById(R.id.thumb_up); + mThumbUpButton.setOnClickListener(this); + mThumbDownButton = (ImageButton) view.findViewById(R.id.thumb_down); + mThumbDownButton.setOnClickListener(this); + } +} diff --git a/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java new file mode 100644 index 00000000000..87c43a1757c --- /dev/null +++ b/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsController.java @@ -0,0 +1,77 @@ +/* + * 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. + */ + +package com.android.settings.fuelgauge.batteryusage; + +import android.content.Context; + +import androidx.preference.PreferenceScreen; + +import com.android.settings.core.BasePreferenceController; +import com.android.settings.fuelgauge.PowerUsageFeatureProvider; +import com.android.settings.overlay.FeatureFactory; + +/** 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 final PowerUsageFeatureProvider mPowerUsageFeatureProvider; + + private Context mPrefContext; + private BatteryTipsCardPreference mCardPreference; + + public BatteryTipsController(Context context) { + super(context, ROOT_PREFERENCE_KEY); + mPowerUsageFeatureProvider = FeatureFactory.getFeatureFactory() + .getPowerUsageFeatureProvider(); + } + + @Override + public int getAvailabilityStatus() { + return AVAILABLE; + } + + @Override + public void displayPreference(PreferenceScreen screen) { + super.displayPreference(screen); + mPrefContext = screen.getContext(); + mCardPreference = screen.findPreference(CARD_PREFERENCE_KEY); + } + + /** + * Update the card visibility and contents. + * @param title a string not extend 2 lines. + * @param summary a string not extend 10 lines. + */ + // TODO: replace parameters with SettingsAnomaly Data Proto + public void handleBatteryTipsCardUpdated(String title, String summary) { + if (!mPowerUsageFeatureProvider.isBatteryTipsEnabled()) { + mCardPreference.setVisible(false); + return; + } + if (title == null || summary == null) { + mCardPreference.setVisible(false); + return; + } + mCardPreference.setTitle(title); + mCardPreference.setSummary(summary); + mCardPreference.setVisible(true); + } + +} diff --git a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java index 7c4478e66c6..5a96fb40abc 100644 --- a/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java +++ b/src/com/android/settings/fuelgauge/batteryusage/PowerUsageAdvanced.java @@ -34,6 +34,8 @@ import androidx.loader.content.Loader; import com.android.settings.R; import com.android.settings.SettingsActivity; import com.android.settings.fuelgauge.BatteryBroadcastReceiver; +import com.android.settings.fuelgauge.PowerUsageFeatureProvider; +import com.android.settings.overlay.FeatureFactory; import com.android.settings.search.BaseSearchIndexProvider; import com.android.settingslib.core.AbstractPreferenceController; import com.android.settingslib.search.SearchIndexable; @@ -143,6 +145,16 @@ public class PowerUsageAdvanced extends PowerUsageBase { controllers.add(screenOnTimeController); controllers.add(batteryUsageBreakdownController); setBatteryChartPreferenceController(); + + final PowerUsageFeatureProvider powerUsageFeatureProvider = + FeatureFactory.getFeatureFactory().getPowerUsageFeatureProvider(); + if (powerUsageFeatureProvider.isBatteryTipsEnabled()) { + BatteryTipsController batteryTipsController = new BatteryTipsController(context); + mBatteryChartPreferenceController.setOnBatteryTipsUpdatedListener( + batteryTipsController::handleBatteryTipsCardUpdated); + controllers.add(batteryTipsController); + } + return controllers; } diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java index 1a43dbbe8d2..c9591a51b08 100644 --- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java +++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageFeatureProviderImplTest.java @@ -67,6 +67,15 @@ public class PowerUsageFeatureProviderImplTest { assertThat(mPowerFeatureProvider.isBatteryUsageEnabled()).isTrue(); } + @Test + public void testIsBatteryTipsEnabled_returnFalse() { + assertThat(mPowerFeatureProvider.isBatteryTipsEnabled()).isFalse(); + } + + @Test + public void testIsBatteryTipsFeedbackEnabled_returnTrue() { + assertThat(mPowerFeatureProvider.isBatteryTipsFeedbackEnabled()).isTrue(); + } @Test public void testGetBatteryUsageListConsumePowerThreshold_return0() { assertThat(mPowerFeatureProvider.getBatteryUsageListConsumePowerThreshold()).isEqualTo(0.0); diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java new file mode 100644 index 00000000000..6f9a47416ae --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/batteryusage/BatteryTipsCardPreferenceTest.java @@ -0,0 +1,50 @@ +/* + * 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. + */ + +package com.android.settings.fuelgauge.batteryusage; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; + +import android.content.Context; + +import com.android.settings.R; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.RuntimeEnvironment; + +@RunWith(RobolectricTestRunner.class) +public final class BatteryTipsCardPreferenceTest { + + private Context mContext; + private BatteryTipsCardPreference mBatteryTipsCardPreference; + + @Before + public void setUp() { + mContext = spy(RuntimeEnvironment.application); + mBatteryTipsCardPreference = new BatteryTipsCardPreference(mContext, /*attrs=*/ null); + } + + @Test + public void constructor_returnExpectedResult() { + assertThat(mBatteryTipsCardPreference.getLayoutResource()).isEqualTo( + R.layout.battery_tips_card); + } +}