From 03a5612355617803d8c355b3eef70379fb6f05da Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Wed, 13 Dec 2017 13:40:24 -0800 Subject: [PATCH 1/2] Add BatteryTipPolicy BatteryTipPolicy contains all experimental values we could tune for battery tip. Bug: 70570352 Test: RunSettingsRoboTests Change-Id: I26a3c2260dc6ff5cb10e3a4c1d55a715cc5c9a9d --- .../batterytip/BatteryTipPolicy.java | 153 ++++++++++++++++++ .../batterytip/BatteryTipPolicyTest.java | 95 +++++++++++ 2 files changed, 248 insertions(+) create mode 100644 src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java new file mode 100644 index 00000000000..ac5072d2b2c --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2017 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.batterytip; + +import android.content.Context; +import android.provider.Settings; +import android.support.annotation.VisibleForTesting; +import android.util.KeyValueListParser; +import android.util.Log; + +/** + * Class to store the policy for battery tips, which comes from + * {@link Settings.Global} + */ +public class BatteryTipPolicy { + public static final String TAG = "BatteryTipPolicy"; + + private static final String KEY_BATTERY_TIP_ENABLED = "battery_tip_enabled"; + private static final String KEY_SUMMARY_ENABLED = "summary_enabled"; + private static final String KEY_BATTERY_SAVER_TIP_ENABLED = "battery_saver_tip_enabled"; + private static final String KEY_HIGH_USAGE_ENABLED = "high_usage_enabled"; + private static final String KEY_HIGH_USAGE_APP_COUNT = "high_usage_app_count"; + private static final String KEY_APP_RESTRICTION_ENABLED = "app_restriction_enabled"; + private static final String KEY_REDUCED_BATTERY_ENABLED = "reduced_battery_enabled"; + private static final String KEY_REDUCED_BATTERY_PERCENT = "reduced_battery_percent"; + private static final String KEY_LOW_BATTERY_ENABLED = "low_battery_enabled"; + private static final String KEY_LOW_BATTERY_HOUR = "low_battery_hour"; + + /** + * {@code true} if general battery tip is enabled + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_BATTERY_TIP_ENABLED + */ + public final boolean batteryTipEnabled; + + /** + * {@code true} if summary tip is enabled + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_SUMMARY_ENABLED + */ + public final boolean summaryEnabled; + + /** + * {@code true} if battery saver tip is enabled + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_BATTERY_SAVER_TIP_ENABLED + */ + public final boolean batterySaverTipEnabled; + + /** + * {@code true} if high usage tip is enabled + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_HIGH_USAGE_ENABLED + */ + public final boolean highUsageEnabled; + + /** + * The maximum number of apps shown in high usage + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_HIGH_USAGE_APP_COUNT + */ + public final int highUsageAppCount; + + /** + * {@code true} if app restriction tip is enabled + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_APP_RESTRICTION_ENABLED + */ + public final boolean appRestrictionEnabled; + + /** + * {@code true} if reduced battery tip is enabled + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_REDUCED_BATTERY_ENABLED + */ + public final boolean reducedBatteryEnabled; + + /** + * The percentage of reduced battery to trigger the tip(e.g. 50%) + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_REDUCED_BATTERY_PERCENT + */ + public final int reducedBatteryPercent; + + /** + * {@code true} if low battery tip is enabled + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_LOW_BATTERY_ENABLED + */ + public final boolean lowBatteryEnabled; + + /** + * Remaining battery hour to trigger the tip(e.g. 16 hours) + * + * @see Settings.Global#BATTERY_TIP_CONSTANTS + * @see #KEY_LOW_BATTERY_HOUR + */ + public final int lowBatteryHour; + + private final KeyValueListParser mParser; + + public BatteryTipPolicy(Context context) { + this(context, new KeyValueListParser(',')); + } + + @VisibleForTesting + BatteryTipPolicy(Context context, KeyValueListParser parser) { + mParser = parser; + final String value = Settings.Global.getString(context.getContentResolver(), + Settings.Global.BATTERY_TIP_CONSTANTS); + + try { + mParser.setString(value); + } catch (IllegalArgumentException e) { + Log.e(TAG, "Bad battery tip constants"); + } + + batteryTipEnabled = mParser.getBoolean(KEY_BATTERY_TIP_ENABLED, true); + summaryEnabled = mParser.getBoolean(KEY_SUMMARY_ENABLED, true); + batterySaverTipEnabled = mParser.getBoolean(KEY_BATTERY_SAVER_TIP_ENABLED, true); + highUsageEnabled = mParser.getBoolean(KEY_HIGH_USAGE_ENABLED, true); + highUsageAppCount = mParser.getInt(KEY_HIGH_USAGE_APP_COUNT, 3); + appRestrictionEnabled = mParser.getBoolean(KEY_APP_RESTRICTION_ENABLED, true); + reducedBatteryEnabled = mParser.getBoolean(KEY_REDUCED_BATTERY_ENABLED, true); + reducedBatteryPercent = mParser.getInt(KEY_REDUCED_BATTERY_PERCENT, 50); + lowBatteryEnabled = mParser.getBoolean(KEY_LOW_BATTERY_ENABLED, true); + lowBatteryHour = mParser.getInt(KEY_LOW_BATTERY_HOUR, 16); + } + +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java new file mode 100644 index 00000000000..1198b270cf2 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2017 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.batterytip; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import android.content.Context; +import android.provider.Settings; + +import com.android.settings.TestConfig; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class BatteryTipPolicyTest { + private static final String BATTERY_TIP_CONSTANTS_VALUE = "battery_tip_enabled=true" + + ",summary_enabled=false" + + ",battery_saver_tip_enabled=false" + + ",high_usage_enabled=true" + + ",high_usage_app_count=5" + + ",app_restriction_enabled=true" + + ",reduced_battery_enabled=true" + + ",reduced_battery_percent=30" + + ",low_battery_enabled=false" + + ",low_battery_hour=10"; + private Context mContext; + + @Before + public void setUp() { + mContext = RuntimeEnvironment.application; + } + + @Test + public void testInit_usesConfigValues() { + Settings.Global.putString(mContext.getContentResolver(), + Settings.Global.BATTERY_TIP_CONSTANTS, BATTERY_TIP_CONSTANTS_VALUE); + + final BatteryTipPolicy batteryTipPolicy = new BatteryTipPolicy(mContext); + + assertThat(batteryTipPolicy.batteryTipEnabled).isTrue(); + assertThat(batteryTipPolicy.summaryEnabled).isFalse(); + assertThat(batteryTipPolicy.batterySaverTipEnabled).isFalse(); + assertThat(batteryTipPolicy.highUsageEnabled).isTrue(); + assertThat(batteryTipPolicy.highUsageAppCount).isEqualTo(5); + assertThat(batteryTipPolicy.appRestrictionEnabled).isTrue(); + assertThat(batteryTipPolicy.reducedBatteryEnabled).isTrue(); + assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(30); + assertThat(batteryTipPolicy.lowBatteryEnabled).isFalse(); + assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(10); + } + + @Test + public void testInit_defaultValues() { + Settings.Global.putString(mContext.getContentResolver(), + Settings.Global.BATTERY_TIP_CONSTANTS, ""); + + final BatteryTipPolicy batteryTipPolicy = new BatteryTipPolicy(mContext); + + assertThat(batteryTipPolicy.batteryTipEnabled).isTrue(); + assertThat(batteryTipPolicy.summaryEnabled).isTrue(); + assertThat(batteryTipPolicy.batterySaverTipEnabled).isTrue(); + assertThat(batteryTipPolicy.highUsageEnabled).isTrue(); + assertThat(batteryTipPolicy.highUsageAppCount).isEqualTo(3); + assertThat(batteryTipPolicy.appRestrictionEnabled).isTrue(); + assertThat(batteryTipPolicy.reducedBatteryEnabled).isTrue(); + assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(50); + assertThat(batteryTipPolicy.lowBatteryEnabled).isTrue(); + assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(16); + } + +} From 5f0b09648b6f43fc5ca01473266cf85b28de832b Mon Sep 17 00:00:00 2001 From: jackqdyulei Date: Thu, 14 Dec 2017 11:15:04 -0800 Subject: [PATCH 2/2] Add BatteryTipDetector and LowBatteryTip stuffs. This cl adds the infra of BatteryTipDetector and use LowBatteryTip as an example(tip model + detector). Also add SummaryTipDetector and related tests Bug: 70570352 Test: RunSettingsRoboTests Change-Id: Icf1349b6ede9eb7ee5ed69b39ee3a2661ac660fa --- .../ic_perm_device_information_red_24dp.xml | 27 ++++++ res/values/strings.xml | 4 + .../batterytip/BatteryTipLoader.java | 43 ++++++++- .../detectors/BatteryTipDetector.java | 28 ++++++ .../detectors/LowBatteryDetector.java | 46 ++++++++++ .../batterytip/detectors/SummaryDetector.java | 44 ++++++++++ .../fuelgauge/batterytip/tips/BatteryTip.java | 11 ++- .../batterytip/tips/LowBatteryTip.java | 65 ++++++++++++++ .../fuelgauge/batterytip/tips/SummaryTip.java | 1 + .../batterytip/BatteryTipLoaderTest.java | 87 +++++++++++++++++++ .../detectors/LowBatteryDetectorTest.java | 80 +++++++++++++++++ .../detectors/SummaryDetectorTest.java | 72 +++++++++++++++ 12 files changed, 504 insertions(+), 4 deletions(-) create mode 100644 res/drawable/ic_perm_device_information_red_24dp.xml create mode 100644 src/com/android/settings/fuelgauge/batterytip/detectors/BatteryTipDetector.java create mode 100644 src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java create mode 100644 src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetector.java create mode 100644 src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java create mode 100644 tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java diff --git a/res/drawable/ic_perm_device_information_red_24dp.xml b/res/drawable/ic_perm_device_information_red_24dp.xml new file mode 100644 index 00000000000..135e212411a --- /dev/null +++ b/res/drawable/ic_perm_device_information_red_24dp.xml @@ -0,0 +1,27 @@ + + + + + diff --git a/res/values/strings.xml b/res/values/strings.xml index 65f73c81bfc..c94eb1ba3b4 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -4742,6 +4742,10 @@ Battery is in good shape Apps are behaving normally + + Low battery capacity + + Battery can\'t provide good battery life Stop app? diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java index b8cb6c48b15..9c3f48c0a6b 100644 --- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java +++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java @@ -17,13 +17,21 @@ package com.android.settings.fuelgauge.batterytip; import android.content.Context; +import android.support.annotation.VisibleForTesting; import com.android.internal.os.BatteryStatsHelper; +import com.android.settings.fuelgauge.BatteryInfo; +import com.android.settings.fuelgauge.BatteryUtils; +import com.android.settings.fuelgauge.batterytip.detectors.BatteryTipDetector; +import com.android.settings.fuelgauge.batterytip.detectors.LowBatteryDetector; +import com.android.settings.fuelgauge.batterytip.detectors.SummaryDetector; import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; +import com.android.settings.fuelgauge.batterytip.tips.LowBatteryTip; import com.android.settings.fuelgauge.batterytip.tips.SummaryTip; import com.android.settingslib.utils.AsyncLoader; import java.util.ArrayList; +import java.util.Collections; import java.util.List; /** @@ -36,18 +44,31 @@ public class BatteryTipLoader extends AsyncLoader> { private static final boolean USE_FAKE_DATA = false; private BatteryStatsHelper mBatteryStatsHelper; + private BatteryUtils mBatteryUtils; + @VisibleForTesting + int mVisibleTips; public BatteryTipLoader(Context context, BatteryStatsHelper batteryStatsHelper) { super(context); mBatteryStatsHelper = batteryStatsHelper; + mBatteryUtils = BatteryUtils.getInstance(context); } @Override public List loadInBackground() { - List tips = new ArrayList<>(); + if (USE_FAKE_DATA) { + return getFakeData(); + } + final List tips = new ArrayList<>(); + final BatteryTipPolicy policy = new BatteryTipPolicy(getContext()); + final BatteryInfo batteryInfo = mBatteryUtils.getBatteryInfo(mBatteryStatsHelper, TAG); + mVisibleTips = 0; - //TODO(b/70570352): add battery tip detectors - tips.add(new SummaryTip(BatteryTip.StateType.NEW)); + addBatteryTipFromDetector(tips, new LowBatteryDetector(policy, batteryInfo)); + // Add summary detector at last since it need other detectors to update the mVisibleTips + addBatteryTipFromDetector(tips, new SummaryDetector(policy, mVisibleTips)); + + Collections.sort(tips); return tips; } @@ -55,4 +76,20 @@ public class BatteryTipLoader extends AsyncLoader> { protected void onDiscardResult(List result) { } + private List getFakeData() { + final List tips = new ArrayList<>(); + tips.add(new SummaryTip(BatteryTip.StateType.NEW)); + tips.add(new LowBatteryTip(BatteryTip.StateType.NEW)); + + return tips; + } + + @VisibleForTesting + void addBatteryTipFromDetector(final List tips, + final BatteryTipDetector detector) { + final BatteryTip batteryTip = detector.detect(); + mVisibleTips += batteryTip.isVisible() ? 1 : 0; + tips.add(batteryTip); + } + } diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryTipDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryTipDetector.java new file mode 100644 index 00000000000..cb38e40faff --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/detectors/BatteryTipDetector.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2017 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.batterytip.detectors; + +import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; + +public interface BatteryTipDetector { + /** + * Detect and update the status of {@link BatteryTip} + * + * @return a not null {@link BatteryTip} + */ + BatteryTip detect(); +} diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java new file mode 100644 index 00000000000..2a6302efbc5 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2017 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.batterytip.detectors; + +import android.text.format.DateUtils; + +import com.android.settings.fuelgauge.BatteryInfo; +import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy; +import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; +import com.android.settings.fuelgauge.batterytip.tips.LowBatteryTip; + +/** + * Detect whether the battery is too low + */ +public class LowBatteryDetector implements BatteryTipDetector { + private BatteryInfo mBatteryInfo; + private BatteryTipPolicy mPolicy; + + public LowBatteryDetector(BatteryTipPolicy policy, BatteryInfo batteryInfo) { + mPolicy = policy; + mBatteryInfo = batteryInfo; + } + + @Override + public BatteryTip detect() { + // Show it if battery life is less than mPolicy.lowBatteryHour + final boolean isShown = mPolicy.lowBatteryEnabled && mBatteryInfo.discharging + && mBatteryInfo.remainingTimeUs < mPolicy.lowBatteryHour * DateUtils.HOUR_IN_MILLIS; + return new LowBatteryTip( + isShown ? BatteryTip.StateType.NEW : BatteryTip.StateType.INVISIBLE); + } +} diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetector.java new file mode 100644 index 00000000000..8c1783bd662 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetector.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2017 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.batterytip.detectors; + +import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy; +import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; +import com.android.settings.fuelgauge.batterytip.tips.SummaryTip; + +/** + * Detector whether to show summary tip. This detector should be executed as the last + * {@link BatteryTipDetector} since it need the most up-to-date {@code visibleTips} + */ +public class SummaryDetector implements BatteryTipDetector { + private BatteryTipPolicy mPolicy; + private int mVisibleTips; + + public SummaryDetector(BatteryTipPolicy policy, int visibleTips) { + mPolicy = policy; + mVisibleTips = visibleTips; + } + + @Override + public BatteryTip detect() { + // Show it if there is no other tips shown + final int state = mPolicy.summaryEnabled && mVisibleTips == 0 + ? BatteryTip.StateType.NEW + : BatteryTip.StateType.INVISIBLE; + return new SummaryTip(state); + } +} diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java index e6332724874..17e395ef185 100644 --- a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java +++ b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java @@ -31,7 +31,7 @@ import java.lang.annotation.RetentionPolicy; * Each {@link BatteryTip} contains basic data(e.g. title, summary, icon) as well as the * pre-defined action(e.g. turn on battery saver) */ -public abstract class BatteryTip { +public abstract class BatteryTip implements Comparable { @Retention(RetentionPolicy.SOURCE) @IntDef({StateType.NEW, StateType.HANDLED, @@ -114,4 +114,13 @@ public abstract class BatteryTip { public int getState() { return mState; } + + public boolean isVisible() { + return mState != StateType.INVISIBLE; + } + + @Override + public int compareTo(BatteryTip o) { + return mType - o.mType; + } } diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java new file mode 100644 index 00000000000..8605fbb6319 --- /dev/null +++ b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2017 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.batterytip.tips; + +import android.app.Dialog; +import android.content.Context; + +import com.android.settings.R; + +/** + * Tip to show current battery life is short + */ +public class LowBatteryTip extends BatteryTip { + + public LowBatteryTip(@StateType int state) { + mShowDialog = false; + mState = state; + mType = TipType.LOW_BATTERY; + } + + @Override + public CharSequence getTitle(Context context) { + return context.getString(R.string.battery_tip_low_battery_title); + } + + @Override + public CharSequence getSummary(Context context) { + return context.getString(R.string.battery_tip_low_battery_summary); + } + + @Override + public int getIconId() { + return R.drawable.ic_perm_device_information_red_24dp; + } + + @Override + public void updateState(BatteryTip tip) { + mState = tip.mState; + } + + @Override + public void action() { + // do nothing + } + + @Override + public Dialog buildDialog() { + //TODO(b/70570352): create the dialog for low battery tip and add test + return null; + } +} diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTip.java index ab2a6c3f197..2a2deabfa8f 100644 --- a/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTip.java +++ b/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTip.java @@ -29,6 +29,7 @@ public class SummaryTip extends BatteryTip { public SummaryTip(@StateType int state) { mShowDialog = false; mState = state; + mType = TipType.SUMMARY; } @Override diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java new file mode 100644 index 00000000000..e4e8eef5721 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2017 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.batterytip; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.doReturn; + +import android.content.Context; + +import com.android.internal.os.BatteryStatsHelper; +import com.android.settings.TestConfig; +import com.android.settings.fuelgauge.batterytip.detectors.BatteryTipDetector; +import com.android.settings.fuelgauge.batterytip.tips.BatteryTip; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; + +import java.util.ArrayList; +import java.util.List; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class BatteryTipLoaderTest { + @Mock + private BatteryStatsHelper mBatteryStatsHelper; + @Mock + private BatteryTipDetector mBatteryTipDetector; + @Mock + private BatteryTip mBatteryTip; + private Context mContext; + private BatteryTipLoader mBatteryTipLoader; + private List mBatteryTips; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = RuntimeEnvironment.application; + doReturn(mBatteryTip).when(mBatteryTipDetector).detect(); + mBatteryTipLoader = new BatteryTipLoader(mContext, mBatteryStatsHelper); + mBatteryTips = new ArrayList<>(); + } + + @Test + public void testAddBatteryTipFromDetector_tipVisible_addAndUpdateCount() { + doReturn(true).when(mBatteryTip).isVisible(); + mBatteryTipLoader.mVisibleTips = 0; + + mBatteryTipLoader.addBatteryTipFromDetector(mBatteryTips, mBatteryTipDetector); + + assertThat(mBatteryTips.contains(mBatteryTip)).isTrue(); + assertThat(mBatteryTipLoader.mVisibleTips).isEqualTo(1); + } + + @Test + public void testAddBatteryTipFromDetector_tipInvisible_doNotAddCount() { + doReturn(false).when(mBatteryTip).isVisible(); + mBatteryTipLoader.mVisibleTips = 0; + + mBatteryTipLoader.addBatteryTipFromDetector(mBatteryTips, mBatteryTipDetector); + + assertThat(mBatteryTips.contains(mBatteryTip)).isTrue(); + assertThat(mBatteryTipLoader.mVisibleTips).isEqualTo(0); + } + +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java new file mode 100644 index 00000000000..4866a6a7348 --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2017 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.batterytip.detectors; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; + +import android.content.Context; +import android.text.format.DateUtils; + +import com.android.settings.TestConfig; +import com.android.settings.fuelgauge.BatteryInfo; +import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class LowBatteryDetectorTest { + private Context mContext; + @Mock + private BatteryInfo mBatteryInfo; + private BatteryTipPolicy mPolicy; + private LowBatteryDetector mLowBatteryDetector; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = RuntimeEnvironment.application; + mPolicy = spy(new BatteryTipPolicy(mContext)); + mLowBatteryDetector = new LowBatteryDetector(mPolicy, mBatteryInfo); + } + + @Test + public void testDetect_disabledByPolicy_tipInvisible() { + ReflectionHelpers.setField(mPolicy, "lowBatteryEnabled", false); + + assertThat(mLowBatteryDetector.detect().isVisible()).isFalse(); + } + + @Test + public void testDetect_shortBatteryLife_tipVisible() { + mBatteryInfo.discharging = true; + mBatteryInfo.remainingTimeUs = 1 * DateUtils.MINUTE_IN_MILLIS; + + assertThat(mLowBatteryDetector.detect().isVisible()).isTrue(); + } + + @Test + public void testDetect_longBatteryLife_tipInvisible() { + mBatteryInfo.discharging = true; + mBatteryInfo.remainingTimeUs = 1 * DateUtils.DAY_IN_MILLIS; + + assertThat(mLowBatteryDetector.detect().isVisible()).isFalse(); + } +} diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java new file mode 100644 index 00000000000..389a6c3fc2a --- /dev/null +++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 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.batterytip.detectors; + +import static com.google.common.truth.Truth.assertThat; + +import static org.mockito.Mockito.spy; + +import android.content.Context; + +import com.android.settings.TestConfig; +import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy; +import com.android.settings.testutils.SettingsRobolectricTestRunner; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.MockitoAnnotations; +import org.robolectric.RuntimeEnvironment; +import org.robolectric.annotation.Config; +import org.robolectric.util.ReflectionHelpers; + +@RunWith(SettingsRobolectricTestRunner.class) +@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) +public class SummaryDetectorTest { + private Context mContext; + private BatteryTipPolicy mPolicy; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + + mContext = RuntimeEnvironment.application; + mPolicy = spy(new BatteryTipPolicy(mContext)); + } + + @Test + public void testDetect_disabledByPolicy_tipInvisible() { + ReflectionHelpers.setField(mPolicy, "summaryEnabled", false); + SummaryDetector detector = new SummaryDetector(mPolicy, 0 /* visibleTips */); + + assertThat(detector.detect().isVisible()).isFalse(); + } + + @Test + public void testDetect_noOtherTips_tipVisible() { + SummaryDetector detector = new SummaryDetector(mPolicy, 0 /* visibleTips */); + + assertThat(detector.detect().isVisible()).isTrue(); + } + + @Test + public void testDetect_hasOtherTips_tipInVisible() { + SummaryDetector detector = new SummaryDetector(mPolicy, 1 /* visibleTips */); + + assertThat(detector.detect().isVisible()).isFalse(); + } +}