Update the smearing methods in framework.
1. Fix the bug about foregroundActivityTime. It should take microseconds as parameter and return microseconds 2. Use the min time of foregroundActivity time and Top time as "screen time" 3. Hide bluetooth, wifi, idle but don't smear it Bug: 63176214 Test: runtest -x BatteryStatsHelperTest Change-Id: I5798577da17d60fb3e3b18351deb31ae77939154
This commit is contained in:
@@ -840,7 +840,10 @@ public class BatteryStatsHelper {
|
||||
if (sipper.shouldHide) {
|
||||
if (sipper.drainType != BatterySipper.DrainType.OVERCOUNTED
|
||||
&& sipper.drainType != BatterySipper.DrainType.SCREEN
|
||||
&& sipper.drainType != BatterySipper.DrainType.UNACCOUNTED) {
|
||||
&& sipper.drainType != BatterySipper.DrainType.UNACCOUNTED
|
||||
&& sipper.drainType != BatterySipper.DrainType.BLUETOOTH
|
||||
&& sipper.drainType != BatterySipper.DrainType.WIFI
|
||||
&& sipper.drainType != BatterySipper.DrainType.IDLE) {
|
||||
// Don't add it if it is overcounted, unaccounted or screen
|
||||
proportionalSmearPowerMah += sipper.totalPowerMah;
|
||||
}
|
||||
@@ -861,19 +864,19 @@ public class BatteryStatsHelper {
|
||||
* time.
|
||||
*/
|
||||
public 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);
|
||||
final long timeMs = getProcessForegroundTimeMs(uid,
|
||||
BatteryStats.STATS_SINCE_CHARGED);
|
||||
activityTimeArray.put(uid.getUid(), timeMs);
|
||||
totalActivityTimeMs += timeMs;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalActivityTimeMs >= 10 * DateUtils.MINUTE_IN_MILLIS) {
|
||||
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);
|
||||
@@ -936,16 +939,41 @@ public class BatteryStatsHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
public long convertUsToMs(long timeUs) {
|
||||
return timeUs / 1000;
|
||||
}
|
||||
|
||||
public long convertMsToUs(long timeMs) {
|
||||
return timeMs * 1000;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public long getForegroundActivityTotalTimeMs(BatteryStats.Uid uid, long rawRealtimeMs) {
|
||||
public long getForegroundActivityTotalTimeUs(BatteryStats.Uid uid, long rawRealtimeUs) {
|
||||
final BatteryStats.Timer timer = uid.getForegroundActivityTimer();
|
||||
if (timer != null) {
|
||||
return timer.getTotalTimeLocked(rawRealtimeMs, BatteryStats.STATS_SINCE_CHARGED);
|
||||
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;
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
package com.android.internal.os;
|
||||
|
||||
|
||||
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;
|
||||
@@ -54,11 +57,16 @@ import java.util.List;
|
||||
@SmallTest
|
||||
public class BatteryStatsHelperTest extends TestCase {
|
||||
private static final long TIME_FOREGROUND_ACTIVITY_ZERO = 0;
|
||||
private static final long TIME_FOREGROUND_ACTIVITY = 100 * DateUtils.MINUTE_IN_MILLIS;
|
||||
private static final long TIME_FOREGROUND_ACTIVITY = 100 * DateUtils.MINUTE_IN_MILLIS * 1000;
|
||||
private static final long TIME_STATE_FOREGROUND_MS = 10 * DateUtils.MINUTE_IN_MILLIS;
|
||||
private static final long TIME_STATE_FOREGROUND_US = TIME_STATE_FOREGROUND_MS * 1000;
|
||||
|
||||
private static final int UID = 123456;
|
||||
private static final double BATTERY_SCREEN_USAGE = 300;
|
||||
private static final double BATTERY_SYSTEM_USAGE = 600;
|
||||
private static final double BATTERY_WIFI_USAGE = 200;
|
||||
private static final double BATTERY_IDLE_USAGE = 600;
|
||||
private static final double BATTERY_BLUETOOTH_USAGE = 300;
|
||||
private static final double BATTERY_OVERACCOUNTED_USAGE = 500;
|
||||
private static final double BATTERY_UNACCOUNTED_USAGE = 700;
|
||||
private static final double BATTERY_APP_USAGE = 100;
|
||||
@@ -68,6 +76,12 @@ public class BatteryStatsHelperTest extends TestCase {
|
||||
@Mock
|
||||
private BatteryStats.Uid mUid;
|
||||
@Mock
|
||||
private BatterySipper mWifiBatterySipper;
|
||||
@Mock
|
||||
private BatterySipper mBluetoothBatterySipper;
|
||||
@Mock
|
||||
private BatterySipper mIdleBatterySipper;
|
||||
@Mock
|
||||
private BatterySipper mNormalBatterySipper;
|
||||
@Mock
|
||||
private BatterySipper mScreenBatterySipper;
|
||||
@@ -109,6 +123,15 @@ public class BatteryStatsHelperTest extends TestCase {
|
||||
mUnaccountedBatterySipper.drainType = BatterySipper.DrainType.UNACCOUNTED;
|
||||
mUnaccountedBatterySipper.totalPowerMah = BATTERY_UNACCOUNTED_USAGE;
|
||||
|
||||
mWifiBatterySipper.drainType = BatterySipper.DrainType.WIFI;
|
||||
mWifiBatterySipper.totalPowerMah = BATTERY_WIFI_USAGE;
|
||||
|
||||
mBluetoothBatterySipper.drainType = BatterySipper.DrainType.BLUETOOTH;
|
||||
mBluetoothBatterySipper.totalPowerMah = BATTERY_BLUETOOTH_USAGE;
|
||||
|
||||
mIdleBatterySipper.drainType = BatterySipper.DrainType.IDLE;
|
||||
mIdleBatterySipper.totalPowerMah = BATTERY_IDLE_USAGE;
|
||||
|
||||
mContext = InstrumentationRegistry.getContext();
|
||||
mBatteryStatsHelper = spy(new BatteryStatsHelper(mContext));
|
||||
mBatteryStatsHelper.setPackageManager(mPackageManager);
|
||||
@@ -165,6 +188,9 @@ public class BatteryStatsHelperTest extends TestCase {
|
||||
sippers.add(mSystemBatterySipper);
|
||||
sippers.add(mOvercountedBatterySipper);
|
||||
sippers.add(mUnaccountedBatterySipper);
|
||||
sippers.add(mWifiBatterySipper);
|
||||
sippers.add(mBluetoothBatterySipper);
|
||||
sippers.add(mIdleBatterySipper);
|
||||
doReturn(true).when(mBatteryStatsHelper).isTypeSystem(mSystemBatterySipper);
|
||||
doNothing().when(mBatteryStatsHelper).smearScreenBatterySipper(any(), any());
|
||||
|
||||
@@ -219,6 +245,19 @@ public class BatteryStatsHelperTest extends TestCase {
|
||||
assertThat(mBatteryStatsHelper.isTypeService(mNormalBatterySipper)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetProcessForegroundTimeMs_largerActivityTime_returnMinTime() {
|
||||
doReturn(TIME_STATE_FOREGROUND_US + 500).when(mBatteryStatsHelper)
|
||||
.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);
|
||||
|
||||
assertThat(time).isEqualTo(TIME_STATE_FOREGROUND_MS);
|
||||
}
|
||||
|
||||
private BatterySipper createTestSmearBatterySipper(long activityTime, double totalPowerMah,
|
||||
int uidCode, boolean isUidNull) {
|
||||
final BatterySipper sipper = mock(BatterySipper.class);
|
||||
@@ -227,8 +266,8 @@ public class BatteryStatsHelperTest extends TestCase {
|
||||
doReturn(uidCode).when(sipper).getUid();
|
||||
if (!isUidNull) {
|
||||
final BatteryStats.Uid uid = mock(BatteryStats.Uid.class, RETURNS_DEEP_STUBS);
|
||||
doReturn(activityTime).when(mBatteryStatsHelper).getForegroundActivityTotalTimeMs(
|
||||
eq(uid), anyLong());
|
||||
doReturn(activityTime).when(mBatteryStatsHelper).getProcessForegroundTimeMs(eq(uid),
|
||||
anyInt());
|
||||
doReturn(uidCode).when(uid).getUid();
|
||||
sipper.uidObj = uid;
|
||||
}
|
||||
@@ -236,5 +275,4 @@ public class BatteryStatsHelperTest extends TestCase {
|
||||
return sipper;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user