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 implements Parcelable {
35 
36     private final double mConsumedPowerMah;
37 
AggregateBatteryConsumer(@onNull Builder builder)38     public AggregateBatteryConsumer(@NonNull Builder builder) {
39         super(builder.mPowerComponentsBuilder.build());
40         mConsumedPowerMah = builder.mConsumedPowerMah;
41     }
42 
AggregateBatteryConsumer(@onNull Parcel source)43     private AggregateBatteryConsumer(@NonNull Parcel source) {
44         super(new PowerComponents(source));
45         mConsumedPowerMah = source.readDouble();
46     }
47 
48     @Override
dump(PrintWriter pw, boolean skipEmptyComponents)49     public void dump(PrintWriter pw, boolean skipEmptyComponents) {
50         mPowerComponents.dump(pw, skipEmptyComponents);
51     }
52 
53     @Override
writeToParcel(@onNull Parcel dest, int flags)54     public void writeToParcel(@NonNull Parcel dest, int flags) {
55         super.writeToParcel(dest, flags);
56         dest.writeDouble(mConsumedPowerMah);
57     }
58 
59     @Override
describeContents()60     public int describeContents() {
61         return 0;
62     }
63 
64     @NonNull
65     public static final Creator<AggregateBatteryConsumer> CREATOR =
66             new Creator<AggregateBatteryConsumer>() {
67                 public AggregateBatteryConsumer createFromParcel(@NonNull Parcel source) {
68                     return new AggregateBatteryConsumer(source);
69                 }
70 
71                 public AggregateBatteryConsumer[] newArray(int size) {
72                     return new AggregateBatteryConsumer[size];
73                 }
74             };
75 
76     @Override
getConsumedPower()77     public double getConsumedPower() {
78         return mConsumedPowerMah;
79     }
80 
81     /** Serializes this object to XML */
writeToXml(TypedXmlSerializer serializer, @BatteryUsageStats.AggregateBatteryConsumerScope int scope)82     void writeToXml(TypedXmlSerializer serializer,
83             @BatteryUsageStats.AggregateBatteryConsumerScope int scope) throws IOException {
84         serializer.startTag(null, BatteryUsageStats.XML_TAG_AGGREGATE);
85         serializer.attributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE, scope);
86         serializer.attributeDouble(null, BatteryUsageStats.XML_ATTR_POWER, mConsumedPowerMah);
87         mPowerComponents.writeToXml(serializer);
88         serializer.endTag(null, BatteryUsageStats.XML_TAG_AGGREGATE);
89     }
90 
91     /** Parses an XML representation and populates the BatteryUsageStats builder */
parseXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)92     static void parseXml(TypedXmlPullParser parser, BatteryUsageStats.Builder builder)
93             throws XmlPullParserException, IOException {
94         final int scope = parser.getAttributeInt(null, BatteryUsageStats.XML_ATTR_SCOPE);
95         final Builder consumerBuilder = builder.getAggregateBatteryConsumerBuilder(scope);
96 
97         int eventType = parser.getEventType();
98         if (eventType != XmlPullParser.START_TAG || !parser.getName().equals(
99                 BatteryUsageStats.XML_TAG_AGGREGATE)) {
100             throw new XmlPullParserException("Invalid XML parser state");
101         }
102 
103         consumerBuilder.setConsumedPower(
104                 parser.getAttributeDouble(null, BatteryUsageStats.XML_ATTR_POWER));
105 
106         while (!(eventType == XmlPullParser.END_TAG && parser.getName().equals(
107                 BatteryUsageStats.XML_TAG_AGGREGATE))
108                 && eventType != XmlPullParser.END_DOCUMENT) {
109             if (eventType == XmlPullParser.START_TAG) {
110                 if (parser.getName().equals(BatteryUsageStats.XML_TAG_POWER_COMPONENTS)) {
111                     PowerComponents.parseXml(parser, consumerBuilder.mPowerComponentsBuilder);
112                 }
113             }
114             eventType = parser.next();
115         }
116     }
117 
118     /**
119      * Builder for DeviceBatteryConsumer.
120      */
121     public static final class Builder extends BaseBuilder<AggregateBatteryConsumer.Builder> {
122         private double mConsumedPowerMah;
123 
Builder(@onNull String[] customPowerComponentNames, boolean includePowerModels)124         public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels) {
125             super(customPowerComponentNames, includePowerModels);
126         }
127 
128         /**
129          * Sets the total power included in this aggregate.
130          */
setConsumedPower(double consumedPowerMah)131         public Builder setConsumedPower(double consumedPowerMah) {
132             mConsumedPowerMah = consumedPowerMah;
133             return this;
134         }
135 
136         /**
137          * Adds power and usage duration from the supplied AggregateBatteryConsumer.
138          */
add(AggregateBatteryConsumer aggregateBatteryConsumer)139         public void add(AggregateBatteryConsumer aggregateBatteryConsumer) {
140             mConsumedPowerMah += aggregateBatteryConsumer.mConsumedPowerMah;
141             mPowerComponentsBuilder.addPowerAndDuration(aggregateBatteryConsumer.mPowerComponents);
142         }
143 
144         /**
145          * Creates a read-only object out of the Builder values.
146          */
147         @NonNull
build()148         public AggregateBatteryConsumer build() {
149             return new AggregateBatteryConsumer(this);
150         }
151     }
152 }
153