Merge changes I573e4fb9,I8e7baadc into oc-dev

* changes:
  Drop the misc and not smear it.
  Smear screen power usage based on activity time.
diff --git a/src/com/android/settings/fuelgauge/BatteryUtils.java b/src/com/android/settings/fuelgauge/BatteryUtils.java
index 86cb203..8e730c0 100644
--- a/src/com/android/settings/fuelgauge/BatteryUtils.java
+++ b/src/com/android/settings/fuelgauge/BatteryUtils.java
@@ -22,7 +22,9 @@
 import android.support.annotation.IntDef;
 import android.support.annotation.Nullable;
 import android.support.annotation.VisibleForTesting;
+import android.text.format.DateUtils;
 import android.util.Log;
+import android.util.SparseLongArray;
 
 import com.android.internal.os.BatterySipper;
 import com.android.settings.overlay.FeatureFactory;
@@ -115,25 +117,64 @@
     }
 
     /**
-     * Remove the {@link BatterySipper} that we should hide.
+     * Remove the {@link BatterySipper} that we should hide and smear the screen usage based on
+     * foreground activity time.
      *
      * @param sippers sipper list that need to check and remove
      * @return the total power of the hidden items of {@link BatterySipper}
+     * for proportional smearing
      */
     public double removeHiddenBatterySippers(List<BatterySipper> sippers) {
-        double totalPowerMah = 0;
+        double proportionalSmearPowerMah = 0;
+        BatterySipper screenSipper = null;
         for (int i = sippers.size() - 1; i >= 0; i--) {
             final BatterySipper sipper = sippers.get(i);
             if (shouldHideSipper(sipper)) {
                 sippers.remove(i);
-                if (sipper.drainType != BatterySipper.DrainType.OVERCOUNTED) {
-                    // Don't add it if it is overcounted
-                    totalPowerMah += sipper.totalPowerMah;
+                if (sipper.drainType != BatterySipper.DrainType.OVERCOUNTED
+                        && sipper.drainType != BatterySipper.DrainType.SCREEN
+                        && sipper.drainType != BatterySipper.DrainType.UNACCOUNTED) {
+                    // Don't add it if it is overcounted, unaccounted or screen
+                    proportionalSmearPowerMah += sipper.totalPowerMah;
                 }
             }
+
+            if (sipper.drainType == BatterySipper.DrainType.SCREEN) {
+                screenSipper = sipper;
+            }
         }
 
-        return totalPowerMah;
+        smearScreenBatterySipper(sippers, screenSipper);
+
+        return proportionalSmearPowerMah;
+    }
+
+    /**
+     * Smear the screen on power usage among {@code sippers}, based on ratio of foreground activity
+     * time.
+     */
+    @VisibleForTesting
+    void smearScreenBatterySipper(List<BatterySipper> sippers, BatterySipper screenSipper) {
+        final long rawRealtimeMs = SystemClock.elapsedRealtime();
+        long totalActivityTimeMs = 0;
+        final SparseLongArray activityTimeArray = new SparseLongArray();
+        for (int i = 0, size = sippers.size(); i < size; i++) {
+            final BatteryStats.Uid uid = sippers.get(i).uidObj;
+            if (uid != null) {
+                final long timeMs = getForegroundActivityTotalTimeMs(uid, rawRealtimeMs);
+                activityTimeArray.put(uid.getUid(), timeMs);
+                totalActivityTimeMs += timeMs;
+            }
+        }
+
+        if (totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) {
+            final double screenPowerMah = screenSipper.totalPowerMah;
+            for (int i = 0, size = sippers.size(); i < size; i++) {
+                final BatterySipper sipper = sippers.get(i);
+                sipper.totalPowerMah += screenPowerMah * activityTimeArray.get(sipper.getUid(), 0)
+                        / totalActivityTimeMs;
+            }
+        }
     }
 
     /**
@@ -186,5 +227,15 @@
         return mPackageManager == null;
     }
 
+    @VisibleForTesting
+    long getForegroundActivityTotalTimeMs(BatteryStats.Uid uid, long rawRealtimeMs) {
+        final BatteryStats.Timer timer = uid.getForegroundActivityTimer();
+        if (timer != null) {
+            return timer.getTotalTimeLocked(rawRealtimeMs, BatteryStats.STATS_SINCE_CHARGED);
+        }
+
+        return 0;
+    }
+
 }
 
diff --git a/src/com/android/settings/fuelgauge/PowerUsageBase.java b/src/com/android/settings/fuelgauge/PowerUsageBase.java
index aee55d6..060abdd 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageBase.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageBase.java
@@ -57,7 +57,7 @@
 
         mBatteryBroadcastReceiver = new BatteryBroadcastReceiver(getContext());
         mBatteryBroadcastReceiver.setBatteryChangedListener(() -> {
-            getLoaderManager().restartLoader(0, null, this);
+            restartBatteryStatsLoader();
         });
 
         getLoaderManager().initLoader(0, icicle, this);
@@ -95,6 +95,10 @@
         }
     }
 
+    protected void restartBatteryStatsLoader() {
+        getLoaderManager().restartLoader(0, Bundle.EMPTY, this);
+    }
+
     protected abstract void refreshUi();
 
     protected void updatePreference(BatteryHistoryPreference historyPref) {
diff --git a/src/com/android/settings/fuelgauge/PowerUsageSummary.java b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
index 0309296..d0343c3 100644
--- a/src/com/android/settings/fuelgauge/PowerUsageSummary.java
+++ b/src/com/android/settings/fuelgauge/PowerUsageSummary.java
@@ -287,7 +287,7 @@
                 item.setTitle(mShowAllApps ? R.string.hide_extra_apps : R.string.show_all_apps);
                 metricsFeatureProvider.action(context,
                         MetricsEvent.ACTION_SETTINGS_MENU_BATTERY_APPS_TOGGLE, mShowAllApps);
-                refreshUi();
+                restartBatteryStatsLoader();
                 return true;
             default:
                 return super.onOptionsItemSelected(item);
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
index fd89558..f6a8587 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/BatteryUtilsTest.java
@@ -18,6 +18,7 @@
 import android.content.Context;
 import android.os.BatteryStats;
 import android.os.Process;
+import android.text.format.DateUtils;
 
 import com.android.internal.os.BatterySipper;
 import com.android.settings.SettingsRobolectricTestRunner;
@@ -47,8 +48,11 @@
 import static org.mockito.Matchers.any;
 import static org.mockito.Matchers.anyInt;
 import static org.mockito.Matchers.anyLong;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 import static org.mockito.Mockito.spy;
 
@@ -62,6 +66,8 @@
     private static final long TIME_STATE_TOP_SLEEPING = 2500 * UNIT;
     private static final long TIME_STATE_FOREGROUND = 3000 * UNIT;
     private static final long TIME_STATE_BACKGROUND = 6000 * UNIT;
+    private static final long TIME_FOREGROUND_ACTIVITY_ZERO = 0;
+    private static final long TIME_FOREGROUND_ACTIVITY = 100 * DateUtils.MINUTE_IN_MILLIS;
 
     private static final int UID = 123;
     private static final long TIME_EXPECTED_FOREGROUND = 1500;
@@ -71,6 +77,7 @@
     private static final double BATTERY_SYSTEM_USAGE = 600;
     private static final double BATTERY_OVERACCOUNTED_USAGE = 500;
     private static final double BATTERY_UNACCOUNTED_USAGE = 700;
+    private static final double BATTERY_APP_USAGE = 100;
     private static final double TOTAL_BATTERY_USAGE = 1000;
     private static final double HIDDEN_USAGE = 200;
     private static final int DISCHARGE_AMOUNT = 80;
@@ -180,11 +187,12 @@
         sippers.add(mUnaccountedBatterySipper);
         when(mProvider.isTypeSystem(mSystemBatterySipper))
                 .thenReturn(true);
+        doNothing().when(mBatteryUtils).smearScreenBatterySipper(any(), any());
 
         final double totalUsage = mBatteryUtils.removeHiddenBatterySippers(sippers);
+
         assertThat(sippers).containsExactly(mNormalBatterySipper);
-        assertThat(totalUsage).isWithin(PRECISION).of(
-                BATTERY_SCREEN_USAGE + BATTERY_SYSTEM_USAGE + BATTERY_UNACCOUNTED_USAGE);
+        assertThat(totalUsage).isWithin(PRECISION).of(BATTERY_SYSTEM_USAGE);
     }
 
     @Test
@@ -259,4 +267,43 @@
                 HIDDEN_USAGE, DISCHARGE_AMOUNT))
                 .isWithin(PRECISION).of(PERCENT_SYSTEM_USAGE);
     }
+
+    @Test
+    public void testSmearScreenBatterySipper() {
+        final BatterySipper sipperNull = createTestSmearBatterySipper(TIME_FOREGROUND_ACTIVITY_ZERO,
+                BATTERY_APP_USAGE, 0 /* uid */, true /* isUidNull */);
+        final BatterySipper sipperBg = createTestSmearBatterySipper(TIME_FOREGROUND_ACTIVITY_ZERO,
+                BATTERY_APP_USAGE, 1 /* uid */, false /* isUidNull */);
+        final BatterySipper sipperFg = createTestSmearBatterySipper(TIME_FOREGROUND_ACTIVITY,
+                BATTERY_APP_USAGE, 2 /* uid */, false /* isUidNull */);
+
+        final List<BatterySipper> sippers = new ArrayList<>();
+        sippers.add(sipperNull);
+        sippers.add(sipperBg);
+        sippers.add(sipperFg);
+
+        mBatteryUtils.smearScreenBatterySipper(sippers, mScreenBatterySipper);
+
+        assertThat(sipperNull.totalPowerMah).isWithin(PRECISION).of(BATTERY_APP_USAGE);
+        assertThat(sipperBg.totalPowerMah).isWithin(PRECISION).of(BATTERY_APP_USAGE);
+        assertThat(sipperFg.totalPowerMah).isWithin(PRECISION).of(
+                BATTERY_APP_USAGE + BATTERY_SCREEN_USAGE);
+    }
+
+    private BatterySipper createTestSmearBatterySipper(long activityTime, double totalPowerMah,
+            int uidCode, boolean isUidNull) {
+        final BatterySipper sipper = mock(BatterySipper.class);
+        sipper.drainType = BatterySipper.DrainType.APP;
+        sipper.totalPowerMah = totalPowerMah;
+        doReturn(uidCode).when(sipper).getUid();
+        if (!isUidNull) {
+            final BatteryStats.Uid uid = mock(BatteryStats.Uid.class, RETURNS_DEEP_STUBS);
+            doReturn(activityTime).when(mBatteryUtils).getForegroundActivityTotalTimeMs(eq(uid),
+                    anyLong());
+            doReturn(uidCode).when(uid).getUid();
+            sipper.uidObj = uid;
+        }
+
+        return sipper;
+    }
 }
diff --git a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
index 3d5d5dc..0856d2d 100644
--- a/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
+++ b/tests/robotests/src/com/android/settings/fuelgauge/PowerUsageSummaryTest.java
@@ -68,6 +68,7 @@
 import static org.mockito.Matchers.anyLong;
 import static org.mockito.Matchers.anyString;
 import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doNothing;
 import static org.mockito.Mockito.doReturn;
 import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.spy;
@@ -165,6 +166,7 @@
         mFragment.initFeatureProvider();
         mBatteryMeterView = spy(new BatteryMeterView(mRealContext));
         mBatteryMeterView.mDrawable = new BatteryMeterView.BatteryMeterDrawable(mRealContext, 0);
+        doNothing().when(mFragment).restartBatteryStatsLoader();
 
         when(mFragment.getActivity()).thenReturn(mSettingsActivity);
         when(mAdditionalBatteryInfoMenu.getItemId())