OSDN Git Service

Ui changes in battery main page
authorjackqdyulei <jackqdyulei@google.com>
Tue, 28 Mar 2017 23:22:20 +0000 (16:22 -0700)
committerjackqdyulei <jackqdyulei@google.com>
Tue, 4 Apr 2017 17:06:35 +0000 (10:06 -0700)
1. Refine the battery header view
2. Move stats section to the place above power management
3. Add last full charge battery stat
4. Add the disclaimer as a footer

Also update the method name in test file, and this ui changes
also fix the header flash problem.

Bug: 36576021
Bug: 36494178
Test: RunSettingsRoboTests
Change-Id: I9784dbbbe16e61da7287f300183347dd4eee6a2b
(cherry picked from commit edfd09d5908746ea688494b39fe905ad0150e7d4)

res/layout/battery_header.xml
res/xml/power_usage_summary.xml
src/com/android/settings/fuelgauge/BatteryMeterView.java
src/com/android/settings/fuelgauge/PowerGaugePreference.java
src/com/android/settings/fuelgauge/PowerUsageSummary.java
tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java

index ef39d8b..04ef74d 100644 (file)
     android:background="@drawable/selectable_card_grey"
     style="@style/EntityHeader">
 
-    <com.android.settings.fuelgauge.BatteryMeterView
-        android:id="@+id/battery_header_icon"
-        android:layout_width="@dimen/battery_meter_width"
-        android:layout_height="@dimen/battery_meter_height"/>
-
     <LinearLayout
-        android:layout_width="wrap_content"
+        android:layout_width="216dp"
         android:layout_height="wrap_content"
-        android:layout_marginStart="12dp"
+        android:layout_marginStart="48dp"
         android:layout_marginEnd="12dp"
         android:orientation="vertical">
 
         <TextView
-            android:id="@+id/time"
+            android:id="@+id/battery_percent"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="12dp"
-            android:gravity="center"
-            android:textAppearance="@android:style/TextAppearance.Material.Medium"/>
+            android:textAppearance="@android:style/TextAppearance.Material.Display1"/>
 
         <TextView
             android:id="@+id/summary1"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_marginTop="12dp"
-            android:gravity="center"
             android:textAppearance="@android:style/TextAppearance.Material.Small"
             android:text="@string/estimated_time_left"/>
 
-        <TextView
-            android:id="@+id/summary2"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_marginTop="12dp"
-            android:gravity="center"
-            android:textAppearance="@android:style/TextAppearance.Material.Small"
-            android:text="@string/estimated_time_description"/>
-
     </LinearLayout>
 
+    <com.android.settings.fuelgauge.BatteryMeterView
+        android:id="@+id/battery_header_icon"
+        android:layout_width="@dimen/battery_meter_width"
+        android:layout_height="@dimen/battery_meter_height"
+        android:layout_gravity="end"
+        android:layout_marginEnd="24dp"/>
+
 </LinearLayout>
\ No newline at end of file
index a387813..b486776 100644 (file)
         android:layout="@layout/battery_header"/>
 
     <PreferenceCategory
+        android:key="device_usage_list">
+
+        <com.android.settings.fuelgauge.PowerGaugePreference
+            android:key="last_full_charge"
+            android:title="@string/battery_last_full_charge"/>
+
+        <com.android.settings.fuelgauge.PowerGaugePreference
+            android:key="screen_usage"
+            android:title="@string/device_screen_usage"/>
+
+    </PreferenceCategory>
+
+    <PreferenceCategory
         android:key="power_management"
         android:title="@string/battery_power_management">
 
         android:key="app_list"
         android:title="@string/power_usage_list_summary"/>
 
-    <PreferenceCategory
-        android:key="device_usage_list"
-        android:title="@string/device_usage_list_summary">
-
-        <Preference
-            android:key="screen_usage"
-            android:title="@string/device_screen_usage"/>
-
-        <Preference
-            android:key="screen_consumption"
-            android:title="@string/device_screen_consumption"/>
-
-        <Preference
-            android:key="cellular_network"
-            android:title="@string/device_cellular_network"/>
-
-    </PreferenceCategory>
-
 </PreferenceScreen>
