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 21 import com.android.modules.utils.TypedXmlPullParser; 22 import com.android.modules.utils.TypedXmlSerializer; 23 24 import org.xmlpull.v1.XmlPullParser; 25 import org.xmlpull.v1.XmlPullParserException; 26 27 import java.io.IOException; 28 import java.io.PrintWriter; 29 30 /** 31 * Contains power consumption data across the entire device. 32 * 33 * {@hide} 34 */ 35 @android.ravenwood.annotation.RavenwoodKeepWholeClass 36 public final class AggregateBatteryConsumer extends BatteryConsumer { 37 static final int CONSUMER_TYPE_AGGREGATE = 0; 38 39 static final int COLUMN_INDEX_SCOPE = BatteryConsumer.COLUMN_COUNT; 40 static final int COLUMN_INDEX_CONSUMED_POWER = COLUMN_INDEX_SCOPE + 1; 41 static final int COLUMN_COUNT = BatteryConsumer.COLUMN_COUNT + 2; 42 AggregateBatteryConsumer(BatteryConsumerData data)43 AggregateBatteryConsumer(BatteryConsumerData data) { 44 super(data); 45 } 46 AggregateBatteryConsumer(@onNull Builder builder)47 private AggregateBatteryConsumer(@NonNull Builder builder) { 48 super(builder.mData, builder.mPowerComponentsBuilder.build()); 49 } 50 getScope()51 int getScope() { 52 return mData.getInt(COLUMN_INDEX_SCOPE); 53 } 54 55 @Override dump(PrintWriter pw, boolean skipEmptyComponents)56 public void dump(PrintWriter pw, boolean skipEmptyComponents) { 57 mPowerComponents.dump(pw, SCREEN_STATE_ANY, POWER_STATE_ANY, skipEmptyComponents); 58 } 59 60 @Override getConsumedPower()61 public double getConsumedPower() { 62 return mData.getDouble(COLUMN_INDEX_CONSUMED_POWER); 63 } 64 65 /** Serializes this object to XML */ writeToXml(TypedXmlSerializer serializer, @BatteryUsageStats.AggregateBatteryConsumerScope int scope)66 void writeToXml(TypedXmlSerializer serializer, 67 @BatteryUsageStats.AggregateBatteryConsumerScope int scope) throws IOException { 68 serializer.startTag(null, BatteryUsageStats.XML_TAG_AGGREGATE); 69 serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE, scope); 70 serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, getConsumedPower()); 71 mPowerComponents.writeToXml(serializer); 72 serializer.endTag(null, BatteryUsageStats.XML_TAG_AGGREGATE); 73 } 74 75 /** Parses an XML representation and populates the BatteryUsageStats builder */ parseXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)76 static void parseXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder) 77 throws XmlPullParserException, IOException { 78 final int scope = parser.getAttributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE); 79 final Builder consumerBuilder = builder.getAggregateBatteryConsumerBuilder(scope); 80 81 int eventType = parser.getEventType(); 82 if (eventType != XmlPullParser.START_TAG || !parser.getName().equals( 83 BatteryUsageStats.XML_TAG_AGGREGATE)) { 84 throw new XmlPullParserException("Invalid XML parser state"); 85 } 86 87 consumerBuilder.addConsumedPower( 88 parser.getAttributeDouble(null, BatteryUsageStats.XML_ATTR_POWER)); 89 90 while (!(eventType == XmlPullParser.END_TAG && parser.getName().equals( 91 BatteryUsageStats.XML_TAG_AGGREGATE)) 92 && eventType != XmlPullParser.END_DOCUMENT) { 93 if (eventType == XmlPullParser.START_TAG) { 94 if (parser.getName().equals(BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) { 95 PowerComponents.parseXml(parser, consumerBuilder.mPowerComponentsBuilder); 96 } 97 } 98 eventType = parser.next(); 99 } 100 } 101 102 /** 103 * Builder for DeviceBatteryConsumer. 104 */ 105 public static final class Builder extends BaseBuilder<AggregateBatteryConsumer.Builder> { Builder(BatteryConsumer.BatteryConsumerData data, int scope, double minConsumedPowerThreshold)106 public Builder(BatteryConsumer.BatteryConsumerData data, int scope, 107 double minConsumedPowerThreshold) { 108 super(data, CONSUMER_TYPE_AGGREGATE, minConsumedPowerThreshold); 109 data.putInt(COLUMN_INDEX_SCOPE, scope); 110 } 111 112 /** 113 * Sets the total power included in this aggregate. 114 */ setConsumedPower(double consumedPowerMah)115 public Builder setConsumedPower(double consumedPowerMah) { 116 mData.putDouble(COLUMN_INDEX_CONSUMED_POWER, consumedPowerMah); 117 return this; 118 } 119 120 /** 121 * Adds the total power included in this aggregate. 122 */ addConsumedPower(double consumedPowerMah)123 public Builder addConsumedPower(double consumedPowerMah) { 124 mData.putDouble(COLUMN_INDEX_CONSUMED_POWER, 125 mData.getDouble(COLUMN_INDEX_CONSUMED_POWER) + consumedPowerMah); 126 return this; 127 } 128 129 /** 130 * Adds power and usage duration from the supplied AggregateBatteryConsumer. 131 */ add(AggregateBatteryConsumer aggregateBatteryConsumer)132 public void add(AggregateBatteryConsumer aggregateBatteryConsumer) { 133 addConsumedPower(aggregateBatteryConsumer.getConsumedPower()); 134 mPowerComponentsBuilder.addPowerAndDuration(aggregateBatteryConsumer.mPowerComponents); 135 } 136 137 /** 138 * Creates a read-only object out of the Builder values. 139 */ 140 @NonNull build()141 public AggregateBatteryConsumer build() { 142 return new AggregateBatteryConsumer(this); 143 } 144 } 145 } 146