summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHelper.java67
-rw-r--r--core/java/com/android/internal/os/ScreenPowerCalculator.java64
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java23
3 files changed, 76 insertions, 78 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index a21c68b4f01a..fcf8bb4e748b 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -41,7 +41,6 @@ import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.Log;
import android.util.SparseArray;
-import android.util.SparseLongArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
@@ -379,6 +378,7 @@ public class BatteryStatsHelper {
mMaxDrainedPower = (mStats.getHighDischargeAmountSinceCharge()
* mPowerProfile.getBatteryCapacity()) / 100;
+ // Create list of (almost all) sippers, calculate their usage, and put them in mUsageList.
processAppUsage(asUsers);
Collections.sort(mUsageList);
@@ -556,8 +556,7 @@ public class BatteryStatsHelper {
}
/**
- * Mark the {@link BatterySipper} that we should hide and smear the screen usage based on
- * foreground activity time.
+ * Mark the {@link BatterySipper} that we should hide.
*
* @param sippers sipper list that need to check and remove
* @return the total power of the hidden items of {@link BatterySipper}
@@ -565,7 +564,6 @@ public class BatteryStatsHelper {
*/
public double removeHiddenBatterySippers(List<BatterySipper> sippers) {
double proportionalSmearPowerMah = 0;
- BatterySipper screenSipper = null;
for (int i = sippers.size() - 1; i >= 0; i--) {
final BatterySipper sipper = sippers.get(i);
sipper.shouldHide = shouldHideSipper(sipper);
@@ -581,45 +579,11 @@ public class BatteryStatsHelper {
proportionalSmearPowerMah += sipper.totalPowerMah;
}
}
-
- if (sipper.drainType == BatterySipper.DrainType.SCREEN) {
- screenSipper = sipper;
- }
}
-
- smearScreenBatterySipper(sippers, screenSipper);
-
return proportionalSmearPowerMah;
}
/**
- * Smear the screen on power usage among {@code sippers}, based on ratio of foreground activity
- * time.
- */
- public void smearScreenBatterySipper(List<BatterySipper> sippers, BatterySipper screenSipper) {
- 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 = getProcessForegroundTimeMs(uid,
- BatteryStats.STATS_SINCE_CHARGED);
- activityTimeArray.put(uid.getUid(), timeMs);
- totalActivityTimeMs += timeMs;
- }
- }
-
- if (screenSipper != null && 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.screenPowerMah = screenPowerMah * activityTimeArray.get(sipper.getUid(), 0)
- / totalActivityTimeMs;
- }
- }
- }
-
- /**
* Check whether we should hide the battery sipper.
*/
public boolean shouldHideSipper(BatterySipper sipper) {
@@ -682,33 +646,6 @@ public class BatteryStatsHelper {
}
@VisibleForTesting
- public long getForegroundActivityTotalTimeUs(BatteryStats.Uid uid, long rawRealtimeUs) {
- final BatteryStats.Timer timer = uid.getForegroundActivityTimer();
- if (timer != null) {
- return timer.getTotalTimeLocked(rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
- }
-
- return 0;
- }
-
- @VisibleForTesting
- public long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) {
- final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
- final int foregroundTypes[] = {BatteryStats.Uid.PROCESS_STATE_TOP};
-
- long timeUs = 0;
- for (int type : foregroundTypes) {
- final long localTime = uid.getProcessStateTime(type, rawRealTimeUs, which);
- timeUs += localTime;
- }
-
- // Return the min value of STATE_TOP time and foreground activity time, since both of these
- // time have some errors.
- return convertUsToMs(
- Math.min(timeUs, getForegroundActivityTotalTimeUs(uid, rawRealTimeUs)));
- }
-
- @VisibleForTesting
public void setPackageManager(PackageManager packageManager) {
mPackageManager = packageManager;
}
diff --git a/core/java/com/android/internal/os/ScreenPowerCalculator.java b/core/java/com/android/internal/os/ScreenPowerCalculator.java
index 25f6b4d16971..9c4a26724ba8 100644
--- a/core/java/com/android/internal/os/ScreenPowerCalculator.java
+++ b/core/java/com/android/internal/os/ScreenPowerCalculator.java
@@ -21,9 +21,14 @@ import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.SystemBatteryConsumer;
+import android.os.SystemClock;
import android.os.UserHandle;
+import android.text.format.DateUtils;
import android.util.Log;
import android.util.SparseArray;
+import android.util.SparseLongArray;
+
+import com.android.internal.annotations.VisibleForTesting;
import java.util.List;
@@ -57,6 +62,7 @@ public class ScreenPowerCalculator extends PowerCalculator {
.setUsageDurationMillis(BatteryConsumer.TIME_COMPONENT_USAGE, durationMs)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_USAGE, powerMah);
}
+ // TODO(b/178140704): Attribute screen usage similar to smearScreenBatterySipper.
}
/**
@@ -73,6 +79,8 @@ public class ScreenPowerCalculator extends PowerCalculator {
bs.usageTimeMs = durationMs;
bs.sumPower();
sippers.add(bs);
+
+ smearScreenBatterySipper(sippers, bs);
}
}
@@ -96,4 +104,60 @@ public class ScreenPowerCalculator extends PowerCalculator {
}
return power;
}
+
+ /**
+ * Smear the screen on power usage among {@code sippers}, based on ratio of foreground activity
+ * time, and store this in the {@link BatterySipper#screenPowerMah} field.
+ */
+ @VisibleForTesting
+ public void smearScreenBatterySipper(List<BatterySipper> sippers, BatterySipper screenSipper) {
+
+ long totalActivityTimeMs = 0;
+ final SparseLongArray activityTimeArray = new SparseLongArray();
+ for (int i = sippers.size() - 1; i >= 0; i--) {
+ final BatteryStats.Uid uid = sippers.get(i).uidObj;
+ if (uid != null) {
+ final long timeMs = getProcessForegroundTimeMs(uid);
+ activityTimeArray.put(uid.getUid(), timeMs);
+ totalActivityTimeMs += timeMs;
+ }
+ }
+
+ if (screenSipper != null && totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) {
+ final double screenPowerMah = screenSipper.totalPowerMah;
+ for (int i = sippers.size() - 1; i >= 0; i--) {
+ final BatterySipper sipper = sippers.get(i);
+ sipper.screenPowerMah = screenPowerMah * activityTimeArray.get(sipper.getUid(), 0)
+ / totalActivityTimeMs;
+ }
+ }
+ }
+
+ /** Get the minimum of the uid's ForegroundActivity time and its TOP time. */
+ @VisibleForTesting
+ public long getProcessForegroundTimeMs(BatteryStats.Uid uid) {
+ final long rawRealTimeUs = SystemClock.elapsedRealtime() * 1000;
+ final int[] foregroundTypes = {BatteryStats.Uid.PROCESS_STATE_TOP};
+
+ long timeUs = 0;
+ for (int type : foregroundTypes) {
+ final long localTime = uid.getProcessStateTime(type, rawRealTimeUs,
+ BatteryStats.STATS_SINCE_CHARGED);
+ timeUs += localTime;
+ }
+
+ // Return the min value of STATE_TOP time and foreground activity time, since both of these
+ // time have some errors.
+ return Math.min(timeUs, getForegroundActivityTotalTimeUs(uid, rawRealTimeUs)) / 1000;
+ }
+
+ /** Get the ForegroundActivity time of the given uid. */
+ @VisibleForTesting
+ public long getForegroundActivityTotalTimeUs(BatteryStats.Uid uid, long rawRealtimeUs) {
+ final BatteryStats.Timer timer = uid.getForegroundActivityTimer();
+ if (timer == null) {
+ return 0;
+ }
+ return timer.getTotalTimeLocked(rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
+ }
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java
index fbe16f2c39d1..d2107eaefefc 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsHelperTest.java
@@ -21,12 +21,10 @@ import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;
import static com.google.common.truth.Truth.assertThat;
-import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
-import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
@@ -194,7 +192,6 @@ public class BatteryStatsHelperTest extends TestCase {
sippers.add(mBluetoothBatterySipper);
sippers.add(mIdleBatterySipper);
doReturn(true).when(mBatteryStatsHelper).isTypeSystem(mSystemBatterySipper);
- doNothing().when(mBatteryStatsHelper).smearScreenBatterySipper(any(), any());
final double totalUsage = mBatteryStatsHelper.removeHiddenBatterySippers(sippers);
@@ -208,19 +205,20 @@ public class BatteryStatsHelperTest extends TestCase {
@Test
public void testSmearScreenBatterySipper() {
+ final ScreenPowerCalculator spc = spy(ScreenPowerCalculator.class);
final BatterySipper sipperNull = createTestSmearBatterySipper(TIME_FOREGROUND_ACTIVITY_ZERO,
- BATTERY_APP_USAGE, 0 /* uid */, true /* isUidNull */);
+ BATTERY_APP_USAGE, 0 /* uid */, true /* isUidNull */, spc);
final BatterySipper sipperBg = createTestSmearBatterySipper(TIME_FOREGROUND_ACTIVITY_ZERO,
- BATTERY_APP_USAGE, 1 /* uid */, false /* isUidNull */);
+ BATTERY_APP_USAGE, 1 /* uid */, false /* isUidNull */, spc);
final BatterySipper sipperFg = createTestSmearBatterySipper(TIME_FOREGROUND_ACTIVITY,
- BATTERY_APP_USAGE, 2 /* uid */, false /* isUidNull */);
+ BATTERY_APP_USAGE, 2 /* uid */, false /* isUidNull */, spc);
final List<BatterySipper> sippers = new ArrayList<>();
sippers.add(sipperNull);
sippers.add(sipperBg);
sippers.add(sipperFg);
- mBatteryStatsHelper.smearScreenBatterySipper(sippers, mScreenBatterySipper);
+ spc.smearScreenBatterySipper(sippers, mScreenBatterySipper);
assertThat(sipperNull.screenPowerMah).isWithin(PRECISION).of(0);
assertThat(sipperBg.screenPowerMah).isWithin(PRECISION).of(0);
@@ -249,13 +247,13 @@ public class BatteryStatsHelperTest extends TestCase {
@Test
public void testGetProcessForegroundTimeMs_largerActivityTime_returnMinTime() {
- doReturn(TIME_STATE_FOREGROUND_US + 500).when(mBatteryStatsHelper)
+ final ScreenPowerCalculator spc = spy(ScreenPowerCalculator.class);
+ doReturn(TIME_STATE_FOREGROUND_US + 500).when(spc)
.getForegroundActivityTotalTimeUs(eq(mUid), anyLong());
doReturn(TIME_STATE_FOREGROUND_US).when(mUid).getProcessStateTime(eq(PROCESS_STATE_TOP),
anyLong(), anyInt());
- final long time = mBatteryStatsHelper.getProcessForegroundTimeMs(mUid,
- BatteryStats.STATS_SINCE_CHARGED);
+ final long time = spc.getProcessForegroundTimeMs(mUid);
assertThat(time).isEqualTo(TIME_STATE_FOREGROUND_MS);
}
@@ -291,15 +289,14 @@ public class BatteryStatsHelperTest extends TestCase {
}
private BatterySipper createTestSmearBatterySipper(long activityTime, double totalPowerMah,
- int uidCode, boolean isUidNull) {
+ int uidCode, boolean isUidNull, ScreenPowerCalculator spc) {
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(mBatteryStatsHelper).getProcessForegroundTimeMs(eq(uid),
- anyInt());
+ doReturn(activityTime).when(spc).getProcessForegroundTimeMs(eq(uid));
doReturn(uidCode).when(uid).getUid();
sipper.uidObj = uid;
}