OSDN Git Service

Add BatteryTipDetector and LowBatteryTip stuffs.
authorjackqdyulei <jackqdyulei@google.com>
Thu, 14 Dec 2017 19:15:04 +0000 (11:15 -0800)
committerjackqdyulei <jackqdyulei@google.com>
Wed, 20 Dec 2017 00:49:08 +0000 (16:49 -0800)
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

12 files changed:
res/drawable/ic_perm_device_information_red_24dp.xml [new file with mode: 0644]
res/values/strings.xml
src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
src/com/android/settings/fuelgauge/batterytip/detectors/BatteryTipDetector.java [new file with mode: 0644]
src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetector.java [new file with mode: 0644]
src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetector.java [new file with mode: 0644]
src/com/android/settings/fuelgauge/batterytip/tips/BatteryTip.java
src/com/android/settings/fuelgauge/batterytip/tips/LowBatteryTip.java [new file with mode: 0644]
src/com/android/settings/fuelgauge/batterytip/tips/SummaryTip.java
tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoaderTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/LowBatteryDetectorTest.java [new file with mode: 0644]
tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java [new file with mode: 0644]

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 (file)
index 0000000..135e212
--- /dev/null
@@ -0,0 +1,27 @@
+<!--
+    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.
+-->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?android:attr/colorError">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M13,7h-2v2h2L13,7zM13,11h-2v6h2v-6zM17,1.01L7,1c-1.1,0 -2,0.9 -2,2v18c0,
+        1.1 0.9,2 2,2h10c1.1,0 2,-0.9 2,-2L19,3c0,-1.1 -0.9,-1.99 -2,-1.99zM17,19L7,19L7,5h10v14z"/>
+</vector>
index 65f73c8..c94eb1b 100644 (file)
     <string name="battery_tip_summary_title">Battery is in good shape</string>
     <!-- Summary for the battery summary tip [CHAR LIMIT=NONE] -->
     <string name="battery_tip_summary_summary">Apps are behaving normally</string>
+    <!-- Title for the low battery tip [CHAR LIMIT=NONE] -->
+    <string name="battery_tip_low_battery_title">Low battery capacity</string>
+    <!-- Summary for the low battery tip [CHAR LIMIT=NONE] -->
+    <string name="battery_tip_low_battery_summary">Battery can\'t provide good battery life</string>
 
     <!-- Title for force stop dialog [CHAR LIMIT=30] -->
     <string name="dialog_stop_title">Stop app?</string>
index b8cb6c4..9c3f48c 100644 (file)
 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<List<BatteryTip>> {
     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<BatteryTip> loadInBackground() {
-        List<BatteryTip> tips = new ArrayList<>();
+        if (USE_FAKE_DATA) {
+            return getFakeData();
+        }
+        final List<BatteryTip> 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<List<BatteryTip>> {
     protected void onDiscardResult(List<BatteryTip> result) {
     }
 
+    private List<BatteryTip> getFakeData() {
+        final List<BatteryTip> tips = new ArrayList<>();
+        tips.add(new SummaryTip(BatteryTip.StateType.NEW));
+        tips.add(new LowBatteryTip(BatteryTip.StateType.NEW));
+
+        return tips;
+    }
+
+    @VisibleForTesting
+    void addBatteryTipFromDetector(final List<BatteryTip> 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 (file)
index 0000000..cb38e40
--- /dev/null
@@ -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 (file)
index 0000000..2a6302e
--- /dev/null
@@ -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 (file)
index 0000000..8c1783b
--- /dev/null
@@ -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);
+    }
+}
index e633272..17e395e 100644 (file)
@@ -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<BatteryTip> {
     @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 (file)
index 0000000..8605fbb
--- /dev/null
@@ -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;
+    }
+}
index ab2a6c3..2a2deab 100644 (file)
@@ -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 (file)
index 0000000..e4e8eef
--- /dev/null
@@ -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<BatteryTip> 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 (file)
index 0000000..4866a6a
--- /dev/null
@@ -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 (file)
index 0000000..389a6c3
--- /dev/null
@@ -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();
+    }
+}