• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 com.android.server.power.stats.processor;
18 
19 import android.annotation.NonNull;
20 import android.content.Context;
21 import android.hardware.SensorManager;
22 import android.os.BatteryConsumer;
23 import android.os.BatteryUsageStats;
24 import android.util.IndentingPrintWriter;
25 import android.util.Slog;
26 import android.util.SparseBooleanArray;
27 
28 import com.android.internal.annotations.VisibleForTesting;
29 import com.android.internal.os.BatteryStatsHistory;
30 import com.android.internal.os.CpuScalingPolicies;
31 import com.android.internal.os.PowerProfile;
32 import com.android.server.power.stats.PowerAttributor;
33 import com.android.server.power.stats.PowerStatsSpan;
34 import com.android.server.power.stats.PowerStatsStore;
35 
36 import java.util.List;
37 import java.util.function.DoubleSupplier;
38 
39 public class MultiStatePowerAttributor implements PowerAttributor {
40     private static final String TAG = "MultiStatePowerAttributor";
41 
42     private final PowerStatsStore mPowerStatsStore;
43     private final PowerStatsExporter mPowerStatsExporter;
44     private final PowerStatsAggregator mPowerStatsAggregator;
45     private final SparseBooleanArray mPowerStatsExporterEnabled = new SparseBooleanArray();
46 
MultiStatePowerAttributor(Context context, PowerStatsStore powerStatsStore, @NonNull PowerProfile powerProfile, @NonNull CpuScalingPolicies cpuScalingPolicies, @NonNull DoubleSupplier batteryCapacitySupplier)47     public MultiStatePowerAttributor(Context context, PowerStatsStore powerStatsStore,
48             @NonNull PowerProfile powerProfile, @NonNull CpuScalingPolicies cpuScalingPolicies,
49             @NonNull DoubleSupplier batteryCapacitySupplier) {
50         this(powerStatsStore, new PowerStatsAggregator(
51                 createAggregatedPowerStatsConfig(context, powerProfile, cpuScalingPolicies,
52                         batteryCapacitySupplier)));
53     }
54 
55     @VisibleForTesting
MultiStatePowerAttributor(PowerStatsStore powerStatsStore, PowerStatsAggregator powerStatsAggregator)56     MultiStatePowerAttributor(PowerStatsStore powerStatsStore,
57             PowerStatsAggregator powerStatsAggregator) {
58         mPowerStatsStore = powerStatsStore;
59         mPowerStatsAggregator = powerStatsAggregator;
60         mPowerStatsStore.addSectionReader(
61                 new AggregatedPowerStatsSection.Reader(mPowerStatsAggregator.getConfig()));
62         mPowerStatsExporter = new PowerStatsExporter(mPowerStatsStore, mPowerStatsAggregator);
63         setPowerComponentSupported(BatteryConsumer.POWER_COMPONENT_BASE, true);
64     }
65 
createAggregatedPowerStatsConfig(Context context, PowerProfile powerProfile, CpuScalingPolicies cpuScalingPolicies, DoubleSupplier batteryCapacitySupplier)66     private static AggregatedPowerStatsConfig createAggregatedPowerStatsConfig(Context context,
67             PowerProfile powerProfile, CpuScalingPolicies cpuScalingPolicies,
68             DoubleSupplier batteryCapacitySupplier) {
69         AggregatedPowerStatsConfig config = new AggregatedPowerStatsConfig();
70         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_BASE)
71                 .trackDeviceStates(
72                         AggregatedPowerStatsConfig.STATE_POWER,
73                         AggregatedPowerStatsConfig.STATE_SCREEN)
74                 .trackUidStates(
75                         AggregatedPowerStatsConfig.STATE_POWER,
76                         AggregatedPowerStatsConfig.STATE_SCREEN,
77                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
78                 .setProcessorSupplier(() -> new BasePowerStatsProcessor(batteryCapacitySupplier));
79 
80         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_WAKELOCK)
81                 .trackDeviceStates(
82                         AggregatedPowerStatsConfig.STATE_POWER,
83                         AggregatedPowerStatsConfig.STATE_SCREEN)
84                 .trackUidStates(
85                         AggregatedPowerStatsConfig.STATE_POWER,
86                         AggregatedPowerStatsConfig.STATE_SCREEN,
87                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
88                 .setProcessorSupplier(
89                         () -> new WakelockPowerStatsProcessor(powerProfile));
90 
91         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_CPU,
92                         BatteryConsumer.POWER_COMPONENT_WAKELOCK)
93                 .setProcessorSupplier(
94                         () -> new CpuPowerStatsProcessor(powerProfile, cpuScalingPolicies));
95 
96         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_SCREEN)
97                 .trackDeviceStates(
98                         AggregatedPowerStatsConfig.STATE_POWER,
99                         AggregatedPowerStatsConfig.STATE_SCREEN)
100                 .trackUidStates(
101                         AggregatedPowerStatsConfig.STATE_POWER,
102                         AggregatedPowerStatsConfig.STATE_SCREEN)
103                 .setProcessorSupplier(
104                         () -> new ScreenPowerStatsProcessor(powerProfile));
105 
106         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY,
107                         BatteryConsumer.POWER_COMPONENT_SCREEN)
108                 .setProcessorSupplier(AmbientDisplayPowerStatsProcessor::new);
109 
110         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)
111                 .trackDeviceStates(
112                         AggregatedPowerStatsConfig.STATE_POWER,
113                         AggregatedPowerStatsConfig.STATE_SCREEN)
114                 .trackUidStates(
115                         AggregatedPowerStatsConfig.STATE_POWER,
116                         AggregatedPowerStatsConfig.STATE_SCREEN,
117                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
118                 .setProcessorSupplier(
119                         () -> new MobileRadioPowerStatsProcessor(powerProfile));
120 
121         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_PHONE,
122                         BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO)
123                 .setProcessorSupplier(PhoneCallPowerStatsProcessor::new);
124 
125         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_WIFI)
126                 .trackDeviceStates(
127                         AggregatedPowerStatsConfig.STATE_POWER,
128                         AggregatedPowerStatsConfig.STATE_SCREEN)
129                 .trackUidStates(
130                         AggregatedPowerStatsConfig.STATE_POWER,
131                         AggregatedPowerStatsConfig.STATE_SCREEN,
132                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
133                 .setProcessorSupplier(
134                         () -> new WifiPowerStatsProcessor(powerProfile));
135 
136         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_BLUETOOTH)
137                 .trackDeviceStates(
138                         AggregatedPowerStatsConfig.STATE_POWER,
139                         AggregatedPowerStatsConfig.STATE_SCREEN)
140                 .trackUidStates(
141                         AggregatedPowerStatsConfig.STATE_POWER,
142                         AggregatedPowerStatsConfig.STATE_SCREEN,
143                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
144                 .setProcessorSupplier(
145                         () -> new BluetoothPowerStatsProcessor(powerProfile));
146 
147         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_AUDIO)
148                 .trackDeviceStates(
149                         AggregatedPowerStatsConfig.STATE_POWER,
150                         AggregatedPowerStatsConfig.STATE_SCREEN)
151                 .trackUidStates(
152                         AggregatedPowerStatsConfig.STATE_POWER,
153                         AggregatedPowerStatsConfig.STATE_SCREEN,
154                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
155                 .setProcessorSupplier(
156                         () -> new AudioPowerStatsProcessor(powerProfile));
157 
158         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_VIDEO)
159                 .trackDeviceStates(
160                         AggregatedPowerStatsConfig.STATE_POWER,
161                         AggregatedPowerStatsConfig.STATE_SCREEN)
162                 .trackUidStates(
163                         AggregatedPowerStatsConfig.STATE_POWER,
164                         AggregatedPowerStatsConfig.STATE_SCREEN,
165                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
166                 .setProcessorSupplier(
167                         () -> new VideoPowerStatsProcessor(powerProfile));
168 
169         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_FLASHLIGHT)
170                 .trackDeviceStates(
171                         AggregatedPowerStatsConfig.STATE_POWER,
172                         AggregatedPowerStatsConfig.STATE_SCREEN)
173                 .trackUidStates(
174                         AggregatedPowerStatsConfig.STATE_POWER,
175                         AggregatedPowerStatsConfig.STATE_SCREEN,
176                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
177                 .setProcessorSupplier(
178                         () -> new FlashlightPowerStatsProcessor(powerProfile));
179 
180         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_CAMERA)
181                 .trackDeviceStates(
182                         AggregatedPowerStatsConfig.STATE_POWER,
183                         AggregatedPowerStatsConfig.STATE_SCREEN)
184                 .trackUidStates(
185                         AggregatedPowerStatsConfig.STATE_POWER,
186                         AggregatedPowerStatsConfig.STATE_SCREEN,
187                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
188                 .setProcessorSupplier(
189                         () -> new CameraPowerStatsProcessor(powerProfile));
190 
191         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_GNSS)
192                 .trackDeviceStates(
193                         AggregatedPowerStatsConfig.STATE_POWER,
194                         AggregatedPowerStatsConfig.STATE_SCREEN)
195                 .trackUidStates(
196                         AggregatedPowerStatsConfig.STATE_POWER,
197                         AggregatedPowerStatsConfig.STATE_SCREEN,
198                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
199                 .setProcessorSupplier(
200                         () -> new GnssPowerStatsProcessor(powerProfile));
201 
202         config.trackPowerComponent(BatteryConsumer.POWER_COMPONENT_SENSORS)
203                 .trackDeviceStates(
204                         AggregatedPowerStatsConfig.STATE_POWER,
205                         AggregatedPowerStatsConfig.STATE_SCREEN)
206                 .trackUidStates(
207                         AggregatedPowerStatsConfig.STATE_POWER,
208                         AggregatedPowerStatsConfig.STATE_SCREEN,
209                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE)
210                 .setProcessorSupplier(() -> new SensorPowerStatsProcessor(
211                         () -> context.getSystemService(SensorManager.class)));
212 
213         config.trackCustomPowerComponents(CustomEnergyConsumerPowerStatsProcessor::new)
214                 .trackDeviceStates(
215                         AggregatedPowerStatsConfig.STATE_POWER,
216                         AggregatedPowerStatsConfig.STATE_SCREEN)
217                 .trackUidStates(
218                         AggregatedPowerStatsConfig.STATE_POWER,
219                         AggregatedPowerStatsConfig.STATE_SCREEN,
220                         AggregatedPowerStatsConfig.STATE_PROCESS_STATE);
221         return config;
222     }
223 
224     /**
225      * Marks the specified power component as supported by this PowerAttributor
226      */
setPowerComponentSupported(@atteryConsumer.PowerComponentId int powerComponentId, boolean enabled)227     public void setPowerComponentSupported(@BatteryConsumer.PowerComponentId int powerComponentId,
228             boolean enabled) {
229         mPowerStatsExporterEnabled.put(powerComponentId, enabled);
230         mPowerStatsExporter.setPowerComponentEnabled(powerComponentId, enabled);
231     }
232 
233     @Override
isPowerComponentSupported( @atteryConsumer.PowerComponentId int powerComponentId)234     public boolean isPowerComponentSupported(
235             @BatteryConsumer.PowerComponentId int powerComponentId) {
236         return mPowerStatsExporterEnabled.get(powerComponentId);
237     }
238 
239     @Override
estimatePowerConsumption(BatteryUsageStats.Builder batteryUsageStatsBuilder, BatteryStatsHistory batteryHistory, long monotonicStartTime, long monotonicEndTime)240     public void estimatePowerConsumption(BatteryUsageStats.Builder batteryUsageStatsBuilder,
241             BatteryStatsHistory batteryHistory, long monotonicStartTime, long monotonicEndTime) {
242         mPowerStatsExporter.exportAggregatedPowerStats(batteryUsageStatsBuilder, batteryHistory,
243                 monotonicStartTime, monotonicEndTime);
244     }
245 
246     @Override
dumpEstimatedPowerConsumption(IndentingPrintWriter ipw, BatteryStatsHistory batteryStatsHistory, long startTime, long endTime)247     public void dumpEstimatedPowerConsumption(IndentingPrintWriter ipw,
248             BatteryStatsHistory batteryStatsHistory,
249             long startTime, long endTime) {
250         mPowerStatsAggregator.aggregatePowerStats(batteryStatsHistory, startTime, endTime,
251                 stats -> {
252                     // Create a PowerStatsSpan for consistency of the textual output
253                     PowerStatsSpan span = createPowerStatsSpan(stats);
254                     if (span != null) {
255                         span.dump(ipw);
256                     }
257                 });
258     }
259 
260     @Override
storeEstimatedPowerConsumption(BatteryStatsHistory batteryStatsHistory, long startTime, long endTimeMs)261     public long storeEstimatedPowerConsumption(BatteryStatsHistory batteryStatsHistory,
262             long startTime, long endTimeMs) {
263         long[] lastSavedMonotonicTime = new long[1];
264         mPowerStatsAggregator.aggregatePowerStats(batteryStatsHistory, startTime, endTimeMs,
265                 stats -> {
266                     storeAggregatedPowerStats(stats);
267                     lastSavedMonotonicTime[0] = stats.getStartTime() + stats.getDuration();
268                 });
269         return lastSavedMonotonicTime[0];
270     }
271 
272     @VisibleForTesting
storeAggregatedPowerStats(AggregatedPowerStats stats)273     void storeAggregatedPowerStats(AggregatedPowerStats stats) {
274         PowerStatsSpan span = createPowerStatsSpan(stats);
275         if (span == null) {
276             return;
277         }
278         mPowerStatsStore.storePowerStatsSpan(span);
279     }
280 
createPowerStatsSpan(AggregatedPowerStats stats)281     private static PowerStatsSpan createPowerStatsSpan(AggregatedPowerStats stats) {
282         List<AggregatedPowerStats.ClockUpdate> clockUpdates = stats.getClockUpdates();
283         if (clockUpdates.isEmpty()) {
284             Slog.w(TAG, "No clock updates in aggregated power stats " + stats);
285             return null;
286         }
287 
288         long monotonicTime = clockUpdates.get(0).monotonicTime;
289         long durationSum = 0;
290         PowerStatsSpan span = new PowerStatsSpan(monotonicTime);
291         for (int i = 0; i < clockUpdates.size(); i++) {
292             AggregatedPowerStats.ClockUpdate clockUpdate = clockUpdates.get(i);
293             long duration;
294             if (i == clockUpdates.size() - 1) {
295                 duration = stats.getDuration() - durationSum;
296             } else {
297                 duration = clockUpdate.monotonicTime - monotonicTime;
298             }
299             span.addTimeFrame(clockUpdate.monotonicTime, clockUpdate.currentTime, duration);
300             monotonicTime = clockUpdate.monotonicTime;
301             durationSum += duration;
302         }
303 
304         span.addSection(new AggregatedPowerStatsSection(stats));
305         return span;
306     }
307 
308     @Override
getLastSavedEstimatesPowerConsumptionTimestamp()309     public long getLastSavedEstimatesPowerConsumptionTimestamp() {
310         long timestamp = -1;
311         for (PowerStatsSpan.Metadata metadata : mPowerStatsStore.getTableOfContents()) {
312             if (metadata.getSections().contains(AggregatedPowerStatsSection.TYPE)) {
313                 for (PowerStatsSpan.TimeFrame timeFrame : metadata.getTimeFrames()) {
314                     long endMonotonicTime = timeFrame.startMonotonicTime + timeFrame.duration;
315                     if (endMonotonicTime > timestamp) {
316                         timestamp = endMonotonicTime;
317                     }
318                 }
319             }
320         }
321         return timestamp;
322     }
323 }
324