• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.internal.os;
18 
19 import static android.os.BatteryConsumer.POWER_COMPONENT_ANY;
20 import static android.os.BatteryConsumer.POWER_MODEL_MEASURED_ENERGY;
21 import static android.os.BatteryConsumer.POWER_MODEL_UNDEFINED;
22 import static android.os.BatteryConsumer.PROCESS_STATE_BACKGROUND;
23 import static android.os.BatteryConsumer.PROCESS_STATE_CACHED;
24 import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND;
25 import static android.os.BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE;
26 
27 import static com.google.common.truth.Truth.assertThat;
28 
29 import static org.junit.Assert.assertThrows;
30 import static org.junit.Assert.fail;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.when;
33 
34 import android.os.AggregateBatteryConsumer;
35 import android.os.BatteryConsumer;
36 import android.os.BatteryUsageStats;
37 import android.os.Parcel;
38 import android.os.UidBatteryConsumer;
39 import android.os.UserBatteryConsumer;
40 import android.util.TypedXmlPullParser;
41 import android.util.TypedXmlSerializer;
42 import android.util.Xml;
43 
44 import androidx.test.filters.SmallTest;
45 import androidx.test.runner.AndroidJUnit4;
46 
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 
50 import java.io.ByteArrayInputStream;
51 import java.io.ByteArrayOutputStream;
52 import java.io.PrintWriter;
53 import java.io.StringWriter;
54 import java.nio.charset.StandardCharsets;
55 import java.util.HashSet;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.Set;
59 import java.util.stream.Collectors;
60 
61 @SmallTest
62 @RunWith(AndroidJUnit4.class)
63 public class BatteryUsageStatsTest {
64 
65     private static final int USER_ID = 42;
66     private static final int APP_UID1 = 271;
67     private static final int APP_UID2 = 314;
68 
69     @Test
testBuilder()70     public void testBuilder() {
71         BatteryUsageStats batteryUsageStats = buildBatteryUsageStats1(true).build();
72         assertBatteryUsageStats1(batteryUsageStats, true);
73     }
74 
75     @Test
testBuilder_noProcessStateData()76     public void testBuilder_noProcessStateData() {
77         BatteryUsageStats batteryUsageStats = buildBatteryUsageStats1(false).build();
78         assertBatteryUsageStats1(batteryUsageStats, false);
79     }
80 
81     @Test
testParcelability_smallNumberOfUids()82     public void testParcelability_smallNumberOfUids() {
83         final BatteryUsageStats outBatteryUsageStats = buildBatteryUsageStats1(true).build();
84         final Parcel parcel = Parcel.obtain();
85         parcel.writeParcelable(outBatteryUsageStats, 0);
86 
87         assertThat(parcel.dataSize()).isLessThan(8000);
88 
89         parcel.setDataPosition(0);
90 
91         final BatteryUsageStats inBatteryUsageStats =
92                 parcel.readParcelable(getClass().getClassLoader());
93         assertThat(inBatteryUsageStats).isNotNull();
94         assertBatteryUsageStats1(inBatteryUsageStats, true);
95     }
96 
97     @Test
testParcelability_largeNumberOfUids()98     public void testParcelability_largeNumberOfUids() {
99         final BatteryUsageStats.Builder builder =
100                 new BatteryUsageStats.Builder(new String[0]);
101 
102         // Without the use of a CursorWindow, this BatteryUsageStats object would generate a Parcel
103         // larger than 64 Kb
104         final int uidCount = 200;
105         for (int i = 0; i < uidCount; i++) {
106             BatteryStatsImpl.Uid mockUid = mock(BatteryStatsImpl.Uid.class);
107             when(mockUid.getUid()).thenReturn(i);
108             builder.getOrCreateUidBatteryConsumerBuilder(mockUid)
109                     .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, i * 100);
110         }
111 
112         BatteryUsageStats outBatteryUsageStats = builder.build();
113 
114         final Parcel parcel = Parcel.obtain();
115         parcel.writeParcelable(outBatteryUsageStats, 0);
116 
117         assertThat(parcel.dataSize()).isLessThan(2000);
118 
119         parcel.setDataPosition(0);
120 
121         final BatteryUsageStats inBatteryUsageStats =
122                 parcel.readParcelable(getClass().getClassLoader());
123         parcel.recycle();
124 
125         assertThat(inBatteryUsageStats.getUidBatteryConsumers()).hasSize(uidCount);
126         final Map<Integer, UidBatteryConsumer> consumersByUid =
127                 inBatteryUsageStats.getUidBatteryConsumers().stream().collect(
128                         Collectors.toMap(UidBatteryConsumer::getUid, c -> c));
129         for (int i = 0; i < uidCount; i++) {
130             final UidBatteryConsumer uidBatteryConsumer = consumersByUid.get(i);
131             assertThat(uidBatteryConsumer).isNotNull();
132             assertThat(uidBatteryConsumer.getConsumedPower()).isEqualTo(i * 100);
133         }
134     }
135 
136     @Test
testDefaultSessionDuration()137     public void testDefaultSessionDuration() {
138         final BatteryUsageStats stats =
139                 buildBatteryUsageStats1(true).setStatsDuration(10000).build();
140         assertThat(stats.getStatsDuration()).isEqualTo(10000);
141     }
142 
143     @Test
testDump()144     public void testDump() {
145         final BatteryUsageStats stats = buildBatteryUsageStats1(true).build();
146         final StringWriter out = new StringWriter();
147         try (PrintWriter pw = new PrintWriter(out)) {
148             stats.dump(pw, "  ");
149         }
150         final String dump = out.toString();
151 
152         assertThat(dump).contains("Capacity: 4000");
153         assertThat(dump).contains("Computed drain: 30000");
154         assertThat(dump).contains("actual drain: 1000-2000");
155         assertThat(dump).contains("cpu: 20100 apps: 10100 duration: 20s 300ms");
156         assertThat(dump).contains("cpu(fg): 2333 apps: 1333 duration: 3s 332ms");
157         assertThat(dump).contains("cpu(bg): 2444 apps: 1444 duration: 4s 442ms");
158         assertThat(dump).contains("cpu(fgs): 2555 apps: 1555 duration: 5s 552ms");
159         assertThat(dump).contains("cpu(cached): 123 apps: 123 duration: 456ms");
160         assertThat(dump).contains("FOO: 20200 apps: 10200 duration: 20s 400ms");
161         assertThat(dump).contains("UID 271: 1200 fg: 1777 bg: 1888 fgs: 1999 cached: 123 "
162                 + "( screen=300 cpu=400 (600ms) cpu:fg=1777 (7s 771ms) cpu:bg=1888 (8s 881ms) "
163                 + "cpu:fgs=1999 (9s 991ms) cpu:cached=123 (456ms) FOO=500 )");
164         assertThat(dump).contains("User 42: 30.0 ( cpu=10.0 (30ms) FOO=20.0 )");
165     }
166 
167     @Test
testPowerComponentNames_existAndUnique()168     public void testPowerComponentNames_existAndUnique() {
169         Set<String> allNames = new HashSet<>();
170         for (int i = 0; i < BatteryConsumer.POWER_COMPONENT_COUNT; i++) {
171             assertThat(BatteryConsumer.powerComponentIdToString(i)).isNotNull();
172             allNames.add(BatteryConsumer.powerComponentIdToString(i));
173         }
174         assertThat(allNames).hasSize(BatteryConsumer.POWER_COMPONENT_COUNT);
175     }
176 
177     @Test
testAdd()178     public void testAdd() {
179         final BatteryUsageStats stats1 = buildBatteryUsageStats1(false).build();
180         final BatteryUsageStats stats2 = buildBatteryUsageStats2(new String[]{"FOO"}, true).build();
181 
182         final BatteryUsageStats sum =
183                 new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true)
184                         .add(stats1)
185                         .add(stats2)
186                         .build();
187 
188         assertBatteryUsageStats(sum, 42345, 50, 2234, 4345, 1234, 1000, 5000, 5000);
189 
190         final List<UidBatteryConsumer> uidBatteryConsumers =
191                 sum.getUidBatteryConsumers();
192         for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
193             if (uidBatteryConsumer.getUid() == APP_UID1) {
194                 assertUidBatteryConsumer(uidBatteryConsumer, 2124, null,
195                         5321, 7432, 423, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 745,
196                         POWER_MODEL_UNDEFINED,
197                         956, 1167, 1478,
198                         true, 3554, 3776, 3998, 444, 3554, 15542, 3776, 17762, 3998, 19982,
199                         444, 1110);
200             } else if (uidBatteryConsumer.getUid() == APP_UID2) {
201                 assertUidBatteryConsumer(uidBatteryConsumer, 1332, "bar",
202                         1111, 2222, 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
203                         BatteryConsumer.POWER_MODEL_POWER_PROFILE,
204                         555, 666, 777,
205                         true, 1777, 1888, 1999, 321, 1777, 7771, 1888, 8881, 1999, 9991,
206                         321, 654);
207             } else {
208                 fail("Unexpected UID " + uidBatteryConsumer.getUid());
209             }
210         }
211 
212         assertAggregateBatteryConsumer(sum,
213                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS,
214                 20223, 20434, 20645, 20856);
215 
216         assertAggregateBatteryConsumer(sum,
217                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE,
218                 40211, 40422, 40633, 40844);
219     }
220 
221     @Test
testAdd_customComponentMismatch()222     public void testAdd_customComponentMismatch() {
223         final BatteryUsageStats.Builder builder =
224                 new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true);
225         final BatteryUsageStats stats = buildBatteryUsageStats2(new String[]{"BAR"}, false).build();
226 
227         assertThrows(IllegalArgumentException.class, () -> builder.add(stats));
228     }
229 
230     @Test
testAdd_processStateDataMismatch()231     public void testAdd_processStateDataMismatch() {
232         final BatteryUsageStats.Builder builder =
233                 new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true);
234         final BatteryUsageStats stats = buildBatteryUsageStats2(new String[]{"FOO"}, false).build();
235 
236         assertThrows(IllegalArgumentException.class, () -> builder.add(stats));
237     }
238 
239     @Test
testXml()240     public void testXml() throws Exception {
241         ByteArrayOutputStream out = new ByteArrayOutputStream();
242         TypedXmlSerializer serializer = Xml.newBinarySerializer();
243         serializer.setOutput(out, StandardCharsets.UTF_8.name());
244         serializer.startDocument(null, true);
245         final BatteryUsageStats stats = buildBatteryUsageStats1(true).build();
246         stats.writeXml(serializer);
247         serializer.endDocument();
248 
249         ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
250         TypedXmlPullParser parser = Xml.newBinaryPullParser();
251         parser.setInput(in, StandardCharsets.UTF_8.name());
252         final BatteryUsageStats fromXml = BatteryUsageStats.createFromXml(parser);
253 
254         assertBatteryUsageStats1(fromXml, true);
255     }
256 
buildBatteryUsageStats1(boolean includeUserBatteryConsumer)257     private BatteryUsageStats.Builder buildBatteryUsageStats1(boolean includeUserBatteryConsumer) {
258         final MockClock clocks = new MockClock();
259         final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
260 
261         final BatteryUsageStats.Builder builder =
262                 new BatteryUsageStats.Builder(new String[]{"FOO"}, true, true)
263                         .setBatteryCapacity(4000)
264                         .setDischargePercentage(20)
265                         .setDischargedPowerRange(1000, 2000)
266                         .setDischargeDurationMs(1234)
267                         .setStatsStartTimestamp(1000)
268                         .setStatsEndTimestamp(3000);
269 
270         addUidBatteryConsumer(builder, batteryStats, APP_UID1, "foo",
271                 1000, 2000,
272                 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
273                 BatteryConsumer.POWER_MODEL_POWER_PROFILE, 500, 600, 800,
274                 1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
275 
276         addAggregateBatteryConsumer(builder,
277                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, 0,
278                 10100, 10200, 10300, 10400,
279                 1333, 3331, 1444, 4441, 1555, 5551, 123, 456);
280 
281         addAggregateBatteryConsumer(builder,
282                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, 30000,
283                 20100, 20200, 20300, 20400,
284                 2333, 3332, 2444, 4442, 2555, 5552, 123, 456);
285 
286         if (includeUserBatteryConsumer) {
287             builder.getOrCreateUserBatteryConsumerBuilder(USER_ID)
288                     .setConsumedPower(
289                             BatteryConsumer.POWER_COMPONENT_CPU, 10)
290                     .setConsumedPowerForCustomComponent(
291                             BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 20)
292                     .setUsageDurationMillis(
293                             BatteryConsumer.POWER_COMPONENT_CPU, 30)
294                     .setUsageDurationForCustomComponentMillis(
295                             BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 40);
296         }
297         return builder;
298     }
299 
buildBatteryUsageStats2(String[] customPowerComponentNames, boolean includeProcessStateData)300     private BatteryUsageStats.Builder buildBatteryUsageStats2(String[] customPowerComponentNames,
301             boolean includeProcessStateData) {
302         final MockClock clocks = new MockClock();
303         final MockBatteryStatsImpl batteryStats = new MockBatteryStatsImpl(clocks);
304 
305         final BatteryUsageStats.Builder builder =
306                 new BatteryUsageStats.Builder(customPowerComponentNames, true,
307                         includeProcessStateData);
308         builder.setDischargePercentage(30)
309                 .setDischargedPowerRange(1234, 2345)
310                 .setStatsStartTimestamp(2000)
311                 .setStatsEndTimestamp(5000);
312 
313         addUidBatteryConsumer(builder, batteryStats, APP_UID1, null,
314                 4321, 5432,
315                 123, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 345, POWER_MODEL_MEASURED_ENERGY,
316                 456, 567, 678,
317                 1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
318 
319         addUidBatteryConsumer(builder, batteryStats, APP_UID2, "bar",
320                 1111, 2222,
321                 333, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 444,
322                 BatteryConsumer.POWER_MODEL_POWER_PROFILE, 555, 666, 777,
323                 1777, 7771, 1888, 8881, 1999, 9991, 321, 654);
324 
325         addAggregateBatteryConsumer(builder,
326                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS, 0,
327                 10123, 10234, 10345, 10456,
328                 4333, 3334, 5444, 4445, 6555, 5556, 321, 654);
329 
330         addAggregateBatteryConsumer(builder,
331                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE, 12345,
332                 20111, 20222, 20333, 20444,
333                 7333, 3337, 8444, 4448, 9555, 5559, 123, 456);
334 
335         return builder;
336     }
337 
addUidBatteryConsumer(BatteryUsageStats.Builder builder, MockBatteryStatsImpl batteryStats, int uid, String packageWithHighestDrain, int timeInStateForeground, int timeInStateBackground, double screenPower, int screenPowerModel, double cpuPower, int cpuPowerModel, double customComponentPower, int cpuDuration, int customComponentDuration, double cpuPowerForeground, int cpuDurationForeground, double cpuPowerBackground, int cpuDurationBackground, double cpuPowerFgs, int cpuDurationFgs, double cpuPowerCached, long cpuDurationCached)338     private void addUidBatteryConsumer(BatteryUsageStats.Builder builder,
339             MockBatteryStatsImpl batteryStats, int uid, String packageWithHighestDrain,
340             int timeInStateForeground, int timeInStateBackground, double screenPower,
341             int screenPowerModel, double cpuPower, int cpuPowerModel, double customComponentPower,
342             int cpuDuration, int customComponentDuration, double cpuPowerForeground,
343             int cpuDurationForeground, double cpuPowerBackground, int cpuDurationBackground,
344             double cpuPowerFgs, int cpuDurationFgs, double cpuPowerCached, long cpuDurationCached) {
345         final BatteryStatsImpl.Uid batteryStatsUid = batteryStats.getUidStatsLocked(uid);
346         final UidBatteryConsumer.Builder uidBuilder =
347                 builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid);
348         uidBuilder
349                 .setPackageWithHighestDrain(packageWithHighestDrain)
350                 .setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, timeInStateForeground)
351                 .setTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND, timeInStateBackground)
352                 .setConsumedPower(
353                         BatteryConsumer.POWER_COMPONENT_SCREEN, screenPower, screenPowerModel)
354                 .setConsumedPower(
355                         BatteryConsumer.POWER_COMPONENT_CPU, cpuPower, cpuPowerModel)
356                 .setConsumedPowerForCustomComponent(
357                         BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentPower)
358                 .setUsageDurationMillis(
359                         BatteryConsumer.POWER_COMPONENT_CPU, cpuDuration)
360                 .setUsageDurationForCustomComponentMillis(
361                         BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, customComponentDuration);
362         if (builder.isProcessStateDataNeeded()) {
363             final BatteryConsumer.Key cpuFgKey = uidBuilder.getKey(
364                     BatteryConsumer.POWER_COMPONENT_CPU,
365                     BatteryConsumer.PROCESS_STATE_FOREGROUND);
366             final BatteryConsumer.Key cpuBgKey = uidBuilder.getKey(
367                     BatteryConsumer.POWER_COMPONENT_CPU,
368                     BatteryConsumer.PROCESS_STATE_BACKGROUND);
369             final BatteryConsumer.Key cpuFgsKey = uidBuilder.getKey(
370                     BatteryConsumer.POWER_COMPONENT_CPU,
371                     BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
372             final BatteryConsumer.Key cachedKey = uidBuilder.getKey(
373                     BatteryConsumer.POWER_COMPONENT_CPU,
374                     BatteryConsumer.PROCESS_STATE_CACHED);
375             uidBuilder
376                     .setConsumedPower(cpuFgKey, cpuPowerForeground,
377                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
378                     .setUsageDurationMillis(cpuFgKey, cpuDurationForeground)
379                     .setConsumedPower(cpuBgKey, cpuPowerBackground,
380                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
381                     .setUsageDurationMillis(cpuBgKey, cpuDurationBackground)
382                     .setConsumedPower(cpuFgsKey, cpuPowerFgs,
383                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
384                     .setUsageDurationMillis(cpuFgsKey, cpuDurationFgs)
385                     .setConsumedPower(cachedKey, cpuPowerCached,
386                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
387                     .setUsageDurationMillis(cachedKey, cpuDurationCached);
388         }
389     }
390 
addAggregateBatteryConsumer(BatteryUsageStats.Builder builder, int scope, double consumedPower, int cpuPower, int customComponentPower, int cpuDuration, int customComponentDuration, double cpuPowerForeground, long cpuDurationForeground, double cpuPowerBackground, long cpuDurationBackground, double cpuPowerFgs, long cpuDurationFgs, double cpuPowerCached, long cpuDurationCached)391     private void addAggregateBatteryConsumer(BatteryUsageStats.Builder builder, int scope,
392             double consumedPower, int cpuPower, int customComponentPower, int cpuDuration,
393             int customComponentDuration, double cpuPowerForeground, long cpuDurationForeground,
394             double cpuPowerBackground, long cpuDurationBackground, double cpuPowerFgs,
395             long cpuDurationFgs, double cpuPowerCached, long cpuDurationCached) {
396         final AggregateBatteryConsumer.Builder aggBuilder =
397                 builder.getAggregateBatteryConsumerBuilder(scope)
398                         .setConsumedPower(consumedPower)
399                         .setConsumedPower(
400                                 BatteryConsumer.POWER_COMPONENT_CPU, cpuPower)
401                         .setConsumedPowerForCustomComponent(
402                                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
403                                 customComponentPower)
404                         .setUsageDurationMillis(
405                                 BatteryConsumer.POWER_COMPONENT_CPU, cpuDuration)
406                         .setUsageDurationForCustomComponentMillis(
407                                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID,
408                                 customComponentDuration);
409         if (builder.isProcessStateDataNeeded()) {
410             final BatteryConsumer.Key cpuFgKey = aggBuilder.getKey(
411                     BatteryConsumer.POWER_COMPONENT_CPU,
412                     BatteryConsumer.PROCESS_STATE_FOREGROUND);
413             final BatteryConsumer.Key cpuBgKey = aggBuilder.getKey(
414                     BatteryConsumer.POWER_COMPONENT_CPU,
415                     BatteryConsumer.PROCESS_STATE_BACKGROUND);
416             final BatteryConsumer.Key cpuFgsKey = aggBuilder.getKey(
417                     BatteryConsumer.POWER_COMPONENT_CPU,
418                     BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
419             final BatteryConsumer.Key cpuCachedKey = aggBuilder.getKey(
420                     BatteryConsumer.POWER_COMPONENT_CPU,
421                     BatteryConsumer.PROCESS_STATE_CACHED);
422             aggBuilder
423                     .setConsumedPower(cpuFgKey, cpuPowerForeground,
424                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
425                     .setUsageDurationMillis(cpuFgKey, cpuDurationForeground)
426                     .setConsumedPower(cpuBgKey, cpuPowerBackground,
427                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
428                     .setUsageDurationMillis(cpuBgKey, cpuDurationBackground)
429                     .setConsumedPower(cpuFgsKey, cpuPowerFgs,
430                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
431                     .setUsageDurationMillis(cpuFgsKey, cpuDurationFgs)
432                     .setConsumedPower(cpuCachedKey, cpuPowerCached,
433                             BatteryConsumer.POWER_MODEL_POWER_PROFILE)
434                     .setUsageDurationMillis(cpuCachedKey, cpuDurationCached);
435         }
436     }
437 
assertBatteryUsageStats1(BatteryUsageStats batteryUsageStats, boolean includesUserBatteryConsumers)438     public void assertBatteryUsageStats1(BatteryUsageStats batteryUsageStats,
439             boolean includesUserBatteryConsumers) {
440         assertBatteryUsageStats(batteryUsageStats, 30000, 20, 1000, 2000, 1234, 1000, 3000, 2000);
441 
442         final List<UidBatteryConsumer> uidBatteryConsumers =
443                 batteryUsageStats.getUidBatteryConsumers();
444         assertThat(uidBatteryConsumers).hasSize(1);
445         for (UidBatteryConsumer uidBatteryConsumer : uidBatteryConsumers) {
446             if (uidBatteryConsumer.getUid() == APP_UID1) {
447                 assertUidBatteryConsumer(uidBatteryConsumer, 1200, "foo",
448                         1000, 2000, 300, BatteryConsumer.POWER_MODEL_POWER_PROFILE, 400,
449                         BatteryConsumer.POWER_MODEL_POWER_PROFILE,
450                         500, 600, 800,
451                         true, 1777, 1888, 1999, 123, 1777, 7771, 1888, 8881, 1999, 9991, 123, 456);
452             } else {
453                 fail("Unexpected UID " + uidBatteryConsumer.getUid());
454             }
455         }
456 
457         final List<UserBatteryConsumer> userBatteryConsumers =
458                 batteryUsageStats.getUserBatteryConsumers();
459         if (includesUserBatteryConsumers) {
460             assertThat(userBatteryConsumers).hasSize(1);
461             for (UserBatteryConsumer userBatteryConsumer : userBatteryConsumers) {
462                 if (userBatteryConsumer.getUserId() == USER_ID) {
463                     assertUserBatteryConsumer(userBatteryConsumer, 42, 10, 20, 30, 40);
464                 } else {
465                     fail("Unexpected User ID " + userBatteryConsumer.getUserId());
466                 }
467             }
468         } else {
469             assertThat(userBatteryConsumers).isEmpty();
470         }
471 
472         assertAggregateBatteryConsumer(batteryUsageStats,
473                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS,
474                 10100, 10200, 10300, 10400);
475 
476         assertAggregateBatteryConsumer(batteryUsageStats,
477                 BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE,
478                 20100, 20200, 20300, 20400);
479     }
480 
assertBatteryUsageStats(BatteryUsageStats batteryUsageStats, int consumedPower, int dischargePercentage, int dischagePowerLower, int dischargePowerUpper, int dischargeDuration, int statsStartTimestamp, int statsEndTimestamp, int statsDuration)481     private void assertBatteryUsageStats(BatteryUsageStats batteryUsageStats, int consumedPower,
482             int dischargePercentage, int dischagePowerLower, int dischargePowerUpper,
483             int dischargeDuration, int statsStartTimestamp, int statsEndTimestamp,
484             int statsDuration) {
485         assertThat(batteryUsageStats.getConsumedPower()).isEqualTo(consumedPower);
486         assertThat(batteryUsageStats.getDischargePercentage()).isEqualTo(dischargePercentage);
487         assertThat(batteryUsageStats.getDischargedPowerRange().getLower()).isEqualTo(
488                 dischagePowerLower);
489         assertThat(batteryUsageStats.getDischargedPowerRange().getUpper()).isEqualTo(
490                 dischargePowerUpper);
491         assertThat(batteryUsageStats.getDischargeDurationMs()).isEqualTo(dischargeDuration);
492         assertThat(batteryUsageStats.getStatsStartTimestamp()).isEqualTo(statsStartTimestamp);
493         assertThat(batteryUsageStats.getStatsEndTimestamp()).isEqualTo(statsEndTimestamp);
494         assertThat(batteryUsageStats.getStatsDuration()).isEqualTo(statsDuration);
495     }
496 
assertUidBatteryConsumer(UidBatteryConsumer uidBatteryConsumer, double consumedPower, String packageWithHighestDrain, int timeInStateForeground, int timeInStateBackground, int screenPower, int screenPowerModel, double cpuPower, int cpuPowerModel, double customComponentPower, int cpuDuration, int customComponentDuration, boolean processStateDataIncluded, double totalPowerForeground, double totalPowerBackground, double totalPowerFgs, double totalPowerCached, double cpuPowerForeground, int cpuDurationForeground, double cpuPowerBackground, int cpuDurationBackground, double cpuPowerFgs, int cpuDurationFgs, int cpuPowerCached, int cpuDurationCached)497     private void assertUidBatteryConsumer(UidBatteryConsumer uidBatteryConsumer,
498             double consumedPower, String packageWithHighestDrain, int timeInStateForeground,
499             int timeInStateBackground, int screenPower, int screenPowerModel, double cpuPower,
500             int cpuPowerModel, double customComponentPower, int cpuDuration,
501             int customComponentDuration, boolean processStateDataIncluded,
502             double totalPowerForeground, double totalPowerBackground, double totalPowerFgs,
503             double totalPowerCached, double cpuPowerForeground, int cpuDurationForeground,
504             double cpuPowerBackground,
505             int cpuDurationBackground, double cpuPowerFgs, int cpuDurationFgs,
506             int cpuPowerCached, int cpuDurationCached) {
507         assertThat(uidBatteryConsumer.getConsumedPower()).isEqualTo(consumedPower);
508         assertThat(uidBatteryConsumer.getPackageWithHighestDrain()).isEqualTo(
509                 packageWithHighestDrain);
510         assertThat(uidBatteryConsumer.getTimeInStateMs(
511                 UidBatteryConsumer.STATE_FOREGROUND)).isEqualTo(timeInStateForeground);
512         assertThat(uidBatteryConsumer.getTimeInStateMs(
513                 UidBatteryConsumer.STATE_BACKGROUND)).isEqualTo(timeInStateBackground);
514         assertThat(uidBatteryConsumer.getConsumedPower(
515                 BatteryConsumer.POWER_COMPONENT_SCREEN)).isEqualTo(screenPower);
516         assertThat(uidBatteryConsumer.getPowerModel(
517                 BatteryConsumer.POWER_COMPONENT_SCREEN)).isEqualTo(screenPowerModel);
518         assertThat(uidBatteryConsumer.getConsumedPower(
519                 BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower);
520         assertThat(uidBatteryConsumer.getPowerModel(
521                 BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPowerModel);
522         assertThat(uidBatteryConsumer.getConsumedPowerForCustomComponent(
523                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower);
524         assertThat(uidBatteryConsumer.getUsageDurationMillis(
525                 BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuDuration);
526         assertThat(uidBatteryConsumer.getUsageDurationForCustomComponentMillis(
527                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(
528                 customComponentDuration);
529         assertThat(uidBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
530         assertThat(uidBatteryConsumer.getCustomPowerComponentName(
531                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
532 
533         if (processStateDataIncluded) {
534             assertThat(uidBatteryConsumer.getConsumedPower(
535                     new BatteryConsumer.Dimensions(POWER_COMPONENT_ANY,
536                             PROCESS_STATE_FOREGROUND)))
537                     .isEqualTo(totalPowerForeground);
538             assertThat(uidBatteryConsumer.getConsumedPower(
539                     new BatteryConsumer.Dimensions(POWER_COMPONENT_ANY,
540                             PROCESS_STATE_BACKGROUND)))
541                     .isEqualTo(totalPowerBackground);
542             assertThat(uidBatteryConsumer.getConsumedPower(
543                     new BatteryConsumer.Dimensions(POWER_COMPONENT_ANY,
544                             PROCESS_STATE_FOREGROUND_SERVICE)))
545                     .isEqualTo(totalPowerFgs);
546             assertThat(uidBatteryConsumer.getConsumedPower(
547                     new BatteryConsumer.Dimensions(POWER_COMPONENT_ANY,
548                             PROCESS_STATE_CACHED)))
549                     .isEqualTo(totalPowerCached);
550         }
551 
552         final BatteryConsumer.Key cpuFgKey = uidBatteryConsumer.getKey(
553                 BatteryConsumer.POWER_COMPONENT_CPU, BatteryConsumer.PROCESS_STATE_FOREGROUND);
554         if (processStateDataIncluded) {
555             assertThat(cpuFgKey).isNotNull();
556             assertThat(uidBatteryConsumer.getConsumedPower(cpuFgKey))
557                     .isEqualTo(cpuPowerForeground);
558             assertThat(uidBatteryConsumer.getUsageDurationMillis(cpuFgKey))
559                     .isEqualTo(cpuDurationForeground);
560         } else {
561             assertThat(cpuFgKey).isNull();
562         }
563 
564         final BatteryConsumer.Key cpuBgKey = uidBatteryConsumer.getKey(
565                 BatteryConsumer.POWER_COMPONENT_CPU, BatteryConsumer.PROCESS_STATE_BACKGROUND);
566         if (processStateDataIncluded) {
567             assertThat(cpuBgKey).isNotNull();
568             assertThat(uidBatteryConsumer.getConsumedPower(cpuBgKey))
569                     .isEqualTo(cpuPowerBackground);
570             assertThat(uidBatteryConsumer.getUsageDurationMillis(cpuBgKey))
571                     .isEqualTo(cpuDurationBackground);
572         } else {
573             assertThat(cpuBgKey).isNull();
574         }
575 
576         final BatteryConsumer.Key cpuFgsKey = uidBatteryConsumer.getKey(
577                 BatteryConsumer.POWER_COMPONENT_CPU,
578                 BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE);
579         if (processStateDataIncluded) {
580             assertThat(cpuFgsKey).isNotNull();
581             assertThat(uidBatteryConsumer.getConsumedPower(cpuFgsKey))
582                     .isEqualTo(cpuPowerFgs);
583             assertThat(uidBatteryConsumer.getUsageDurationMillis(cpuFgsKey))
584                     .isEqualTo(cpuDurationFgs);
585         } else {
586             assertThat(cpuFgsKey).isNotNull();
587         }
588 
589         final BatteryConsumer.Key cachedKey = uidBatteryConsumer.getKey(
590                 BatteryConsumer.POWER_COMPONENT_CPU,
591                 BatteryConsumer.PROCESS_STATE_CACHED);
592         if (processStateDataIncluded) {
593             assertThat(cachedKey).isNotNull();
594             assertThat(uidBatteryConsumer.getConsumedPower(cachedKey))
595                     .isEqualTo(cpuPowerCached);
596             assertThat(uidBatteryConsumer.getUsageDurationMillis(cachedKey))
597                     .isEqualTo(cpuDurationCached);
598         } else {
599             assertThat(cpuFgsKey).isNotNull();
600         }
601     }
602 
assertUserBatteryConsumer(UserBatteryConsumer userBatteryConsumer, int userId, int cpuPower, int customComponentPower, int cpuDuration, int customComponentDuration)603     private void assertUserBatteryConsumer(UserBatteryConsumer userBatteryConsumer,
604             int userId, int cpuPower, int customComponentPower,
605             int cpuDuration, int customComponentDuration) {
606         assertThat(userBatteryConsumer.getConsumedPower(
607                 BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower);
608         assertThat(userBatteryConsumer.getConsumedPowerForCustomComponent(
609                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower);
610         assertThat(userBatteryConsumer.getUsageDurationMillis(
611                 BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuDuration);
612         assertThat(userBatteryConsumer.getUsageDurationForCustomComponentMillis(
613                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(
614                 customComponentDuration);
615         assertThat(userBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
616         assertThat(userBatteryConsumer.getCustomPowerComponentName(
617                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
618     }
619 
assertAggregateBatteryConsumer(BatteryUsageStats batteryUsageStats, int aggregateBatteryConsumerScopeAllApps, int cpuPower, int customComponentPower, int cpuDuration, int customComponentDuration)620     private void assertAggregateBatteryConsumer(BatteryUsageStats batteryUsageStats,
621             int aggregateBatteryConsumerScopeAllApps, int cpuPower, int customComponentPower,
622             int cpuDuration, int customComponentDuration) {
623         final BatteryConsumer appsBatteryConsumer = batteryUsageStats.getAggregateBatteryConsumer(
624                 aggregateBatteryConsumerScopeAllApps);
625         assertThat(appsBatteryConsumer.getConsumedPower(
626                 BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuPower);
627         assertThat(appsBatteryConsumer.getConsumedPowerForCustomComponent(
628                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(customComponentPower);
629         assertThat(appsBatteryConsumer.getUsageDurationMillis(
630                 BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(cpuDuration);
631         assertThat(appsBatteryConsumer.getUsageDurationForCustomComponentMillis(
632                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(
633                 customComponentDuration);
634         assertThat(appsBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
635         assertThat(appsBatteryConsumer.getCustomPowerComponentName(
636                 BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
637     }
638 }
639