Merge "ScreenPowerCalculator is responsible for smearing" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
8f15e41d76
@@ -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,44 +579,10 @@ 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.
|
||||
*/
|
||||
@@ -681,33 +645,6 @@ public class BatteryStatsHelper {
|
||||
return timeMs * 1000;
|
||||
}
|
||||
|
||||
@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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user