1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.os; 18 19 import android.annotation.NonNull; 20 import android.util.TypedXmlPullParser; 21 import android.util.TypedXmlSerializer; 22 23 import org.xmlpull.v1.XmlPullParser; 24 import org.xmlpull.v1.XmlPullParserException; 25 26 import java.io.IOException; 27 import java.io.PrintWriter; 28 29 /** 30 * Contains power consumption data across the entire device. 31 * 32 * {@hide} 33 */ 34 public final class AggregateBatteryConsumer extends BatteryConsumer { 35 static final int CONSUMER_TYPE_AGGREGATE = 0; 36 37 static final int COLUMN_INDEX_SCOPE = BatteryConsumer.COLUMN_COUNT; 38 static final int COLUMN_INDEX_CONSUMED_POWER = COLUMN_INDEX_SCOPE + 1; 39 static final int COLUMN_COUNT = BatteryConsumer.COLUMN_COUNT + 2; 40 AggregateBatteryConsumer(BatteryConsumerData data)41 AggregateBatteryConsumer(BatteryConsumerData data) { 42 super(data); 43 } 44 AggregateBatteryConsumer(@onNull Builder builder)45 private AggregateBatteryConsumer(@NonNull Builder builder) { 46 super(builder.mData, builder.mPowerComponentsBuilder.build()); 47 } 48 getScope()49 int getScope() { 50 return mData.getInt(COLUMN_INDEX_SCOPE); 51 } 52 53 @Override dump(PrintWriter pw, boolean skipEmptyComponents)54 public void dump(PrintWriter pw, boolean skipEmptyComponents) { 55 mPowerComponents.dump(pw, skipEmptyComponents); 56 } 57 58 @Override getConsumedPower()59 public double getConsumedPower() { 60 return mData.getDouble(COLUMN_INDEX_CONSUMED_POWER); 61 } 62 63 /** Serializes this object to XML */ writeToXml(TypedXmlSerializer serializer, @BatteryUsageStats.AggregateBatteryConsumerScope int scope)64 void writeToXml(TypedXmlSerializer serializer, 65 @BatteryUsageStats.AggregateBatteryConsumerScope int scope) throws IOException { 66 serializer.startTag(null, BatteryUsageStats.XML_TAG_AGGREGATE); 67 serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE, scope); 68 serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, getConsumedPower()); 69 mPowerComponents.writeToXml(serializer); 70 serializer.endTag(null, BatteryUsageStats.XML_TAG_AGGREGATE); 71 } 72 73 /** Parses an XML representation and populates the BatteryUsageStats builder */ parseXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)74 static void parseXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder) 75 throws XmlPullParserException, IOException { 76 final int scope = parser.getAttributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE); 77 final Builder consumerBuilder = builder.getAggregateBatteryConsumerBuilder(scope); 78 79 int eventType = parser.getEventType(); 80 if (eventType != XmlPullParser.START_TAG || !parser.getName().equals( 81 BatteryUsageStats.XML_TAG_AGGREGATE)) { 82 throw new XmlPullParserException("Invalid XML parser state"); 83 } 84 85 consumerBuilder.setConsumedPower( 86 parser.getAttributeDouble(null, BatteryUsageStats.XML_ATTR_POWER)); 87 88 while (!(eventType == XmlPullParser.END_TAG && parser.getName().equals( 89 BatteryUsageStats.XML_TAG_AGGREGATE)) 90 && eventType != XmlPullParser.END_DOCUMENT) { 91 if (eventType == XmlPullParser.START_TAG) { 92 if (parser.getName().equals(BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) { 93 PowerComponents.parseXml(parser, consumerBuilder.mPowerComponentsBuilder); 94 } 95 } 96 eventType = parser.next(); 97 } 98 } 99 100 /** 101 * Builder for DeviceBatteryConsumer. 102 */ 103 public static final class Builder extends BaseBuilder<AggregateBatteryConsumer.Builder> { Builder(BatteryConsumer.BatteryConsumerData data, int scope)104 public Builder(BatteryConsumer.BatteryConsumerData data, int scope) { 105 super(data, CONSUMER_TYPE_AGGREGATE); 106 data.putInt(COLUMN_INDEX_SCOPE, scope); 107 } 108 109 /** 110 * Sets the total power included in this aggregate. 111 */ setConsumedPower(double consumedPowerMah)112 public Builder setConsumedPower(double consumedPowerMah) { 113 mData.putDouble(COLUMN_INDEX_CONSUMED_POWER, consumedPowerMah); 114 return this; 115 } 116 117 /** 118 * Adds power and usage duration from the supplied AggregateBatteryConsumer. 119 */ add(AggregateBatteryConsumer aggregateBatteryConsumer)120 public void add(AggregateBatteryConsumer aggregateBatteryConsumer) { 121 setConsumedPower(mData.getDouble(COLUMN_INDEX_CONSUMED_POWER) 122 + aggregateBatteryConsumer.getConsumedPower()); 123 mPowerComponentsBuilder.addPowerAndDuration(aggregateBatteryConsumer.mPowerComponents); 124 } 125 126 /** 127 * Creates a read-only object out of the Builder values. 128 */ 129 @NonNull build()130 public AggregateBatteryConsumer build() { 131 return new AggregateBatteryConsumer(this); 132 } 133 } 134 } 135