Convert BatteryUsageStats to and from XML
Bug: 187223764 Test: atest FrameworksCoreTests:BatteryUsageStatsTest#testXml Change-Id: I6aec09bfb87c1003ede1b24cce8cf474675d2448
This commit is contained in:
@@ -17,7 +17,13 @@
|
||||
package android.os;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.TypedXmlSerializer;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
|
||||
/**
|
||||
@@ -72,6 +78,43 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
|
||||
return mConsumedPowerMah;
|
||||
}
|
||||
|
||||
/** Serializes this object to XML */
|
||||
void writeToXml(TypedXmlSerializer serializer,
|
||||
@BatteryUsageStats.AggregateBatteryConsumerScope int scope) throws IOException {
|
||||
serializer.startTag(null, BatteryUsageStats.XML_TAG_AGGREGATE);
|
||||
serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE, scope);
|
||||
serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, mConsumedPowerMah);
|
||||
mPowerComponents.writeToXml(serializer);
|
||||
serializer.endTag(null, BatteryUsageStats.XML_TAG_AGGREGATE);
|
||||
}
|
||||
|
||||
/** Parses an XML representation and populates the BatteryUsageStats builder */
|
||||
static void parseXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)
|
||||
throws XmlPullParserException, IOException {
|
||||
final int scope = parser.getAttributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE);
|
||||
final Builder consumerBuilder = builder.getAggregateBatteryConsumerBuilder(scope);
|
||||
|
||||
int eventType = parser.getEventType();
|
||||
if (eventType != XmlPullParser.START_TAG || !parser.getName().equals(
|
||||
BatteryUsageStats.XML_TAG_AGGREGATE)) {
|
||||
throw new XmlPullParserException("Invalid XML parser state");
|
||||
}
|
||||
|
||||
consumerBuilder.setConsumedPower(
|
||||
parser.getAttributeDouble(null, BatteryUsageStats.XML_ATTR_POWER));
|
||||
|
||||
while (!(eventType == XmlPullParser.END_TAG && parser.getName().equals(
|
||||
BatteryUsageStats.XML_TAG_AGGREGATE))
|
||||
&& eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals(BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) {
|
||||
PowerComponents.parseXml(parser, consumerBuilder.mPowerComponentsBuilder);
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for DeviceBatteryConsumer.
|
||||
*/
|
||||
|
||||
@@ -20,12 +20,18 @@ import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.util.Range;
|
||||
import android.util.SparseArray;
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.TypedXmlSerializer;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.os.BatteryStatsHistory;
|
||||
import com.android.internal.os.BatteryStatsHistoryIterator;
|
||||
import com.android.internal.os.PowerCalculator;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -76,6 +82,34 @@ public final class BatteryUsageStats implements Parcelable {
|
||||
|
||||
public static final int AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT = 2;
|
||||
|
||||
// XML tags and attributes for BatteryUsageStats persistence
|
||||
static final String XML_TAG_BATTERY_USAGE_STATS = "battery_usage_stats";
|
||||
static final String XML_TAG_AGGREGATE = "aggregate";
|
||||
static final String XML_TAG_UID = "uid";
|
||||
static final String XML_TAG_USER = "user";
|
||||
static final String XML_TAG_POWER_COMPONENTS = "power_components";
|
||||
static final String XML_TAG_COMPONENT = "component";
|
||||
static final String XML_TAG_CUSTOM_COMPONENT = "custom_component";
|
||||
static final String XML_ATTR_ID = "id";
|
||||
static final String XML_ATTR_UID = "uid";
|
||||
static final String XML_ATTR_USER_ID = "user_id";
|
||||
static final String XML_ATTR_SCOPE = "scope";
|
||||
static final String XML_ATTR_PREFIX_CUSTOM_COMPONENT = "custom_component_";
|
||||
static final String XML_ATTR_START_TIMESTAMP = "start_timestamp";
|
||||
static final String XML_ATTR_END_TIMESTAMP = "end_timestamp";
|
||||
static final String XML_ATTR_POWER = "power";
|
||||
static final String XML_ATTR_DURATION = "duration";
|
||||
static final String XML_ATTR_MODEL = "model";
|
||||
static final String XML_ATTR_BATTERY_CAPACITY = "battery_capacity";
|
||||
static final String XML_ATTR_DISCHARGE_PERCENT = "discharge_pct";
|
||||
static final String XML_ATTR_DISCHARGE_LOWER = "discharge_lower";
|
||||
static final String XML_ATTR_DISCHARGE_UPPER = "discharge_upper";
|
||||
static final String XML_ATTR_BATTERY_REMAINING = "battery_remaining";
|
||||
static final String XML_ATTR_CHARGE_REMAINING = "charge_remaining";
|
||||
static final String XML_ATTR_HIGHEST_DRAIN_PACKAGE = "highest_drain_package";
|
||||
static final String XML_ATTR_TIME_IN_FOREGROUND = "time_in_foreground";
|
||||
static final String XML_ATTR_TIME_IN_BACKGROUND = "time_in_background";
|
||||
|
||||
private final int mDischargePercentage;
|
||||
private final double mBatteryCapacityMah;
|
||||
private final long mStatsStartTimestampMs;
|
||||
@@ -526,6 +560,109 @@ public final class BatteryUsageStats implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
/** Serializes this object to XML */
|
||||
public void writeXml(TypedXmlSerializer serializer) throws IOException {
|
||||
serializer.startTag(null, XML_TAG_BATTERY_USAGE_STATS);
|
||||
|
||||
for (int i = 0; i < mCustomPowerComponentNames.length; i++) {
|
||||
serializer.attribute(null, XML_ATTR_PREFIX_CUSTOM_COMPONENT + i,
|
||||
mCustomPowerComponentNames[i]);
|
||||
}
|
||||
|
||||
serializer.attributeLong(null, XML_ATTR_START_TIMESTAMP, mStatsStartTimestampMs);
|
||||
serializer.attributeLong(null, XML_ATTR_END_TIMESTAMP, mStatsEndTimestampMs);
|
||||
serializer.attributeLong(null, XML_ATTR_DURATION, mStatsDurationMs);
|
||||
serializer.attributeDouble(null, XML_ATTR_BATTERY_CAPACITY, mBatteryCapacityMah);
|
||||
serializer.attributeInt(null, XML_ATTR_DISCHARGE_PERCENT, mDischargePercentage);
|
||||
serializer.attributeDouble(null, XML_ATTR_DISCHARGE_LOWER, mDischargedPowerLowerBound);
|
||||
serializer.attributeDouble(null, XML_ATTR_DISCHARGE_UPPER, mDischargedPowerUpperBound);
|
||||
serializer.attributeLong(null, XML_ATTR_BATTERY_REMAINING, mBatteryTimeRemainingMs);
|
||||
serializer.attributeLong(null, XML_ATTR_CHARGE_REMAINING, mChargeTimeRemainingMs);
|
||||
|
||||
for (int scope = 0; scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT;
|
||||
scope++) {
|
||||
mAggregateBatteryConsumers[scope].writeToXml(serializer, scope);
|
||||
}
|
||||
for (UidBatteryConsumer consumer : mUidBatteryConsumers) {
|
||||
consumer.writeToXml(serializer);
|
||||
}
|
||||
for (UserBatteryConsumer consumer : mUserBatteryConsumers) {
|
||||
consumer.writeToXml(serializer);
|
||||
}
|
||||
serializer.endTag(null, XML_TAG_BATTERY_USAGE_STATS);
|
||||
}
|
||||
|
||||
/** Parses an XML representation of BatteryUsageStats */
|
||||
public static BatteryUsageStats createFromXml(TypedXmlPullParser parser)
|
||||
throws XmlPullParserException, IOException {
|
||||
Builder builder = null;
|
||||
int eventType = parser.getEventType();
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG
|
||||
&& parser.getName().equals(XML_TAG_BATTERY_USAGE_STATS)) {
|
||||
List<String> customComponentNames = new ArrayList<>();
|
||||
int i = 0;
|
||||
while (true) {
|
||||
int index = parser.getAttributeIndex(null,
|
||||
XML_ATTR_PREFIX_CUSTOM_COMPONENT + i);
|
||||
if (index == -1) {
|
||||
break;
|
||||
}
|
||||
customComponentNames.add(parser.getAttributeValue(index));
|
||||
i++;
|
||||
}
|
||||
|
||||
builder = new Builder(
|
||||
customComponentNames.toArray(new String[0]), true);
|
||||
|
||||
builder.setStatsStartTimestamp(
|
||||
parser.getAttributeLong(null, XML_ATTR_START_TIMESTAMP));
|
||||
builder.setStatsEndTimestamp(
|
||||
parser.getAttributeLong(null, XML_ATTR_END_TIMESTAMP));
|
||||
builder.setStatsDuration(
|
||||
parser.getAttributeLong(null, XML_ATTR_DURATION));
|
||||
builder.setBatteryCapacity(
|
||||
parser.getAttributeDouble(null, XML_ATTR_BATTERY_CAPACITY));
|
||||
builder.setDischargePercentage(
|
||||
parser.getAttributeInt(null, XML_ATTR_DISCHARGE_PERCENT));
|
||||
builder.setDischargedPowerRange(
|
||||
parser.getAttributeDouble(null, XML_ATTR_DISCHARGE_LOWER),
|
||||
parser.getAttributeDouble(null, XML_ATTR_DISCHARGE_UPPER));
|
||||
builder.setBatteryTimeRemainingMs(
|
||||
parser.getAttributeLong(null, XML_ATTR_BATTERY_REMAINING));
|
||||
builder.setChargeTimeRemainingMs(
|
||||
parser.getAttributeLong(null, XML_ATTR_CHARGE_REMAINING));
|
||||
|
||||
eventType = parser.next();
|
||||
break;
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
|
||||
if (builder == null) {
|
||||
throw new XmlPullParserException("No root element");
|
||||
}
|
||||
|
||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
switch (parser.getName()) {
|
||||
case XML_TAG_AGGREGATE:
|
||||
AggregateBatteryConsumer.parseXml(parser, builder);
|
||||
break;
|
||||
case XML_TAG_UID:
|
||||
UidBatteryConsumer.createFromXml(parser, builder);
|
||||
break;
|
||||
case XML_TAG_USER:
|
||||
UserBatteryConsumer.createFromXml(parser, builder);
|
||||
break;
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for BatteryUsageStats.
|
||||
*/
|
||||
|
||||
@@ -19,10 +19,16 @@ import static android.os.BatteryConsumer.convertMahToDeciCoulombs;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.TypedXmlSerializer;
|
||||
import android.util.proto.ProtoOutputStream;
|
||||
|
||||
import com.android.internal.os.PowerCalculator;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -302,6 +308,122 @@ class PowerComponents {
|
||||
return interestingData;
|
||||
}
|
||||
|
||||
void writeToXml(TypedXmlSerializer serializer) throws IOException {
|
||||
serializer.startTag(null, BatteryUsageStats.XML_TAG_POWER_COMPONENTS);
|
||||
for (int componentId = 0; componentId < BatteryConsumer.POWER_COMPONENT_COUNT;
|
||||
componentId++) {
|
||||
final double powerMah = getConsumedPower(componentId);
|
||||
final long durationMs = getUsageDurationMillis(componentId);
|
||||
if (powerMah == 0 && durationMs == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
serializer.startTag(null, BatteryUsageStats.XML_TAG_COMPONENT);
|
||||
serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_ID, componentId);
|
||||
if (powerMah != 0) {
|
||||
serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, powerMah);
|
||||
}
|
||||
if (durationMs != 0) {
|
||||
serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_DURATION, durationMs);
|
||||
}
|
||||
if (mPowerModels != null) {
|
||||
serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_MODEL,
|
||||
mPowerModels[componentId]);
|
||||
}
|
||||
serializer.endTag(null, BatteryUsageStats.XML_TAG_COMPONENT);
|
||||
}
|
||||
|
||||
final int customComponentEnd =
|
||||
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + mCustomPowerComponentCount;
|
||||
for (int componentId = BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID;
|
||||
componentId < customComponentEnd;
|
||||
componentId++) {
|
||||
final double powerMah = getConsumedPowerForCustomComponent(componentId);
|
||||
final long durationMs = getUsageDurationForCustomComponentMillis(componentId);
|
||||
if (powerMah == 0 && durationMs == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
serializer.startTag(null, BatteryUsageStats.XML_TAG_CUSTOM_COMPONENT);
|
||||
serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_ID, componentId);
|
||||
if (powerMah != 0) {
|
||||
serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, powerMah);
|
||||
}
|
||||
if (durationMs != 0) {
|
||||
serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_DURATION, durationMs);
|
||||
}
|
||||
serializer.endTag(null, BatteryUsageStats.XML_TAG_CUSTOM_COMPONENT);
|
||||
}
|
||||
|
||||
serializer.endTag(null, BatteryUsageStats.XML_TAG_POWER_COMPONENTS);
|
||||
}
|
||||
|
||||
|
||||
static void parseXml(TypedXmlPullParser parser, PowerComponents.Builder builder)
|
||||
throws XmlPullParserException, IOException {
|
||||
int eventType = parser.getEventType();
|
||||
if (eventType != XmlPullParser.START_TAG || !parser.getName().equals(
|
||||
BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) {
|
||||
throw new XmlPullParserException("Invalid XML parser state");
|
||||
}
|
||||
|
||||
while (!(eventType == XmlPullParser.END_TAG && parser.getName().equals(
|
||||
BatteryUsageStats.XML_TAG_POWER_COMPONENTS))
|
||||
&& eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
switch (parser.getName()) {
|
||||
case BatteryUsageStats.XML_TAG_COMPONENT: {
|
||||
int componentId = -1;
|
||||
double powerMah = 0;
|
||||
long durationMs = 0;
|
||||
int model = BatteryConsumer.POWER_MODEL_UNDEFINED;
|
||||
for (int i = 0; i < parser.getAttributeCount(); i++) {
|
||||
switch (parser.getAttributeName(i)) {
|
||||
case BatteryUsageStats.XML_ATTR_ID:
|
||||
componentId = parser.getAttributeInt(i);
|
||||
break;
|
||||
case BatteryUsageStats.XML_ATTR_POWER:
|
||||
powerMah = parser.getAttributeDouble(i);
|
||||
break;
|
||||
case BatteryUsageStats.XML_ATTR_DURATION:
|
||||
durationMs = parser.getAttributeLong(i);
|
||||
break;
|
||||
case BatteryUsageStats.XML_ATTR_MODEL:
|
||||
model = parser.getAttributeInt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
builder.setConsumedPower(componentId, powerMah, model);
|
||||
builder.setUsageDurationMillis(componentId, durationMs);
|
||||
break;
|
||||
}
|
||||
case BatteryUsageStats.XML_TAG_CUSTOM_COMPONENT: {
|
||||
int componentId = -1;
|
||||
double powerMah = 0;
|
||||
long durationMs = 0;
|
||||
for (int i = 0; i < parser.getAttributeCount(); i++) {
|
||||
switch (parser.getAttributeName(i)) {
|
||||
case BatteryUsageStats.XML_ATTR_ID:
|
||||
componentId = parser.getAttributeInt(i);
|
||||
break;
|
||||
case BatteryUsageStats.XML_ATTR_POWER:
|
||||
powerMah = parser.getAttributeDouble(i);
|
||||
break;
|
||||
case BatteryUsageStats.XML_ATTR_DURATION:
|
||||
durationMs = parser.getAttributeLong(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
builder.setConsumedPowerForCustomComponent(componentId, powerMah);
|
||||
builder.setUsageDurationForCustomComponentMillis(componentId, durationMs);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for PowerComponents.
|
||||
*/
|
||||
|
||||
@@ -20,9 +20,15 @@ import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.TypedXmlSerializer;
|
||||
|
||||
import com.android.internal.os.PowerCalculator;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -144,6 +150,57 @@ public final class UidBatteryConsumer extends BatteryConsumer implements Parcela
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Serializes this object to XML */
|
||||
void writeToXml(TypedXmlSerializer serializer) throws IOException {
|
||||
if (getConsumedPower() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
serializer.startTag(null, BatteryUsageStats.XML_TAG_UID);
|
||||
serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_UID, getUid());
|
||||
if (!TextUtils.isEmpty(mPackageWithHighestDrain)) {
|
||||
serializer.attribute(null, BatteryUsageStats.XML_ATTR_HIGHEST_DRAIN_PACKAGE,
|
||||
mPackageWithHighestDrain);
|
||||
}
|
||||
serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND,
|
||||
mTimeInForegroundMs);
|
||||
serializer.attributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_BACKGROUND,
|
||||
mTimeInBackgroundMs);
|
||||
mPowerComponents.writeToXml(serializer);
|
||||
serializer.endTag(null, BatteryUsageStats.XML_TAG_UID);
|
||||
}
|
||||
|
||||
/** Parses an XML representation and populates the BatteryUsageStats builder */
|
||||
static void createFromXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)
|
||||
throws XmlPullParserException, IOException {
|
||||
final int uid = parser.getAttributeInt(null, BatteryUsageStats.XML_ATTR_UID);
|
||||
final UidBatteryConsumer.Builder consumerBuilder =
|
||||
builder.getOrCreateUidBatteryConsumerBuilder(uid);
|
||||
|
||||
int eventType = parser.getEventType();
|
||||
if (eventType != XmlPullParser.START_TAG
|
||||
|| !parser.getName().equals(BatteryUsageStats.XML_TAG_UID)) {
|
||||
throw new XmlPullParserException("Invalid XML parser state");
|
||||
}
|
||||
|
||||
consumerBuilder.setPackageWithHighestDrain(
|
||||
parser.getAttributeValue(null, BatteryUsageStats.XML_ATTR_HIGHEST_DRAIN_PACKAGE));
|
||||
consumerBuilder.setTimeInStateMs(STATE_FOREGROUND,
|
||||
parser.getAttributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_FOREGROUND));
|
||||
consumerBuilder.setTimeInStateMs(STATE_BACKGROUND,
|
||||
parser.getAttributeLong(null, BatteryUsageStats.XML_ATTR_TIME_IN_BACKGROUND));
|
||||
while (!(eventType == XmlPullParser.END_TAG
|
||||
&& parser.getName().equals(BatteryUsageStats.XML_TAG_UID))
|
||||
&& eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals(BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) {
|
||||
PowerComponents.parseXml(parser, consumerBuilder.mPowerComponentsBuilder);
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for UidBatteryConsumer.
|
||||
*/
|
||||
|
||||
@@ -17,9 +17,15 @@
|
||||
package android.os;
|
||||
|
||||
import android.annotation.NonNull;
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.TypedXmlSerializer;
|
||||
|
||||
import com.android.internal.os.PowerCalculator;
|
||||
|
||||
import org.xmlpull.v1.XmlPullParser;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -85,6 +91,42 @@ public class UserBatteryConsumer extends BatteryConsumer implements Parcelable {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Serializes this object to XML */
|
||||
void writeToXml(TypedXmlSerializer serializer) throws IOException {
|
||||
if (getConsumedPower() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
serializer.startTag(null, BatteryUsageStats.XML_TAG_USER);
|
||||
serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_USER_ID, getUserId());
|
||||
mPowerComponents.writeToXml(serializer);
|
||||
serializer.endTag(null, BatteryUsageStats.XML_TAG_USER);
|
||||
}
|
||||
|
||||
/** Parses an XML representation and populates the BatteryUsageStats builder */
|
||||
static void createFromXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)
|
||||
throws XmlPullParserException, IOException {
|
||||
final int userId = parser.getAttributeInt(null, BatteryUsageStats.XML_ATTR_USER_ID);
|
||||
final UserBatteryConsumer.Builder consumerBuilder =
|
||||
builder.getOrCreateUserBatteryConsumerBuilder(userId);
|
||||
|
||||
int eventType = parser.getEventType();
|
||||
if (eventType != XmlPullParser.START_TAG
|
||||
|| !parser.getName().equals(BatteryUsageStats.XML_TAG_USER)) {
|
||||
throw new XmlPullParserException("Invalid XML parser state");
|
||||
}
|
||||
while (!(eventType == XmlPullParser.END_TAG
|
||||
&& parser.getName().equals(BatteryUsageStats.XML_TAG_USER))
|
||||
&& eventType != XmlPullParser.END_DOCUMENT) {
|
||||
if (eventType == XmlPullParser.START_TAG) {
|
||||
if (parser.getName().equals(BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) {
|
||||
PowerComponents.parseXml(parser, consumerBuilder.mPowerComponentsBuilder);
|
||||
}
|
||||
}
|
||||
eventType = parser.next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for UserBatteryConsumer.
|
||||
*/
|
||||
|
||||
@@ -30,6 +30,9 @@ import android.os.BatteryUsageStats;
|
||||
import android.os.Parcel;
|
||||
import android.os.UidBatteryConsumer;
|
||||
import android.os.UserBatteryConsumer;
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.TypedXmlSerializer;
|
||||
import android.util.Xml;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
@@ -37,8 +40,11 @@ import androidx.test.runner.AndroidJUnit4;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@@ -157,6 +163,24 @@ public class BatteryUsageStatsTest {
|
||||
assertThrows(IllegalArgumentException.class, () -> builder.add(stats));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXml() throws Exception {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
TypedXmlSerializer serializer = Xml.newBinarySerializer();
|
||||
serializer.setOutput(out, StandardCharsets.UTF_8.name());
|
||||
serializer.startDocument(null, true);
|
||||
final BatteryUsageStats stats = buildBatteryUsageStats1(true).build();
|
||||
stats.writeXml(serializer);
|
||||
serializer.endDocument();
|
||||
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
|
||||
TypedXmlPullParser parser = Xml.newBinaryPullParser();
|
||||
parser.setInput(in, StandardCharsets.UTF_8.name());
|
||||
final BatteryUsageStats fromXml = BatteryUsageStats.createFromXml(parser);
|
||||
|
||||
assertBatteryUsageStats1(fromXml, true);
|
||||
}
|
||||
|
||||
private BatteryUsageStats.Builder buildBatteryUsageStats1(boolean includeUserBatteryConsumer) {
|
||||
final MockClocks clocks = new MockClocks();
|
||||
final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
|
||||
|
||||
Reference in New Issue
Block a user