Merge changes Ifa91ad93,I14f9696a into pi-dev
am: d067cbcfc9
Change-Id: Idddf18d56322a274145be20a0c6858fcd6cd78e0
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
index b9194b4..fc2bbdf 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
@@ -67,7 +67,7 @@
final BatteryInfo batteryInfo = mBatteryUtils.getBatteryInfo(mBatteryStatsHelper, TAG);
final Context context = getContext();
- tips.add(new LowBatteryDetector(policy, batteryInfo).detect());
+ tips.add(new LowBatteryDetector(context, policy, batteryInfo).detect());
tips.add(new HighUsageDetector(context, policy, mBatteryStatsHelper,
batteryInfo.discharging).detect());
tips.add(new SmartBatteryDetector(policy, context.getContentResolver()).detect());
@@ -87,7 +87,8 @@
final List<BatteryTip> tips = new ArrayList<>();
tips.add(new SummaryTip(BatteryTip.StateType.NEW,
Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN));
- tips.add(new LowBatteryTip(BatteryTip.StateType.NEW));
+ tips.add(new LowBatteryTip(BatteryTip.StateType.NEW, false /* powerSaveModeOn */,
+ "Fake data"));
return tips;
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
index 5520bf3..1c7c760 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicy.java
@@ -50,6 +50,7 @@
private static final String KEY_TEST_BATTERY_SAVER_TIP = "test_battery_saver_tip";
private static final String KEY_TEST_HIGH_USAGE_TIP = "test_high_usage_tip";
private static final String KEY_TEST_SMART_BATTERY_TIP = "test_smart_battery_tip";
+ private static final String KEY_TEST_LOW_BATTERY_TIP = "test_low_battery_tip";
/**
* {@code true} if general battery tip is enabled
@@ -192,6 +193,14 @@
*/
public final boolean testSmartBatteryTip;
+ /**
+ * {@code true} if we want to test low battery tip.
+ *
+ * @see Settings.Global#BATTERY_TIP_CONSTANTS
+ * @see #KEY_TEST_LOW_BATTERY_TIP
+ */
+ public final boolean testLowBatteryTip;
+
private final KeyValueListParser mParser;
public BatteryTipPolicy(Context context) {
@@ -222,13 +231,14 @@
reducedBatteryEnabled = mParser.getBoolean(KEY_REDUCED_BATTERY_ENABLED, false);
reducedBatteryPercent = mParser.getInt(KEY_REDUCED_BATTERY_PERCENT, 50);
lowBatteryEnabled = mParser.getBoolean(KEY_LOW_BATTERY_ENABLED, false);
- lowBatteryHour = mParser.getInt(KEY_LOW_BATTERY_HOUR, 16);
+ lowBatteryHour = mParser.getInt(KEY_LOW_BATTERY_HOUR, 3);
dataHistoryRetainDay = mParser.getInt(KEY_DATA_HISTORY_RETAIN_DAY, 30);
excessiveBgDrainPercentage = mParser.getInt(KEY_EXCESSIVE_BG_DRAIN_PERCENTAGE, 10);
testBatterySaverTip = mParser.getBoolean(KEY_TEST_BATTERY_SAVER_TIP, false);
testHighUsageTip = mParser.getBoolean(KEY_TEST_HIGH_USAGE_TIP, false);
testSmartBatteryTip = mParser.getBoolean(KEY_TEST_SMART_BATTERY_TIP, false);
+ testLowBatteryTip = mParser.getBoolean(KEY_TEST_LOW_BATTERY_TIP, false);
}
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
index 2a6302e..c3f9b07 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
@@ -16,31 +16,52 @@
package com.android.settings.fuelgauge.batterytip.detectors;
-import android.text.format.DateUtils;
+import android.content.Context;
+import android.os.PowerManager;
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;
+import java.util.concurrent.TimeUnit;
+
/**
* Detect whether the battery is too low
*/
public class LowBatteryDetector implements BatteryTipDetector {
private BatteryInfo mBatteryInfo;
private BatteryTipPolicy mPolicy;
+ private PowerManager mPowerManager;
+ private int mWarningLevel;
- public LowBatteryDetector(BatteryTipPolicy policy, BatteryInfo batteryInfo) {
+ public LowBatteryDetector(Context context, BatteryTipPolicy policy, BatteryInfo batteryInfo) {
mPolicy = policy;
mBatteryInfo = batteryInfo;
+ mPowerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ mWarningLevel = context.getResources().getInteger(
+ com.android.internal.R.integer.config_lowBatteryWarningLevel);
}
@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;
+ final boolean powerSaveModeOn = mPowerManager.isPowerSaveMode();
+ final boolean lowBattery = mBatteryInfo.batteryLevel <= mWarningLevel
+ || (mBatteryInfo.discharging
+ && mBatteryInfo.remainingTimeUs < TimeUnit.HOURS.toMicros(mPolicy.lowBatteryHour));
+
+ int state = BatteryTip.StateType.INVISIBLE;
+ if (mPolicy.lowBatteryEnabled) {
+ if (powerSaveModeOn) {
+ // Show it is handled if battery saver is on
+ state = BatteryTip.StateType.HANDLED;
+ } else if (mPolicy.testLowBatteryTip || (mBatteryInfo.discharging && lowBattery)) {
+ // Show it is new if in test or in discharging low battery state
+ state = BatteryTip.StateType.NEW;
+ }
+ }
+
return new LowBatteryTip(
- isShown ? BatteryTip.StateType.NEW : BatteryTip.StateType.INVISIBLE);
+ state, powerSaveModeOn, mBatteryInfo.remainingLabel);
}
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
index f02dd72..2afdc81 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
@@ -74,10 +74,10 @@
TIP_ORDER.append(TipType.APP_RESTRICTION, 0);
TIP_ORDER.append(TipType.BATTERY_SAVER, 1);
TIP_ORDER.append(TipType.HIGH_DEVICE_USAGE, 2);
- TIP_ORDER.append(TipType.SUMMARY, 3);
- TIP_ORDER.append(TipType.SMART_BATTERY_MANAGER, 4);
- TIP_ORDER.append(TipType.REDUCED_BATTERY, 5);
- TIP_ORDER.append(TipType.LOW_BATTERY, 6);
+ TIP_ORDER.append(TipType.LOW_BATTERY, 3);
+ TIP_ORDER.append(TipType.SUMMARY, 4);
+ TIP_ORDER.append(TipType.SMART_BATTERY_MANAGER, 5);
+ TIP_ORDER.append(TipType.REDUCED_BATTERY, 6);
TIP_ORDER.append(TipType.REMOVE_APP_RESTRICTION, 7);
}
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
index 86237dd..b48a7dd 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java
@@ -25,36 +25,32 @@
import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
/**
- * Tip to show current battery life is short
+ * Tip to show current battery level is low or remaining time is less than a certain period
*/
-public class LowBatteryTip extends BatteryTip {
+public class LowBatteryTip extends EarlyWarningTip {
+ private CharSequence mSummary;
- public LowBatteryTip(@StateType int state) {
- super(TipType.LOW_BATTERY, state, false /* showDialog */);
+ public LowBatteryTip(@StateType int state, boolean powerSaveModeOn, CharSequence summary) {
+ super(state, powerSaveModeOn);
+ mType = TipType.LOW_BATTERY;
+ mSummary = summary;
}
- private LowBatteryTip(Parcel in) {
+ public LowBatteryTip(Parcel in) {
super(in);
- }
-
- @Override
- public CharSequence getTitle(Context context) {
- return context.getString(R.string.battery_tip_low_battery_title);
+ mSummary = in.readCharSequence();
}
@Override
public CharSequence getSummary(Context context) {
- return context.getString(R.string.battery_tip_low_battery_summary);
+ return mState == StateType.HANDLED ? context.getString(
+ R.string.battery_tip_early_heads_up_done_summary) : mSummary;
}
@Override
- public int getIconId() {
- return R.drawable.ic_perm_device_information_red_24dp;
- }
-
- @Override
- public void updateState(BatteryTip tip) {
- mState = tip.mState;
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeCharSequence(mSummary);
}
@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
index b50cc40..b0d6a7d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java
@@ -48,9 +48,9 @@
BatteryTip.TipType.APP_RESTRICTION,
BatteryTip.TipType.BATTERY_SAVER,
BatteryTip.TipType.HIGH_DEVICE_USAGE,
+ BatteryTip.TipType.LOW_BATTERY,
BatteryTip.TipType.SUMMARY,
- BatteryTip.TipType.SMART_BATTERY_MANAGER,
- BatteryTip.TipType.LOW_BATTERY};
+ BatteryTip.TipType.SMART_BATTERY_MANAGER};
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private BatteryStatsHelper mBatteryStatsHelper;
@Mock
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
index 654b247..350326a 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPolicyTest.java
@@ -48,7 +48,8 @@
+ ",excessive_bg_drain_percentage=25"
+ ",test_battery_saver_tip=true"
+ ",test_high_usage_tip=false"
- + ",test_smart_battery_tip=true";
+ + ",test_smart_battery_tip=true"
+ + ",test_low_battery_tip=true";
private Context mContext;
@Before
@@ -80,6 +81,7 @@
assertThat(batteryTipPolicy.testBatterySaverTip).isTrue();
assertThat(batteryTipPolicy.testHighUsageTip).isFalse();
assertThat(batteryTipPolicy.testSmartBatteryTip).isTrue();
+ assertThat(batteryTipPolicy.testLowBatteryTip).isTrue();
}
@Test
@@ -100,11 +102,12 @@
assertThat(batteryTipPolicy.reducedBatteryEnabled).isFalse();
assertThat(batteryTipPolicy.reducedBatteryPercent).isEqualTo(50);
assertThat(batteryTipPolicy.lowBatteryEnabled).isFalse();
- assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(16);
+ assertThat(batteryTipPolicy.lowBatteryHour).isEqualTo(3);
assertThat(batteryTipPolicy.dataHistoryRetainDay).isEqualTo(30);
assertThat(batteryTipPolicy.excessiveBgDrainPercentage).isEqualTo(10);
assertThat(batteryTipPolicy.testBatterySaverTip).isFalse();
assertThat(batteryTipPolicy.testHighUsageTip).isFalse();
assertThat(batteryTipPolicy.testSmartBatteryTip).isFalse();
+ assertThat(batteryTipPolicy.testLowBatteryTip).isFalse();
}
}
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
index 1f4affa..9764559 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java
@@ -17,12 +17,15 @@
package com.android.settings.fuelgauge.batterytip.detectors;
import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.spy;
-import android.text.format.DateUtils;
+import android.content.Context;
+import android.os.PowerManager;
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.testutils.SettingsRobolectricTestRunner;
import org.junit.Before;
@@ -31,8 +34,12 @@
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.robolectric.RuntimeEnvironment;
+import org.robolectric.Shadows;
+import org.robolectric.shadows.ShadowPowerManager;
import org.robolectric.util.ReflectionHelpers;
+import java.util.concurrent.TimeUnit;
+
@RunWith(SettingsRobolectricTestRunner.class)
public class LowBatteryDetectorTest {
@@ -40,36 +47,68 @@
private BatteryInfo mBatteryInfo;
private BatteryTipPolicy mPolicy;
private LowBatteryDetector mLowBatteryDetector;
+ private ShadowPowerManager mShadowPowerManager;
+ private Context mContext;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mPolicy = spy(new BatteryTipPolicy(RuntimeEnvironment.application));
+ mContext = RuntimeEnvironment.application;
+ mShadowPowerManager = Shadows.shadowOf(mContext.getSystemService(PowerManager.class));
ReflectionHelpers.setField(mPolicy, "lowBatteryEnabled", true);
+ ReflectionHelpers.setField(mPolicy, "lowBatteryHour", 3);
+ mBatteryInfo.discharging = true;
- mLowBatteryDetector = new LowBatteryDetector(mPolicy, mBatteryInfo);
+ mLowBatteryDetector = new LowBatteryDetector(mContext, mPolicy, mBatteryInfo);
}
@Test
public void testDetect_disabledByPolicy_tipInvisible() {
ReflectionHelpers.setField(mPolicy, "lowBatteryEnabled", false);
+ mShadowPowerManager.setIsPowerSaveMode(true);
assertThat(mLowBatteryDetector.detect().isVisible()).isFalse();
}
@Test
- public void testDetect_shortBatteryLife_tipVisible() {
- mBatteryInfo.discharging = true;
- mBatteryInfo.remainingTimeUs = DateUtils.MINUTE_IN_MILLIS;
+ public void testDetect_enabledByTest_tipNew() {
+ ReflectionHelpers.setField(mPolicy, "testLowBatteryTip", true);
- assertThat(mLowBatteryDetector.detect().isVisible()).isTrue();
+ assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.NEW);
}
@Test
- public void testDetect_longBatteryLife_tipInvisible() {
- mBatteryInfo.discharging = true;
- mBatteryInfo.remainingTimeUs = DateUtils.DAY_IN_MILLIS;
+ public void testDetect_lowBattery_tipNew() {
+ mBatteryInfo.batteryLevel = 3;
+ mBatteryInfo.remainingTimeUs = TimeUnit.DAYS.toMillis(1);
+ assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.NEW);
+
+ mBatteryInfo.batteryLevel = 50;
+ mBatteryInfo.remainingTimeUs = TimeUnit.MINUTES.toMillis(1);
+ assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.NEW);
+ }
+
+ @Test
+ public void testDetect_batterySaverOn_tipHandled() {
+ mShadowPowerManager.setIsPowerSaveMode(true);
+
+ assertThat(mLowBatteryDetector.detect().getState())
+ .isEqualTo(BatteryTip.StateType.HANDLED);
+ }
+
+ @Test
+ public void testDetect_charging_tipInvisible() {
+ mBatteryInfo.discharging = false;
+
+ assertThat(mLowBatteryDetector.detect().isVisible()).isFalse();
+ }
+
+ @Test
+ public void testDetect_noEarlyWarning_tipInvisible() {
+ mBatteryInfo.remainingTimeUs = TimeUnit.DAYS.toMicros(1);
+ mBatteryInfo.batteryLevel = 100;
assertThat(mLowBatteryDetector.detect().isVisible()).isFalse();
}
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
new file mode 100644
index 0000000..359d260
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTipTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2018 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 static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.os.Parcel;
+
+import com.android.internal.logging.nano.MetricsProto;
+import com.android.settings.R;
+import com.android.settings.testutils.SettingsRobolectricTestRunner;
+import com.android.settingslib.core.instrumentation.MetricsFeatureProvider;
+
+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;
+
+@RunWith(SettingsRobolectricTestRunner.class)
+public class LowBatteryTipTest {
+
+ private static final CharSequence SUMMARY = "Only 15 minutes left";
+
+ @Mock
+ private MetricsFeatureProvider mMetricsFeatureProvider;
+ private Context mContext;
+ private LowBatteryTip mLowBatteryTip;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+
+ mContext = RuntimeEnvironment.application;
+ mLowBatteryTip = new LowBatteryTip(BatteryTip.StateType.NEW, false /* powerSaveModeOn */,
+ SUMMARY);
+ }
+
+ @Test
+ public void testParcelable() {
+ Parcel parcel = Parcel.obtain();
+ mLowBatteryTip.writeToParcel(parcel, mLowBatteryTip.describeContents());
+ parcel.setDataPosition(0);
+
+ final LowBatteryTip parcelTip = new LowBatteryTip(parcel);
+
+ assertThat(parcelTip.isPowerSaveModeOn()).isFalse();
+ assertThat(parcelTip.getSummary(mContext)).isEqualTo(SUMMARY);
+ }
+
+ @Test
+ public void getSummary_tipHandled_showSummary() {
+ mLowBatteryTip.mState = BatteryTip.StateType.HANDLED;
+
+ assertThat(mLowBatteryTip.getSummary(mContext)).isEqualTo("Some features may be limited");
+ }
+
+ @Test
+ public void getSummary_tipNew_showSummary() {
+ mLowBatteryTip.mState = BatteryTip.StateType.NEW;
+
+ assertThat(mLowBatteryTip.getSummary(mContext)).isEqualTo(SUMMARY);
+ }
+
+ @Test
+ public void log_lowBatteryActionWithCorrectState() {
+ mLowBatteryTip.log(mContext, mMetricsFeatureProvider);
+
+ verify(mMetricsFeatureProvider).action(mContext,
+ MetricsProto.MetricsEvent.ACTION_LOW_BATTERY_TIP, BatteryTip.StateType.NEW);
+ }
+}