Merge "Add dialog for summary tip" into pi-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e4e311d..978c294 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -4892,6 +4892,11 @@
     <!-- CANCEL button for dialog to remove restriction for app [CHAR LIMIT=NONE] -->
     <string name="battery_tip_unrestrict_app_dialog_cancel">Not now</string>
 
+    <!-- Message for battery tip dialog to show the battery summary -->
+    <string name="battery_tip_dialog_summary_message">Based on your usage, your battery usually lasts about <xliff:g id="time_duration">%1$s</xliff:g> when fully charged.\n\nIf you need to extend your battery life, turn on Battery Saver.</string>
+    <!-- Message for battery tip dialog to show the battery summary -->
+    <string name="battery_tip_dialog_summary_message_no_estimation">If you need to extend your battery life, turn on Battery Saver</string>
+
     <!-- Title for the smart battery manager preference [CHAR LIMIT=NONE] -->
     <string name="smart_battery_manager_title">Smart battery manager</string>
     <!-- Title for the smart battery toggle [CHAR LIMIT=NONE] -->
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java
index 9e172de..b39e4ef 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragment.java
@@ -32,11 +32,13 @@
 import com.android.settings.Utils;
 import com.android.settings.core.InstrumentedPreferenceFragment;
 import com.android.settings.core.instrumentation.InstrumentedDialogFragment;
+import com.android.settings.fuelgauge.Estimate;
 import com.android.settings.fuelgauge.batterytip.BatteryTipPreferenceController.BatteryTipListener;
 import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
 import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
+import com.android.settings.fuelgauge.batterytip.tips.SummaryTip;
 import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
 import com.android.settingslib.utils.StringUtil;
 
