1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.internal.os; 18 19 import static android.os.BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS; 20 import static android.os.BatteryStats.STATS_SINCE_CHARGED; 21 import static android.os.BatteryStats.WAKE_TYPE_PARTIAL; 22 23 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU; 24 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY; 25 26 import android.app.ActivityManager; 27 import android.os.BatteryStats; 28 import android.os.BatteryStats.HistoryItem; 29 import android.os.BatteryStats.Uid.Sensor; 30 import android.os.Process; 31 import android.os.UserHandle; 32 import android.os.WorkSource; 33 import android.util.SparseLongArray; 34 import android.view.Display; 35 36 import androidx.test.filters.SmallTest; 37 38 import com.android.internal.os.BatteryStatsImpl.DualTimer; 39 import com.android.internal.os.BatteryStatsImpl.Uid; 40 import com.android.internal.power.MeasuredEnergyStats; 41 42 import junit.framework.TestCase; 43 44 import java.util.Arrays; 45 import java.util.HashMap; 46 import java.util.Map; 47 import java.util.function.IntConsumer; 48 49 /** 50 * Test various BatteryStatsImpl noteStart methods. 51 * 52 * Build/Install/Run: bit FrameworksCoreTests:com.android.internal.os.BatteryStatsNoteTest 53 * 54 * Alternatively, 55 * Build: m FrameworksCoreTests 56 * Install: adb install -r \ 57 * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk 58 * Run: adb shell am instrument -e class com.android.internal.os.BatteryStatsNoteTest -w \ 59 * com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner 60 */ 61 public class BatteryStatsNoteTest extends TestCase { 62 63 private static final int UID = 10500; 64 private static final int ISOLATED_APP_ID = Process.FIRST_ISOLATED_UID + 23; 65 private static final int ISOLATED_UID = UserHandle.getUid(0, ISOLATED_APP_ID); 66 private static final WorkSource WS = new WorkSource(UID); 67 68 /** 69 * Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. 70 */ 71 @SmallTest testNoteBluetoothScanResultLocked()72 public void testNoteBluetoothScanResultLocked() throws Exception { 73 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClocks()); 74 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 75 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 76 77 bi.noteBluetoothScanResultsFromSourceLocked(WS, 1); 78 bi.noteBluetoothScanResultsFromSourceLocked(WS, 100); 79 assertEquals(101, 80 bi.getUidStats().get(UID).getBluetoothScanResultCounter() 81 .getCountLocked(STATS_SINCE_CHARGED)); 82 BatteryStats.Counter bgCntr = bi.getUidStats().get(UID).getBluetoothScanResultBgCounter(); 83 if (bgCntr != null) { 84 assertEquals(0, bgCntr.getCountLocked(STATS_SINCE_CHARGED)); 85 } 86 87 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 88 bi.noteBluetoothScanResultsFromSourceLocked(WS, 17); 89 assertEquals(101 + 17, 90 bi.getUidStats().get(UID).getBluetoothScanResultCounter() 91 .getCountLocked(STATS_SINCE_CHARGED)); 92 assertEquals(17, 93 bi.getUidStats().get(UID).getBluetoothScanResultBgCounter() 94 .getCountLocked(STATS_SINCE_CHARGED)); 95 } 96 97 /** 98 * Test BatteryStatsImpl.Uid.noteStartWakeLocked. 99 */ 100 @SmallTest testNoteStartWakeLocked()101 public void testNoteStartWakeLocked() throws Exception { 102 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 103 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 104 105 int pid = 10; 106 String name = "name"; 107 108 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 109 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 110 bi.getUidStatsLocked(UID) 111 .noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); 112 113 clocks.realtime = clocks.uptime = 100; 114 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 115 116 clocks.realtime = clocks.uptime = 220; 117 bi.getUidStatsLocked(UID).noteStopWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); 118 119 BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID) 120 .getAggregatedPartialWakelockTimer(); 121 long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 122 long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 123 assertEquals(220_000, actualTime); 124 assertEquals(120_000, bgTime); 125 } 126 127 /** 128 * Test BatteryStatsImpl.Uid.noteStartWakeLocked for an isolated uid. 129 */ 130 @SmallTest testNoteStartWakeLocked_isolatedUid()131 public void testNoteStartWakeLocked_isolatedUid() throws Exception { 132 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 133 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 134 135 int pid = 10; 136 String name = "name"; 137 String historyName = "historyName"; 138 139 WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); 140 isolatedWorkChain.addNode(ISOLATED_UID, name); 141 142 // Map ISOLATED_UID to UID. 143 bi.addIsolatedUidLocked(ISOLATED_UID, UID); 144 145 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 146 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 147 bi.noteStartWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName, 148 WAKE_TYPE_PARTIAL, false); 149 150 clocks.realtime = clocks.uptime = 100; 151 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 152 153 clocks.realtime = clocks.uptime = 220; 154 bi.noteStopWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName, 155 WAKE_TYPE_PARTIAL); 156 157 // ISOLATED_UID wakelock time should be attributed to UID. 158 BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID) 159 .getAggregatedPartialWakelockTimer(); 160 long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 161 long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 162 assertEquals(220_000, actualTime); 163 assertEquals(120_000, bgTime); 164 } 165 166 /** 167 * Test BatteryStatsImpl.Uid.noteStartWakeLocked for an isolated uid, with a race where the 168 * isolated uid is removed from batterystats before the wakelock has been stopped. 169 */ 170 @SmallTest testNoteStartWakeLocked_isolatedUidRace()171 public void testNoteStartWakeLocked_isolatedUidRace() throws Exception { 172 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 173 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 174 175 int pid = 10; 176 String name = "name"; 177 String historyName = "historyName"; 178 179 WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); 180 isolatedWorkChain.addNode(ISOLATED_UID, name); 181 182 // Map ISOLATED_UID to UID. 183 bi.addIsolatedUidLocked(ISOLATED_UID, UID); 184 185 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 186 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 187 bi.noteStartWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName, 188 WAKE_TYPE_PARTIAL, false); 189 190 clocks.realtime = clocks.uptime = 100; 191 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 192 193 clocks.realtime = clocks.uptime = 150; 194 bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime); 195 196 clocks.realtime = clocks.uptime = 220; 197 bi.noteStopWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName, 198 WAKE_TYPE_PARTIAL); 199 200 // ISOLATED_UID wakelock time should be attributed to UID. 201 BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID) 202 .getAggregatedPartialWakelockTimer(); 203 long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 204 long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 205 assertEquals(220_000, actualTime); 206 assertEquals(120_000, bgTime); 207 } 208 209 210 /** 211 * Test BatteryStatsImpl.noteUidProcessStateLocked. 212 */ 213 @SmallTest testNoteUidProcessStateLocked()214 public void testNoteUidProcessStateLocked() throws Exception { 215 final MockClocks clocks = new MockClocks(); 216 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 217 218 // map of ActivityManager process states and how long to simulate run time in each state 219 Map<Integer, Integer> stateRuntimeMap = new HashMap<Integer, Integer>(); 220 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP, 1111); 221 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 1234); 222 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 2468); 223 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP_SLEEPING, 7531); 224 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 4455); 225 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 1337); 226 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BACKUP, 90210); 227 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_HEAVY_WEIGHT, 911); 228 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_SERVICE, 404); 229 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_RECEIVER, 31459); 230 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_HOME, 1123); 231 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_LAST_ACTIVITY, 5813); 232 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, 867); 233 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT, 5309); 234 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_EMPTY, 42); 235 236 bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); 237 238 for (Map.Entry<Integer, Integer> entry : stateRuntimeMap.entrySet()) { 239 bi.noteUidProcessStateLocked(UID, entry.getKey()); 240 clocks.realtime += entry.getValue(); 241 clocks.uptime = clocks.realtime; 242 } 243 244 long actualRunTimeUs; 245 long expectedRunTimeMs; 246 long elapsedTimeUs = clocks.realtime * 1000; 247 BatteryStats.Uid uid = bi.getUidStats().get(UID); 248 249 // compare runtime of process states to the Uid process states they map to 250 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP, elapsedTimeUs, 251 STATS_SINCE_CHARGED); 252 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP); 253 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 254 255 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE, 256 elapsedTimeUs, STATS_SINCE_CHARGED); 257 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 258 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 259 260 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING, 261 elapsedTimeUs, STATS_SINCE_CHARGED); 262 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP_SLEEPING); 263 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 264 265 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND, 266 elapsedTimeUs, STATS_SINCE_CHARGED); 267 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) 268 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); 269 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 270 271 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND, 272 elapsedTimeUs, STATS_SINCE_CHARGED); 273 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) 274 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BACKUP) 275 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_SERVICE) 276 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_RECEIVER); 277 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 278 279 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_CACHED, 280 elapsedTimeUs, STATS_SINCE_CHARGED); 281 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_HOME) 282 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_LAST_ACTIVITY) 283 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) 284 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT) 285 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_EMPTY); 286 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 287 288 // Special check for foreground service timer 289 actualRunTimeUs = uid.getForegroundServiceTimer().getTotalTimeLocked(elapsedTimeUs, 290 STATS_SINCE_CHARGED); 291 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 292 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 293 } 294 295 /** 296 * Test BatteryStatsImpl.updateTimeBasesLocked. 297 */ 298 @SmallTest testUpdateTimeBasesLocked()299 public void testUpdateTimeBasesLocked() throws Exception { 300 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 301 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 302 303 bi.updateTimeBasesLocked(false, Display.STATE_OFF, 0, 0); 304 assertFalse(bi.getOnBatteryTimeBase().isRunning()); 305 bi.updateTimeBasesLocked(false, Display.STATE_DOZE, 10, 10); 306 assertFalse(bi.getOnBatteryTimeBase().isRunning()); 307 bi.updateTimeBasesLocked(false, Display.STATE_ON, 20, 20); 308 assertFalse(bi.getOnBatteryTimeBase().isRunning()); 309 310 bi.updateTimeBasesLocked(true, Display.STATE_ON, 30, 30); 311 assertTrue(bi.getOnBatteryTimeBase().isRunning()); 312 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 313 bi.updateTimeBasesLocked(true, Display.STATE_DOZE, 40, 40); 314 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 315 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 40, 40); 316 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 317 } 318 319 /** 320 * Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly. 321 */ 322 @SmallTest testNoteScreenStateLocked()323 public void testNoteScreenStateLocked() throws Exception { 324 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 325 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 326 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 327 328 bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); 329 bi.noteScreenStateLocked(0, Display.STATE_ON); 330 331 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 332 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 333 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 334 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 335 336 bi.noteScreenStateLocked(0, Display.STATE_ON); 337 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 338 assertEquals(Display.STATE_ON, bi.getScreenState()); 339 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 340 341 bi.noteScreenStateLocked(0, Display.STATE_OFF); 342 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 343 assertEquals(Display.STATE_OFF, bi.getScreenState()); 344 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 345 346 bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND); 347 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 348 assertEquals(Display.STATE_DOZE_SUSPEND, bi.getScreenState()); 349 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 350 351 // STATE_VR note should map to STATE_ON. 352 bi.noteScreenStateLocked(0, Display.STATE_VR); 353 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 354 assertEquals(Display.STATE_ON, bi.getScreenState()); 355 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 356 357 // STATE_ON_SUSPEND note should map to STATE_ON. 358 bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND); 359 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 360 assertEquals(Display.STATE_ON, bi.getScreenState()); 361 // Transition from ON to ON state should not cause an External Sync 362 assertEquals(0, bi.getAndClearExternalStatsSyncFlags()); 363 } 364 365 /** 366 * Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly for 367 * multi display devices 368 */ 369 @SmallTest testNoteScreenStateLocked_multiDisplay()370 public void testNoteScreenStateLocked_multiDisplay() throws Exception { 371 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 372 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 373 bi.setDisplayCountLocked(2); 374 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 375 376 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 377 bi.noteScreenStateLocked(0, Display.STATE_OFF); 378 bi.noteScreenStateLocked(1, Display.STATE_OFF); 379 380 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 381 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 382 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 383 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 384 385 bi.noteScreenStateLocked(0, Display.STATE_ON); 386 assertEquals(Display.STATE_ON, bi.getScreenState()); 387 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 388 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 389 390 bi.noteScreenStateLocked(0, Display.STATE_OFF); 391 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 392 assertEquals(Display.STATE_OFF, bi.getScreenState()); 393 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 394 395 bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND); 396 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 397 assertEquals(Display.STATE_DOZE_SUSPEND, bi.getScreenState()); 398 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 399 400 // STATE_VR note should map to STATE_ON. 401 bi.noteScreenStateLocked(0, Display.STATE_VR); 402 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 403 assertEquals(Display.STATE_ON, bi.getScreenState()); 404 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 405 406 // STATE_ON_SUSPEND note should map to STATE_ON. 407 bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND); 408 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 409 assertEquals(Display.STATE_ON, bi.getScreenState()); 410 // Transition from ON to ON state should not cause an External Sync 411 assertEquals(0, bi.getAndClearExternalStatsSyncFlags()); 412 413 bi.noteScreenStateLocked(1, Display.STATE_DOZE); 414 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 415 // Should remain STATE_ON since display0 is still on. 416 assertEquals(Display.STATE_ON, bi.getScreenState()); 417 // Overall screen state did not change, so no need to sync CPU stats. 418 assertEquals(UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 419 420 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 421 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 422 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 423 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 424 425 bi.noteScreenStateLocked(0, Display.STATE_ON); 426 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 427 assertEquals(Display.STATE_ON, bi.getScreenState()); 428 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 429 430 bi.noteScreenStateLocked(0, Display.STATE_OFF); 431 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 432 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 433 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 434 435 bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND); 436 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 437 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 438 // Overall screen state did not change, so no need to sync CPU stats. 439 assertEquals(UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 440 441 bi.noteScreenStateLocked(0, Display.STATE_VR); 442 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 443 assertEquals(Display.STATE_ON, bi.getScreenState()); 444 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 445 446 bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND); 447 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 448 assertEquals(Display.STATE_ON, bi.getScreenState()); 449 assertEquals(0, bi.getAndClearExternalStatsSyncFlags()); 450 } 451 452 /* 453 * Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly. 454 * 455 * Unknown and doze should both be subset of off state 456 * 457 * Timeline 0----100----200----310----400------------1000 458 * Unknown ------- 459 * On ------- 460 * Off ------- ---------------------- 461 * Doze ---------------- 462 */ 463 @SmallTest testNoteScreenStateTimersLocked()464 public void testNoteScreenStateTimersLocked() throws Exception { 465 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 466 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 467 468 clocks.realtime = clocks.uptime = 100; 469 // Device startup, setOnBatteryLocked calls updateTimebases 470 bi.updateTimeBasesLocked(true, Display.STATE_UNKNOWN, 100_000, 100_000); 471 // Turn on display at 200us 472 clocks.realtime = clocks.uptime = 200; 473 bi.noteScreenStateLocked(0, Display.STATE_ON); 474 assertEquals(150_000, bi.computeBatteryRealtime(250_000, STATS_SINCE_CHARGED)); 475 assertEquals(100_000, bi.computeBatteryScreenOffRealtime(250_000, STATS_SINCE_CHARGED)); 476 assertEquals(50_000, bi.getScreenOnTime(250_000, STATS_SINCE_CHARGED)); 477 assertEquals(0, bi.getScreenDozeTime(250_000, STATS_SINCE_CHARGED)); 478 assertEquals(50_000, bi.getDisplayScreenOnTime(0, 250_000)); 479 assertEquals(0, bi.getDisplayScreenDozeTime(0, 250_000)); 480 481 clocks.realtime = clocks.uptime = 310; 482 bi.noteScreenStateLocked(0, Display.STATE_OFF); 483 assertEquals(250_000, bi.computeBatteryRealtime(350_000, STATS_SINCE_CHARGED)); 484 assertEquals(140_000, bi.computeBatteryScreenOffRealtime(350_000, STATS_SINCE_CHARGED)); 485 assertEquals(110_000, bi.getScreenOnTime(350_000, STATS_SINCE_CHARGED)); 486 assertEquals(0, bi.getScreenDozeTime(350_000, STATS_SINCE_CHARGED)); 487 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 350_000)); 488 assertEquals(0, bi.getDisplayScreenDozeTime(0, 350_000)); 489 490 clocks.realtime = clocks.uptime = 400; 491 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 492 assertEquals(400_000, bi.computeBatteryRealtime(500_000, STATS_SINCE_CHARGED)); 493 assertEquals(290_000, bi.computeBatteryScreenOffRealtime(500_000, STATS_SINCE_CHARGED)); 494 assertEquals(110_000, bi.getScreenOnTime(500_000, STATS_SINCE_CHARGED)); 495 assertEquals(100_000, bi.getScreenDozeTime(500_000, STATS_SINCE_CHARGED)); 496 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 500_000)); 497 assertEquals(100_000, bi.getDisplayScreenDozeTime(0, 500_000)); 498 499 clocks.realtime = clocks.uptime = 1000; 500 bi.noteScreenStateLocked(0, Display.STATE_OFF); 501 assertEquals(1400_000, bi.computeBatteryRealtime(1500_000, STATS_SINCE_CHARGED)); 502 assertEquals(1290_000, bi.computeBatteryScreenOffRealtime(1500_000, STATS_SINCE_CHARGED)); 503 assertEquals(110_000, bi.getScreenOnTime(1500_000, STATS_SINCE_CHARGED)); 504 assertEquals(600_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED)); 505 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1500_000)); 506 assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1500_000)); 507 } 508 509 /* 510 * Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly for multi display 511 * devices. 512 */ 513 @SmallTest testNoteScreenStateTimersLocked_multiDisplay()514 public void testNoteScreenStateTimersLocked_multiDisplay() throws Exception { 515 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 516 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 517 bi.setDisplayCountLocked(2); 518 519 clocks.realtime = clocks.uptime = 100; 520 // Device startup, setOnBatteryLocked calls updateTimebases 521 bi.updateTimeBasesLocked(true, Display.STATE_UNKNOWN, 100_000, 100_000); 522 // Turn on display at 200us 523 clocks.realtime = clocks.uptime = 200; 524 bi.noteScreenStateLocked(0, Display.STATE_ON); 525 bi.noteScreenStateLocked(1, Display.STATE_OFF); 526 assertEquals(150_000, bi.computeBatteryRealtime(250_000, STATS_SINCE_CHARGED)); 527 assertEquals(100_000, bi.computeBatteryScreenOffRealtime(250_000, STATS_SINCE_CHARGED)); 528 assertEquals(50_000, bi.getScreenOnTime(250_000, STATS_SINCE_CHARGED)); 529 assertEquals(0, bi.getScreenDozeTime(250_000, STATS_SINCE_CHARGED)); 530 assertEquals(50_000, bi.getDisplayScreenOnTime(0, 250_000)); 531 assertEquals(0, bi.getDisplayScreenDozeTime(0, 250_000)); 532 assertEquals(0, bi.getDisplayScreenOnTime(1, 250_000)); 533 assertEquals(0, bi.getDisplayScreenDozeTime(1, 250_000)); 534 535 clocks.realtime = clocks.uptime = 310; 536 bi.noteScreenStateLocked(0, Display.STATE_OFF); 537 assertEquals(250_000, bi.computeBatteryRealtime(350_000, STATS_SINCE_CHARGED)); 538 assertEquals(140_000, bi.computeBatteryScreenOffRealtime(350_000, STATS_SINCE_CHARGED)); 539 assertEquals(110_000, bi.getScreenOnTime(350_000, STATS_SINCE_CHARGED)); 540 assertEquals(0, bi.getScreenDozeTime(350_000, STATS_SINCE_CHARGED)); 541 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 350_000)); 542 assertEquals(0, bi.getDisplayScreenDozeTime(0, 350_000)); 543 assertEquals(0, bi.getDisplayScreenOnTime(1, 350_000)); 544 assertEquals(0, bi.getDisplayScreenDozeTime(1, 350_000)); 545 546 clocks.realtime = clocks.uptime = 400; 547 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 548 assertEquals(400_000, bi.computeBatteryRealtime(500_000, STATS_SINCE_CHARGED)); 549 assertEquals(290_000, bi.computeBatteryScreenOffRealtime(500_000, STATS_SINCE_CHARGED)); 550 assertEquals(110_000, bi.getScreenOnTime(500_000, STATS_SINCE_CHARGED)); 551 assertEquals(100_000, bi.getScreenDozeTime(500_000, STATS_SINCE_CHARGED)); 552 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 500_000)); 553 assertEquals(100_000, bi.getDisplayScreenDozeTime(0, 500_000)); 554 assertEquals(0, bi.getDisplayScreenOnTime(1, 500_000)); 555 assertEquals(0, bi.getDisplayScreenDozeTime(1, 500_000)); 556 557 clocks.realtime = clocks.uptime = 1000; 558 bi.noteScreenStateLocked(0, Display.STATE_OFF); 559 assertEquals(1000_000, bi.computeBatteryRealtime(1100_000, STATS_SINCE_CHARGED)); 560 assertEquals(890_000, bi.computeBatteryScreenOffRealtime(1100_000, STATS_SINCE_CHARGED)); 561 assertEquals(110_000, bi.getScreenOnTime(1100_000, STATS_SINCE_CHARGED)); 562 assertEquals(600_000, bi.getScreenDozeTime(1100_000, STATS_SINCE_CHARGED)); 563 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1100_000)); 564 assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1100_000)); 565 assertEquals(0, bi.getDisplayScreenOnTime(1, 1100_000)); 566 assertEquals(0, bi.getDisplayScreenDozeTime(1, 1100_000)); 567 568 clocks.realtime = clocks.uptime = 1200; 569 // Change state of second display to doze 570 bi.noteScreenStateLocked(1, Display.STATE_DOZE); 571 assertEquals(1150_000, bi.computeBatteryRealtime(1250_000, STATS_SINCE_CHARGED)); 572 assertEquals(1040_000, bi.computeBatteryScreenOffRealtime(1250_000, STATS_SINCE_CHARGED)); 573 assertEquals(110_000, bi.getScreenOnTime(1250_000, STATS_SINCE_CHARGED)); 574 assertEquals(650_000, bi.getScreenDozeTime(1250_000, STATS_SINCE_CHARGED)); 575 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1250_000)); 576 assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1250_000)); 577 assertEquals(0, bi.getDisplayScreenOnTime(1, 1250_000)); 578 assertEquals(50_000, bi.getDisplayScreenDozeTime(1, 1250_000)); 579 580 clocks.realtime = clocks.uptime = 1310; 581 bi.noteScreenStateLocked(0, Display.STATE_ON); 582 assertEquals(1250_000, bi.computeBatteryRealtime(1350_000, STATS_SINCE_CHARGED)); 583 assertEquals(1100_000, bi.computeBatteryScreenOffRealtime(1350_000, STATS_SINCE_CHARGED)); 584 assertEquals(150_000, bi.getScreenOnTime(1350_000, STATS_SINCE_CHARGED)); 585 assertEquals(710_000, bi.getScreenDozeTime(1350_000, STATS_SINCE_CHARGED)); 586 assertEquals(150_000, bi.getDisplayScreenOnTime(0, 1350_000)); 587 assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1350_000)); 588 assertEquals(0, bi.getDisplayScreenOnTime(1, 1350_000)); 589 assertEquals(150_000, bi.getDisplayScreenDozeTime(1, 1350_000)); 590 591 clocks.realtime = clocks.uptime = 1400; 592 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 593 assertEquals(1400_000, bi.computeBatteryRealtime(1500_000, STATS_SINCE_CHARGED)); 594 assertEquals(1200_000, bi.computeBatteryScreenOffRealtime(1500_000, STATS_SINCE_CHARGED)); 595 assertEquals(200_000, bi.getScreenOnTime(1500_000, STATS_SINCE_CHARGED)); 596 assertEquals(810_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED)); 597 assertEquals(200_000, bi.getDisplayScreenOnTime(0, 1500_000)); 598 assertEquals(700_000, bi.getDisplayScreenDozeTime(0, 1500_000)); 599 assertEquals(0, bi.getDisplayScreenOnTime(1, 1500_000)); 600 assertEquals(300_000, bi.getDisplayScreenDozeTime(1, 1500_000)); 601 602 clocks.realtime = clocks.uptime = 2000; 603 bi.noteScreenStateLocked(0, Display.STATE_OFF); 604 assertEquals(2000_000, bi.computeBatteryRealtime(2100_000, STATS_SINCE_CHARGED)); 605 assertEquals(1800_000, bi.computeBatteryScreenOffRealtime(2100_000, STATS_SINCE_CHARGED)); 606 assertEquals(200_000, bi.getScreenOnTime(2100_000, STATS_SINCE_CHARGED)); 607 assertEquals(1410_000, bi.getScreenDozeTime(2100_000, STATS_SINCE_CHARGED)); 608 assertEquals(200_000, bi.getDisplayScreenOnTime(0, 2100_000)); 609 assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2100_000)); 610 assertEquals(0, bi.getDisplayScreenOnTime(1, 2100_000)); 611 assertEquals(900_000, bi.getDisplayScreenDozeTime(1, 2100_000)); 612 613 614 clocks.realtime = clocks.uptime = 2200; 615 // Change state of second display to on 616 bi.noteScreenStateLocked(1, Display.STATE_ON); 617 assertEquals(2150_000, bi.computeBatteryRealtime(2250_000, STATS_SINCE_CHARGED)); 618 assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2250_000, STATS_SINCE_CHARGED)); 619 assertEquals(250_000, bi.getScreenOnTime(2250_000, STATS_SINCE_CHARGED)); 620 assertEquals(1510_000, bi.getScreenDozeTime(2250_000, STATS_SINCE_CHARGED)); 621 assertEquals(200_000, bi.getDisplayScreenOnTime(0, 2250_000)); 622 assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2250_000)); 623 assertEquals(50_000, bi.getDisplayScreenOnTime(1, 2250_000)); 624 assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2250_000)); 625 626 clocks.realtime = clocks.uptime = 2310; 627 bi.noteScreenStateLocked(0, Display.STATE_ON); 628 assertEquals(2250_000, bi.computeBatteryRealtime(2350_000, STATS_SINCE_CHARGED)); 629 assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2350_000, STATS_SINCE_CHARGED)); 630 assertEquals(350_000, bi.getScreenOnTime(2350_000, STATS_SINCE_CHARGED)); 631 assertEquals(1510_000, bi.getScreenDozeTime(2350_000, STATS_SINCE_CHARGED)); 632 assertEquals(240_000, bi.getDisplayScreenOnTime(0, 2350_000)); 633 assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2350_000)); 634 assertEquals(150_000, bi.getDisplayScreenOnTime(1, 2350_000)); 635 assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2350_000)); 636 637 clocks.realtime = clocks.uptime = 2400; 638 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 639 assertEquals(2400_000, bi.computeBatteryRealtime(2500_000, STATS_SINCE_CHARGED)); 640 assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2500_000, STATS_SINCE_CHARGED)); 641 assertEquals(500_000, bi.getScreenOnTime(2500_000, STATS_SINCE_CHARGED)); 642 assertEquals(1510_000, bi.getScreenDozeTime(2500_000, STATS_SINCE_CHARGED)); 643 assertEquals(290_000, bi.getDisplayScreenOnTime(0, 2500_000)); 644 assertEquals(1300_000, bi.getDisplayScreenDozeTime(0, 2500_000)); 645 assertEquals(300_000, bi.getDisplayScreenOnTime(1, 2500_000)); 646 assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2500_000)); 647 648 clocks.realtime = clocks.uptime = 3000; 649 bi.noteScreenStateLocked(0, Display.STATE_OFF); 650 assertEquals(3000_000, bi.computeBatteryRealtime(3100_000, STATS_SINCE_CHARGED)); 651 assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(3100_000, STATS_SINCE_CHARGED)); 652 assertEquals(1100_000, bi.getScreenOnTime(3100_000, STATS_SINCE_CHARGED)); 653 assertEquals(1510_000, bi.getScreenDozeTime(3100_000, STATS_SINCE_CHARGED)); 654 assertEquals(290_000, bi.getDisplayScreenOnTime(0, 3100_000)); 655 assertEquals(1800_000, bi.getDisplayScreenDozeTime(0, 3100_000)); 656 assertEquals(900_000, bi.getDisplayScreenOnTime(1, 3100_000)); 657 assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 3100_000)); 658 } 659 660 661 /** 662 * Test BatteryStatsImpl.noteScreenBrightnessLocked updates timers correctly. 663 */ 664 @SmallTest testScreenBrightnessLocked_multiDisplay()665 public void testScreenBrightnessLocked_multiDisplay() throws Exception { 666 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 667 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 668 669 final int numDisplay = 2; 670 bi.setDisplayCountLocked(numDisplay); 671 672 673 final long[] overallExpected = new long[NUM_SCREEN_BRIGHTNESS_BINS]; 674 final long[][] perDisplayExpected = new long[numDisplay][NUM_SCREEN_BRIGHTNESS_BINS]; 675 class Bookkeeper { 676 public long currentTimeMs = 100; 677 public int overallActiveBin = -1; 678 public int[] perDisplayActiveBin = new int[numDisplay]; 679 } 680 final Bookkeeper bk = new Bookkeeper(); 681 Arrays.fill(bk.perDisplayActiveBin, -1); 682 683 IntConsumer incrementTime = inc -> { 684 bk.currentTimeMs += inc; 685 if (bk.overallActiveBin >= 0) { 686 overallExpected[bk.overallActiveBin] += inc; 687 } 688 for (int i = 0; i < numDisplay; i++) { 689 final int bin = bk.perDisplayActiveBin[i]; 690 if (bin >= 0) { 691 perDisplayExpected[i][bin] += inc; 692 } 693 } 694 clocks.realtime = clocks.uptime = bk.currentTimeMs; 695 }; 696 697 bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); 698 bi.noteScreenStateLocked(0, Display.STATE_ON); 699 bi.noteScreenStateLocked(1, Display.STATE_ON); 700 701 incrementTime.accept(100); 702 bi.noteScreenBrightnessLocked(0, 25); 703 bi.noteScreenBrightnessLocked(1, 25); 704 // floor(25/256*5) = bin 0 705 bk.overallActiveBin = 0; 706 bk.perDisplayActiveBin[0] = 0; 707 bk.perDisplayActiveBin[1] = 0; 708 709 incrementTime.accept(50); 710 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 711 712 incrementTime.accept(13); 713 bi.noteScreenBrightnessLocked(0, 100); 714 // floor(25/256*5) = bin 1 715 bk.overallActiveBin = 1; 716 bk.perDisplayActiveBin[0] = 1; 717 718 incrementTime.accept(44); 719 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 720 721 incrementTime.accept(22); 722 bi.noteScreenBrightnessLocked(1, 200); 723 // floor(200/256*5) = bin 3 724 bk.overallActiveBin = 3; 725 bk.perDisplayActiveBin[1] = 3; 726 727 incrementTime.accept(33); 728 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 729 730 incrementTime.accept(77); 731 bi.noteScreenBrightnessLocked(0, 150); 732 // floor(150/256*5) = bin 2 733 // Overall active bin should not change 734 bk.perDisplayActiveBin[0] = 2; 735 736 incrementTime.accept(88); 737 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 738 739 incrementTime.accept(11); 740 bi.noteScreenStateLocked(1, Display.STATE_OFF); 741 // Display 1 should timers should stop incrementing 742 // Overall active bin should fallback to display 0's bin 743 bk.overallActiveBin = 2; 744 bk.perDisplayActiveBin[1] = -1; 745 746 incrementTime.accept(99); 747 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 748 749 incrementTime.accept(200); 750 bi.noteScreenBrightnessLocked(0, 255); 751 // floor(150/256*5) = bin 4 752 bk.overallActiveBin = 4; 753 bk.perDisplayActiveBin[0] = 4; 754 755 incrementTime.accept(300); 756 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 757 758 incrementTime.accept(200); 759 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 760 // No displays are on. No brightness timers should be active. 761 bk.overallActiveBin = -1; 762 bk.perDisplayActiveBin[0] = -1; 763 764 incrementTime.accept(300); 765 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 766 767 incrementTime.accept(400); 768 bi.noteScreenStateLocked(1, Display.STATE_ON); 769 // Display 1 turned back on. 770 bk.overallActiveBin = 3; 771 bk.perDisplayActiveBin[1] = 3; 772 773 incrementTime.accept(500); 774 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 775 776 incrementTime.accept(600); 777 bi.noteScreenStateLocked(0, Display.STATE_ON); 778 // Display 0 turned back on. 779 bk.overallActiveBin = 4; 780 bk.perDisplayActiveBin[0] = 4; 781 782 incrementTime.accept(700); 783 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 784 } 785 786 @SmallTest 787 @SkipPresubmit("b/180015146") testAlarmStartAndFinishLocked()788 public void testAlarmStartAndFinishLocked() throws Exception { 789 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 790 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 791 bi.setRecordAllHistoryLocked(true); 792 bi.forceRecordAllHistory(); 793 794 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 795 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 796 797 clocks.realtime = clocks.uptime = 100; 798 bi.noteAlarmStartLocked("foo", null, UID); 799 clocks.realtime = clocks.uptime = 5000; 800 bi.noteAlarmFinishLocked("foo", null, UID); 801 802 HistoryItem item = new HistoryItem(); 803 assertTrue(bi.startIteratingHistoryLocked()); 804 805 assertTrue(bi.getNextHistoryLocked(item)); 806 assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); 807 assertEquals("foo", item.eventTag.string); 808 assertEquals(UID, item.eventTag.uid); 809 810 // TODO(narayan): Figure out why this event is written to the history buffer. See 811 // test below where it is being interspersed between multiple START events too. 812 assertTrue(bi.getNextHistoryLocked(item)); 813 assertEquals(HistoryItem.EVENT_NONE, item.eventCode); 814 815 assertTrue(bi.getNextHistoryLocked(item)); 816 assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); 817 assertTrue(item.isDeltaData()); 818 assertEquals("foo", item.eventTag.string); 819 assertEquals(UID, item.eventTag.uid); 820 821 assertFalse(bi.getNextHistoryLocked(item)); 822 } 823 824 @SmallTest 825 @SkipPresubmit("b/180015146") testAlarmStartAndFinishLocked_workSource()826 public void testAlarmStartAndFinishLocked_workSource() throws Exception { 827 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 828 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 829 bi.setRecordAllHistoryLocked(true); 830 bi.forceRecordAllHistory(); 831 832 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 833 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 834 835 WorkSource ws = new WorkSource(); 836 ws.add(100); 837 ws.createWorkChain().addNode(500, "tag"); 838 bi.noteAlarmStartLocked("foo", ws, UID); 839 clocks.realtime = clocks.uptime = 5000; 840 bi.noteAlarmFinishLocked("foo", ws, UID); 841 842 HistoryItem item = new HistoryItem(); 843 assertTrue(bi.startIteratingHistoryLocked()); 844 845 assertTrue(bi.getNextHistoryLocked(item)); 846 assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); 847 assertEquals("foo", item.eventTag.string); 848 assertEquals(100, item.eventTag.uid); 849 850 assertTrue(bi.getNextHistoryLocked(item)); 851 assertEquals(HistoryItem.EVENT_NONE, item.eventCode); 852 853 assertTrue(bi.getNextHistoryLocked(item)); 854 assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); 855 assertEquals("foo", item.eventTag.string); 856 assertEquals(500, item.eventTag.uid); 857 858 assertTrue(bi.getNextHistoryLocked(item)); 859 assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); 860 assertEquals("foo", item.eventTag.string); 861 assertEquals(100, item.eventTag.uid); 862 863 assertTrue(bi.getNextHistoryLocked(item)); 864 assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); 865 assertEquals("foo", item.eventTag.string); 866 assertEquals(500, item.eventTag.uid); 867 } 868 869 @SmallTest testNoteWakupAlarmLocked()870 public void testNoteWakupAlarmLocked() { 871 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 872 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 873 bi.setRecordAllHistoryLocked(true); 874 bi.forceRecordAllHistory(); 875 bi.mForceOnBattery = true; 876 877 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 878 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 879 880 bi.noteWakupAlarmLocked("com.foo.bar", UID, null, "tag"); 881 882 Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); 883 assertEquals(1, pkg.getWakeupAlarmStats().get("tag").getCountLocked(STATS_SINCE_CHARGED)); 884 assertEquals(1, pkg.getWakeupAlarmStats().size()); 885 } 886 887 @SmallTest testNoteWakupAlarmLocked_workSource_uid()888 public void testNoteWakupAlarmLocked_workSource_uid() { 889 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 890 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 891 bi.setRecordAllHistoryLocked(true); 892 bi.forceRecordAllHistory(); 893 bi.mForceOnBattery = true; 894 895 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 896 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 897 898 WorkSource ws = new WorkSource(); 899 ws.add(100); 900 901 // When a WorkSource is present, "UID" should not be used - only the uids present in the 902 // WorkSource should be reported. 903 bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag"); 904 Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); 905 assertEquals(0, pkg.getWakeupAlarmStats().size()); 906 pkg = bi.getPackageStatsLocked(100, "com.foo.bar"); 907 assertEquals(1, pkg.getWakeupAlarmStats().size()); 908 909 // If the WorkSource contains a "name", it should be interpreted as a package name and 910 // the packageName supplied as an argument must be ignored. 911 ws = new WorkSource(); 912 ws.add(100, "com.foo.baz_alternate"); 913 bi.noteWakupAlarmLocked("com.foo.baz", UID, ws, "tag"); 914 pkg = bi.getPackageStatsLocked(100, "com.foo.baz"); 915 assertEquals(0, pkg.getWakeupAlarmStats().size()); 916 pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate"); 917 assertEquals(1, pkg.getWakeupAlarmStats().size()); 918 } 919 920 @SmallTest testNoteWakupAlarmLocked_workSource_workChain()921 public void testNoteWakupAlarmLocked_workSource_workChain() { 922 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 923 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 924 bi.setRecordAllHistoryLocked(true); 925 bi.forceRecordAllHistory(); 926 bi.mForceOnBattery = true; 927 928 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 929 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 930 931 WorkSource ws = new WorkSource(); 932 ws.createWorkChain().addNode(100, "com.foo.baz_alternate"); 933 bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag"); 934 935 // For WorkChains, again we must only attribute to the uids present in the WorkSource 936 // (and not to "UID"). However, unlike the older "tags" we do not change the packagename 937 // supplied as an argument, given that we're logging the entire attribution chain. 938 Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); 939 assertEquals(0, pkg.getWakeupAlarmStats().size()); 940 pkg = bi.getPackageStatsLocked(100, "com.foo.bar"); 941 assertEquals(1, pkg.getWakeupAlarmStats().size()); 942 pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate"); 943 assertEquals(0, pkg.getWakeupAlarmStats().size()); 944 } 945 946 @SmallTest testNoteGpsChanged()947 public void testNoteGpsChanged() { 948 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 949 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 950 bi.setRecordAllHistoryLocked(true); 951 bi.forceRecordAllHistory(); 952 bi.mForceOnBattery = true; 953 954 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 955 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 956 957 WorkSource ws = new WorkSource(); 958 ws.add(UID); 959 960 bi.noteGpsChangedLocked(new WorkSource(), ws); 961 DualTimer t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false); 962 assertNotNull(t); 963 assertTrue(t.isRunningLocked()); 964 965 bi.noteGpsChangedLocked(ws, new WorkSource()); 966 t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false); 967 assertFalse(t.isRunningLocked()); 968 } 969 970 @SmallTest testNoteGpsChanged_workSource()971 public void testNoteGpsChanged_workSource() { 972 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 973 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 974 bi.setRecordAllHistoryLocked(true); 975 bi.forceRecordAllHistory(); 976 bi.mForceOnBattery = true; 977 978 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 979 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 980 981 WorkSource ws = new WorkSource(); 982 ws.createWorkChain().addNode(UID, "com.foo"); 983 984 bi.noteGpsChangedLocked(new WorkSource(), ws); 985 DualTimer t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false); 986 assertNotNull(t); 987 assertTrue(t.isRunningLocked()); 988 989 bi.noteGpsChangedLocked(ws, new WorkSource()); 990 t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false); 991 assertFalse(t.isRunningLocked()); 992 } 993 994 @SmallTest testUpdateDisplayMeasuredEnergyStatsLocked()995 public void testUpdateDisplayMeasuredEnergyStatsLocked() { 996 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 997 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 998 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 999 1000 clocks.realtime = 0; 1001 int[] screen = new int[]{Display.STATE_OFF}; 1002 boolean battery = false; 1003 1004 final int uid1 = 10500; 1005 final int uid2 = 10501; 1006 long blame1 = 0; 1007 long blame2 = 0; 1008 long globalDoze = 0; 1009 1010 // Case A: uid1 off, uid2 off, battery off, screen off 1011 bi.updateTimeBasesLocked(battery, screen[0], clocks.realtime * 1000, 0); 1012 bi.setOnBatteryInternal(battery); 1013 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{500_000}, screen, clocks.realtime); 1014 checkMeasuredCharge("A", uid1, blame1, uid2, blame2, globalDoze, bi); 1015 1016 // Case B: uid1 off, uid2 off, battery ON, screen off 1017 clocks.realtime += 17; 1018 battery = true; 1019 bi.updateTimeBasesLocked(battery, screen[0], clocks.realtime * 1000, 0); 1020 bi.setOnBatteryInternal(battery); 1021 clocks.realtime += 19; 1022 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{510_000}, screen, clocks.realtime); 1023 checkMeasuredCharge("B", uid1, blame1, uid2, blame2, globalDoze, bi); 1024 1025 // Case C: uid1 ON, uid2 off, battery on, screen off 1026 clocks.realtime += 18; 1027 setFgState(uid1, true, bi); 1028 clocks.realtime += 18; 1029 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{520_000}, screen, clocks.realtime); 1030 checkMeasuredCharge("C", uid1, blame1, uid2, blame2, globalDoze, bi); 1031 1032 // Case D: uid1 on, uid2 off, battery on, screen ON 1033 clocks.realtime += 17; 1034 screen[0] = Display.STATE_ON; 1035 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{521_000}, screen, clocks.realtime); 1036 blame1 += 0; // Screen had been off during the measurement period 1037 checkMeasuredCharge("D.1", uid1, blame1, uid2, blame2, globalDoze, bi); 1038 clocks.realtime += 101; 1039 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{530_000}, screen, clocks.realtime); 1040 blame1 += 530_000; 1041 checkMeasuredCharge("D.2", uid1, blame1, uid2, blame2, globalDoze, bi); 1042 1043 // Case E: uid1 on, uid2 ON, battery on, screen on 1044 clocks.realtime += 20; 1045 setFgState(uid2, true, bi); 1046 clocks.realtime += 40; 1047 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{540_000}, screen, clocks.realtime); 1048 // In the past 60ms, sum of fg is 20+40+40=100ms. uid1 is blamed for 60/100; uid2 for 40/100 1049 blame1 += 540_000 * (20 + 40) / (20 + 40 + 40); 1050 blame2 += 540_000 * (0 + 40) / (20 + 40 + 40); 1051 checkMeasuredCharge("E", uid1, blame1, uid2, blame2, globalDoze, bi); 1052 1053 // Case F: uid1 on, uid2 OFF, battery on, screen on 1054 clocks.realtime += 40; 1055 setFgState(uid2, false, bi); 1056 clocks.realtime += 120; 1057 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{550_000}, screen, clocks.realtime); 1058 // In the past 160ms, sum f fg is 200ms. uid1 is blamed for 40+120 of it; uid2 for 40 of it. 1059 blame1 += 550_000 * (40 + 120) / (40 + 40 + 120); 1060 blame2 += 550_000 * (40 + 0) / (40 + 40 + 120); 1061 checkMeasuredCharge("F", uid1, blame1, uid2, blame2, globalDoze, bi); 1062 1063 // Case G: uid1 on, uid2 off, battery on, screen DOZE 1064 clocks.realtime += 5; 1065 screen[0] = Display.STATE_DOZE; 1066 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{570_000}, screen, clocks.realtime); 1067 blame1 += 570_000; // All of this pre-doze time is blamed on uid1. 1068 checkMeasuredCharge("G", uid1, blame1, uid2, blame2, globalDoze, bi); 1069 1070 // Case H: uid1 on, uid2 off, battery on, screen ON 1071 clocks.realtime += 6; 1072 screen[0] = Display.STATE_ON; 1073 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{580_000}, screen, clocks.realtime); 1074 blame1 += 0; // The screen had been doze during the energy period 1075 globalDoze += 580_000; 1076 checkMeasuredCharge("H", uid1, blame1, uid2, blame2, globalDoze, bi); 1077 } 1078 1079 @SmallTest testUpdateCustomMeasuredEnergyStatsLocked_neverCalled()1080 public void testUpdateCustomMeasuredEnergyStatsLocked_neverCalled() { 1081 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 1082 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1083 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 1084 bi.setOnBatteryInternal(true); 1085 1086 final int uid1 = 11500; 1087 final int uid2 = 11501; 1088 1089 // Initially, all custom buckets report charge of 0. 1090 checkCustomBatteryConsumption("0", 0, 0, uid1, 0, 0, uid2, 0, 0, bi); 1091 } 1092 1093 @SmallTest testUpdateCustomMeasuredEnergyStatsLocked()1094 public void testUpdateCustomMeasuredEnergyStatsLocked() { 1095 final MockClocks clocks = new MockClocks(); // holds realtime and uptime in ms 1096 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1097 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 1098 1099 final int bucketA = 0; // Custom bucket 0 1100 final int bucketB = 1; // Custom bucket 1 1101 1102 long totalBlameA = 0; // Total charge consumption for bucketA (may exceed sum of uids) 1103 long totalBlameB = 0; // Total charge consumption for bucketB (may exceed sum of uids) 1104 1105 final int uid1 = 10500; 1106 long blame1A = 0; // Blame for uid1 in bucketA 1107 long blame1B = 0; // Blame for uid1 in bucketB 1108 1109 final int uid2 = 10501; 1110 long blame2A = 0; // Blame for uid2 in bucketA 1111 long blame2B = 0; // Blame for uid2 in bucketB 1112 1113 final SparseLongArray newChargesA = new SparseLongArray(2); 1114 final SparseLongArray newChargesB = new SparseLongArray(2); 1115 1116 1117 // ----- Case A: battery off (so blame does not increase) 1118 bi.setOnBatteryInternal(false); 1119 1120 newChargesA.put(uid1, 20_000); 1121 // Implicit newChargesA.put(uid2, 0); 1122 bi.updateCustomMeasuredEnergyStatsLocked(bucketA, 500_000, newChargesA); 1123 1124 newChargesB.put(uid1, 60_000); 1125 // Implicit newChargesB.put(uid2, 0); 1126 bi.updateCustomMeasuredEnergyStatsLocked(bucketB, 700_000, newChargesB); 1127 1128 checkCustomBatteryConsumption( 1129 "A", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi); 1130 1131 1132 // ----- Case B: battery on 1133 bi.setOnBatteryInternal(true); 1134 1135 newChargesA.put(uid1, 7_000); blame1A += 7_000; 1136 // Implicit newChargesA.put(uid2, 0); blame2A += 0; 1137 bi.updateCustomMeasuredEnergyStatsLocked(bucketA, 310_000, newChargesA); 1138 totalBlameA += 310_000; 1139 1140 newChargesB.put(uid1, 63_000); blame1B += 63_000; 1141 newChargesB.put(uid2, 15_000); blame2B += 15_000; 1142 bi.updateCustomMeasuredEnergyStatsLocked(bucketB, 790_000, newChargesB); 1143 totalBlameB += 790_000; 1144 1145 checkCustomBatteryConsumption( 1146 "B", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi); 1147 1148 1149 // ----- Case C: battery still on 1150 newChargesA.delete(uid1); blame1A += 0; 1151 newChargesA.put(uid2, 16_000); blame2A += 16_000; 1152 bi.updateCustomMeasuredEnergyStatsLocked(bucketA, 560_000, newChargesA); 1153 totalBlameA += 560_000; 1154 1155 bi.updateCustomMeasuredEnergyStatsLocked(bucketB, 10_000, null); 1156 totalBlameB += 10_000; 1157 1158 checkCustomBatteryConsumption( 1159 "C", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi); 1160 1161 1162 // ----- Case D: battery still on 1163 bi.updateCustomMeasuredEnergyStatsLocked(bucketA, 0, newChargesA); 1164 bi.updateCustomMeasuredEnergyStatsLocked(bucketB, 15_000, new SparseLongArray(1)); 1165 totalBlameB += 15_000; 1166 checkCustomBatteryConsumption( 1167 "D", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi); 1168 } 1169 setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi)1170 private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) { 1171 // Note that noteUidProcessStateLocked uses ActivityManager process states. 1172 if (fgOn) { 1173 bi.noteActivityResumedLocked(uid); 1174 bi.noteUidProcessStateLocked(uid, ActivityManager.PROCESS_STATE_TOP); 1175 } else { 1176 bi.noteActivityPausedLocked(uid); 1177 bi.noteUidProcessStateLocked(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 1178 } 1179 } 1180 checkMeasuredCharge(String caseName, int uid1, long blame1, int uid2, long blame2, long globalDoze, MockBatteryStatsImpl bi)1181 private void checkMeasuredCharge(String caseName, int uid1, long blame1, int uid2, long blame2, 1182 long globalDoze, MockBatteryStatsImpl bi) { 1183 final int bucket = MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON; 1184 1185 assertEquals("Wrong uid1 blame for Case " + caseName, blame1, 1186 bi.getUidStatsLocked(uid1).getMeasuredBatteryConsumptionUC(bucket)); 1187 1188 assertEquals("Wrong uid2 blame for Case " + caseName, blame2, 1189 bi.getUidStatsLocked(uid2).getMeasuredBatteryConsumptionUC(bucket)); 1190 1191 assertEquals("Wrong total blame for Case " + caseName, blame1 + blame2, 1192 bi.getScreenOnMeasuredBatteryConsumptionUC()); 1193 1194 assertEquals("Wrong doze for Case " + caseName, globalDoze, 1195 bi.getScreenDozeMeasuredBatteryConsumptionUC()); 1196 } 1197 checkCustomBatteryConsumption(String caseName, long totalBlameA, long totalBlameB, int uid1, long blame1A, long blame1B, int uid2, long blame2A, long blame2B, MockBatteryStatsImpl bi)1198 private void checkCustomBatteryConsumption(String caseName, 1199 long totalBlameA, long totalBlameB, 1200 int uid1, long blame1A, long blame1B, 1201 int uid2, long blame2A, long blame2B, 1202 MockBatteryStatsImpl bi) { 1203 1204 final long[] actualTotal = bi.getCustomConsumerMeasuredBatteryConsumptionUC(); 1205 final long[] actualUid1 = 1206 bi.getUidStatsLocked(uid1).getCustomConsumerMeasuredBatteryConsumptionUC(); 1207 final long[] actualUid2 = 1208 bi.getUidStatsLocked(uid2).getCustomConsumerMeasuredBatteryConsumptionUC(); 1209 1210 assertNotNull(actualTotal); 1211 assertNotNull(actualUid1); 1212 assertNotNull(actualUid2); 1213 1214 assertEquals("Wrong total blame in bucket 0 for Case " + caseName, totalBlameA, 1215 actualTotal[0]); 1216 1217 assertEquals("Wrong total blame in bucket 1 for Case " + caseName, totalBlameB, 1218 actualTotal[1]); 1219 1220 assertEquals("Wrong uid1 blame in bucket 0 for Case " + caseName, blame1A, actualUid1[0]); 1221 1222 assertEquals("Wrong uid1 blame in bucket 1 for Case " + caseName, blame1B, actualUid1[1]); 1223 1224 assertEquals("Wrong uid2 blame in bucket 0 for Case " + caseName, blame2A, actualUid2[0]); 1225 1226 assertEquals("Wrong uid2 blame in bucket 1 for Case " + caseName, blame2B, actualUid2[1]); 1227 } 1228 checkScreenBrightnesses(long[] overallExpected, long[][] perDisplayExpected, BatteryStatsImpl bi, long currentTimeMs)1229 private void checkScreenBrightnesses(long[] overallExpected, long[][] perDisplayExpected, 1230 BatteryStatsImpl bi, long currentTimeMs) { 1231 final int numDisplay = bi.getDisplayCount(); 1232 for (int bin = 0; bin < NUM_SCREEN_BRIGHTNESS_BINS; bin++) { 1233 for (int display = 0; display < numDisplay; display++) { 1234 assertEquals("Failure for display " + display + " screen brightness bin " + bin, 1235 perDisplayExpected[display][bin] * 1000, 1236 bi.getDisplayScreenBrightnessTime(display, bin, currentTimeMs * 1000)); 1237 } 1238 assertEquals("Failure for overall screen brightness bin " + bin, 1239 overallExpected[bin] * 1000, 1240 bi.getScreenBrightnessTime(bin, currentTimeMs * 1000, STATS_SINCE_CHARGED)); 1241 } 1242 } 1243 } 1244