Loading core/java/android/os/AggregateBatteryConsumer.java +43 −0 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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. */ Loading core/java/android/os/BatteryUsageStats.java +137 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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. */ Loading core/java/android/os/PowerComponents.java +122 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading core/java/android/os/UidBatteryConsumer.java +57 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading core/java/android/os/UserBatteryConsumer.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading Loading
core/java/android/os/AggregateBatteryConsumer.java +43 −0 Original line number Diff line number Diff line Loading @@ -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; /** Loading Loading @@ -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. */ Loading
core/java/android/os/BatteryUsageStats.java +137 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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. */ Loading
core/java/android/os/PowerComponents.java +122 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading
core/java/android/os/UidBatteryConsumer.java +57 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading
core/java/android/os/UserBatteryConsumer.java +42 −0 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. */ Loading