@@ -72,9 +74,18 @@
 
         switch (mBatteryTip.getType()) {
             case BatteryTip.TipType.SUMMARY:
-            case BatteryTip.TipType.LOW_BATTERY:
-                //TODO(b/70570352): add dialog
-                return null;
+                final long averageTimeMs = ((SummaryTip) mBatteryTip).getAverageTimeMs();
+                final String message = context.getString(
+                        averageTimeMs == Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN
+                                ? R.string.battery_tip_dialog_summary_message_no_estimation
+                                : R.string.battery_tip_dialog_summary_message,
+                        StringUtil.formatElapsedTime(context, averageTimeMs,
+                                false /* withSeconds */));
+
+                return new AlertDialog.Builder(context)
+                        .setMessage(message)
+                        .setPositiveButton(android.R.string.ok, null)
+                        .create();
             case BatteryTip.TipType.HIGH_DEVICE_USAGE:
                 final HighUsageTip highUsageTip = (HighUsageTip) mBatteryTip;
                 final RecyclerView view = (RecyclerView) LayoutInflater.from(context).inflate(
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
index ebb4790..5efc04a 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipLoader.java
@@ -22,6 +22,7 @@
 import com.android.internal.os.BatteryStatsHelper;
 import com.android.settings.fuelgauge.BatteryInfo;
 import com.android.settings.fuelgauge.BatteryUtils;
+import com.android.settings.fuelgauge.Estimate;
 import com.android.settings.fuelgauge.batterytip.detectors.EarlyWarningDetector;
 import com.android.settings.fuelgauge.batterytip.detectors.HighUsageDetector;
 import com.android.settings.fuelgauge.batterytip.detectors.LowBatteryDetector;
@@ -70,7 +71,7 @@
         tips.add(new HighUsageDetector(context, policy, mBatteryStatsHelper).detect());
         tips.add(new SmartBatteryDetector(policy, context.getContentResolver()).detect());
         tips.add(new EarlyWarningDetector(policy, context).detect());
-        tips.add(new SummaryDetector(policy).detect());
+        tips.add(new SummaryDetector(policy, batteryInfo.averageTimeToDischarge).detect());
         tips.add(new RestrictAppDetector(context, policy).detect());
 
         Collections.sort(tips);
@@ -83,7 +84,8 @@
 
     private List<BatteryTip> getFakeData() {
         final List<BatteryTip> tips = new ArrayList<>();
-        tips.add(new SummaryTip(BatteryTip.StateType.NEW));
+        tips.add(new SummaryTip(BatteryTip.StateType.NEW,
+                Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN));
         tips.add(new LowBatteryTip(BatteryTip.StateType.NEW));
 
         return tips;
diff --git a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
index d2af589..9e47782 100644
--- a/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
+++ b/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceController.java
@@ -27,6 +27,7 @@
 import com.android.settings.SettingsActivity;
 import com.android.settings.core.BasePreferenceController;
 import com.android.settings.core.InstrumentedPreferenceFragment;
+import com.android.settings.fuelgauge.Estimate;
 import com.android.settings.fuelgauge.batterytip.actions.BatteryTipAction;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.fuelgauge.batterytip.tips.SummaryTip;
@@ -82,7 +83,8 @@
         mPreferenceGroup = (PreferenceGroup) screen.findPreference(getPreferenceKey());
 
         // Add summary tip in advance to avoid UI flakiness
-        final SummaryTip summaryTip = new SummaryTip(BatteryTip.StateType.NEW);
+        final SummaryTip summaryTip = new SummaryTip(BatteryTip.StateType.NEW,
+                Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN);
         mPreferenceGroup.addPreference(summaryTip.buildPreference(mPrefContext));
     }
 
diff --git a/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetector.java b/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetector.java
index a45dc09..0a20aac 100644
--- a/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetector.java
+++ b/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetector.java
@@ -26,9 +26,11 @@
  */
 public class SummaryDetector implements BatteryTipDetector {
     private BatteryTipPolicy mPolicy;
+    private long mAverageTimeMs;
 
-    public SummaryDetector(BatteryTipPolicy policy) {
+    public SummaryDetector(BatteryTipPolicy policy, long averageTimeMs) {
         mPolicy = policy;
+        mAverageTimeMs = averageTimeMs;
     }
 
     @Override
@@ -37,6 +39,6 @@
         final int state = mPolicy.summaryEnabled
                 ? BatteryTip.StateType.NEW
                 : BatteryTip.StateType.INVISIBLE;
-        return new SummaryTip(state);
+        return new SummaryTip(state, mAverageTimeMs);
     }
 }
diff --git a/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTip.java b/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTip.java
index 8993754..8ed8692 100644
--- a/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTip.java
+++ b/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTip.java
@@ -19,6 +19,7 @@
 import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.support.annotation.VisibleForTesting;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.R;
@@ -28,13 +29,17 @@
  * Tip to show general summary about battery life
  */
 public class SummaryTip extends BatteryTip {
+    private long mAverageTimeMs;
 
-    public SummaryTip(@StateType int state) {
-        super(TipType.SUMMARY, state, false /* showDialog */);
+    public SummaryTip(@StateType int state, long averageTimeMs) {
+        super(TipType.SUMMARY, state, true /* showDialog */);
+        mAverageTimeMs = averageTimeMs;
     }
 
-    private SummaryTip(Parcel in) {
+    @VisibleForTesting
+    SummaryTip(Parcel in) {
         super(in);
+        mAverageTimeMs = in.readLong();
     }
 
     @Override
@@ -58,11 +63,21 @@
     }
 
     @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        super.writeToParcel(dest, flags);
+        dest.writeLong(mAverageTimeMs);
+    }
+
+    @Override
     public void log(Context context, MetricsFeatureProvider metricsFeatureProvider) {
         metricsFeatureProvider.action(context, MetricsProto.MetricsEvent.ACTION_SUMMARY_TIP,
                 mState);
     }
 
+    public long getAverageTimeMs() {
+        return mAverageTimeMs;
+    }
+
     public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
         public BatteryTip createFromParcel(Parcel in) {
             return new SummaryTip(in);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java
index 9f1bb31..6f8bb26 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipDialogFragmentTest.java
@@ -18,6 +18,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 
+import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.spy;
 import static org.robolectric.Shadows.shadowOf;
 
@@ -26,9 +27,11 @@
 import android.text.format.DateUtils;
 
 import com.android.settings.R;
+import com.android.settings.fuelgauge.Estimate;
 import com.android.settings.fuelgauge.batterytip.tips.BatteryTip;
 import com.android.settings.fuelgauge.batterytip.tips.HighUsageTip;
 import com.android.settings.fuelgauge.batterytip.tips.RestrictAppTip;
+import com.android.settings.fuelgauge.batterytip.tips.SummaryTip;
 import com.android.settings.fuelgauge.batterytip.tips.UnrestrictAppTip;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 import com.android.settings.testutils.shadow.ShadowUtils;
@@ -54,6 +57,7 @@
     private static final String PACKAGE_NAME = "com.android.app";
     private static final String DISPLAY_NAME = "app";
     private static final long SCREEN_TIME_MS = DateUtils.HOUR_IN_MILLIS;
+    private static final long AVERAGE_TIME_MS = DateUtils.HOUR_IN_MILLIS;
 
     private BatteryTipDialogFragment mDialogFragment;
     private Context mContext;
@@ -61,6 +65,7 @@
     private RestrictAppTip mRestrictedOneAppTip;
     private RestrictAppTip mRestrictAppsTip;
     private UnrestrictAppTip mUnrestrictAppTip;
+    private SummaryTip mSummaryTip;
 
     @Before
     public void setUp() {
@@ -85,6 +90,8 @@
                 new ArrayList<>(restrictApps));
 
         mUnrestrictAppTip = new UnrestrictAppTip(BatteryTip.StateType.NEW, appInfo);
+        mSummaryTip = spy(new SummaryTip(BatteryTip.StateType.NEW,
+                Estimate.AVERAGE_TIME_TO_DISCHARGE_UNKNOWN));
     }
 
     @Test
@@ -151,4 +158,32 @@
         assertThat(shadowDialog.getMessage())
                 .isEqualTo(mContext.getString(R.string.battery_tip_unrestrict_app_dialog_message));
     }
+
+    @Test
+    public void testOnCreateDialog_summaryTipWithEstimation_fireDialogWithEstimation() {
+        doReturn(AVERAGE_TIME_MS).when(mSummaryTip).getAverageTimeMs();
+        mDialogFragment = BatteryTipDialogFragment.newInstance(mSummaryTip);
+
+        FragmentTestUtil.startFragment(mDialogFragment);
+
+        final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
+        ShadowAlertDialog shadowDialog = shadowOf(dialog);
+
+        assertThat(shadowDialog.getMessage()).isEqualTo(
+                "Based on your usage, your battery usually lasts about 1h when fully charged"
+                        + ".\n\nIf you need to extend your battery life, turn on Battery Saver.");
+    }
+
+    @Test
+    public void testOnCreateDialog_summaryTipWithoutEstimation_fireDialogWithoutEstimation() {
+        mDialogFragment = BatteryTipDialogFragment.newInstance(mSummaryTip);
+
+        FragmentTestUtil.startFragment(mDialogFragment);
+
+        final AlertDialog dialog = (AlertDialog) ShadowDialog.getLatestDialog();
+        ShadowAlertDialog shadowDialog = shadowOf(dialog);
+
+        assertThat(shadowDialog.getMessage()).isEqualTo(
+                "If you need to extend your battery life, turn on Battery Saver");
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
index 6f898b2..0ac94c0 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/BatteryTipPreferenceControllerTest.java
@@ -15,8 +15,11 @@
  */
 package com.android.settings.fuelgauge.batterytip;
 
-import static com.android.settings.fuelgauge.batterytip.tips.BatteryTip.TipType.SMART_BATTERY_MANAGER;
+import static com.android.settings.fuelgauge.batterytip.tips.BatteryTip.TipType
+        .SMART_BATTERY_MANAGER;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
@@ -30,6 +33,7 @@
 import android.support.v7.preference.PreferenceGroup;
 import android.support.v7.preference.PreferenceManager;
 import android.support.v7.preference.PreferenceScreen;
+import android.text.format.DateUtils;
 
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.settings.SettingsActivity;
@@ -54,6 +58,8 @@
 
     private static final String KEY_PREF = "battery_tip";
     private static final String KEY_TIP = "key_battery_tip";
+    private static final long AVERAGE_TIME_MS = DateUtils.HOUR_IN_MILLIS;
+
     @Mock
     private BatteryTipPreferenceController.BatteryTipListener mBatteryTipListener;
     @Mock
@@ -87,9 +93,9 @@
         mFeatureFactory = FakeFeatureFactory.setupForTest();
 
         mOldBatteryTips = new ArrayList<>();
-        mOldBatteryTips.add(new SummaryTip(BatteryTip.StateType.NEW));
+        mOldBatteryTips.add(new SummaryTip(BatteryTip.StateType.NEW, AVERAGE_TIME_MS));
         mNewBatteryTips = new ArrayList<>();
-        mNewBatteryTips.add(new SummaryTip(BatteryTip.StateType.INVISIBLE));
+        mNewBatteryTips.add(new SummaryTip(BatteryTip.StateType.INVISIBLE, AVERAGE_TIME_MS));
 
         mBatteryTipPreferenceController = new BatteryTipPreferenceController(mContext, KEY_PREF,
                 mSettingsActivity, null, mBatteryTipListener);
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
index 5ca1ad2..df38d34 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/detectors/SummaryDetectorTest.java
@@ -19,6 +19,8 @@
 import static com.google.common.truth.Truth.assertThat;
 import static org.mockito.Mockito.spy;
 
+import android.text.format.DateUtils;
+
 import com.android.settings.fuelgauge.batterytip.BatteryTipPolicy;
 import com.android.settings.testutils.SettingsRobolectricTestRunner;
 
@@ -33,6 +35,7 @@
 public class SummaryDetectorTest {
 
     private BatteryTipPolicy mPolicy;
+    private static final long AVERAGE_TIME_MS = DateUtils.HOUR_IN_MILLIS;
 
     @Before
     public void setUp() {
@@ -44,14 +47,14 @@
     @Test
     public void testDetect_disabledByPolicy_tipInvisible() {
         ReflectionHelpers.setField(mPolicy, "summaryEnabled", false);
-        SummaryDetector detector = new SummaryDetector(mPolicy);
+        SummaryDetector detector = new SummaryDetector(mPolicy, AVERAGE_TIME_MS);
 
         assertThat(detector.detect().isVisible()).isFalse();
     }
 
     @Test
     public void testDetect_notDisabled_tipVisible() {
-        SummaryDetector detector = new SummaryDetector(mPolicy);
+        SummaryDetector detector = new SummaryDetector(mPolicy, AVERAGE_TIME_MS);
 
         assertThat(detector.detect().isVisible()).isTrue();
     }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTipTest.java b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTipTest.java
new file mode 100644
index 0000000..221c37f
--- /dev/null
+++ b/tests/robotests/src/com/android/settings/fuelgauge/batterytip/tips/SummaryTipTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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 android.text.format.DateUtils;
+
+import com.android.internal.logging.nano.MetricsProto;
+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 SummaryTipTest {
+
+    private static final long AVERAGE_TIME_MS = DateUtils.HOUR_IN_MILLIS;
+
+    @Mock
+    private MetricsFeatureProvider mMetricsFeatureProvider;
+    private Context mContext;
+    private SummaryTip mSummaryTip;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+
+        mContext = RuntimeEnvironment.application;
+        mSummaryTip =
+                new SummaryTip(BatteryTip.StateType.NEW, AVERAGE_TIME_MS);
+    }
+
+    @Test
+    public void testParcelable() {
+        Parcel parcel = Parcel.obtain();
+        mSummaryTip.writeToParcel(parcel, mSummaryTip.describeContents());
+        parcel.setDataPosition(0);
+
+        final SummaryTip parcelTip = new SummaryTip(parcel);
+
+        assertThat(parcelTip.getAverageTimeMs()).isEqualTo(AVERAGE_TIME_MS);
+    }
+
+    @Test
+    public void testLog() {
+        mSummaryTip.log(mContext, mMetricsFeatureProvider);
+
+        verify(mMetricsFeatureProvider).action(mContext,
+                MetricsProto.MetricsEvent.ACTION_SUMMARY_TIP, BatteryTip.StateType.NEW);
+    }
+}