Add dialog for summary tip

Also change SummaryTip to store the time data, which is used
in the dialog. If "Full last charge" time is available, show
normal message otherwise show message without it.

Bug: 72997971
Test: RunSettingsRoboTests
Change-Id: I4ce94f0935465a18275edb13e3be343313427c3b
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 185732d..504bcd3 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);
+    }
+}