• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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 package com.android.internal.os;
17 
18 import android.annotation.NonNull;
19 import android.os.BatteryConsumer;
20 import android.os.BatteryStats;
21 import android.os.BatteryUsageStats;
22 import android.os.BatteryUsageStatsQuery;
23 import android.os.UidBatteryConsumer;
24 import android.os.UserHandle;
25 import android.util.SparseArray;
26 
27 import java.io.PrintWriter;
28 import java.util.List;
29 import java.util.Locale;
30 
31 /**
32  * Calculates power use of a device subsystem for an app.
33  */
34 public abstract class PowerCalculator {
35 
36     protected static final double MILLIAMPHOUR_PER_MICROCOULOMB = 1.0 / 1000.0 / 60.0 / 60.0;
37 
38     /**
39      * Attributes the total amount of power used by this subsystem to various consumers such
40      * as apps.
41      *
42      * @param sippers       A list of battery sippers that contains battery attribution data.
43      *                      The calculator may modify the list.
44      * @param batteryStats  The recorded battery stats.
45      * @param rawRealtimeUs The raw system realtime in microseconds.
46      * @param rawUptimeUs   The raw system uptime in microseconds.
47      * @param statsType     The type of stats. As of {@link android.os.Build.VERSION_CODES#Q}, this
48      *                      can only be {@link BatteryStats#STATS_SINCE_CHARGED}, since
49      *                      {@link BatteryStats#STATS_CURRENT} and
50      *                      {@link BatteryStats#STATS_SINCE_UNPLUGGED} are deprecated.
51      * @param asUsers       An array of users for which the attribution is requested.  It may
52      *                      contain {@link UserHandle#USER_ALL} to indicate that the attribution
53      *                      should be performed for all users.
54      */
calculate(List<BatterySipper> sippers, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers)55     public void calculate(List<BatterySipper> sippers, BatteryStats batteryStats,
56             long rawRealtimeUs, long rawUptimeUs, int statsType, SparseArray<UserHandle> asUsers) {
57         for (int i = sippers.size() - 1; i >= 0; i--) {
58             final BatterySipper app = sippers.get(i);
59             if (app.drainType == BatterySipper.DrainType.APP) {
60                 calculateApp(app, app.uidObj, rawRealtimeUs, rawUptimeUs, statsType);
61             }
62         }
63     }
64 
65     /**
66      * Attributes the total amount of power used by this subsystem to various consumers such
67      * as apps.
68      *
69      * @param builder       {@link BatteryUsageStats.Builder that contains a list of
70      *                      per-UID battery consumer builders for attribution data.
71      *                      The calculator may modify the builder and its constituent parts.
72      * @param batteryStats  The recorded battery stats.
73      * @param rawRealtimeUs The raw system realtime in microseconds.
74      * @param rawUptimeUs   The raw system uptime in microseconds.
75      * @param query         The query parameters for the calculator.
76      */
calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query)77     public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
78             long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
79         final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders =
80                 builder.getUidBatteryConsumerBuilders();
81         for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
82             final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
83             calculateApp(app, app.getBatteryStatsUid(), rawRealtimeUs, rawUptimeUs, query);
84         }
85     }
86 
87     /**
88      * Calculate the amount of power an app used for this subsystem.
89      * @param app The BatterySipper that represents the power use of an app.
90      * @param u The recorded stats for the app.
91      * @param rawRealtimeUs The raw system realtime in microseconds.
92      * @param rawUptimeUs The raw system uptime in microseconds.
93      * @param statsType The type of stats. As of {@link android.os.Build.VERSION_CODES#Q}, this can
94      *                  only be {@link BatteryStats#STATS_SINCE_CHARGED}, since
95      *                  {@link BatteryStats#STATS_CURRENT} and
96      *                  {@link BatteryStats#STATS_SINCE_UNPLUGGED} are deprecated.
97      */
calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, int statsType)98     protected void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
99                                       long rawUptimeUs, int statsType) {
100     }
101 
102     /**
103      * Calculate the amount of power an app used for this subsystem.
104      * @param app The UidBatteryConsumer.Builder that represents the power use of an app.
105      * @param u The recorded stats for the app.
106      * @param rawRealtimeUs The raw system realtime in microseconds.
107      * @param rawUptimeUs The raw system uptime in microseconds.
108      * @param query Power calculation parameters.
109      */
calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u, long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query)110     protected void calculateApp(UidBatteryConsumer.Builder app, BatteryStats.Uid u,
111             long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
112     }
113 
114     /**
115      * Reset any state maintained in this calculator.
116      */
reset()117     public void reset() {
118     }
119 
getPowerModel( long measuredEnergyUC, @NonNull BatteryUsageStatsQuery query)120     protected static @BatteryConsumer.PowerModel int getPowerModel(
121             long measuredEnergyUC, @NonNull BatteryUsageStatsQuery query) {
122         if (measuredEnergyUC != BatteryStats.POWER_DATA_UNAVAILABLE
123                 && !query.shouldForceUsePowerProfileModel()) {
124             return BatteryConsumer.POWER_MODEL_MEASURED_ENERGY;
125         }
126         return BatteryConsumer.POWER_MODEL_POWER_PROFILE;
127     }
128 
getPowerModel(long measuredEnergyUC)129     protected static @BatteryConsumer.PowerModel int getPowerModel(long measuredEnergyUC) {
130         return measuredEnergyUC != BatteryStats.POWER_DATA_UNAVAILABLE
131                 ? BatteryConsumer.POWER_MODEL_MEASURED_ENERGY
132                 : BatteryConsumer.POWER_MODEL_POWER_PROFILE;
133     }
134 
135     /**
136      * Returns either the measured energy converted to mAh or a usage-based estimate.
137      */
getMeasuredOrEstimatedPower(@atteryConsumer.PowerModel int powerModel, long measuredEnergyUC, UsageBasedPowerEstimator powerEstimator, long durationMs)138     protected static double getMeasuredOrEstimatedPower(@BatteryConsumer.PowerModel int powerModel,
139             long measuredEnergyUC, UsageBasedPowerEstimator powerEstimator, long durationMs) {
140         switch (powerModel) {
141             case BatteryConsumer.POWER_MODEL_MEASURED_ENERGY:
142                 return uCtoMah(measuredEnergyUC);
143             case BatteryConsumer.POWER_MODEL_POWER_PROFILE:
144             default:
145                 return powerEstimator.calculatePower(durationMs);
146         }
147     }
148 
149     /**
150      * Returns either the measured energy converted to mAh or a usage-based estimate.
151      */
getMeasuredOrEstimatedPower( long measuredEnergyUC, UsageBasedPowerEstimator powerEstimator, long durationMs)152     protected static double getMeasuredOrEstimatedPower(
153             long measuredEnergyUC, UsageBasedPowerEstimator powerEstimator, long durationMs) {
154         if (measuredEnergyUC != BatteryStats.POWER_DATA_UNAVAILABLE) {
155             return uCtoMah(measuredEnergyUC);
156         } else {
157             return powerEstimator.calculatePower(durationMs);
158         }
159     }
160 
161     /**
162      * Prints formatted amount of power in milli-amp-hours.
163      */
printPowerMah(PrintWriter pw, double powerMah)164     public static void printPowerMah(PrintWriter pw, double powerMah) {
165         pw.print(formatCharge(powerMah));
166     }
167 
168     /**
169      * Converts charge in mAh to string.
170      */
formatCharge(double power)171     public static String formatCharge(double power) {
172         if (power == 0) return "0";
173 
174         final String format;
175         if (power < .00001) {
176             format = "%.8f";
177         } else if (power < .0001) {
178             format = "%.7f";
179         } else if (power < .001) {
180             format = "%.6f";
181         } else if (power < .01) {
182             format = "%.5f";
183         } else if (power < .1) {
184             format = "%.4f";
185         } else if (power < 1) {
186             format = "%.3f";
187         } else if (power < 10) {
188             format = "%.2f";
189         } else if (power < 100) {
190             format = "%.1f";
191         } else {
192             format = "%.0f";
193         }
194 
195         // Use English locale because this is never used in UI (only in checkin and dump).
196         return String.format(Locale.ENGLISH, format, power);
197     }
198 
uCtoMah(long chargeUC)199     static double uCtoMah(long chargeUC) {
200         return chargeUC * MILLIAMPHOUR_PER_MICROCOULOMB;
201     }
202 }
203