[BatteryTips] Separate the low battery tips

Bug: 315748218
Test: atest SettingsRoboTestStub:com.android.settings.fuelgauge.batterytip.detectors.LowBatteryDetectorTest
Change-Id: Id973be37012da414d6125a4dd29ec4522ab80e95
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java
index cc333a5..62be5df 100644
--- a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java
+++ b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProvider.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 
+import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 
 import java.util.List;
@@ -35,5 +36,9 @@
     boolean isBatteryInfoEnabled(Context context);
 
     /** A way to add more battery tip detectors. */
-    void addBatteryTipDetector(Context context, List<BatteryTip> tips, BatteryInfo batteryInfo);
+    void addBatteryTipDetector(
+            Context context,
+            List<BatteryTip> batteryTips,
+            BatteryInfo batteryInfo,
+            BatteryTipPolicy batteryTipPolicy);
 }
diff --git a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java
index f974b9d..f398373 100644
--- a/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java
+++ b/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImpl.java
@@ -18,6 +18,8 @@
 
 import android.content.Context;
 
+import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
+import com.android.settings.fuelgauge.batterytip.detectors.LowBatteryDetector;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 
 import java.util.List;
@@ -42,5 +44,10 @@
 
     @Override
     public void addBatteryTipDetector(
-            Context context, List<BatteryTip> tips, BatteryInfo batteryInfo) {}
+            Context context,
+            List<BatteryTip> batteryTips,
+            BatteryInfo batteryInfo,
+            BatteryTipPolicy batteryTipPolicy) {
+        batteryTips.add(new LowBatteryDetector(context, batteryTipPolicy, batteryInfo).detect());
+    }
 }
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
index 5352105..d68bf39 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
@@ -18,7 +18,6 @@
 
 import android.content.Context;
 import android.os.BatteryUsageStats;
-import android.os.PowerManager;
 
 import androidx.annotation.VisibleForTesting;
 
@@ -27,7 +26,6 @@
 import com.android.settings.fuelgauge.batterytip.detectors.BatteryDefenderDetector;
 import com.android.settings.fuelgauge.batterytip.detectors.HighUsageDetector;
 import com.android.settings.fuelgauge.batterytip.detectors.IncompatibleChargerDetector;
-import com.android.settings.fuelgauge.batterytip.detectors.LowBatteryDetector;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settingslib.utils.AsyncLoaderCompat;
@@ -56,19 +54,18 @@
     @Override
     public List<BatteryTip> loadInBackground() {
         final List<BatteryTip> tips = new ArrayList<>();
-        final BatteryTipPolicy policy = new BatteryTipPolicy(getContext());
+        final BatteryTipPolicy batteryTipPolicy = new BatteryTipPolicy(getContext());
         final BatteryInfo batteryInfo = mBatteryUtils.getBatteryInfo(TAG);
         final Context context = getContext().getApplicationContext();
-        final boolean isPowerSaveMode =
-                context.getSystemService(PowerManager.class).isPowerSaveMode();
 
-        tips.add(new LowBatteryDetector(context, policy, batteryInfo, isPowerSaveMode).detect());
-        tips.add(new HighUsageDetector(context, policy, mBatteryUsageStats, batteryInfo).detect());
+        tips.add(
+                new HighUsageDetector(context, batteryTipPolicy, mBatteryUsageStats, batteryInfo)
+                        .detect());
         tips.add(new BatteryDefenderDetector(batteryInfo, context).detect());
         tips.add(new IncompatibleChargerDetector(context).detect());
         FeatureFactory.getFeatureFactory()
                 .getBatterySettingsFeatureProvider()
-                .addBatteryTipDetector(context, tips, batteryInfo);
+                .addBatteryTipDetector(context, tips, batteryInfo, batteryTipPolicy);
         Collections.sort(tips);
         return tips;
     }
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
index 1ce5a8e..b1a1562 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java
@@ -17,6 +17,7 @@
 package com.android.settings.fuelgauge.batterytip.detectors;
 
 import android.content.Context;
+import android.os.PowerManager;
 
 import com.android.settings.fuelgauge.BatteryInfo;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
