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