index 9127782..dcbf472 100644 (file)
@@ -46,7 +46,7 @@ public class BatteryMeterView extends ImageView {
 
         mDrawable = new BatteryMeterDrawable(context, frameColor);
         mDrawable.setColorFilter(new PorterDuffColorFilter(tintColor, PorterDuff.Mode.SRC_IN));
-        mDrawable.setShowPercent(true);
+        mDrawable.setShowPercent(false);
         setImageDrawable(mDrawable);
     }
 
index d4f2dd2..bdadf4c 100644 (file)
@@ -29,8 +29,11 @@ import com.android.settings.TintablePreference;
 import com.android.settings.Utils;
 
 /**
- * Custom preference for displaying power consumption as a bar and an icon on
+ * Custom preference for displaying battery usage info as a bar and an icon on
  * the left for the subsystem/app type.
+ *
+ * The battery usage info could be usage percentage or usage time. The preference
+ * won't show any icon if it is null.
  */
 public class PowerGaugePreference extends TintablePreference {
     private final int mIconSize;
@@ -41,7 +44,20 @@ public class PowerGaugePreference extends TintablePreference {
 
     public PowerGaugePreference(Context context, Drawable icon, CharSequence contentDescription,
             BatteryEntry info) {
-        super(context, null);
+        this(context, null, icon, contentDescription, info);
+    }
+
+    public PowerGaugePreference(Context context) {
+        this(context, null, null, null, null);
+    }
+
+    public PowerGaugePreference(Context context, AttributeSet attrs) {
+        this(context, attrs, null, null, null);
+    }
+
+    private PowerGaugePreference(Context context, AttributeSet attrs, Drawable icon,
+            CharSequence contentDescription, BatteryEntry info) {
+        super(context, attrs);
         setIcon(icon != null ? icon : new ColorDrawable(0));
         setWidgetLayoutResource(R.layout.preference_widget_summary);
         mInfo = info;
@@ -49,10 +65,6 @@ public class PowerGaugePreference extends TintablePreference {
         mIconSize = context.getResources().getDimensionPixelSize(R.dimen.app_icon_size);
     }
 
-    public PowerGaugePreference(Context context) {
-        this(context, null, null, null);
-    }
-
     public void setContentDescription(String name) {
         mContentDescription = name;
         notifyChanged();
@@ -67,6 +79,11 @@ public class PowerGaugePreference extends TintablePreference {
         return mProgress.toString();
     }
 
+    public void setSubtitle(String subtitle) {
+        mProgress = subtitle;
+        notifyChanged();
+    }
+
     BatteryEntry getInfo() {
         return mInfo;
     }
index 96141f9..2c1fd78 100644 (file)
@@ -16,7 +16,6 @@
 
 package com.android.settings.fuelgauge;
 
-import android.annotation.StringRes;
 import android.app.Activity;
 import android.content.Context;
 import android.graphics.drawable.Drawable;
@@ -26,6 +25,7 @@ import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
 import android.os.Process;
+import android.os.SystemClock;
 import android.os.UserHandle;
 import android.provider.SearchIndexableResource;
 import android.support.annotation.VisibleForTesting;
@@ -39,7 +39,6 @@ import android.util.TypedValue;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 import android.widget.TextView;
 
 import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -60,6 +59,7 @@ import com.android.settings.display.BatteryPercentagePreferenceController;
 import com.android.settings.display.TimeoutPreferenceController;
 import com.android.settings.overlay.FeatureFactory;
 import com.android.settings.search.BaseSearchIndexProvider;
+import com.android.settings.widget.FooterPreferenceMixin;
 import com.android.settingslib.BatteryInfo;
 
 import java.util.ArrayList;
@@ -87,8 +87,7 @@ public class PowerUsageSummary extends PowerUsageBase {
     private static final int SECONDS_IN_HOUR = 60 * 60;
 
     private static final String KEY_SCREEN_USAGE = "screen_usage";
-    private static final String KEY_SCREEN_CONSUMPTION = "screen_consumption";
-    private static final String KEY_CELLULAR_NETWORK = "cellular_network";
+    private static final String KEY_TIME_SINCE_LAST_FULL_CHARGE = "last_full_charge";
 
 
     private static final int MENU_STATS_TYPE = Menu.FIRST;
@@ -100,14 +99,15 @@ public class PowerUsageSummary extends PowerUsageBase {
     static final int MENU_TOGGLE_APPS = Menu.FIRST + 5;
     private static final int MENU_HELP = Menu.FIRST + 6;
 
+    private final FooterPreferenceMixin mFooterPreferenceMixin =
+            new FooterPreferenceMixin(this, getLifecycle());
+
     @VisibleForTesting
     boolean mShowAllApps = false;
     @VisibleForTesting
-    Preference mScreenUsagePref;
-    @VisibleForTesting
-    Preference mScreenConsumptionPref;
+    PowerGaugePreference mScreenUsagePref;
     @VisibleForTesting
-    Preference mCellularNetworkPref;
+    PowerGaugePreference mLastFullChargePref;
     @VisibleForTesting
     PowerUsageFeatureProvider mPowerFeatureProvider;
 
@@ -122,9 +122,10 @@ public class PowerUsageSummary extends PowerUsageBase {
 
         mBatteryLayoutPref = (LayoutPreference) findPreference(KEY_BATTERY_HEADER);
         mAppListGroup = (PreferenceGroup) findPreference(KEY_APP_LIST);
-        mScreenUsagePref = findPreference(KEY_SCREEN_USAGE);
-        mScreenConsumptionPref = findPreference(KEY_SCREEN_CONSUMPTION);
-        mCellularNetworkPref = findPreference(KEY_CELLULAR_NETWORK);
+        mScreenUsagePref = (PowerGaugePreference) findPreference(KEY_SCREEN_USAGE);
+        mLastFullChargePref = (PowerGaugePreference) findPreference(
+                KEY_TIME_SINCE_LAST_FULL_CHARGE);
+        mFooterPreferenceMixin.createFooterPreference().setTitle(R.string.battery_footer_summary);
 
         initFeatureProvider();
     }
@@ -417,8 +418,11 @@ public class PowerUsageSummary extends PowerUsageBase {
         final int dischargeAmount = USE_FAKE_DATA ? 5000
                 : stats != null ? stats.getDischargeAmount(mStatsType) : 0;
 
-        updateScreenPreference(dischargeAmount);
-        updateCellularPreference(dischargeAmount);
+        final long runningTime = calculateRunningTimeBasedOnStatsType();
+        updateScreenPreference();
+        updateLastFullChargePreference(runningTime);
+        mAppListGroup.setTitle(getString(R.string.power_usage_list_summary,
+                Utils.formatElapsedTime(context, runningTime, false)));
 
         if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP || USE_FAKE_DATA) {
             final List<BatterySipper> usageList = getCoalescedUsageList(
@@ -527,28 +531,27 @@ public class PowerUsageSummary extends PowerUsageBase {
     }
 
     @VisibleForTesting
-    void updateScreenPreference(final int dischargeAmount) {
+    void updateScreenPreference() {
         final BatterySipper sipper = findBatterySipperByType(
                 mStatsHelper.getUsageList(), DrainType.SCREEN);
         final Context context = getContext();
-        final double totalPowerMah = sipper != null ? sipper.totalPowerMah : 0;
         final long usageTimeMs = sipper != null ? sipper.usageTimeMs : 0;
-        final double percentOfTotal = calculatePercentage(totalPowerMah, dischargeAmount);
 
-        mScreenUsagePref.setSummary(getString(R.string.battery_used_for,
-                Utils.formatElapsedTime(context, usageTimeMs, false)));
-        mScreenConsumptionPref.setSummary(getString(R.string.battery_overall_usage,
-                Utils.formatPercentage(percentOfTotal, true)));
+        mScreenUsagePref.setSubtitle(Utils.formatElapsedTime(context, usageTimeMs, false));
     }
 
     @VisibleForTesting
-    void updateCellularPreference(final int dischargeAmount) {
-        final BatterySipper sipper = findBatterySipperByType(
-                mStatsHelper.getUsageList(), DrainType.CELL);
-        final double totalPowerMah = sipper != null ? sipper.totalPowerMah : 0;
-        final double percentOfTotal = calculatePercentage(totalPowerMah, dischargeAmount);
-        mCellularNetworkPref.setSummary(getString(R.string.battery_overall_usage,
-                Utils.formatPercentage(percentOfTotal, true)));
+    void updateLastFullChargePreference(long timeMs) {
+        mLastFullChargePref.setSubtitle(getString(R.string.power_last_full_charge_summary,
+                Utils.formatElapsedTime(getContext(), timeMs, false)));
+    }
+
+    @VisibleForTesting
+    long calculateRunningTimeBasedOnStatsType() {
+        final long elapsedRealtimeUs = SystemClock.elapsedRealtime() * 1000;
+        // Return the battery time (millisecond) on status mStatsType
+        return mStatsHelper.getStats().computeBatteryRealtime(elapsedRealtimeUs,
+                mStatsType /* STATS_SINCE_CHARGED */) / 1000;
     }
 
     @VisibleForTesting
@@ -559,22 +562,15 @@ public class PowerUsageSummary extends PowerUsageBase {
         }
         final BatteryMeterView batteryView = (BatteryMeterView) mBatteryLayoutPref
                 .findViewById(R.id.battery_header_icon);
-        final TextView timeText = (TextView) mBatteryLayoutPref.findViewById(R.id.time);
+        final TextView timeText = (TextView) mBatteryLayoutPref.findViewById(R.id.battery_percent);
         final TextView summary1 = (TextView) mBatteryLayoutPref.findViewById(R.id.summary1);
-        final TextView summary2 = (TextView) mBatteryLayoutPref.findViewById(R.id.summary2);
-        final int visible = info.remainingTimeUs != 0 ? View.VISIBLE : View.INVISIBLE;
-        final int summaryResId = info.mDischarging ?
-                R.string.estimated_time_left : R.string.estimated_charging_time_left;
-
-        if (info.remainingTimeUs != 0) {
-            timeText.setText(Utils.formatElapsedTime(context, info.remainingTimeUs / 1000, false));
+        timeText.setText(Utils.formatPercentage(info.mBatteryLevel));
+        if (info.remainingLabel == null ) {
+            summary1.setText(info.statusLabel);
         } else {
-            timeText.setText(info.statusLabel);
+            summary1.setText(info.remainingLabel);
         }
 
-        summary1.setText(summaryResId);
-        summary1.setVisibility(visible);
-        summary2.setVisibility(visible);
         batteryView.setBatteryInfo(info.mBatteryLevel);
     }
 
index a6e0943..5f2d54f 100644 (file)
  */
 package com.android.settings.fuelgauge;
 
-import android.app.Activity;
 import android.content.Context;
 import android.content.Intent;
 import android.os.PowerManager;
 import android.os.Process;
-import android.support.v7.preference.Preference;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
-import android.view.View;
 import android.widget.TextView;
+
 import com.android.internal.logging.nano.MetricsProto;
 import com.android.internal.os.BatterySipper;
 import com.android.internal.os.BatteryStatsHelper;
@@ -40,6 +38,7 @@ import com.android.settings.Utils;
 import com.android.settings.applications.LayoutPreference;
 import com.android.settings.testutils.FakeFeatureFactory;
 import com.android.settingslib.BatteryInfo;
+
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -53,13 +52,15 @@ import org.robolectric.annotation.Config;
 import java.util.ArrayList;
 import java.util.List;
 
-import static com.android.settings.fuelgauge.PowerUsageBase.MENU_STATS_REFRESH;
 import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_ADDITIONAL_BATTERY_INFO;
 import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_HIGH_POWER_APPS;
 import static com.android.settings.fuelgauge.PowerUsageSummary.MENU_TOGGLE_APPS;
+
 import static com.google.common.truth.Truth.assertThat;
+
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
 import static org.mockito.Mockito.doReturn;
@@ -77,9 +78,13 @@ import static org.mockito.Mockito.when;
 public class PowerUsageSummaryTest {
     private static final String[] PACKAGE_NAMES = {"com.app1", "com.app2"};
     private static final String TIME_LEFT = "2h30min";
+    private static final int BATTERY_LEVEL = 55;
     private static final int UID = 123;
     private static final int POWER_MAH = 100;
     private static final long REMAINING_TIME_US = 100000;
+    private static final long TIME_SINCE_LAST_FULL_CHARGE_MS = 25000;
+    private static final long TIME_SINCE_LAST_FULL_CHARGE_US =
+            TIME_SINCE_LAST_FULL_CHARGE_MS * 1000;
     private static final int DISCHARGE_AMOUNT = 100;
     private static final long USAGE_TIME_MS = 10000;
     private static final double TOTAL_POWER = 200;
@@ -117,20 +122,16 @@ public class PowerUsageSummaryTest {
     @Mock
     private BatteryMeterView mBatteryMeterView;
     @Mock
-    private TextView mTimeText;
+    private TextView mBatteryPercentText;
     @Mock
     private TextView mSummary1;
     @Mock
-    private TextView mSummary2;
-    @Mock
     private BatteryInfo mBatteryInfo;
     @Mock
-    private Preference mScreenUsagePref;
-    @Mock
-    private Preference mScreenConsumptionPref;
-    @Mock
-    private Preference mCellularNetworkPref;
+    private PowerGaugePreference mScreenUsagePref;
     @Mock
+    private PowerGaugePreference mLastFullChargePref;
+    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
     private BatteryStatsHelper mBatteryHelper;
     @Mock
     private PowerManager mPowerManager;
@@ -153,7 +154,7 @@ public class PowerUsageSummaryTest {
 
         mFragment = spy(new TestFragment(mContext));
         mFragment.initFeatureProvider();
-        
+
         when(mFragment.getActivity()).thenReturn(mSettingsActivity);
         when(mAdditionalBatteryInfoMenu.getItemId())
                 .thenReturn(MENU_ADDITIONAL_BATTERY_INFO);
@@ -162,6 +163,8 @@ public class PowerUsageSummaryTest {
         when(mFeatureFactory.powerUsageFeatureProvider.getAdditionalBatteryInfoIntent())
                 .thenReturn(ADDITIONAL_BATTERY_INFO_INTENT);
         when(mBatteryHelper.getTotalPower()).thenReturn(TOTAL_POWER);
+        when(mBatteryHelper.getStats().computeBatteryRealtime(anyLong(), anyInt())).thenReturn(
+                TIME_SINCE_LAST_FULL_CHARGE_US);
 
         when(mNormalBatterySipper.getPackages()).thenReturn(PACKAGE_NAMES);
         when(mNormalBatterySipper.getUid()).thenReturn(UID);
@@ -172,8 +175,7 @@ public class PowerUsageSummaryTest {
         mCellBatterySipper.totalPowerMah = POWER_MAH;
 
         when(mBatteryLayoutPref.findViewById(R.id.summary1)).thenReturn(mSummary1);
-        when(mBatteryLayoutPref.findViewById(R.id.summary2)).thenReturn(mSummary2);
-        when(mBatteryLayoutPref.findViewById(R.id.time)).thenReturn(mTimeText);
+        when(mBatteryLayoutPref.findViewById(R.id.battery_percent)).thenReturn(mBatteryPercentText);
         when(mBatteryLayoutPref.findViewById(R.id.battery_header_icon))
                 .thenReturn(mBatteryMeterView);
         mFragment.setBatteryLayoutPreference(mBatteryLayoutPref);
@@ -194,8 +196,9 @@ public class PowerUsageSummaryTest {
         mFragment.mStatsHelper = mBatteryHelper;
         when(mBatteryHelper.getUsageList()).thenReturn(mUsageList);
         mFragment.mScreenUsagePref = mScreenUsagePref;
-        mFragment.mScreenConsumptionPref = mScreenConsumptionPref;
-        mFragment.mCellularNetworkPref = mCellularNetworkPref;
+        mFragment.mLastFullChargePref = mLastFullChargePref;
+
+        mBatteryInfo.mBatteryLevel = BATTERY_LEVEL;
     }
 
     @Test
@@ -226,7 +229,7 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testOptionsMenu_MenuHighPower_MetricEventInvoked() {
+    public void testOptionsMenu_menuHighPower_metricEventInvoked() {
         mFragment.onOptionsItemSelected(mHighPowerMenu);
 
         verify(mFeatureFactory.metricsFeatureProvider).action(mContext,
@@ -234,7 +237,7 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testOptionsMenu_MenuAdditionalBattery_MetricEventInvoked() {
+    public void testOptionsMenu_menuAdditionalBattery_metricEventInvoked() {
         mFragment.onOptionsItemSelected(mAdditionalBatteryInfoMenu);
 
         verify(mFeatureFactory.metricsFeatureProvider).action(mContext,
@@ -242,7 +245,7 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testOptionsMenu_MenuAppToggle_MetricEventInvoked() {
+    public void testOptionsMenu_menuAppToggle_metricEventInvoked() {
         mFragment.onOptionsItemSelected(mToggleAppsMenu);
         mFragment.mShowAllApps = false;
 
@@ -251,7 +254,7 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testOptionsMenu_ToggleAppsEnabled() {
+    public void testOptionsMenu_toggleAppsEnabled() {
         when(mFeatureFactory.powerUsageFeatureProvider.isPowerAccountingToggleEnabled())
                 .thenReturn(true);
         mFragment.mShowAllApps = false;
@@ -262,13 +265,13 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testOptionsMenu_ClickToggleAppsMenu_DataChanged() {
+    public void testOptionsMenu_clickToggleAppsMenu_dataChanged() {
         testToggleAllApps(true);
         testToggleAllApps(false);
     }
 
     @Test
-    public void testExtractKeyFromSipper_TypeAPPUidObjectNull_ReturnPackageNames() {
+    public void testExtractKeyFromSipper_typeAPPUidObjectNull_returnPackageNames() {
         mNormalBatterySipper.uidObj = null;
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
 
@@ -277,7 +280,7 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testExtractKeyFromSipper_TypeOther_ReturnDrainType() {
+    public void testExtractKeyFromSipper_typeOther_returnDrainType() {
         mNormalBatterySipper.uidObj = null;
         mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
 
@@ -286,7 +289,7 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testExtractKeyFromSipper_TypeAPPUidObjectNotNull_ReturnUid() {
+    public void testExtractKeyFromSipper_typeAPPUidObjectNotNull_returnUid() {
         mNormalBatterySipper.uidObj = new BatteryStatsImpl.Uid(new BatteryStatsImpl(), UID);
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
 
@@ -295,7 +298,7 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testRemoveHiddenBatterySippers_ContainsHiddenSippers_RemoveAndReturnValue() {
+    public void testRemoveHiddenBatterySippers_containsHiddenSippers_removeAndReturnValue() {
         final List<BatterySipper> sippers = new ArrayList<>();
         sippers.add(mNormalBatterySipper);
         sippers.add(mScreenBatterySipper);
@@ -309,37 +312,37 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testShouldHideSipper_TypeIdle_ReturnTrue() {
+    public void testShouldHideSipper_typeIdle_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.IDLE;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeWifi_ReturnTrue() {
+    public void testShouldHideSipper_typeWifi_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.WIFI;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeCell_ReturnTrue() {
+    public void testShouldHideSipper_typeCell_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.CELL;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeScreen_ReturnTrue() {
+    public void testShouldHideSipper_typeScreen_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.SCREEN;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeBluetooth_ReturnTrue() {
+    public void testShouldHideSipper_typeBluetooth_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isTrue();
     }
 
     @Test
-    public void testShouldHideSipper_TypeSystem_ReturnTrue() {
+    public void testShouldHideSipper_typeSystem_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         when(mNormalBatterySipper.getUid()).thenReturn(Process.ROOT_UID);
         when(mFeatureFactory.powerUsageFeatureProvider.isTypeSystem(Matchers.<BatterySipper>any()))
@@ -348,14 +351,14 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testShouldHideSipper_UidNormal_ReturnFalse() {
+    public void testShouldHideSipper_uidNormal_returnFalse() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         when(mNormalBatterySipper.getUid()).thenReturn(UID);
         assertThat(mFragment.shouldHideSipper(mNormalBatterySipper)).isFalse();
     }
 
     @Test
-    public void testShouldHideSipper_TypeService_ReturnTrue() {
+    public void testShouldHideSipper_typeService_returnTrue() {
         mNormalBatterySipper.drainType = BatterySipper.DrainType.APP;
         when(mNormalBatterySipper.getUid()).thenReturn(UID);
         when(mFeatureFactory.powerUsageFeatureProvider.isTypeService(Matchers.<BatterySipper>any()))
@@ -365,7 +368,7 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testSetUsageSummary_TimeLessThanOneMinute_DoNotSetSummary() {
+    public void testSetUsageSummary_timeLessThanOneMinute_doNotSetSummary() {
         final long usageTimeMs = 59 * DateUtils.SECOND_IN_MILLIS;
 
         mFragment.setUsageSummary(mPreference, "", usageTimeMs);
@@ -373,7 +376,7 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testSetUsageSummary_TimeMoreThanOneMinute_SetSummary() {
+    public void testSetUsageSummary_timeMoreThanOneMinute_setSummary() {
         final long usageTimeMs = 2 * DateUtils.MINUTE_IN_MILLIS;
 
         mFragment.setUsageSummary(mPreference, "", usageTimeMs);
@@ -381,45 +384,25 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testUpdatePreference_NoEstimatedTime_DoNotShowSummary() {
-        mBatteryInfo.remainingTimeUs = 0;
+    public void testUpdatePreference_hasRemainingTime_showRemainingLabel() {
         mBatteryInfo.remainingLabel = TIME_LEFT;
-        mFragment.updateHeaderPreference(mBatteryInfo);
-
-        verify(mSummary1).setVisibility(View.INVISIBLE);
-        verify(mSummary2).setVisibility(View.INVISIBLE);
-    }
 
-    @Test
-    public void testUpdatePreference_HasEstimatedTime_ShowSummary() {
-        mBatteryInfo.remainingTimeUs = REMAINING_TIME_US;
-        mBatteryInfo.remainingLabel = TIME_LEFT;
         mFragment.updateHeaderPreference(mBatteryInfo);
 
-        verify(mSummary1).setVisibility(View.VISIBLE);
-        verify(mSummary2).setVisibility(View.VISIBLE);
+        verify(mSummary1).setText(mBatteryInfo.remainingLabel);
     }
 
     @Test
-    public void testUpdatePreference_Charging_ShowChargingTimeLeft() {
-        mBatteryInfo.remainingTimeUs = REMAINING_TIME_US;
-        mBatteryInfo.mDischarging = false;
+    public void testUpdatePreference_noRemainingTime_showStatusLabel() {
+        mBatteryInfo.remainingLabel = null;
 
         mFragment.updateHeaderPreference(mBatteryInfo);
-        verify(mSummary1).setText(R.string.estimated_charging_time_left);
-    }
 
-    @Test
-    public void testUpdatePreference_NotCharging_ShowTimeLeft() {
-        mBatteryInfo.remainingTimeUs = REMAINING_TIME_US;
-        mBatteryInfo.mDischarging = true;
-
-        mFragment.updateHeaderPreference(mBatteryInfo);
-        verify(mSummary1).setText(R.string.estimated_time_left);
+        verify(mSummary1).setText(mBatteryInfo.statusLabel);
     }
 
     @Test
-    public void testUpdateHeaderPreference_AsyncUpdate_ShouldNotCrash() {
+    public void testUpdateHeaderPreference_asyncUpdate_shouldNotCrash() {
         when(mFragment.getContext()).thenReturn(null);
         mBatteryInfo.remainingTimeUs = REMAINING_TIME_US;
 
@@ -451,43 +434,36 @@ public class PowerUsageSummaryTest {
     }
 
     @Test
-    public void testUpdateCellularPreference_ShowCorrectSummary() {
-        final double percent = POWER_MAH / TOTAL_POWER * DISCHARGE_AMOUNT;
-        final String expectedSummary = mRealContext.getString(R.string.battery_overall_usage,
-                Utils.formatPercentage((int) percent));
-        doReturn(expectedSummary).when(mFragment)
-                .getString(eq(R.string.battery_overall_usage), anyInt());
-        mFragment.updateCellularPreference(DISCHARGE_AMOUNT);
+    public void testUpdateScreenPreference_showCorrectSummary() {
+        final String expectedUsedTime = Utils.formatElapsedTime(mRealContext, USAGE_TIME_MS, false);
+        doReturn(mScreenBatterySipper).when(mFragment).findBatterySipperByType(any(), any());
+        doReturn(mRealContext).when(mFragment).getContext();
+
+        mFragment.updateScreenPreference();
 
-        verify(mCellularNetworkPref).setSummary(expectedSummary);
+        verify(mScreenUsagePref).setSubtitle(expectedUsedTime);
     }
 
     @Test
-    public void testUpdateScreenPreference_ShowCorrectSummary() {
-        final String expectedUsedTime = mRealContext.getString(R.string.battery_used_for,
-                Utils.formatElapsedTime(mRealContext, USAGE_TIME_MS, false));
-        final double percent = BATTERY_SCREEN_USAGE / TOTAL_POWER * DISCHARGE_AMOUNT;
-        final String expectedOverallUsage = mRealContext.getString(R.string.battery_overall_usage,
-                Utils.formatPercentage((int) percent));
-        doReturn(expectedUsedTime).when(mFragment).getString(
-                eq(R.string.battery_used_for), anyInt());
-        doReturn(expectedOverallUsage).when(mFragment).getString(
-                eq(R.string.battery_overall_usage), anyInt());
+    public void testUpdateLastFullChargePreference_showCorrectSummary() {
+        doReturn(mRealContext).when(mFragment).getContext();
+        final String expected = mRealContext.getString(R.string.power_last_full_charge_summary,
+                Utils.formatElapsedTime(mRealContext, TIME_SINCE_LAST_FULL_CHARGE_MS, false));
+        doReturn(expected).when(mFragment).getString(eq(R.string.power_last_full_charge_summary),
+                any());
 
-        mFragment.updateScreenPreference(DISCHARGE_AMOUNT);
+        mFragment.updateLastFullChargePreference(TIME_SINCE_LAST_FULL_CHARGE_MS);
 
-        verify(mScreenUsagePref).setSummary(expectedUsedTime);
-        verify(mScreenConsumptionPref).setSummary(expectedOverallUsage);
+        verify(mLastFullChargePref).setSubtitle(expected);
     }
 
     @Test
-    public void testUpdatePreference_UsageListEmpty_ShouldNotCrash() {
+    public void testUpdatePreference_usageListEmpty_shouldNotCrash() {
         when(mBatteryHelper.getUsageList()).thenReturn(new ArrayList<BatterySipper>());
-        doReturn("").when(mFragment).getString(anyInt(), Matchers.anyObject());
+        doReturn("").when(mFragment).getString(anyInt(), any());
 
         // Should not crash when update
-        mFragment.updateScreenPreference(DISCHARGE_AMOUNT);
-        mFragment.updateCellularPreference(DISCHARGE_AMOUNT);
+        mFragment.updateScreenPreference();
     }
 
     @Test
@@ -496,6 +472,12 @@ public class PowerUsageSummaryTest {
         assertThat(percent).isWithin(PRECISION).of(POWER_USAGE_PERCENTAGE);
     }
 
+    @Test
+    public void testCalculateRunningTimeBasedOnStatsType() {
+        assertThat(mFragment.calculateRunningTimeBasedOnStatsType()).isEqualTo(
+                TIME_SINCE_LAST_FULL_CHARGE_MS);
+    }
+
     public static class TestFragment extends PowerUsageSummary {
 
         private Context mContext;