Merge changes from topic "bscamera3"
* changes: Add per-UID measured camera stats Add measured camera stats to BatteryUsageStats Collect camera power consumption into BatteryStats
This commit is contained in:
@@ -1142,6 +1142,16 @@ public abstract class BatteryStats {
|
||||
@BatteryConsumer.ProcessState int processState);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Returns the battery consumption (in microcoulombs) of UID's camera usage, derived from
|
||||
* on-device power measurement data.
|
||||
* Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getCameraEnergyConsumptionUC();
|
||||
|
||||
/**
|
||||
* Returns the battery consumption (in microcoulombs) used by this uid for each
|
||||
* {@link android.hardware.power.stats.EnergyConsumer.ordinal} of (custom) energy consumer
|
||||
@@ -2920,6 +2930,15 @@ public abstract class BatteryStats {
|
||||
*/
|
||||
public abstract long getWifiEnergyConsumptionUC();
|
||||
|
||||
/**
|
||||
* Returns the battery consumption (in microcoulombs) of camera, derived from on
|
||||
* device power measurement data.
|
||||
* Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable.
|
||||
*
|
||||
* {@hide}
|
||||
*/
|
||||
public abstract long getCameraEnergyConsumptionUC();
|
||||
|
||||
/**
|
||||
* Returns the battery consumption (in microcoulombs) that each
|
||||
* {@link android.hardware.power.stats.EnergyConsumer.ordinal} of (custom) energy consumer
|
||||
|
||||
@@ -58,7 +58,8 @@ public class EnergyConsumerStats {
|
||||
public static final int POWER_BUCKET_BLUETOOTH = 5;
|
||||
public static final int POWER_BUCKET_GNSS = 6;
|
||||
public static final int POWER_BUCKET_MOBILE_RADIO = 7;
|
||||
public static final int NUMBER_STANDARD_POWER_BUCKETS = 8; // Buckets above this are custom.
|
||||
public static final int POWER_BUCKET_CAMERA = 8;
|
||||
public static final int NUMBER_STANDARD_POWER_BUCKETS = 9; // Buckets above this are custom.
|
||||
|
||||
@IntDef(prefix = {"POWER_BUCKET_"}, value = {
|
||||
POWER_BUCKET_UNKNOWN,
|
||||
@@ -70,6 +71,7 @@ public class EnergyConsumerStats {
|
||||
POWER_BUCKET_BLUETOOTH,
|
||||
POWER_BUCKET_GNSS,
|
||||
POWER_BUCKET_MOBILE_RADIO,
|
||||
POWER_BUCKET_CAMERA,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface StandardPowerBucket {
|
||||
|
||||
@@ -170,7 +170,7 @@ java_library_static {
|
||||
"android.hardware.ir-V1-java",
|
||||
"android.hardware.rebootescrow-V1-java",
|
||||
"android.hardware.soundtrigger-V2.3-java",
|
||||
"android.hardware.power.stats-V1-java",
|
||||
"android.hardware.power.stats-V2-java",
|
||||
"android.hardware.power-V4-java",
|
||||
"android.hidl.manager-V1.2-java",
|
||||
"icu4j_calendar_astronomer",
|
||||
|
||||
@@ -710,6 +710,11 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
|
||||
if (gnssChargeUC != EnergyConsumerSnapshot.UNAVAILABLE) {
|
||||
mStats.updateGnssEnergyConsumerStatsLocked(gnssChargeUC, elapsedRealtime);
|
||||
}
|
||||
|
||||
final long cameraChargeUC = energyConsumerDeltas.cameraChargeUC;
|
||||
if (cameraChargeUC != EnergyConsumerSnapshot.UNAVAILABLE) {
|
||||
mStats.updateCameraEnergyConsumerStatsLocked(cameraChargeUC, elapsedRealtime);
|
||||
}
|
||||
}
|
||||
// Inform mStats about each applicable custom energy bucket.
|
||||
if (energyConsumerDeltas != null
|
||||
@@ -904,6 +909,9 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
|
||||
case EnergyConsumerType.WIFI:
|
||||
buckets[EnergyConsumerStats.POWER_BUCKET_WIFI] = true;
|
||||
break;
|
||||
case EnergyConsumerType.CAMERA:
|
||||
buckets[EnergyConsumerStats.POWER_BUCKET_CAMERA] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buckets;
|
||||
@@ -955,6 +963,9 @@ public class BatteryExternalStatsWorker implements BatteryStatsImpl.ExternalStat
|
||||
if ((flags & UPDATE_WIFI) != 0) {
|
||||
addEnergyConsumerIdLocked(energyConsumerIds, EnergyConsumerType.WIFI);
|
||||
}
|
||||
if ((flags & UPDATE_CAMERA) != 0) {
|
||||
addEnergyConsumerIdLocked(energyConsumerIds, EnergyConsumerType.CAMERA);
|
||||
}
|
||||
|
||||
if (energyConsumerIds.size() == 0) {
|
||||
return null;
|
||||
|
||||
@@ -178,7 +178,7 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
// TODO: remove "tcp" from network methods, since we measure total stats.
|
||||
|
||||
// Current on-disk Parcel version. Must be updated when the format of the parcelable changes
|
||||
public static final int VERSION = 210;
|
||||
public static final int VERSION = 211;
|
||||
|
||||
// The maximum number of names wakelocks we will keep track of
|
||||
// per uid; once the limit is reached, we batch the remaining wakelocks
|
||||
@@ -649,10 +649,12 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
int UPDATE_BT = 0x08;
|
||||
int UPDATE_RPM = 0x10;
|
||||
int UPDATE_DISPLAY = 0x20;
|
||||
int RESET = 0x40;
|
||||
int UPDATE_CAMERA = 0x40;
|
||||
int RESET = 0x80;
|
||||
|
||||
int UPDATE_ALL =
|
||||
UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM | UPDATE_DISPLAY;
|
||||
UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM | UPDATE_DISPLAY
|
||||
| UPDATE_CAMERA;
|
||||
|
||||
int UPDATE_ON_PROC_STATE_CHANGE = UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT;
|
||||
|
||||
@@ -665,6 +667,7 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
UPDATE_BT,
|
||||
UPDATE_RPM,
|
||||
UPDATE_DISPLAY,
|
||||
UPDATE_CAMERA,
|
||||
UPDATE_ALL,
|
||||
})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
@@ -6244,6 +6247,8 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
}
|
||||
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
|
||||
.noteCameraTurnedOnLocked(elapsedRealtimeMs);
|
||||
|
||||
scheduleSyncExternalStatsLocked("camera-on", ExternalStatsSync.UPDATE_CAMERA);
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
@@ -6259,6 +6264,8 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
}
|
||||
getUidStatsLocked(uid, elapsedRealtimeMs, uptimeMs)
|
||||
.noteCameraTurnedOffLocked(elapsedRealtimeMs);
|
||||
|
||||
scheduleSyncExternalStatsLocked("camera-off", ExternalStatsSync.UPDATE_CAMERA);
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
@@ -6273,6 +6280,8 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
uid.noteResetCameraLocked(elapsedRealtimeMs);
|
||||
}
|
||||
}
|
||||
|
||||
scheduleSyncExternalStatsLocked("camera-reset", ExternalStatsSync.UPDATE_CAMERA);
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
@@ -7414,6 +7423,12 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_WIFI);
|
||||
}
|
||||
|
||||
@GuardedBy("this")
|
||||
@Override
|
||||
public long getCameraEnergyConsumptionUC() {
|
||||
return getPowerBucketConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the consumption (in microcoulombs) that the given standard power bucket consumed.
|
||||
* Will return {@link #POWER_DATA_UNAVAILABLE} if data is unavailable
|
||||
@@ -8427,6 +8442,12 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
processState);
|
||||
}
|
||||
|
||||
@GuardedBy("mBsi")
|
||||
@Override
|
||||
public long getCameraEnergyConsumptionUC() {
|
||||
return getEnergyConsumptionUC(EnergyConsumerStats.POWER_BUCKET_CAMERA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum of the uid's foreground activity time and its PROCESS_STATE_TOP time
|
||||
* since last marked. Also sets the mark time for both these timers.
|
||||
@@ -8477,6 +8498,20 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
return gnssTimeUs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the uid's time spent using the camera since last marked. Also sets the mark time for
|
||||
* the camera timer.
|
||||
*/
|
||||
private long markCameraTimeUs(long elapsedRealtimeMs) {
|
||||
final StopwatchTimer timer = mCameraTurnedOnTimer;
|
||||
if (timer == null) {
|
||||
return 0;
|
||||
}
|
||||
final long cameraTimeUs = timer.getTimeSinceMarkLocked(elapsedRealtimeMs * 1000);
|
||||
timer.setMark(elapsedRealtimeMs);
|
||||
return cameraTimeUs;
|
||||
}
|
||||
|
||||
public StopwatchTimer createAudioTurnedOnTimerLocked() {
|
||||
if (mAudioTurnedOnTimer == null) {
|
||||
mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClock, Uid.this, AUDIO_TURNED_ON,
|
||||
@@ -12901,6 +12936,53 @@ public class BatteryStatsImpl extends BatteryStats {
|
||||
gnssTimeUsArray, 0, elapsedRealtimeMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulate camera charge consumption and distribute it to the correct state and the apps.
|
||||
*
|
||||
* @param chargeUC amount of charge (microcoulombs) used by the camera since this was last
|
||||
* called.
|
||||
*/
|
||||
@GuardedBy("this")
|
||||
public void updateCameraEnergyConsumerStatsLocked(long chargeUC, long elapsedRealtimeMs) {
|
||||
if (DEBUG_ENERGY) Slog.d(TAG, "Updating camera stats: " + chargeUC);
|
||||
if (mGlobalEnergyConsumerStats == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mOnBatteryInternal || chargeUC <= 0) {
|
||||
// There's nothing further to update.
|
||||
return;
|
||||
}
|
||||
|
||||
if (mIgnoreNextExternalStats) {
|
||||
// Although under ordinary resets we won't get here, and typically a new sync will
|
||||
// happen right after the reset, strictly speaking we need to set all mark times to now.
|
||||
final int uidStatsSize = mUidStats.size();
|
||||
for (int i = 0; i < uidStatsSize; i++) {
|
||||
final Uid uid = mUidStats.valueAt(i);
|
||||
uid.markCameraTimeUs(elapsedRealtimeMs);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
mGlobalEnergyConsumerStats.updateStandardBucket(
|
||||
EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC);
|
||||
|
||||
// Collect the per uid time since mark so that we can normalize power.
|
||||
final SparseDoubleArray cameraTimeUsArray = new SparseDoubleArray();
|
||||
|
||||
// Note: Iterating over all UIDs may be suboptimal.
|
||||
final int uidStatsSize = mUidStats.size();
|
||||
for (int i = 0; i < uidStatsSize; i++) {
|
||||
final Uid uid = mUidStats.valueAt(i);
|
||||
final long cameraTimeUs = uid.markCameraTimeUs(elapsedRealtimeMs);
|
||||
if (cameraTimeUs == 0) continue;
|
||||
cameraTimeUsArray.put(uid.getUid(), (double) cameraTimeUs);
|
||||
}
|
||||
distributeEnergyToUidsLocked(EnergyConsumerStats.POWER_BUCKET_CAMERA, chargeUC,
|
||||
cameraTimeUsArray, 0, elapsedRealtimeMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Accumulate Custom power bucket charge, globally and for each app.
|
||||
*
|
||||
|
||||
@@ -48,27 +48,44 @@ public class CameraPowerCalculator extends PowerCalculator {
|
||||
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
|
||||
super.calculate(builder, batteryStats, rawRealtimeUs, rawUptimeUs, query);
|
||||
|
||||
final long durationMs = batteryStats.getCameraOnTime(rawRealtimeUs,
|
||||
BatteryStats.STATS_SINCE_CHARGED) / 1000;
|
||||
final double powerMah = mPowerEstimator.calculatePower(durationMs);
|
||||
long consumptionUc = batteryStats.getCameraEnergyConsumptionUC();
|
||||
int powerModel = getPowerModel(consumptionUc, query);
|
||||
long durationMs =
|
||||
batteryStats.getCameraOnTime(
|
||||
rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED) / 1000;
|
||||
double powerMah;
|
||||
if (powerModel == BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION) {
|
||||
powerMah = uCtoMah(consumptionUc);
|
||||
} else {
|
||||
powerMah = mPowerEstimator.calculatePower(durationMs);
|
||||
}
|
||||
|
||||
builder.getAggregateBatteryConsumerBuilder(
|
||||
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
|
||||
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
|
||||
.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA, durationMs)
|
||||
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA, powerMah);
|
||||
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA, powerMah, powerModel);
|
||||
builder.getAggregateBatteryConsumerBuilder(
|
||||
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
|
||||
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
|
||||
.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA, durationMs)
|
||||
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA, powerMah);
|
||||
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA, powerMah, powerModel);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
|
||||
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
|
||||
final long durationMs =
|
||||
long consumptionUc = app.getBatteryStatsUid().getCameraEnergyConsumptionUC();
|
||||
int powerModel = getPowerModel(consumptionUc, query);
|
||||
long durationMs =
|
||||
mPowerEstimator.calculateDuration(u.getCameraTurnedOnTimer(), rawRealtimeUs,
|
||||
BatteryStats.STATS_SINCE_CHARGED);
|
||||
final double powerMah = mPowerEstimator.calculatePower(durationMs);
|
||||
double powerMah;
|
||||
if (powerModel == BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION) {
|
||||
powerMah = uCtoMah(consumptionUc);
|
||||
} else {
|
||||
powerMah = mPowerEstimator.calculatePower(durationMs);
|
||||
}
|
||||
|
||||
app.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA, durationMs)
|
||||
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA, powerMah);
|
||||
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA, powerMah, powerModel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,6 +123,9 @@ public class EnergyConsumerSnapshot {
|
||||
/** The chargeUC for {@link EnergyConsumerType#WIFI}. */
|
||||
public long wifiChargeUC = UNAVAILABLE;
|
||||
|
||||
/** The chargeUC for {@link EnergyConsumerType#CAMERA}. */
|
||||
public long cameraChargeUC = UNAVAILABLE;
|
||||
|
||||
/** Map of {@link EnergyConsumerType#OTHER} ordinals to their total chargeUC. */
|
||||
public @Nullable long[] otherTotalChargeUC = null;
|
||||
|
||||
@@ -256,6 +259,10 @@ public class EnergyConsumerSnapshot {
|
||||
output.wifiChargeUC = deltaChargeUC;
|
||||
break;
|
||||
|
||||
case EnergyConsumerType.CAMERA:
|
||||
output.cameraChargeUC = deltaChargeUC;
|
||||
break;
|
||||
|
||||
case EnergyConsumerType.OTHER:
|
||||
if (output.otherTotalChargeUC == null) {
|
||||
output.otherTotalChargeUC = new long[mNumOtherOrdinals];
|
||||
@@ -458,6 +465,9 @@ public class EnergyConsumerSnapshot {
|
||||
case EnergyConsumerType.WIFI:
|
||||
chargeUC[i] = delta.wifiChargeUC;
|
||||
break;
|
||||
case EnergyConsumerType.CAMERA:
|
||||
chargeUC[i] = delta.cameraChargeUC;
|
||||
break;
|
||||
case EnergyConsumerType.OTHER:
|
||||
if (delta.otherTotalChargeUC != null) {
|
||||
chargeUC[i] = delta.otherTotalChargeUC[energyConsumer.ordinal];
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.server.power.stats;
|
||||
|
||||
import static com.android.server.power.stats.BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL;
|
||||
import static com.android.server.power.stats.BatteryStatsImpl.ExternalStatsSync.UPDATE_BT;
|
||||
import static com.android.server.power.stats.BatteryStatsImpl.ExternalStatsSync.UPDATE_CAMERA;
|
||||
import static com.android.server.power.stats.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
|
||||
import static com.android.server.power.stats.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY;
|
||||
import static com.android.server.power.stats.BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO;
|
||||
@@ -104,6 +105,11 @@ public class BatteryExternalStatsWorkerTest {
|
||||
tempAllIds.add(gnssId);
|
||||
mPowerStatsInternal.incrementEnergyConsumption(gnssId, 787878);
|
||||
|
||||
final int cameraId =
|
||||
mPowerStatsInternal.addEnergyConsumer(EnergyConsumerType.CAMERA, 0, "camera");
|
||||
tempAllIds.add(cameraId);
|
||||
mPowerStatsInternal.incrementEnergyConsumption(cameraId, 901234);
|
||||
|
||||
final int mobileRadioId = mPowerStatsInternal.addEnergyConsumer(
|
||||
EnergyConsumerType.MOBILE_RADIO, 0, "mobile_radio");
|
||||
tempAllIds.add(mobileRadioId);
|
||||
@@ -171,6 +177,12 @@ public class BatteryExternalStatsWorkerTest {
|
||||
Arrays.sort(receivedCpuIds);
|
||||
assertArrayEquals(cpuClusterIds, receivedCpuIds);
|
||||
|
||||
final EnergyConsumerResult[] cameraResults =
|
||||
mBatteryExternalStatsWorker.getEnergyConsumersLocked(UPDATE_CAMERA).getNow(null);
|
||||
// Results should only have the camera energy consumer
|
||||
assertEquals(1, cameraResults.length);
|
||||
assertEquals(cameraId, cameraResults[0].id);
|
||||
|
||||
final EnergyConsumerResult[] allResults =
|
||||
mBatteryExternalStatsWorker.getEnergyConsumersLocked(UPDATE_ALL).getNow(null);
|
||||
// All energy consumer results should be available
|
||||
|
||||
@@ -36,41 +36,113 @@ import org.junit.runner.RunWith;
|
||||
public class CameraPowerCalculatorTest {
|
||||
private static final double PRECISION = 0.00001;
|
||||
|
||||
private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
|
||||
private static final int APP1_UID = Process.FIRST_APPLICATION_UID + 42;
|
||||
private static final int APP2_UID = Process.FIRST_APPLICATION_UID + 43;
|
||||
|
||||
@Rule
|
||||
public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
|
||||
.setAveragePower(PowerProfile.POWER_CAMERA, 360.0);
|
||||
.setAveragePower(PowerProfile.POWER_CAMERA, 360.0)
|
||||
.initMeasuredEnergyStatsLocked();
|
||||
|
||||
@Test
|
||||
public void testTimerBasedModel() {
|
||||
BatteryStatsImpl stats = mStatsRule.getBatteryStats();
|
||||
stats.noteCameraOnLocked(APP_UID, 1000, 1000);
|
||||
stats.noteCameraOffLocked(APP_UID, 2000, 2000);
|
||||
synchronized (stats) { // To keep the GuardedBy check happy
|
||||
stats.noteCameraOnLocked(APP1_UID, 1000, 1000);
|
||||
stats.noteCameraOffLocked(APP1_UID, 2000, 2000);
|
||||
stats.noteCameraOnLocked(APP2_UID, 3000, 3000);
|
||||
stats.noteCameraOffLocked(APP2_UID, 5000, 5000);
|
||||
}
|
||||
|
||||
CameraPowerCalculator calculator =
|
||||
new CameraPowerCalculator(mStatsRule.getPowerProfile());
|
||||
|
||||
mStatsRule.apply(BatteryUsageStatsRule.POWER_PROFILE_MODEL_ONLY, calculator);
|
||||
|
||||
UidBatteryConsumer app1Consumer = mStatsRule.getUidBatteryConsumer(APP1_UID);
|
||||
assertThat(app1Consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(1000);
|
||||
assertThat(app1Consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isWithin(PRECISION).of(0.1);
|
||||
assertThat(app1Consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
|
||||
|
||||
UidBatteryConsumer app2Consumer = mStatsRule.getUidBatteryConsumer(APP2_UID);
|
||||
assertThat(app2Consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(2000);
|
||||
assertThat(app2Consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isWithin(PRECISION).of(0.2);
|
||||
assertThat(app2Consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
|
||||
|
||||
final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer();
|
||||
assertThat(deviceBatteryConsumer
|
||||
.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(3000);
|
||||
assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isWithin(PRECISION).of(0.3);
|
||||
assertThat(deviceBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
|
||||
|
||||
final BatteryConsumer appsBatteryConsumer = mStatsRule.getAppsBatteryConsumer();
|
||||
assertThat(appsBatteryConsumer
|
||||
.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(3000);
|
||||
assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isWithin(PRECISION).of(0.3);
|
||||
assertThat(appsBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnergyConsumptionBasedModel() {
|
||||
BatteryStatsImpl stats = mStatsRule.getBatteryStats();
|
||||
synchronized (stats) { // To keep the GuardedBy check happy
|
||||
stats.noteCameraOnLocked(APP1_UID, 1000, 1000);
|
||||
stats.noteCameraOffLocked(APP1_UID, 2000, 2000);
|
||||
stats.updateCameraEnergyConsumerStatsLocked(720_000, 2100); // 0.72C == 0.2mAh
|
||||
stats.noteCameraOnLocked(APP2_UID, 3000, 3000);
|
||||
stats.noteCameraOffLocked(APP2_UID, 5000, 5000);
|
||||
stats.updateCameraEnergyConsumerStatsLocked(1_080_000, 5100); // 0.3mAh
|
||||
}
|
||||
|
||||
CameraPowerCalculator calculator =
|
||||
new CameraPowerCalculator(mStatsRule.getPowerProfile());
|
||||
|
||||
mStatsRule.apply(calculator);
|
||||
|
||||
UidBatteryConsumer consumer = mStatsRule.getUidBatteryConsumer(APP_UID);
|
||||
assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
UidBatteryConsumer app1Consumer = mStatsRule.getUidBatteryConsumer(APP1_UID);
|
||||
assertThat(app1Consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(1000);
|
||||
assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isWithin(PRECISION).of(0.1);
|
||||
assertThat(app1Consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isWithin(PRECISION).of(0.2);
|
||||
assertThat(app1Consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
|
||||
|
||||
UidBatteryConsumer app2Consumer = mStatsRule.getUidBatteryConsumer(APP2_UID);
|
||||
assertThat(app2Consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(2000);
|
||||
assertThat(app2Consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isWithin(PRECISION).of(0.3);
|
||||
assertThat(app2Consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
|
||||
|
||||
final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer();
|
||||
assertThat(deviceBatteryConsumer
|
||||
.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(1000);
|
||||
.isEqualTo(3000);
|
||||
assertThat(deviceBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isWithin(PRECISION).of(0.1);
|
||||
.isWithin(PRECISION).of(0.5);
|
||||
assertThat(deviceBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
|
||||
|
||||
final BatteryConsumer appsBatteryConsumer = mStatsRule.getAppsBatteryConsumer();
|
||||
assertThat(appsBatteryConsumer
|
||||
.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(1000);
|
||||
.isEqualTo(3000);
|
||||
assertThat(appsBatteryConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isWithin(PRECISION).of(0.1);
|
||||
.isWithin(PRECISION).of(0.5);
|
||||
assertThat(appsBatteryConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_CAMERA))
|
||||
.isEqualTo(BatteryConsumer.POWER_MODEL_ENERGY_CONSUMPTION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,6 +248,32 @@ public final class EnergyConsumerSnapshotTest {
|
||||
assertThat(details.toString()).isEqualTo("DISPLAY=2667 HPU=3200000 GPU=0 IPU &_=0");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateAndGetDelta_updatesCameraCharge() {
|
||||
EnergyConsumer cameraConsumer =
|
||||
createEnergyConsumer(7, 0, EnergyConsumerType.CAMERA, "CAMERA");
|
||||
final EnergyConsumerSnapshot snapshot =
|
||||
new EnergyConsumerSnapshot(createIdToConsumerMap(cameraConsumer));
|
||||
|
||||
// An initial result with only one energy consumer
|
||||
EnergyConsumerResult[] result0 = new EnergyConsumerResult[]{
|
||||
createEnergyConsumerResult(cameraConsumer.id, 60_000, null, null),
|
||||
};
|
||||
snapshot.updateAndGetDelta(result0, VOLTAGE_1);
|
||||
|
||||
// A subsequent result
|
||||
EnergyConsumerResult[] result1 = new EnergyConsumerResult[]{
|
||||
createEnergyConsumerResult(cameraConsumer.id, 90_000, null, null),
|
||||
};
|
||||
EnergyConsumerDeltaData delta = snapshot.updateAndGetDelta(result1, VOLTAGE_1);
|
||||
|
||||
// Verify that the delta between the two results is reported.
|
||||
BatteryStats.EnergyConsumerDetails details = snapshot.getEnergyConsumerDetails(delta);
|
||||
assertThat(details.consumers).hasLength(1);
|
||||
long expectedDeltaUC = calculateChargeConsumedUC(60_000, VOLTAGE_1, 90_000, VOLTAGE_1);
|
||||
assertThat(details.chargeUC[0]).isEqualTo(expectedDeltaUC);
|
||||
}
|
||||
|
||||
private static EnergyConsumer createEnergyConsumer(int id, int ord, byte type, String name) {
|
||||
final EnergyConsumer ec = new EnergyConsumer();
|
||||
ec.id = id;
|
||||
|
||||
Reference in New Issue
Block a user