@@ -26,37 +27,33 @@
 /** Detect whether the battery is too low */
 public class LowBatteryDetector implements BatteryTipDetector {
     private final BatteryInfo mBatteryInfo;
-    private final BatteryTipPolicy mPolicy;
+    private final BatteryTipPolicy mBatteryTipPolicy;
     private final boolean mIsPowerSaveMode;
     private final int mWarningLevel;
 
     public LowBatteryDetector(
-            Context context,
-            BatteryTipPolicy policy,
-            BatteryInfo batteryInfo,
-            boolean isPowerSaveMode) {
-        mPolicy = policy;
+            Context context, BatteryTipPolicy batteryTipPolicy, BatteryInfo batteryInfo) {
+        mBatteryTipPolicy = batteryTipPolicy;
         mBatteryInfo = batteryInfo;
         mWarningLevel =
                 context.getResources()
                         .getInteger(com.android.internal.R.integer.config_lowBatteryWarningLevel);
-        mIsPowerSaveMode = isPowerSaveMode;
+        mIsPowerSaveMode = context.getSystemService(PowerManager.class).isPowerSaveMode();
     }
 
     @Override
     public BatteryTip detect() {
         final boolean lowBattery = mBatteryInfo.batteryLevel <= mWarningLevel;
-        final boolean lowBatteryEnabled = mPolicy.lowBatteryEnabled && !mIsPowerSaveMode;
+        final boolean lowBatteryEnabled = mBatteryTipPolicy.lowBatteryEnabled && !mIsPowerSaveMode;
         final boolean dischargingLowBatteryState =
-                mPolicy.testLowBatteryTip || (mBatteryInfo.discharging && lowBattery);
-
-        int state = BatteryTip.StateType.INVISIBLE;
+                mBatteryTipPolicy.testLowBatteryTip || (mBatteryInfo.discharging && lowBattery);
 
         // Show it as new if in test or in discharging low battery state,
         // dismiss it if battery saver is on or disabled by config.
-        if (lowBatteryEnabled && dischargingLowBatteryState) {
-            state = BatteryTip.StateType.NEW;
-        }
+        final int state =
+                lowBatteryEnabled && dischargingLowBatteryState
+                        ? BatteryTip.StateType.NEW
+                        : BatteryTip.StateType.INVISIBLE;
 
         return new LowBatteryTip(state, mIsPowerSaveMode);
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImplTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImplTest.java
index 554227e..14ba337 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImplTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatterySettingsFeatureProviderImplTest.java
@@ -22,11 +22,17 @@
 
 import androidx.test.core.app.ApplicationProvider;
 
+import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
+import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
+import com.android.settings.fuelgauge.batterytip.tips.LowBatteryTip;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.robolectric.RobolectricTestRunner;
 
+import java.util.ArrayList;
+
 @RunWith(RobolectricTestRunner.class)
 public class BatterySettingsFeatureProviderImplTest {
     private BatterySettingsFeatureProviderImpl mImpl;
@@ -52,4 +58,15 @@
     public void isBatteryInfoEnabled_returnFalse() {
         assertThat(mImpl.isBatteryInfoEnabled(mContext)).isFalse();
     }
+
+    @Test
+    public void addBatteryTipDetector_containsLowBatteryTip() {
+        var tips = new ArrayList<BatteryTip>();
+
+        mImpl.addBatteryTipDetector(
+                mContext, tips, new BatteryInfo(), new BatteryTipPolicy(mContext));
+
+        var expectedResult = tips.stream().anyMatch(tip -> tip instanceof LowBatteryTip);
+        assertThat(expectedResult).isTrue();
+    }
 }
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 8e3de7c..c5897f2 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
@@ -19,20 +19,25 @@
 import static com.google.common.truth.Truth.assertThat;
 
 import static org.mockito.Mockito.spy;
+import static org.robolectric.Shadows.shadowOf;
 
 import android.content.Context;
+import android.os.PowerManager;
+
+import androidx.test.core.app.ApplicationProvider;
 
 import com.android.settings.fuelgauge.BatteryInfo;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 
 import org.junit.Before;
+import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
 import org.robolectric.RobolectricTestRunner;
-import org.robolectric.RuntimeEnvironment;
 import org.robolectric.util.ReflectionHelpers;
 
 import java.util.concurrent.TimeUnit;
@@ -40,73 +45,79 @@
 @RunWith(RobolectricTestRunner.class)
 public class LowBatteryDetectorTest {
 
+    @Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
+
     @Mock private BatteryInfo mBatteryInfo;
-    private BatteryTipPolicy mPolicy;
+
+    private BatteryTipPolicy mBatteryTipPolicy;
     private LowBatteryDetector mLowBatteryDetector;
     private Context mContext;
+    private PowerManager mPowerManager;
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
+        mContext = ApplicationProvider.getApplicationContext();
+        mBatteryTipPolicy = spy(new BatteryTipPolicy(mContext));
 
-        mPolicy = spy(new BatteryTipPolicy(RuntimeEnvironment.application));
-        mContext = RuntimeEnvironment.application;
-        ReflectionHelpers.setField(mPolicy, "lowBatteryEnabled", true);
+        mPowerManager = mContext.getSystemService(PowerManager.class);
+        shadowOf(mPowerManager).setIsPowerSaveMode(false);
+
+        ReflectionHelpers.setField(mBatteryTipPolicy, "lowBatteryEnabled", true);
         mBatteryInfo.discharging = true;
 
-        mLowBatteryDetector =
-                new LowBatteryDetector(
-                        mContext, mPolicy, mBatteryInfo, false /* isPowerSaveMode */);
+        mLowBatteryDetector = new LowBatteryDetector(mContext, mBatteryTipPolicy, mBatteryInfo);
     }
 
     @Test
-    public void testDetect_disabledByPolicy_tipInvisible() {
-        ReflectionHelpers.setField(mPolicy, "lowBatteryEnabled", false);
-        mLowBatteryDetector =
-                new LowBatteryDetector(mContext, mPolicy, mBatteryInfo, true /* isPowerSaveMode */);
+    public void detect_disabledByPolicy_tipInvisible() {
+        ReflectionHelpers.setField(mBatteryTipPolicy, "lowBatteryEnabled", false);
+        shadowOf(mPowerManager).setIsPowerSaveMode(true);
+        mLowBatteryDetector = new LowBatteryDetector(mContext, mBatteryTipPolicy, mBatteryInfo);
 
         assertThat(mLowBatteryDetector.detect().isVisible()).isFalse();
     }
 
     @Test
-    public void testDetect_enabledByTest_tipNew() {
-        ReflectionHelpers.setField(mPolicy, "testLowBatteryTip", true);
+    public void detect_enabledByTest_tipNew() {
+        ReflectionHelpers.setField(mBatteryTipPolicy, "testLowBatteryTip", true);
 
         assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.NEW);
     }
 
     @Test
-    public void testDetect_lowBattery_tipNew() {
+    public void detect_lowBattery_tipNew() {
         mBatteryInfo.batteryLevel = 20;
         mBatteryInfo.remainingTimeUs = TimeUnit.DAYS.toMillis(1);
+
         assertThat(mLowBatteryDetector.detect().getState()).isEqualTo(BatteryTip.StateType.NEW);
     }
 
     @Test
-    public void testDetect_batterySaverOn_tipInvisible() {
-        mLowBatteryDetector =
-                new LowBatteryDetector(mContext, mPolicy, mBatteryInfo, true /* isPowerSaveMode */);
+    public void detect_batterySaverOn_tipInvisible() {
+        shadowOf(mPowerManager).setIsPowerSaveMode(true);
+        mLowBatteryDetector = new LowBatteryDetector(mContext, mBatteryTipPolicy, mBatteryInfo);
 
         assertThat(mLowBatteryDetector.detect().getState())
                 .isEqualTo(BatteryTip.StateType.INVISIBLE);
     }
 
     @Test
-    public void testDetect_charging_tipInvisible() {
+    public void detect_charging_tipInvisible() {
         mBatteryInfo.discharging = false;
 
         assertThat(mLowBatteryDetector.detect().isVisible()).isFalse();
     }
 
     @Test
-    public void testDetect_lowTimeEstimation_tipInvisible() {
+    public void detect_lowTimeEstimation_tipInvisible() {
         mBatteryInfo.batteryLevel = 50;
         mBatteryInfo.remainingTimeUs = TimeUnit.MINUTES.toMillis(1);
+
         assertThat(mLowBatteryDetector.detect().isVisible()).isFalse();
     }
 
     @Test
-    public void testDetect_noEarlyWarning_tipInvisible() {
+    public void detect_noEarlyWarning_tipInvisible() {
         mBatteryInfo.remainingTimeUs = TimeUnit.DAYS.toMicros(1);
         mBatteryInfo.batteryLevel = 100;