Merge "Add Power Model info to the BatteryUsageStats atom"
This commit is contained in:
committed by
Android (Google) Code Review
commit
0575637c2f
@@ -19,6 +19,7 @@ package android.os;
|
||||
import android.annotation.NonNull;
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.TypedXmlSerializer;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
@@ -97,6 +98,19 @@ public final class AggregateBatteryConsumer extends BatteryConsumer {
|
||||
}
|
||||
}
|
||||
|
||||
void writePowerComponentModelProto(@NonNull ProtoOutputStream proto) {
|
||||
for (int i = 0; i < POWER_COMPONENT_COUNT; i++) {
|
||||
final int powerModel = getPowerModel(i);
|
||||
if (powerModel == BatteryConsumer.POWER_MODEL_UNDEFINED) continue;
|
||||
|
||||
final long token = proto.start(BatteryUsageStatsAtomsProto.COMPONENT_MODELS);
|
||||
proto.write(BatteryUsageStatsAtomsProto.PowerComponentModel.COMPONENT, i);
|
||||
proto.write(BatteryUsageStatsAtomsProto.PowerComponentModel.POWER_MODEL,
|
||||
powerModelToProtoEnum(powerModel));
|
||||
proto.end(token);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for DeviceBatteryConsumer.
|
||||
*/
|
||||
|
||||
@@ -478,6 +478,21 @@ public abstract class BatteryConsumer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the equivalent PowerModel enum for the specified power model.
|
||||
* {@see BatteryUsageStatsAtomsProto.BatteryConsumerData.PowerComponentUsage.PowerModel}
|
||||
*/
|
||||
public static int powerModelToProtoEnum(@BatteryConsumer.PowerModel int powerModel) {
|
||||
switch (powerModel) {
|
||||
case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY:
|
||||
return BatteryUsageStatsAtomsProto.PowerComponentModel.MEASURED_ENERGY;
|
||||
case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
|
||||
return BatteryUsageStatsAtomsProto.PowerComponentModel.POWER_PROFILE;
|
||||
default:
|
||||
return BatteryUsageStatsAtomsProto.PowerComponentModel.UNDEFINED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of the specified process state. Intended for logging and debugging.
|
||||
*/
|
||||
|
||||
@@ -276,7 +276,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
|
||||
/**
|
||||
* Returns a battery consumer for the specified battery consumer type.
|
||||
*/
|
||||
public BatteryConsumer getAggregateBatteryConsumer(
|
||||
public AggregateBatteryConsumer getAggregateBatteryConsumer(
|
||||
@AggregateBatteryConsumerScope int scope) {
|
||||
return mAggregateBatteryConsumers[scope];
|
||||
}
|
||||
@@ -450,7 +450,7 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
|
||||
|
||||
@NonNull
|
||||
private void writeStatsProto(ProtoOutputStream proto, int maxRawSize) {
|
||||
final BatteryConsumer deviceBatteryConsumer = getAggregateBatteryConsumer(
|
||||
final AggregateBatteryConsumer deviceBatteryConsumer = getAggregateBatteryConsumer(
|
||||
AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
|
||||
|
||||
proto.write(BatteryUsageStatsAtomsProto.SESSION_START_MILLIS, getStatsStartTimestamp());
|
||||
@@ -462,6 +462,9 @@ public final class BatteryUsageStats implements Parcelable, Closeable {
|
||||
getDischargeDurationMs());
|
||||
deviceBatteryConsumer.writeStatsProto(proto,
|
||||
BatteryUsageStatsAtomsProto.DEVICE_BATTERY_CONSUMER);
|
||||
if (mIncludesPowerModels) {
|
||||
deviceBatteryConsumer.writePowerComponentModelProto(proto);
|
||||
}
|
||||
writeUidBatteryConsumersProto(proto, maxRawSize);
|
||||
}
|
||||
|
||||
|
||||
@@ -102,4 +102,21 @@ message BatteryUsageStatsAtomsProto {
|
||||
|
||||
// Total amount of time battery was discharging during the reported session
|
||||
optional int64 discharge_duration_millis = 7;
|
||||
|
||||
// Notes the power model used for a power component.
|
||||
message PowerComponentModel {
|
||||
// Holds android.os.PowerComponentEnum, or custom component value between 1000 and 9999.
|
||||
optional int32 component = 1;
|
||||
|
||||
enum PowerModel {
|
||||
UNDEFINED = 0;
|
||||
POWER_PROFILE = 1;
|
||||
MEASURED_ENERGY = 2;
|
||||
}
|
||||
|
||||
optional PowerModel power_model = 2;
|
||||
}
|
||||
|
||||
// The power model used for each power component.
|
||||
repeated PowerComponentModel component_models = 8;
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import android.os.AggregateBatteryConsumer;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryUsageStats;
|
||||
import android.os.UidBatteryConsumer;
|
||||
@@ -69,10 +70,17 @@ public class BatteryUsageStatsPulledTest {
|
||||
assertEquals(bus.getDischargeDurationMs(), proto.dischargeDurationMillis);
|
||||
|
||||
assertEquals(3, proto.deviceBatteryConsumer.powerComponents.length); // Only 3 are non-empty
|
||||
|
||||
final AggregateBatteryConsumer abc = bus.getAggregateBatteryConsumer(
|
||||
AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
|
||||
assertSameBatteryConsumer("For deviceBatteryConsumer",
|
||||
bus.getAggregateBatteryConsumer(AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE),
|
||||
proto.deviceBatteryConsumer);
|
||||
|
||||
for (int i = 0; i < BatteryConsumer.POWER_COMPONENT_COUNT; i++) {
|
||||
assertPowerComponentModel(i, abc.getPowerModel(i), proto);
|
||||
}
|
||||
|
||||
// Now for the UidBatteryConsumers.
|
||||
final List<android.os.UidBatteryConsumer> uidConsumers = bus.getUidBatteryConsumers();
|
||||
uidConsumers.sort((a, b) -> a.getUid() - b.getUid());
|
||||
@@ -196,6 +204,34 @@ public class BatteryUsageStatsPulledTest {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the PowerComponentModel object that matches powerComponent.
|
||||
*/
|
||||
private void assertPowerComponentModel(int powerComponent,
|
||||
@BatteryConsumer.PowerModel int powerModel, BatteryUsageStatsAtomsProto proto) {
|
||||
boolean found = false;
|
||||
for (BatteryUsageStatsAtomsProto.PowerComponentModel powerComponentModel :
|
||||
proto.componentModels) {
|
||||
if (powerComponentModel.component == powerComponent) {
|
||||
if (found) {
|
||||
fail("Power component " + BatteryConsumer.powerComponentIdToString(
|
||||
powerComponent) + " found multiple times in the proto");
|
||||
}
|
||||
found = true;
|
||||
final int expectedPowerModel = BatteryConsumer.powerModelToProtoEnum(powerModel);
|
||||
assertEquals(expectedPowerModel, powerComponentModel.powerModel);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
final int model = BatteryConsumer.powerModelToProtoEnum(powerModel);
|
||||
assertEquals(
|
||||
"Power component " + BatteryConsumer.powerComponentIdToString(powerComponent)
|
||||
+ " was not found in the proto but has a defined power model.",
|
||||
BatteryUsageStatsAtomsProto.PowerComponentModel.UNDEFINED,
|
||||
model);
|
||||
}
|
||||
}
|
||||
|
||||
/** Converts charge from milliamp hours (mAh) to decicoulombs (dC). */
|
||||
private long convertMahToDc(double powerMah) {
|
||||
return (long) (powerMah * 36 + 0.5);
|
||||
@@ -259,11 +295,14 @@ public class BatteryUsageStatsPulledTest {
|
||||
builder.getAggregateBatteryConsumerBuilder(AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
|
||||
.setConsumedPower(30000)
|
||||
.setConsumedPower(
|
||||
BatteryConsumer.POWER_COMPONENT_CPU, 20100)
|
||||
BatteryConsumer.POWER_COMPONENT_CPU, 20100,
|
||||
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
|
||||
.setConsumedPower(
|
||||
BatteryConsumer.POWER_COMPONENT_AUDIO, 0) // Empty
|
||||
BatteryConsumer.POWER_COMPONENT_AUDIO, 0,
|
||||
BatteryConsumer.POWER_MODEL_POWER_PROFILE) // Empty
|
||||
.setConsumedPower(
|
||||
BatteryConsumer.POWER_COMPONENT_CAMERA, 20150)
|
||||
BatteryConsumer.POWER_COMPONENT_CAMERA, 20150,
|
||||
BatteryConsumer.POWER_MODEL_MEASURED_ENERGY)
|
||||
.setConsumedPowerForCustomComponent(
|
||||
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20200)
|
||||
.setUsageDurationMillis(
|
||||
@@ -275,7 +314,8 @@ public class BatteryUsageStatsPulledTest {
|
||||
builder.getAggregateBatteryConsumerBuilder(
|
||||
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
|
||||
.setConsumedPower(
|
||||
BatteryConsumer.POWER_COMPONENT_CPU, 10100)
|
||||
BatteryConsumer.POWER_COMPONENT_CPU, 10100,
|
||||
BatteryConsumer.POWER_MODEL_POWER_PROFILE)
|
||||
.setConsumedPowerForCustomComponent(
|
||||
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200);
|
||||
|
||||
@@ -285,7 +325,7 @@ public class BatteryUsageStatsPulledTest {
|
||||
@Test
|
||||
public void testLargeAtomTruncated() {
|
||||
final BatteryUsageStats.Builder builder =
|
||||
new BatteryUsageStats.Builder(new String[0]);
|
||||
new BatteryUsageStats.Builder(new String[0], true, false);
|
||||
// If not truncated, this BatteryUsageStats object would generate a proto buffer
|
||||
// significantly larger than 50 Kb
|
||||
for (int i = 0; i < 3000; i++) {
|
||||
|
||||
@@ -758,6 +758,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
|
||||
.setMaxStatsAgeMs(0)
|
||||
.includeProcessStateData()
|
||||
.includeVirtualUids()
|
||||
.includePowerModels()
|
||||
.build();
|
||||
bus = getBatteryUsageStats(List.of(querySinceReset)).get(0);
|
||||
break;
|
||||
@@ -768,6 +769,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
|
||||
.includeProcessStateData()
|
||||
.includeVirtualUids()
|
||||
.powerProfileModeledOnly()
|
||||
.includePowerModels()
|
||||
.build();
|
||||
bus = getBatteryUsageStats(List.of(queryPowerProfile)).get(0);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user