Merge "Fix system service power calculation when measured energy is available" into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
16d1188b7d
@@ -201,7 +201,10 @@ public class CpuPowerCalculator extends PowerCalculator {
|
|||||||
result.packageWithHighestDrain = packageWithHighestDrain;
|
result.packageWithHighestDrain = packageWithHighestDrain;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calculateUidModeledPowerMah(BatteryStats.Uid u, int statsType) {
|
/**
|
||||||
|
* Calculates CPU power consumed by the specified app, using the PowerProfile model.
|
||||||
|
*/
|
||||||
|
public double calculateUidModeledPowerMah(BatteryStats.Uid u, int statsType) {
|
||||||
// Constant battery drain when CPU is active
|
// Constant battery drain when CPU is active
|
||||||
double powerMah = calculateActiveCpuPowerMah(u.getCpuActiveTime());
|
double powerMah = calculateActiveCpuPowerMah(u.getCpuActiveTime());
|
||||||
|
|
||||||
|
|||||||
@@ -40,8 +40,10 @@ public class SystemServicePowerCalculator extends PowerCalculator {
|
|||||||
// to this layout:
|
// to this layout:
|
||||||
// {cluster1-speed1, cluster1-speed2, ..., cluster2-speed1, cluster2-speed2, ...}
|
// {cluster1-speed1, cluster1-speed2, ..., cluster2-speed1, cluster2-speed2, ...}
|
||||||
private final UsageBasedPowerEstimator[] mPowerEstimators;
|
private final UsageBasedPowerEstimator[] mPowerEstimators;
|
||||||
|
private final CpuPowerCalculator mCpuPowerCalculator;
|
||||||
|
|
||||||
public SystemServicePowerCalculator(PowerProfile powerProfile) {
|
public SystemServicePowerCalculator(PowerProfile powerProfile) {
|
||||||
|
mCpuPowerCalculator = new CpuPowerCalculator(powerProfile);
|
||||||
int numFreqs = 0;
|
int numFreqs = 0;
|
||||||
final int numCpuClusters = powerProfile.getNumCpuClusters();
|
final int numCpuClusters = powerProfile.getNumCpuClusters();
|
||||||
for (int cluster = 0; cluster < numCpuClusters; cluster++) {
|
for (int cluster = 0; cluster < numCpuClusters; cluster++) {
|
||||||
@@ -62,7 +64,22 @@ public class SystemServicePowerCalculator extends PowerCalculator {
|
|||||||
@Override
|
@Override
|
||||||
public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
|
public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
|
||||||
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
|
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
|
||||||
double systemServicePowerMah = calculateSystemServicePower(batteryStats);
|
final BatteryStats.Uid systemUid = batteryStats.getUidStats().get(Process.SYSTEM_UID);
|
||||||
|
if (systemUid == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final long consumptionUC = systemUid.getCpuMeasuredBatteryConsumptionUC();
|
||||||
|
final int powerModel = getPowerModel(consumptionUC, query);
|
||||||
|
|
||||||
|
double systemServicePowerMah;
|
||||||
|
if (powerModel == BatteryConsumer.POWER_MODEL_MEASURED_ENERGY) {
|
||||||
|
systemServicePowerMah = calculatePowerUsingMeasuredConsumption(batteryStats,
|
||||||
|
systemUid, consumptionUC);
|
||||||
|
} else {
|
||||||
|
systemServicePowerMah = calculatePowerUsingPowerProfile(batteryStats);
|
||||||
|
}
|
||||||
|
|
||||||
final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders =
|
final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders =
|
||||||
builder.getUidBatteryConsumerBuilders();
|
builder.getUidBatteryConsumerBuilders();
|
||||||
final UidBatteryConsumer.Builder systemServerConsumer = uidBatteryConsumerBuilders.get(
|
final UidBatteryConsumer.Builder systemServerConsumer = uidBatteryConsumerBuilders.get(
|
||||||
@@ -76,7 +93,7 @@ public class SystemServicePowerCalculator extends PowerCalculator {
|
|||||||
// distributed to applications
|
// distributed to applications
|
||||||
systemServerConsumer.setConsumedPower(
|
systemServerConsumer.setConsumedPower(
|
||||||
BatteryConsumer.POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS,
|
BatteryConsumer.POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS,
|
||||||
-systemServicePowerMah);
|
-systemServicePowerMah, powerModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
|
for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
|
||||||
@@ -84,7 +101,8 @@ public class SystemServicePowerCalculator extends PowerCalculator {
|
|||||||
if (app != systemServerConsumer) {
|
if (app != systemServerConsumer) {
|
||||||
final BatteryStats.Uid uid = app.getBatteryStatsUid();
|
final BatteryStats.Uid uid = app.getBatteryStatsUid();
|
||||||
app.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES,
|
app.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES,
|
||||||
systemServicePowerMah * uid.getProportionalSystemServiceUsage());
|
systemServicePowerMah * uid.getProportionalSystemServiceUsage(),
|
||||||
|
powerModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +120,20 @@ public class SystemServicePowerCalculator extends PowerCalculator {
|
|||||||
public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats,
|
public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats,
|
||||||
long rawRealtimeUs, long rawUptimeUs, int statsType,
|
long rawRealtimeUs, long rawUptimeUs, int statsType,
|
||||||
SparseArray<UserHandle> asUsers) {
|
SparseArray<UserHandle> asUsers) {
|
||||||
double systemServicePowerMah = calculateSystemServicePower(batteryStats);
|
final BatteryStats.Uid systemUid = batteryStats.getUidStats().get(Process.SYSTEM_UID);
|
||||||
|
if (systemUid == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final long consumptionUC = systemUid.getCpuMeasuredBatteryConsumptionUC();
|
||||||
|
double systemServicePowerMah;
|
||||||
|
if (getPowerModel(consumptionUC) == BatteryConsumer.POWER_MODEL_MEASURED_ENERGY) {
|
||||||
|
systemServicePowerMah = calculatePowerUsingMeasuredConsumption(batteryStats,
|
||||||
|
systemUid, consumptionUC);
|
||||||
|
} else {
|
||||||
|
systemServicePowerMah = calculatePowerUsingPowerProfile(batteryStats);
|
||||||
|
}
|
||||||
|
|
||||||
BatterySipper systemServerSipper = null;
|
BatterySipper systemServerSipper = null;
|
||||||
for (int i = sippers.size() - 1; i >= 0; i--) {
|
for (int i = sippers.size() - 1; i >= 0; i--) {
|
||||||
final BatterySipper app = sippers.get(i);
|
final BatterySipper app = sippers.get(i);
|
||||||
@@ -134,7 +165,21 @@ public class SystemServicePowerCalculator extends PowerCalculator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calculateSystemServicePower(BatteryStats batteryStats) {
|
private double calculatePowerUsingMeasuredConsumption(BatteryStats batteryStats,
|
||||||
|
BatteryStats.Uid systemUid, long consumptionUC) {
|
||||||
|
// Use the PowerProfile based model to estimate the ratio between the power consumed
|
||||||
|
// while handling incoming binder calls and the entire System UID power consumption.
|
||||||
|
// Apply that ratio to the _measured_ system UID power consumption to get a more
|
||||||
|
// accurate estimate of the power consumed by incoming binder calls.
|
||||||
|
final double systemServiceModeledPowerMah = calculatePowerUsingPowerProfile(batteryStats);
|
||||||
|
final double systemUidModeledPowerMah = mCpuPowerCalculator.calculateUidModeledPowerMah(
|
||||||
|
systemUid, BatteryStats.STATS_SINCE_CHARGED);
|
||||||
|
|
||||||
|
return uCtoMah(consumptionUC) * systemServiceModeledPowerMah
|
||||||
|
/ systemUidModeledPowerMah;
|
||||||
|
}
|
||||||
|
|
||||||
|
private double calculatePowerUsingPowerProfile(BatteryStats batteryStats) {
|
||||||
final long[] systemServiceTimeAtCpuSpeeds = batteryStats.getSystemServiceTimeAtCpuSpeeds();
|
final long[] systemServiceTimeAtCpuSpeeds = batteryStats.getSystemServiceTimeAtCpuSpeeds();
|
||||||
if (systemServiceTimeAtCpuSpeeds == null) {
|
if (systemServiceTimeAtCpuSpeeds == null) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -145,13 +190,12 @@ public class SystemServicePowerCalculator extends PowerCalculator {
|
|||||||
double powerMah = 0;
|
double powerMah = 0;
|
||||||
final int size = Math.min(mPowerEstimators.length, systemServiceTimeAtCpuSpeeds.length);
|
final int size = Math.min(mPowerEstimators.length, systemServiceTimeAtCpuSpeeds.length);
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
powerMah += mPowerEstimators[i].calculatePower(systemServiceTimeAtCpuSpeeds[i]);
|
powerMah += mPowerEstimators[i].calculatePower(systemServiceTimeAtCpuSpeeds[i] / 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.d(TAG, "System service power:" + powerMah);
|
Log.d(TAG, "System service power:" + powerMah);
|
||||||
}
|
}
|
||||||
|
|
||||||
return powerMah;
|
return powerMah;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,25 +18,28 @@ package com.android.internal.os;
|
|||||||
|
|
||||||
import static com.google.common.truth.Truth.assertThat;
|
import static com.google.common.truth.Truth.assertThat;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||||
import static org.mockito.ArgumentMatchers.anyInt;
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.Mockito.doAnswer;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.when;
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import android.os.BatteryConsumer;
|
import android.os.BatteryConsumer;
|
||||||
import android.os.BatteryStats;
|
|
||||||
import android.os.BatteryUsageStatsQuery;
|
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.UidBatteryConsumer;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
import androidx.test.runner.AndroidJUnit4;
|
||||||
|
|
||||||
|
import com.android.internal.power.MeasuredEnergyStats;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Rule;
|
import org.junit.Rule;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -47,6 +50,8 @@ import java.util.Collection;
|
|||||||
public class SystemServicePowerCalculatorTest {
|
public class SystemServicePowerCalculatorTest {
|
||||||
|
|
||||||
private static final double PRECISION = 0.000001;
|
private static final double PRECISION = 0.000001;
|
||||||
|
private static final int APP_UID1 = 100;
|
||||||
|
private static final int APP_UID2 = 200;
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
|
public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
|
||||||
@@ -61,73 +66,52 @@ public class SystemServicePowerCalculatorTest {
|
|||||||
.setAveragePowerForCpuCore(1, 0, 500)
|
.setAveragePowerForCpuCore(1, 0, 500)
|
||||||
.setAveragePowerForCpuCore(1, 1, 600);
|
.setAveragePowerForCpuCore(1, 1, 600);
|
||||||
|
|
||||||
|
@Mock
|
||||||
private BatteryStatsImpl.UserInfoProvider mMockUserInfoProvider;
|
private BatteryStatsImpl.UserInfoProvider mMockUserInfoProvider;
|
||||||
|
@Mock
|
||||||
|
private KernelCpuUidTimeReader.KernelCpuUidClusterTimeReader mMockKernelCpuUidClusterTimeReader;
|
||||||
|
@Mock
|
||||||
|
private KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader mMockCpuUidFreqTimeReader;
|
||||||
|
@Mock
|
||||||
|
private KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader mMockKernelCpuUidUserSysTimeReader;
|
||||||
|
@Mock
|
||||||
|
private KernelCpuUidTimeReader.KernelCpuUidActiveTimeReader mMockKerneCpuUidActiveTimeReader;
|
||||||
|
@Mock
|
||||||
|
private SystemServerCpuThreadReader mMockSystemServerCpuThreadReader;
|
||||||
|
|
||||||
|
private final KernelCpuSpeedReader[] mMockKernelCpuSpeedReaders = new KernelCpuSpeedReader[]{
|
||||||
|
mock(KernelCpuSpeedReader.class),
|
||||||
|
mock(KernelCpuSpeedReader.class),
|
||||||
|
};
|
||||||
|
|
||||||
private MockBatteryStatsImpl mMockBatteryStats;
|
private MockBatteryStatsImpl mMockBatteryStats;
|
||||||
private MockKernelCpuUidFreqTimeReader mMockCpuUidFreqTimeReader;
|
|
||||||
private MockSystemServerCpuThreadReader mMockSystemServerCpuThreadReader;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws IOException {
|
public void setUp() throws IOException {
|
||||||
mMockUserInfoProvider = mock(BatteryStatsImpl.UserInfoProvider.class);
|
MockitoAnnotations.initMocks(this);
|
||||||
mMockSystemServerCpuThreadReader = new MockSystemServerCpuThreadReader();
|
|
||||||
mMockCpuUidFreqTimeReader = new MockKernelCpuUidFreqTimeReader();
|
|
||||||
mMockBatteryStats = mStatsRule.getBatteryStats()
|
mMockBatteryStats = mStatsRule.getBatteryStats()
|
||||||
.setSystemServerCpuThreadReader(mMockSystemServerCpuThreadReader)
|
.setUserInfoProvider(mMockUserInfoProvider)
|
||||||
|
.setKernelCpuSpeedReaders(mMockKernelCpuSpeedReaders)
|
||||||
.setKernelCpuUidFreqTimeReader(mMockCpuUidFreqTimeReader)
|
.setKernelCpuUidFreqTimeReader(mMockCpuUidFreqTimeReader)
|
||||||
.setUserInfoProvider(mMockUserInfoProvider);
|
.setKernelCpuUidClusterTimeReader(mMockKernelCpuUidClusterTimeReader)
|
||||||
|
.setKernelCpuUidUserSysTimeReader(mMockKernelCpuUidUserSysTimeReader)
|
||||||
|
.setKernelCpuUidActiveTimeReader(mMockKerneCpuUidActiveTimeReader)
|
||||||
|
.setSystemServerCpuThreadReader(mMockSystemServerCpuThreadReader);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPowerProfileBasedModel() {
|
public void testPowerProfileBasedModel() {
|
||||||
when(mMockUserInfoProvider.exists(anyInt())).thenReturn(true);
|
prepareBatteryStats(null);
|
||||||
|
|
||||||
// Test Power Profile has two CPU clusters with 2 speeds each, thus 4 freq times total
|
|
||||||
mMockSystemServerCpuThreadReader.setCpuTimes(
|
|
||||||
new long[] {30000, 40000, 50000, 60000},
|
|
||||||
new long[] {20000, 30000, 40000, 50000});
|
|
||||||
|
|
||||||
mMockCpuUidFreqTimeReader.setSystemServerCpuTimes(
|
|
||||||
new long[] {10000, 20000, 30000, 40000}
|
|
||||||
);
|
|
||||||
|
|
||||||
mMockBatteryStats.readKernelUidCpuFreqTimesLocked(null, true, false, null);
|
|
||||||
|
|
||||||
int workSourceUid1 = 100;
|
|
||||||
int workSourceUid2 = 200;
|
|
||||||
int transactionCode = 42;
|
|
||||||
|
|
||||||
Collection<BinderCallsStats.CallStat> callStats = new ArrayList<>();
|
|
||||||
BinderCallsStats.CallStat stat1 = new BinderCallsStats.CallStat(workSourceUid1,
|
|
||||||
Binder.class, transactionCode, true /*screenInteractive */);
|
|
||||||
stat1.incrementalCallCount = 100;
|
|
||||||
stat1.recordedCallCount = 100;
|
|
||||||
stat1.cpuTimeMicros = 1000000;
|
|
||||||
callStats.add(stat1);
|
|
||||||
|
|
||||||
mMockBatteryStats.noteBinderCallStats(workSourceUid1, 100, callStats);
|
|
||||||
|
|
||||||
callStats.clear();
|
|
||||||
BinderCallsStats.CallStat stat2 = new BinderCallsStats.CallStat(workSourceUid2,
|
|
||||||
Binder.class, transactionCode, true /*screenInteractive */);
|
|
||||||
stat2.incrementalCallCount = 100;
|
|
||||||
stat2.recordedCallCount = 100;
|
|
||||||
stat2.cpuTimeMicros = 9000000;
|
|
||||||
callStats.add(stat2);
|
|
||||||
|
|
||||||
mMockBatteryStats.noteBinderCallStats(workSourceUid2, 100, callStats);
|
|
||||||
|
|
||||||
mMockBatteryStats.updateSystemServiceCallStats();
|
|
||||||
mMockBatteryStats.updateSystemServerThreadStats();
|
|
||||||
|
|
||||||
SystemServicePowerCalculator calculator = new SystemServicePowerCalculator(
|
SystemServicePowerCalculator calculator = new SystemServicePowerCalculator(
|
||||||
mStatsRule.getPowerProfile());
|
mStatsRule.getPowerProfile());
|
||||||
|
|
||||||
mStatsRule.apply(new FakeCpuPowerCalculator(), calculator);
|
mStatsRule.apply(new CpuPowerCalculator(mStatsRule.getPowerProfile()), calculator);
|
||||||
|
|
||||||
assertThat(mStatsRule.getUidBatteryConsumer(workSourceUid1)
|
assertThat(mStatsRule.getUidBatteryConsumer(APP_UID1)
|
||||||
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES))
|
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES))
|
||||||
.isWithin(PRECISION).of(1.888888);
|
.isWithin(PRECISION).of(1.888888);
|
||||||
assertThat(mStatsRule.getUidBatteryConsumer(workSourceUid2)
|
assertThat(mStatsRule.getUidBatteryConsumer(APP_UID2)
|
||||||
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES))
|
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES))
|
||||||
.isWithin(PRECISION).of(17.0);
|
.isWithin(PRECISION).of(17.0);
|
||||||
assertThat(mStatsRule.getUidBatteryConsumer(Process.SYSTEM_UID)
|
assertThat(mStatsRule.getUidBatteryConsumer(Process.SYSTEM_UID)
|
||||||
@@ -141,58 +125,105 @@ public class SystemServicePowerCalculatorTest {
|
|||||||
.isWithin(PRECISION).of(18.888888);
|
.isWithin(PRECISION).of(18.888888);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MockKernelCpuUidFreqTimeReader extends
|
@Test
|
||||||
KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader {
|
public void testMeasuredEnergyBasedModel() {
|
||||||
private long[] mSystemServerCpuTimes;
|
final boolean[] supportedPowerBuckets =
|
||||||
|
new boolean[MeasuredEnergyStats.NUMBER_STANDARD_POWER_BUCKETS];
|
||||||
|
supportedPowerBuckets[MeasuredEnergyStats.POWER_BUCKET_CPU] = true;
|
||||||
|
mStatsRule.getBatteryStats()
|
||||||
|
.initMeasuredEnergyStatsLocked(supportedPowerBuckets, new String[0]);
|
||||||
|
|
||||||
MockKernelCpuUidFreqTimeReader() {
|
prepareBatteryStats(new long[]{50000000, 100000000});
|
||||||
super(/*throttle */false);
|
|
||||||
|
SystemServicePowerCalculator calculator = new SystemServicePowerCalculator(
|
||||||
|
mStatsRule.getPowerProfile());
|
||||||
|
|
||||||
|
mStatsRule.apply(new CpuPowerCalculator(mStatsRule.getPowerProfile()), calculator);
|
||||||
|
|
||||||
|
assertThat(mStatsRule.getUidBatteryConsumer(APP_UID1)
|
||||||
|
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES))
|
||||||
|
.isWithin(PRECISION).of(1.979351);
|
||||||
|
assertThat(mStatsRule.getUidBatteryConsumer(APP_UID2)
|
||||||
|
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES))
|
||||||
|
.isWithin(PRECISION).of(17.814165);
|
||||||
|
assertThat(mStatsRule.getUidBatteryConsumer(Process.SYSTEM_UID)
|
||||||
|
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_REATTRIBUTED_TO_OTHER_CONSUMERS))
|
||||||
|
.isWithin(PRECISION).of(-19.793517);
|
||||||
|
assertThat(mStatsRule.getDeviceBatteryConsumer()
|
||||||
|
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES))
|
||||||
|
.isWithin(PRECISION).of(19.793517);
|
||||||
|
assertThat(mStatsRule.getAppsBatteryConsumer()
|
||||||
|
.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SYSTEM_SERVICES))
|
||||||
|
.isWithin(PRECISION).of(19.793517);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setSystemServerCpuTimes(long[] systemServerCpuTimes) {
|
private void prepareBatteryStats(long[] clusterChargesUc) {
|
||||||
mSystemServerCpuTimes = systemServerCpuTimes;
|
when(mMockUserInfoProvider.exists(anyInt())).thenReturn(true);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
when(mMockKernelCpuSpeedReaders[0].readDelta()).thenReturn(new long[]{1000, 2000});
|
||||||
public boolean perClusterTimesAvailable() {
|
when(mMockKernelCpuSpeedReaders[1].readDelta()).thenReturn(new long[]{3000, 4000});
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
when(mMockCpuUidFreqTimeReader.perClusterTimesAvailable()).thenReturn(false);
|
||||||
public void readDelta(boolean forcedRead, @Nullable Callback<long[]> cb) {
|
|
||||||
if (cb != null) {
|
|
||||||
cb.onUidCpuTime(Process.SYSTEM_UID, mSystemServerCpuTimes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class MockSystemServerCpuThreadReader extends SystemServerCpuThreadReader {
|
// User/System CPU time in microseconds
|
||||||
private final SystemServiceCpuThreadTimes mThreadTimes = new SystemServiceCpuThreadTimes();
|
doAnswer(invocation -> {
|
||||||
|
final KernelCpuUidTimeReader.Callback<long[]> callback = invocation.getArgument(1);
|
||||||
|
callback.onUidCpuTime(APP_UID1, new long[]{1_000_000, 2_000_000});
|
||||||
|
callback.onUidCpuTime(APP_UID2, new long[]{3_000_000, 4_000_000});
|
||||||
|
callback.onUidCpuTime(Process.SYSTEM_UID, new long[]{60_000_000, 80_000_000});
|
||||||
|
return null;
|
||||||
|
}).when(mMockKernelCpuUidUserSysTimeReader).readDelta(anyBoolean(), any());
|
||||||
|
|
||||||
MockSystemServerCpuThreadReader() {
|
// Active CPU time in milliseconds
|
||||||
super(null);
|
doAnswer(invocation -> {
|
||||||
}
|
final KernelCpuUidTimeReader.Callback<Long> callback = invocation.getArgument(1);
|
||||||
|
callback.onUidCpuTime(APP_UID1, 1111L);
|
||||||
|
callback.onUidCpuTime(APP_UID2, 3333L);
|
||||||
|
callback.onUidCpuTime(Process.SYSTEM_UID, 10000L);
|
||||||
|
return null;
|
||||||
|
}).when(mMockKerneCpuUidActiveTimeReader).readDelta(anyBoolean(), any());
|
||||||
|
|
||||||
public void setCpuTimes(long[] threadCpuTimesUs, long[] binderThreadCpuTimesUs) {
|
// Per-cluster CPU time in milliseconds
|
||||||
mThreadTimes.threadCpuTimesUs = threadCpuTimesUs;
|
doAnswer(invocation -> {
|
||||||
mThreadTimes.binderThreadCpuTimesUs = binderThreadCpuTimesUs;
|
final KernelCpuUidTimeReader.Callback<long[]> callback = invocation.getArgument(1);
|
||||||
}
|
callback.onUidCpuTime(APP_UID1, new long[]{1111, 2222});
|
||||||
|
callback.onUidCpuTime(APP_UID2, new long[]{3333, 4444});
|
||||||
|
callback.onUidCpuTime(Process.SYSTEM_UID, new long[]{50_000, 80_000});
|
||||||
|
return null;
|
||||||
|
}).when(mMockKernelCpuUidClusterTimeReader).readDelta(anyBoolean(), any());
|
||||||
|
|
||||||
@Override
|
// System service CPU time
|
||||||
public SystemServiceCpuThreadTimes readDelta() {
|
final SystemServerCpuThreadReader.SystemServiceCpuThreadTimes threadTimes =
|
||||||
return mThreadTimes;
|
new SystemServerCpuThreadReader.SystemServiceCpuThreadTimes();
|
||||||
}
|
threadTimes.binderThreadCpuTimesUs =
|
||||||
}
|
new long[]{20_000_000, 30_000_000, 40_000_000, 50_000_000};
|
||||||
|
|
||||||
private static class FakeCpuPowerCalculator extends PowerCalculator {
|
when(mMockSystemServerCpuThreadReader.readDelta()).thenReturn(threadTimes);
|
||||||
@Override
|
|
||||||
protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
|
int transactionCode = 42;
|
||||||
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
|
|
||||||
if (u.getUid() == Process.SYSTEM_UID) {
|
Collection<BinderCallsStats.CallStat> callStats = new ArrayList<>();
|
||||||
// SystemServer must be attributed at least as much power as the total
|
BinderCallsStats.CallStat stat1 = new BinderCallsStats.CallStat(APP_UID1,
|
||||||
// of all system services requested by apps.
|
Binder.class, transactionCode, true /*screenInteractive */);
|
||||||
app.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CPU, 1000000);
|
stat1.incrementalCallCount = 100;
|
||||||
}
|
stat1.recordedCallCount = 100;
|
||||||
}
|
stat1.cpuTimeMicros = 1_000_000;
|
||||||
|
callStats.add(stat1);
|
||||||
|
|
||||||
|
mMockBatteryStats.noteBinderCallStats(APP_UID1, 100, callStats);
|
||||||
|
|
||||||
|
callStats.clear();
|
||||||
|
BinderCallsStats.CallStat stat2 = new BinderCallsStats.CallStat(APP_UID2,
|
||||||
|
Binder.class, transactionCode, true /*screenInteractive */);
|
||||||
|
stat2.incrementalCallCount = 100;
|
||||||
|
stat2.recordedCallCount = 100;
|
||||||
|
stat2.cpuTimeMicros = 9_000_000;
|
||||||
|
callStats.add(stat2);
|
||||||
|
|
||||||
|
mMockBatteryStats.noteBinderCallStats(APP_UID2, 100, callStats);
|
||||||
|
|
||||||
|
mMockBatteryStats.updateCpuTimeLocked(true, true, clusterChargesUc);
|
||||||
|
|
||||||
|
mMockBatteryStats.prepareForDumpLocked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user