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.POWER_DATA_UNAVAILABLE; 21 import static android.os.BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT; 22 import static android.os.BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR; 23 import static android.os.BatteryStats.STATS_SINCE_CHARGED; 24 import static android.os.BatteryStats.WAKE_TYPE_PARTIAL; 25 26 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU; 27 import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY; 28 29 import static com.google.common.truth.Truth.assertThat; 30 31 import static org.mockito.Mockito.mock; 32 33 import android.app.ActivityManager; 34 import android.app.usage.NetworkStatsManager; 35 import android.hardware.radio.V1_5.AccessNetwork; 36 import android.os.BatteryStats; 37 import android.os.BatteryStats.HistoryItem; 38 import android.os.BatteryStats.Uid.Sensor; 39 import android.os.Process; 40 import android.os.UserHandle; 41 import android.os.WorkSource; 42 import android.telephony.AccessNetworkConstants; 43 import android.telephony.ActivityStatsTechSpecificInfo; 44 import android.telephony.Annotation; 45 import android.telephony.CellSignalStrength; 46 import android.telephony.DataConnectionRealTimeInfo; 47 import android.telephony.ModemActivityInfo; 48 import android.telephony.ServiceState; 49 import android.telephony.TelephonyManager; 50 import android.util.Log; 51 import android.util.MutableInt; 52 import android.util.SparseIntArray; 53 import android.util.SparseLongArray; 54 import android.view.Display; 55 56 import androidx.test.filters.SmallTest; 57 58 import com.android.internal.os.BatteryStatsImpl.DualTimer; 59 import com.android.internal.os.BatteryStatsImpl.Uid; 60 import com.android.internal.power.MeasuredEnergyStats; 61 62 import junit.framework.TestCase; 63 64 import org.mockito.Mock; 65 66 import java.util.ArrayList; 67 import java.util.Arrays; 68 import java.util.HashMap; 69 import java.util.List; 70 import java.util.Map; 71 import java.util.function.IntConsumer; 72 73 /** 74 * Test various BatteryStatsImpl noteStart methods. 75 * 76 * Build/Install/Run: bit FrameworksCoreTests:com.android.internal.os.BatteryStatsNoteTest 77 * 78 * Alternatively, 79 * Build: m FrameworksCoreTests 80 * Install: adb install -r \ 81 * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk 82 * Run: adb shell am instrument -e class com.android.internal.os.BatteryStatsNoteTest -w \ 83 * com.android.frameworks.coretests/androidx.test.runner.AndroidJUnitRunner 84 */ 85 public class BatteryStatsNoteTest extends TestCase { 86 private static final String TAG = BatteryStatsNoteTest.class.getSimpleName(); 87 88 private static final int UID = 10500; 89 private static final int ISOLATED_APP_ID = Process.FIRST_ISOLATED_UID + 23; 90 private static final int ISOLATED_UID = UserHandle.getUid(0, ISOLATED_APP_ID); 91 private static final WorkSource WS = new WorkSource(UID); 92 93 enum ModemState { 94 SLEEP, IDLE, RECEIVING, TRANSMITTING 95 } 96 97 @Mock 98 NetworkStatsManager mNetworkStatsManager; 99 100 /** 101 * Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked. 102 */ 103 @SmallTest testNoteBluetoothScanResultLocked()104 public void testNoteBluetoothScanResultLocked() throws Exception { 105 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClock()); 106 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 107 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 108 109 bi.noteBluetoothScanResultsFromSourceLocked(WS, 1); 110 bi.noteBluetoothScanResultsFromSourceLocked(WS, 100); 111 assertEquals(101, 112 bi.getUidStats().get(UID).getBluetoothScanResultCounter() 113 .getCountLocked(STATS_SINCE_CHARGED)); 114 BatteryStats.Counter bgCntr = bi.getUidStats().get(UID).getBluetoothScanResultBgCounter(); 115 if (bgCntr != null) { 116 assertEquals(0, bgCntr.getCountLocked(STATS_SINCE_CHARGED)); 117 } 118 119 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 120 bi.noteBluetoothScanResultsFromSourceLocked(WS, 17); 121 assertEquals(101 + 17, 122 bi.getUidStats().get(UID).getBluetoothScanResultCounter() 123 .getCountLocked(STATS_SINCE_CHARGED)); 124 assertEquals(17, 125 bi.getUidStats().get(UID).getBluetoothScanResultBgCounter() 126 .getCountLocked(STATS_SINCE_CHARGED)); 127 } 128 129 /** 130 * Test BatteryStatsImpl.Uid.noteStartWakeLocked. 131 */ 132 @SmallTest testNoteStartWakeLocked()133 public void testNoteStartWakeLocked() throws Exception { 134 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 135 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 136 137 int pid = 10; 138 String name = "name"; 139 140 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 141 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 142 bi.getUidStatsLocked(UID) 143 .noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); 144 145 clocks.realtime = clocks.uptime = 100; 146 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 147 148 clocks.realtime = clocks.uptime = 220; 149 bi.getUidStatsLocked(UID).noteStopWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime); 150 151 BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID) 152 .getAggregatedPartialWakelockTimer(); 153 long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 154 long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 155 assertEquals(220_000, actualTime); 156 assertEquals(120_000, bgTime); 157 } 158 159 /** 160 * Test BatteryStatsImpl.Uid.noteStartWakeLocked for an isolated uid. 161 */ 162 @SmallTest testNoteStartWakeLocked_isolatedUid()163 public void testNoteStartWakeLocked_isolatedUid() throws Exception { 164 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 165 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 166 167 int pid = 10; 168 String name = "name"; 169 String historyName = "historyName"; 170 171 WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); 172 isolatedWorkChain.addNode(ISOLATED_UID, name); 173 174 // Map ISOLATED_UID to UID. 175 bi.addIsolatedUidLocked(ISOLATED_UID, UID); 176 177 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 178 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 179 bi.noteStartWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName, 180 WAKE_TYPE_PARTIAL, false); 181 182 clocks.realtime = clocks.uptime = 100; 183 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 184 185 clocks.realtime = clocks.uptime = 220; 186 bi.noteStopWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName, 187 WAKE_TYPE_PARTIAL); 188 189 // ISOLATED_UID wakelock time should be attributed to UID. 190 BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID) 191 .getAggregatedPartialWakelockTimer(); 192 long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 193 long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 194 assertEquals(220_000, actualTime); 195 assertEquals(120_000, bgTime); 196 } 197 198 /** 199 * Test BatteryStatsImpl.Uid.noteStartWakeLocked for an isolated uid, with a race where the 200 * isolated uid is removed from batterystats before the wakelock has been stopped. 201 */ 202 @SmallTest testNoteStartWakeLocked_isolatedUidRace()203 public void testNoteStartWakeLocked_isolatedUidRace() throws Exception { 204 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 205 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 206 207 int pid = 10; 208 String name = "name"; 209 String historyName = "historyName"; 210 211 WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); 212 isolatedWorkChain.addNode(ISOLATED_UID, name); 213 214 // Map ISOLATED_UID to UID. 215 bi.addIsolatedUidLocked(ISOLATED_UID, UID); 216 217 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 218 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 219 bi.noteStartWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName, 220 WAKE_TYPE_PARTIAL, false); 221 222 clocks.realtime = clocks.uptime = 100; 223 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 224 225 clocks.realtime = clocks.uptime = 150; 226 bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime); 227 228 clocks.realtime = clocks.uptime = 220; 229 bi.noteStopWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName, 230 WAKE_TYPE_PARTIAL); 231 232 // ISOLATED_UID wakelock time should be attributed to UID. 233 BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID) 234 .getAggregatedPartialWakelockTimer(); 235 long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 236 long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED); 237 assertEquals(220_000, actualTime); 238 assertEquals(120_000, bgTime); 239 } 240 241 /** 242 * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid. 243 */ 244 @SmallTest testNoteLongPartialWakelockStart_isolatedUid()245 public void testNoteLongPartialWakelockStart_isolatedUid() throws Exception { 246 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 247 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 248 249 250 bi.setRecordAllHistoryLocked(true); 251 bi.forceRecordAllHistory(); 252 253 int pid = 10; 254 String name = "name"; 255 String historyName = "historyName"; 256 257 WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); 258 isolatedWorkChain.addNode(ISOLATED_UID, name); 259 260 // Map ISOLATED_UID to UID. 261 bi.addIsolatedUidLocked(ISOLATED_UID, UID); 262 263 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 264 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 265 bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID); 266 267 clocks.realtime = clocks.uptime = 100; 268 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 269 270 clocks.realtime = clocks.uptime = 220; 271 bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID); 272 273 final BatteryStatsHistoryIterator iterator = 274 bi.createBatteryStatsHistoryIterator(); 275 276 BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); 277 278 while (iterator.next(item)) { 279 if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break; 280 } 281 assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START); 282 assertThat(item.eventTag).isNotNull(); 283 assertThat(item.eventTag.string).isEqualTo(historyName); 284 assertThat(item.eventTag.uid).isEqualTo(UID); 285 286 while (iterator.next(item)) { 287 if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break; 288 } 289 assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); 290 assertThat(item.eventTag).isNotNull(); 291 assertThat(item.eventTag.string).isEqualTo(historyName); 292 assertThat(item.eventTag.uid).isEqualTo(UID); 293 } 294 295 /** 296 * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid. 297 */ 298 @SmallTest testNoteLongPartialWakelockStart_isolatedUidRace()299 public void testNoteLongPartialWakelockStart_isolatedUidRace() throws Exception { 300 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 301 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 302 303 304 bi.setRecordAllHistoryLocked(true); 305 bi.forceRecordAllHistory(); 306 307 int pid = 10; 308 String name = "name"; 309 String historyName = "historyName"; 310 311 WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain(); 312 isolatedWorkChain.addNode(ISOLATED_UID, name); 313 314 // Map ISOLATED_UID to UID. 315 bi.addIsolatedUidLocked(ISOLATED_UID, UID); 316 317 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 318 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 319 bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID); 320 321 clocks.realtime = clocks.uptime = 100; 322 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND); 323 324 clocks.realtime = clocks.uptime = 150; 325 bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime); 326 327 clocks.realtime = clocks.uptime = 220; 328 bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID); 329 330 final BatteryStatsHistoryIterator iterator = 331 bi.createBatteryStatsHistoryIterator(); 332 333 BatteryStats.HistoryItem item = new BatteryStats.HistoryItem(); 334 335 while (iterator.next(item)) { 336 if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break; 337 } 338 assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START); 339 assertThat(item.eventTag).isNotNull(); 340 assertThat(item.eventTag.string).isEqualTo(historyName); 341 assertThat(item.eventTag.uid).isEqualTo(UID); 342 343 while (iterator.next(item)) { 344 if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break; 345 } 346 assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH); 347 assertThat(item.eventTag).isNotNull(); 348 assertThat(item.eventTag.string).isEqualTo(historyName); 349 assertThat(item.eventTag.uid).isEqualTo(UID); 350 } 351 352 /** 353 * Test BatteryStatsImpl.noteUidProcessStateLocked. 354 */ 355 @SmallTest testNoteUidProcessStateLocked()356 public void testNoteUidProcessStateLocked() throws Exception { 357 final MockClock clocks = new MockClock(); 358 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 359 360 // map of ActivityManager process states and how long to simulate run time in each state 361 Map<Integer, Integer> stateRuntimeMap = new HashMap<Integer, Integer>(); 362 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP, 1111); 363 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BOUND_TOP, 7382); 364 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 1234); 365 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 2468); 366 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP_SLEEPING, 7531); 367 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 4455); 368 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 1337); 369 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BACKUP, 90210); 370 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_HEAVY_WEIGHT, 911); 371 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_SERVICE, 404); 372 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_RECEIVER, 31459); 373 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_HOME, 1123); 374 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_LAST_ACTIVITY, 5813); 375 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, 867); 376 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT, 5309); 377 stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_EMPTY, 42); 378 379 bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); 380 381 for (Map.Entry<Integer, Integer> entry : stateRuntimeMap.entrySet()) { 382 bi.noteUidProcessStateLocked(UID, entry.getKey()); 383 clocks.realtime += entry.getValue(); 384 clocks.uptime = clocks.realtime; 385 } 386 387 long actualRunTimeUs; 388 long expectedRunTimeMs; 389 long elapsedTimeUs = clocks.realtime * 1000; 390 BatteryStats.Uid uid = bi.getUidStats().get(UID); 391 392 // compare runtime of process states to the Uid process states they map to 393 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP, elapsedTimeUs, 394 STATS_SINCE_CHARGED); 395 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP); 396 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 397 398 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE, 399 elapsedTimeUs, STATS_SINCE_CHARGED); 400 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) 401 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); 402 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 403 404 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING, 405 elapsedTimeUs, STATS_SINCE_CHARGED); 406 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP_SLEEPING); 407 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 408 409 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND, 410 elapsedTimeUs, STATS_SINCE_CHARGED); 411 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); 412 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 413 414 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND, 415 elapsedTimeUs, STATS_SINCE_CHARGED); 416 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND) 417 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BACKUP) 418 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_SERVICE) 419 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_RECEIVER) 420 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BOUND_TOP); 421 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 422 423 actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_CACHED, 424 elapsedTimeUs, STATS_SINCE_CHARGED); 425 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_HOME) 426 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_LAST_ACTIVITY) 427 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) 428 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT) 429 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_EMPTY); 430 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 431 432 // Special check for foreground service timer 433 actualRunTimeUs = uid.getForegroundServiceTimer().getTotalTimeLocked(elapsedTimeUs, 434 STATS_SINCE_CHARGED); 435 expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE); 436 assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs); 437 } 438 439 /** 440 * Test BatteryStatsImpl.updateTimeBasesLocked. 441 */ 442 @SmallTest testUpdateTimeBasesLocked()443 public void testUpdateTimeBasesLocked() throws Exception { 444 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 445 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 446 447 bi.updateTimeBasesLocked(false, Display.STATE_OFF, 0, 0); 448 assertFalse(bi.getOnBatteryTimeBase().isRunning()); 449 bi.updateTimeBasesLocked(false, Display.STATE_DOZE, 10, 10); 450 assertFalse(bi.getOnBatteryTimeBase().isRunning()); 451 bi.updateTimeBasesLocked(false, Display.STATE_ON, 20, 20); 452 assertFalse(bi.getOnBatteryTimeBase().isRunning()); 453 454 bi.updateTimeBasesLocked(true, Display.STATE_ON, 30, 30); 455 assertTrue(bi.getOnBatteryTimeBase().isRunning()); 456 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 457 bi.updateTimeBasesLocked(true, Display.STATE_DOZE, 40, 40); 458 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 459 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 40, 40); 460 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 461 } 462 463 /** 464 * Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly. 465 */ 466 @SmallTest testNoteScreenStateLocked()467 public void testNoteScreenStateLocked() throws Exception { 468 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 469 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 470 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 471 472 bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); 473 bi.noteScreenStateLocked(0, Display.STATE_ON); 474 475 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 476 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 477 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 478 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 479 480 bi.noteScreenStateLocked(0, Display.STATE_ON); 481 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 482 assertEquals(Display.STATE_ON, bi.getScreenState()); 483 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 484 485 bi.noteScreenStateLocked(0, Display.STATE_OFF); 486 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 487 assertEquals(Display.STATE_OFF, bi.getScreenState()); 488 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 489 490 bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND); 491 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 492 assertEquals(Display.STATE_DOZE_SUSPEND, bi.getScreenState()); 493 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 494 495 // STATE_VR note should map to STATE_ON. 496 bi.noteScreenStateLocked(0, Display.STATE_VR); 497 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 498 assertEquals(Display.STATE_ON, bi.getScreenState()); 499 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 500 501 // STATE_ON_SUSPEND note should map to STATE_ON. 502 bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND); 503 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 504 assertEquals(Display.STATE_ON, bi.getScreenState()); 505 // Transition from ON to ON state should not cause an External Sync 506 assertEquals(0, bi.getAndClearExternalStatsSyncFlags()); 507 } 508 509 /** 510 * Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly for 511 * multi display devices 512 */ 513 @SmallTest testNoteScreenStateLocked_multiDisplay()514 public void testNoteScreenStateLocked_multiDisplay() throws Exception { 515 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 516 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 517 bi.setDisplayCountLocked(2); 518 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 519 520 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 521 bi.noteScreenStateLocked(0, Display.STATE_OFF); 522 bi.noteScreenStateLocked(1, Display.STATE_OFF); 523 524 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 525 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 526 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 527 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 528 529 bi.noteScreenStateLocked(0, Display.STATE_ON); 530 assertEquals(Display.STATE_ON, bi.getScreenState()); 531 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 532 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 533 534 bi.noteScreenStateLocked(0, Display.STATE_OFF); 535 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 536 assertEquals(Display.STATE_OFF, bi.getScreenState()); 537 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 538 539 bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND); 540 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 541 assertEquals(Display.STATE_DOZE_SUSPEND, bi.getScreenState()); 542 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 543 544 // STATE_VR note should map to STATE_ON. 545 bi.noteScreenStateLocked(0, Display.STATE_VR); 546 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 547 assertEquals(Display.STATE_ON, bi.getScreenState()); 548 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 549 550 // STATE_ON_SUSPEND note should map to STATE_ON. 551 bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND); 552 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 553 assertEquals(Display.STATE_ON, bi.getScreenState()); 554 // Transition from ON to ON state should not cause an External Sync 555 assertEquals(0, bi.getAndClearExternalStatsSyncFlags()); 556 557 bi.noteScreenStateLocked(1, Display.STATE_DOZE); 558 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 559 // Should remain STATE_ON since display0 is still on. 560 assertEquals(Display.STATE_ON, bi.getScreenState()); 561 // Overall screen state did not change, so no need to sync CPU stats. 562 assertEquals(UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 563 564 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 565 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 566 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 567 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 568 569 bi.noteScreenStateLocked(0, Display.STATE_ON); 570 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 571 assertEquals(Display.STATE_ON, bi.getScreenState()); 572 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 573 574 bi.noteScreenStateLocked(0, Display.STATE_OFF); 575 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 576 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 577 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 578 579 bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND); 580 assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning()); 581 assertEquals(Display.STATE_DOZE, bi.getScreenState()); 582 // Overall screen state did not change, so no need to sync CPU stats. 583 assertEquals(UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 584 585 bi.noteScreenStateLocked(0, Display.STATE_VR); 586 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 587 assertEquals(Display.STATE_ON, bi.getScreenState()); 588 assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags()); 589 590 bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND); 591 assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning()); 592 assertEquals(Display.STATE_ON, bi.getScreenState()); 593 assertEquals(0, bi.getAndClearExternalStatsSyncFlags()); 594 } 595 596 /* 597 * Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly. 598 * 599 * Unknown and doze should both be subset of off state 600 * 601 * Timeline 0----100----200----310----400------------1000 602 * Unknown ------- 603 * On ------- 604 * Off ------- ---------------------- 605 * Doze ---------------- 606 */ 607 @SmallTest testNoteScreenStateTimersLocked()608 public void testNoteScreenStateTimersLocked() throws Exception { 609 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 610 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 611 612 clocks.realtime = clocks.uptime = 100; 613 // Device startup, setOnBatteryLocked calls updateTimebases 614 bi.updateTimeBasesLocked(true, Display.STATE_UNKNOWN, 100_000, 100_000); 615 // Turn on display at 200us 616 clocks.realtime = clocks.uptime = 200; 617 bi.noteScreenStateLocked(0, Display.STATE_ON); 618 assertEquals(150_000, bi.computeBatteryRealtime(250_000, STATS_SINCE_CHARGED)); 619 assertEquals(100_000, bi.computeBatteryScreenOffRealtime(250_000, STATS_SINCE_CHARGED)); 620 assertEquals(50_000, bi.getScreenOnTime(250_000, STATS_SINCE_CHARGED)); 621 assertEquals(0, bi.getScreenDozeTime(250_000, STATS_SINCE_CHARGED)); 622 assertEquals(50_000, bi.getDisplayScreenOnTime(0, 250_000)); 623 assertEquals(0, bi.getDisplayScreenDozeTime(0, 250_000)); 624 625 clocks.realtime = clocks.uptime = 310; 626 bi.noteScreenStateLocked(0, Display.STATE_OFF); 627 assertEquals(250_000, bi.computeBatteryRealtime(350_000, STATS_SINCE_CHARGED)); 628 assertEquals(140_000, bi.computeBatteryScreenOffRealtime(350_000, STATS_SINCE_CHARGED)); 629 assertEquals(110_000, bi.getScreenOnTime(350_000, STATS_SINCE_CHARGED)); 630 assertEquals(0, bi.getScreenDozeTime(350_000, STATS_SINCE_CHARGED)); 631 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 350_000)); 632 assertEquals(0, bi.getDisplayScreenDozeTime(0, 350_000)); 633 634 clocks.realtime = clocks.uptime = 400; 635 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 636 assertEquals(400_000, bi.computeBatteryRealtime(500_000, STATS_SINCE_CHARGED)); 637 assertEquals(290_000, bi.computeBatteryScreenOffRealtime(500_000, STATS_SINCE_CHARGED)); 638 assertEquals(110_000, bi.getScreenOnTime(500_000, STATS_SINCE_CHARGED)); 639 assertEquals(100_000, bi.getScreenDozeTime(500_000, STATS_SINCE_CHARGED)); 640 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 500_000)); 641 assertEquals(100_000, bi.getDisplayScreenDozeTime(0, 500_000)); 642 643 clocks.realtime = clocks.uptime = 1000; 644 bi.noteScreenStateLocked(0, Display.STATE_OFF); 645 assertEquals(1400_000, bi.computeBatteryRealtime(1500_000, STATS_SINCE_CHARGED)); 646 assertEquals(1290_000, bi.computeBatteryScreenOffRealtime(1500_000, STATS_SINCE_CHARGED)); 647 assertEquals(110_000, bi.getScreenOnTime(1500_000, STATS_SINCE_CHARGED)); 648 assertEquals(600_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED)); 649 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1500_000)); 650 assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1500_000)); 651 } 652 653 /* 654 * Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly for multi display 655 * devices. 656 */ 657 @SmallTest testNoteScreenStateTimersLocked_multiDisplay()658 public void testNoteScreenStateTimersLocked_multiDisplay() throws Exception { 659 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 660 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 661 bi.setDisplayCountLocked(2); 662 663 clocks.realtime = clocks.uptime = 100; 664 // Device startup, setOnBatteryLocked calls updateTimebases 665 bi.updateTimeBasesLocked(true, Display.STATE_UNKNOWN, 100_000, 100_000); 666 // Turn on display at 200us 667 clocks.realtime = clocks.uptime = 200; 668 bi.noteScreenStateLocked(0, Display.STATE_ON); 669 bi.noteScreenStateLocked(1, Display.STATE_OFF); 670 assertEquals(150_000, bi.computeBatteryRealtime(250_000, STATS_SINCE_CHARGED)); 671 assertEquals(100_000, bi.computeBatteryScreenOffRealtime(250_000, STATS_SINCE_CHARGED)); 672 assertEquals(50_000, bi.getScreenOnTime(250_000, STATS_SINCE_CHARGED)); 673 assertEquals(0, bi.getScreenDozeTime(250_000, STATS_SINCE_CHARGED)); 674 assertEquals(50_000, bi.getDisplayScreenOnTime(0, 250_000)); 675 assertEquals(0, bi.getDisplayScreenDozeTime(0, 250_000)); 676 assertEquals(0, bi.getDisplayScreenOnTime(1, 250_000)); 677 assertEquals(0, bi.getDisplayScreenDozeTime(1, 250_000)); 678 679 clocks.realtime = clocks.uptime = 310; 680 bi.noteScreenStateLocked(0, Display.STATE_OFF); 681 assertEquals(250_000, bi.computeBatteryRealtime(350_000, STATS_SINCE_CHARGED)); 682 assertEquals(140_000, bi.computeBatteryScreenOffRealtime(350_000, STATS_SINCE_CHARGED)); 683 assertEquals(110_000, bi.getScreenOnTime(350_000, STATS_SINCE_CHARGED)); 684 assertEquals(0, bi.getScreenDozeTime(350_000, STATS_SINCE_CHARGED)); 685 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 350_000)); 686 assertEquals(0, bi.getDisplayScreenDozeTime(0, 350_000)); 687 assertEquals(0, bi.getDisplayScreenOnTime(1, 350_000)); 688 assertEquals(0, bi.getDisplayScreenDozeTime(1, 350_000)); 689 690 clocks.realtime = clocks.uptime = 400; 691 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 692 assertEquals(400_000, bi.computeBatteryRealtime(500_000, STATS_SINCE_CHARGED)); 693 assertEquals(290_000, bi.computeBatteryScreenOffRealtime(500_000, STATS_SINCE_CHARGED)); 694 assertEquals(110_000, bi.getScreenOnTime(500_000, STATS_SINCE_CHARGED)); 695 assertEquals(100_000, bi.getScreenDozeTime(500_000, STATS_SINCE_CHARGED)); 696 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 500_000)); 697 assertEquals(100_000, bi.getDisplayScreenDozeTime(0, 500_000)); 698 assertEquals(0, bi.getDisplayScreenOnTime(1, 500_000)); 699 assertEquals(0, bi.getDisplayScreenDozeTime(1, 500_000)); 700 701 clocks.realtime = clocks.uptime = 1000; 702 bi.noteScreenStateLocked(0, Display.STATE_OFF); 703 assertEquals(1000_000, bi.computeBatteryRealtime(1100_000, STATS_SINCE_CHARGED)); 704 assertEquals(890_000, bi.computeBatteryScreenOffRealtime(1100_000, STATS_SINCE_CHARGED)); 705 assertEquals(110_000, bi.getScreenOnTime(1100_000, STATS_SINCE_CHARGED)); 706 assertEquals(600_000, bi.getScreenDozeTime(1100_000, STATS_SINCE_CHARGED)); 707 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1100_000)); 708 assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1100_000)); 709 assertEquals(0, bi.getDisplayScreenOnTime(1, 1100_000)); 710 assertEquals(0, bi.getDisplayScreenDozeTime(1, 1100_000)); 711 712 clocks.realtime = clocks.uptime = 1200; 713 // Change state of second display to doze 714 bi.noteScreenStateLocked(1, Display.STATE_DOZE); 715 assertEquals(1150_000, bi.computeBatteryRealtime(1250_000, STATS_SINCE_CHARGED)); 716 assertEquals(1040_000, bi.computeBatteryScreenOffRealtime(1250_000, STATS_SINCE_CHARGED)); 717 assertEquals(110_000, bi.getScreenOnTime(1250_000, STATS_SINCE_CHARGED)); 718 assertEquals(650_000, bi.getScreenDozeTime(1250_000, STATS_SINCE_CHARGED)); 719 assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1250_000)); 720 assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1250_000)); 721 assertEquals(0, bi.getDisplayScreenOnTime(1, 1250_000)); 722 assertEquals(50_000, bi.getDisplayScreenDozeTime(1, 1250_000)); 723 724 clocks.realtime = clocks.uptime = 1310; 725 bi.noteScreenStateLocked(0, Display.STATE_ON); 726 assertEquals(1250_000, bi.computeBatteryRealtime(1350_000, STATS_SINCE_CHARGED)); 727 assertEquals(1100_000, bi.computeBatteryScreenOffRealtime(1350_000, STATS_SINCE_CHARGED)); 728 assertEquals(150_000, bi.getScreenOnTime(1350_000, STATS_SINCE_CHARGED)); 729 assertEquals(710_000, bi.getScreenDozeTime(1350_000, STATS_SINCE_CHARGED)); 730 assertEquals(150_000, bi.getDisplayScreenOnTime(0, 1350_000)); 731 assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1350_000)); 732 assertEquals(0, bi.getDisplayScreenOnTime(1, 1350_000)); 733 assertEquals(150_000, bi.getDisplayScreenDozeTime(1, 1350_000)); 734 735 clocks.realtime = clocks.uptime = 1400; 736 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 737 assertEquals(1400_000, bi.computeBatteryRealtime(1500_000, STATS_SINCE_CHARGED)); 738 assertEquals(1200_000, bi.computeBatteryScreenOffRealtime(1500_000, STATS_SINCE_CHARGED)); 739 assertEquals(200_000, bi.getScreenOnTime(1500_000, STATS_SINCE_CHARGED)); 740 assertEquals(810_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED)); 741 assertEquals(200_000, bi.getDisplayScreenOnTime(0, 1500_000)); 742 assertEquals(700_000, bi.getDisplayScreenDozeTime(0, 1500_000)); 743 assertEquals(0, bi.getDisplayScreenOnTime(1, 1500_000)); 744 assertEquals(300_000, bi.getDisplayScreenDozeTime(1, 1500_000)); 745 746 clocks.realtime = clocks.uptime = 2000; 747 bi.noteScreenStateLocked(0, Display.STATE_OFF); 748 assertEquals(2000_000, bi.computeBatteryRealtime(2100_000, STATS_SINCE_CHARGED)); 749 assertEquals(1800_000, bi.computeBatteryScreenOffRealtime(2100_000, STATS_SINCE_CHARGED)); 750 assertEquals(200_000, bi.getScreenOnTime(2100_000, STATS_SINCE_CHARGED)); 751 assertEquals(1410_000, bi.getScreenDozeTime(2100_000, STATS_SINCE_CHARGED)); 752 assertEquals(200_000, bi.getDisplayScreenOnTime(0, 2100_000)); 753 assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2100_000)); 754 assertEquals(0, bi.getDisplayScreenOnTime(1, 2100_000)); 755 assertEquals(900_000, bi.getDisplayScreenDozeTime(1, 2100_000)); 756 757 758 clocks.realtime = clocks.uptime = 2200; 759 // Change state of second display to on 760 bi.noteScreenStateLocked(1, Display.STATE_ON); 761 assertEquals(2150_000, bi.computeBatteryRealtime(2250_000, STATS_SINCE_CHARGED)); 762 assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2250_000, STATS_SINCE_CHARGED)); 763 assertEquals(250_000, bi.getScreenOnTime(2250_000, STATS_SINCE_CHARGED)); 764 assertEquals(1510_000, bi.getScreenDozeTime(2250_000, STATS_SINCE_CHARGED)); 765 assertEquals(200_000, bi.getDisplayScreenOnTime(0, 2250_000)); 766 assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2250_000)); 767 assertEquals(50_000, bi.getDisplayScreenOnTime(1, 2250_000)); 768 assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2250_000)); 769 770 clocks.realtime = clocks.uptime = 2310; 771 bi.noteScreenStateLocked(0, Display.STATE_ON); 772 assertEquals(2250_000, bi.computeBatteryRealtime(2350_000, STATS_SINCE_CHARGED)); 773 assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2350_000, STATS_SINCE_CHARGED)); 774 assertEquals(350_000, bi.getScreenOnTime(2350_000, STATS_SINCE_CHARGED)); 775 assertEquals(1510_000, bi.getScreenDozeTime(2350_000, STATS_SINCE_CHARGED)); 776 assertEquals(240_000, bi.getDisplayScreenOnTime(0, 2350_000)); 777 assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2350_000)); 778 assertEquals(150_000, bi.getDisplayScreenOnTime(1, 2350_000)); 779 assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2350_000)); 780 781 clocks.realtime = clocks.uptime = 2400; 782 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 783 assertEquals(2400_000, bi.computeBatteryRealtime(2500_000, STATS_SINCE_CHARGED)); 784 assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2500_000, STATS_SINCE_CHARGED)); 785 assertEquals(500_000, bi.getScreenOnTime(2500_000, STATS_SINCE_CHARGED)); 786 assertEquals(1510_000, bi.getScreenDozeTime(2500_000, STATS_SINCE_CHARGED)); 787 assertEquals(290_000, bi.getDisplayScreenOnTime(0, 2500_000)); 788 assertEquals(1300_000, bi.getDisplayScreenDozeTime(0, 2500_000)); 789 assertEquals(300_000, bi.getDisplayScreenOnTime(1, 2500_000)); 790 assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2500_000)); 791 792 clocks.realtime = clocks.uptime = 3000; 793 bi.noteScreenStateLocked(0, Display.STATE_OFF); 794 assertEquals(3000_000, bi.computeBatteryRealtime(3100_000, STATS_SINCE_CHARGED)); 795 assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(3100_000, STATS_SINCE_CHARGED)); 796 assertEquals(1100_000, bi.getScreenOnTime(3100_000, STATS_SINCE_CHARGED)); 797 assertEquals(1510_000, bi.getScreenDozeTime(3100_000, STATS_SINCE_CHARGED)); 798 assertEquals(290_000, bi.getDisplayScreenOnTime(0, 3100_000)); 799 assertEquals(1800_000, bi.getDisplayScreenDozeTime(0, 3100_000)); 800 assertEquals(900_000, bi.getDisplayScreenOnTime(1, 3100_000)); 801 assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 3100_000)); 802 } 803 804 805 /** 806 * Test BatteryStatsImpl.noteScreenBrightnessLocked updates timers correctly. 807 */ 808 @SmallTest testScreenBrightnessLocked_multiDisplay()809 public void testScreenBrightnessLocked_multiDisplay() throws Exception { 810 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 811 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 812 813 final int numDisplay = 2; 814 bi.setDisplayCountLocked(numDisplay); 815 816 817 final long[] overallExpected = new long[NUM_SCREEN_BRIGHTNESS_BINS]; 818 final long[][] perDisplayExpected = new long[numDisplay][NUM_SCREEN_BRIGHTNESS_BINS]; 819 class Bookkeeper { 820 public long currentTimeMs = 100; 821 public int overallActiveBin = -1; 822 public int[] perDisplayActiveBin = new int[numDisplay]; 823 } 824 final Bookkeeper bk = new Bookkeeper(); 825 Arrays.fill(bk.perDisplayActiveBin, -1); 826 827 IntConsumer incrementTime = inc -> { 828 bk.currentTimeMs += inc; 829 if (bk.overallActiveBin >= 0) { 830 overallExpected[bk.overallActiveBin] += inc; 831 } 832 for (int i = 0; i < numDisplay; i++) { 833 final int bin = bk.perDisplayActiveBin[i]; 834 if (bin >= 0) { 835 perDisplayExpected[i][bin] += inc; 836 } 837 } 838 clocks.realtime = clocks.uptime = bk.currentTimeMs; 839 }; 840 841 bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); 842 bi.noteScreenStateLocked(0, Display.STATE_ON); 843 bi.noteScreenStateLocked(1, Display.STATE_ON); 844 845 incrementTime.accept(100); 846 bi.noteScreenBrightnessLocked(0, 25); 847 bi.noteScreenBrightnessLocked(1, 25); 848 // floor(25/256*5) = bin 0 849 bk.overallActiveBin = 0; 850 bk.perDisplayActiveBin[0] = 0; 851 bk.perDisplayActiveBin[1] = 0; 852 853 incrementTime.accept(50); 854 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 855 856 incrementTime.accept(13); 857 bi.noteScreenBrightnessLocked(0, 100); 858 // floor(25/256*5) = bin 1 859 bk.overallActiveBin = 1; 860 bk.perDisplayActiveBin[0] = 1; 861 862 incrementTime.accept(44); 863 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 864 865 incrementTime.accept(22); 866 bi.noteScreenBrightnessLocked(1, 200); 867 // floor(200/256*5) = bin 3 868 bk.overallActiveBin = 3; 869 bk.perDisplayActiveBin[1] = 3; 870 871 incrementTime.accept(33); 872 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 873 874 incrementTime.accept(77); 875 bi.noteScreenBrightnessLocked(0, 150); 876 // floor(150/256*5) = bin 2 877 // Overall active bin should not change 878 bk.perDisplayActiveBin[0] = 2; 879 880 incrementTime.accept(88); 881 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 882 883 incrementTime.accept(11); 884 bi.noteScreenStateLocked(1, Display.STATE_OFF); 885 // Display 1 should timers should stop incrementing 886 // Overall active bin should fallback to display 0's bin 887 bk.overallActiveBin = 2; 888 bk.perDisplayActiveBin[1] = -1; 889 890 incrementTime.accept(99); 891 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 892 893 incrementTime.accept(200); 894 bi.noteScreenBrightnessLocked(0, 255); 895 // floor(150/256*5) = bin 4 896 bk.overallActiveBin = 4; 897 bk.perDisplayActiveBin[0] = 4; 898 899 incrementTime.accept(300); 900 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 901 902 incrementTime.accept(200); 903 bi.noteScreenStateLocked(0, Display.STATE_DOZE); 904 // No displays are on. No brightness timers should be active. 905 bk.overallActiveBin = -1; 906 bk.perDisplayActiveBin[0] = -1; 907 908 incrementTime.accept(300); 909 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 910 911 incrementTime.accept(400); 912 bi.noteScreenStateLocked(1, Display.STATE_ON); 913 // Display 1 turned back on. 914 bk.overallActiveBin = 3; 915 bk.perDisplayActiveBin[1] = 3; 916 917 incrementTime.accept(500); 918 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 919 920 incrementTime.accept(600); 921 bi.noteScreenStateLocked(0, Display.STATE_ON); 922 // Display 0 turned back on. 923 bk.overallActiveBin = 4; 924 bk.perDisplayActiveBin[0] = 4; 925 926 incrementTime.accept(700); 927 checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs); 928 } 929 930 @SmallTest testAlarmStartAndFinishLocked()931 public void testAlarmStartAndFinishLocked() throws Exception { 932 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 933 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 934 bi.setRecordAllHistoryLocked(true); 935 bi.forceRecordAllHistory(); 936 937 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 938 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 939 940 clocks.realtime = clocks.uptime = 100; 941 bi.noteAlarmStartLocked("foo", null, UID); 942 clocks.realtime = clocks.uptime = 5000; 943 bi.noteAlarmFinishLocked("foo", null, UID); 944 945 HistoryItem item = new HistoryItem(); 946 assertTrue(bi.startIteratingHistoryLocked()); 947 948 assertTrue(bi.getNextHistoryLocked(item)); 949 assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); 950 assertEquals("foo", item.eventTag.string); 951 assertEquals(UID, item.eventTag.uid); 952 953 // TODO(narayan): Figure out why this event is written to the history buffer. See 954 // test below where it is being interspersed between multiple START events too. 955 assertTrue(bi.getNextHistoryLocked(item)); 956 assertEquals(HistoryItem.EVENT_NONE, item.eventCode); 957 958 assertTrue(bi.getNextHistoryLocked(item)); 959 assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); 960 assertTrue(item.isDeltaData()); 961 assertEquals("foo", item.eventTag.string); 962 assertEquals(UID, item.eventTag.uid); 963 964 assertFalse(bi.getNextHistoryLocked(item)); 965 } 966 967 @SmallTest testAlarmStartAndFinishLocked_workSource()968 public void testAlarmStartAndFinishLocked_workSource() throws Exception { 969 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 970 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 971 bi.setRecordAllHistoryLocked(true); 972 bi.forceRecordAllHistory(); 973 974 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 975 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 976 977 WorkSource ws = new WorkSource(); 978 ws.add(100); 979 ws.createWorkChain().addNode(500, "tag"); 980 bi.noteAlarmStartLocked("foo", ws, UID); 981 clocks.realtime = clocks.uptime = 5000; 982 bi.noteAlarmFinishLocked("foo", ws, UID); 983 984 HistoryItem item = new HistoryItem(); 985 assertTrue(bi.startIteratingHistoryLocked()); 986 987 assertTrue(bi.getNextHistoryLocked(item)); 988 assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); 989 assertEquals("foo", item.eventTag.string); 990 assertEquals(100, item.eventTag.uid); 991 992 assertTrue(bi.getNextHistoryLocked(item)); 993 assertEquals(HistoryItem.EVENT_NONE, item.eventCode); 994 995 assertTrue(bi.getNextHistoryLocked(item)); 996 assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode); 997 assertEquals("foo", item.eventTag.string); 998 assertEquals(500, item.eventTag.uid); 999 1000 assertTrue(bi.getNextHistoryLocked(item)); 1001 assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); 1002 assertEquals("foo", item.eventTag.string); 1003 assertEquals(100, item.eventTag.uid); 1004 1005 assertTrue(bi.getNextHistoryLocked(item)); 1006 assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode); 1007 assertEquals("foo", item.eventTag.string); 1008 assertEquals(500, item.eventTag.uid); 1009 } 1010 1011 @SmallTest testNoteWakupAlarmLocked()1012 public void testNoteWakupAlarmLocked() { 1013 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 1014 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1015 bi.setRecordAllHistoryLocked(true); 1016 bi.forceRecordAllHistory(); 1017 bi.mForceOnBattery = true; 1018 1019 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 1020 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 1021 1022 bi.noteWakupAlarmLocked("com.foo.bar", UID, null, "tag"); 1023 1024 Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); 1025 assertEquals(1, pkg.getWakeupAlarmStats().get("tag").getCountLocked(STATS_SINCE_CHARGED)); 1026 assertEquals(1, pkg.getWakeupAlarmStats().size()); 1027 } 1028 1029 @SmallTest testNoteWakupAlarmLocked_workSource_uid()1030 public void testNoteWakupAlarmLocked_workSource_uid() { 1031 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 1032 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1033 bi.setRecordAllHistoryLocked(true); 1034 bi.forceRecordAllHistory(); 1035 bi.mForceOnBattery = true; 1036 1037 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 1038 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 1039 1040 WorkSource ws = new WorkSource(); 1041 ws.add(100); 1042 1043 // When a WorkSource is present, "UID" should not be used - only the uids present in the 1044 // WorkSource should be reported. 1045 bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag"); 1046 Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); 1047 assertEquals(0, pkg.getWakeupAlarmStats().size()); 1048 pkg = bi.getPackageStatsLocked(100, "com.foo.bar"); 1049 assertEquals(1, pkg.getWakeupAlarmStats().size()); 1050 1051 // If the WorkSource contains a "name", it should be interpreted as a package name and 1052 // the packageName supplied as an argument must be ignored. 1053 ws = new WorkSource(); 1054 ws.add(100, "com.foo.baz_alternate"); 1055 bi.noteWakupAlarmLocked("com.foo.baz", UID, ws, "tag"); 1056 pkg = bi.getPackageStatsLocked(100, "com.foo.baz"); 1057 assertEquals(0, pkg.getWakeupAlarmStats().size()); 1058 pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate"); 1059 assertEquals(1, pkg.getWakeupAlarmStats().size()); 1060 } 1061 1062 @SmallTest testNoteWakupAlarmLocked_workSource_workChain()1063 public void testNoteWakupAlarmLocked_workSource_workChain() { 1064 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 1065 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1066 bi.setRecordAllHistoryLocked(true); 1067 bi.forceRecordAllHistory(); 1068 bi.mForceOnBattery = true; 1069 1070 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 1071 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 1072 1073 WorkSource ws = new WorkSource(); 1074 ws.createWorkChain().addNode(100, "com.foo.baz_alternate"); 1075 bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag"); 1076 1077 // For WorkChains, again we must only attribute to the uids present in the WorkSource 1078 // (and not to "UID"). However, unlike the older "tags" we do not change the packagename 1079 // supplied as an argument, given that we're logging the entire attribution chain. 1080 Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar"); 1081 assertEquals(0, pkg.getWakeupAlarmStats().size()); 1082 pkg = bi.getPackageStatsLocked(100, "com.foo.bar"); 1083 assertEquals(1, pkg.getWakeupAlarmStats().size()); 1084 pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate"); 1085 assertEquals(0, pkg.getWakeupAlarmStats().size()); 1086 } 1087 1088 @SmallTest testNoteGpsChanged()1089 public void testNoteGpsChanged() { 1090 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 1091 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1092 bi.setRecordAllHistoryLocked(true); 1093 bi.forceRecordAllHistory(); 1094 bi.mForceOnBattery = true; 1095 1096 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 1097 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 1098 1099 WorkSource ws = new WorkSource(); 1100 ws.add(UID); 1101 1102 bi.noteGpsChangedLocked(new WorkSource(), ws); 1103 DualTimer t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false); 1104 assertNotNull(t); 1105 assertTrue(t.isRunningLocked()); 1106 1107 bi.noteGpsChangedLocked(ws, new WorkSource()); 1108 t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false); 1109 assertFalse(t.isRunningLocked()); 1110 } 1111 1112 @SmallTest testNoteGpsChanged_workSource()1113 public void testNoteGpsChanged_workSource() { 1114 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 1115 MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1116 bi.setRecordAllHistoryLocked(true); 1117 bi.forceRecordAllHistory(); 1118 bi.mForceOnBattery = true; 1119 1120 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 1121 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP); 1122 1123 WorkSource ws = new WorkSource(); 1124 ws.createWorkChain().addNode(UID, "com.foo"); 1125 1126 bi.noteGpsChangedLocked(new WorkSource(), ws); 1127 DualTimer t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false); 1128 assertNotNull(t); 1129 assertTrue(t.isRunningLocked()); 1130 1131 bi.noteGpsChangedLocked(ws, new WorkSource()); 1132 t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false); 1133 assertFalse(t.isRunningLocked()); 1134 } 1135 1136 @SmallTest testUpdateDisplayMeasuredEnergyStatsLocked()1137 public void testUpdateDisplayMeasuredEnergyStatsLocked() { 1138 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 1139 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1140 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 1141 1142 clocks.realtime = 0; 1143 int[] screen = new int[]{Display.STATE_OFF}; 1144 boolean battery = false; 1145 1146 final int uid1 = 10500; 1147 final int uid2 = 10501; 1148 long blame1 = 0; 1149 long blame2 = 0; 1150 long globalDoze = 0; 1151 1152 // Case A: uid1 off, uid2 off, battery off, screen off 1153 bi.updateTimeBasesLocked(battery, screen[0], clocks.realtime * 1000, 0); 1154 bi.setOnBatteryInternal(battery); 1155 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{500_000}, screen, clocks.realtime); 1156 checkMeasuredCharge("A", uid1, blame1, uid2, blame2, globalDoze, bi); 1157 1158 // Case B: uid1 off, uid2 off, battery ON, screen off 1159 clocks.realtime += 17; 1160 battery = true; 1161 bi.updateTimeBasesLocked(battery, screen[0], clocks.realtime * 1000, 0); 1162 bi.setOnBatteryInternal(battery); 1163 clocks.realtime += 19; 1164 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{510_000}, screen, clocks.realtime); 1165 checkMeasuredCharge("B", uid1, blame1, uid2, blame2, globalDoze, bi); 1166 1167 // Case C: uid1 ON, uid2 off, battery on, screen off 1168 clocks.realtime += 18; 1169 setFgState(uid1, true, bi); 1170 clocks.realtime += 18; 1171 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{520_000}, screen, clocks.realtime); 1172 checkMeasuredCharge("C", uid1, blame1, uid2, blame2, globalDoze, bi); 1173 1174 // Case D: uid1 on, uid2 off, battery on, screen ON 1175 clocks.realtime += 17; 1176 screen[0] = Display.STATE_ON; 1177 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{521_000}, screen, clocks.realtime); 1178 blame1 += 0; // Screen had been off during the measurement period 1179 checkMeasuredCharge("D.1", uid1, blame1, uid2, blame2, globalDoze, bi); 1180 clocks.realtime += 101; 1181 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{530_000}, screen, clocks.realtime); 1182 blame1 += 530_000; 1183 checkMeasuredCharge("D.2", uid1, blame1, uid2, blame2, globalDoze, bi); 1184 1185 // Case E: uid1 on, uid2 ON, battery on, screen on 1186 clocks.realtime += 20; 1187 setFgState(uid2, true, bi); 1188 clocks.realtime += 40; 1189 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{540_000}, screen, clocks.realtime); 1190 // In the past 60ms, sum of fg is 20+40+40=100ms. uid1 is blamed for 60/100; uid2 for 40/100 1191 blame1 += 540_000 * (20 + 40) / (20 + 40 + 40); 1192 blame2 += 540_000 * (0 + 40) / (20 + 40 + 40); 1193 checkMeasuredCharge("E", uid1, blame1, uid2, blame2, globalDoze, bi); 1194 1195 // Case F: uid1 on, uid2 OFF, battery on, screen on 1196 clocks.realtime += 40; 1197 setFgState(uid2, false, bi); 1198 clocks.realtime += 120; 1199 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{550_000}, screen, clocks.realtime); 1200 // In the past 160ms, sum f fg is 200ms. uid1 is blamed for 40+120 of it; uid2 for 40 of it. 1201 blame1 += 550_000 * (40 + 120) / (40 + 40 + 120); 1202 blame2 += 550_000 * (40 + 0) / (40 + 40 + 120); 1203 checkMeasuredCharge("F", uid1, blame1, uid2, blame2, globalDoze, bi); 1204 1205 // Case G: uid1 on, uid2 off, battery on, screen DOZE 1206 clocks.realtime += 5; 1207 screen[0] = Display.STATE_DOZE; 1208 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{570_000}, screen, clocks.realtime); 1209 blame1 += 570_000; // All of this pre-doze time is blamed on uid1. 1210 checkMeasuredCharge("G", uid1, blame1, uid2, blame2, globalDoze, bi); 1211 1212 // Case H: uid1 on, uid2 off, battery on, screen ON 1213 clocks.realtime += 6; 1214 screen[0] = Display.STATE_ON; 1215 bi.updateDisplayMeasuredEnergyStatsLocked(new long[]{580_000}, screen, clocks.realtime); 1216 blame1 += 0; // The screen had been doze during the energy period 1217 globalDoze += 580_000; 1218 checkMeasuredCharge("H", uid1, blame1, uid2, blame2, globalDoze, bi); 1219 } 1220 1221 @SmallTest testUpdateCustomMeasuredEnergyStatsLocked_neverCalled()1222 public void testUpdateCustomMeasuredEnergyStatsLocked_neverCalled() { 1223 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 1224 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1225 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 1226 bi.setOnBatteryInternal(true); 1227 1228 final int uid1 = 11500; 1229 final int uid2 = 11501; 1230 1231 // Initially, all custom buckets report charge of 0. 1232 checkCustomBatteryConsumption("0", 0, 0, uid1, 0, 0, uid2, 0, 0, bi); 1233 } 1234 1235 @SmallTest testUpdateCustomMeasuredEnergyStatsLocked()1236 public void testUpdateCustomMeasuredEnergyStatsLocked() { 1237 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 1238 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 1239 bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"}); 1240 1241 final int bucketA = 0; // Custom bucket 0 1242 final int bucketB = 1; // Custom bucket 1 1243 1244 long totalBlameA = 0; // Total charge consumption for bucketA (may exceed sum of uids) 1245 long totalBlameB = 0; // Total charge consumption for bucketB (may exceed sum of uids) 1246 1247 final int uid1 = 10500; 1248 long blame1A = 0; // Blame for uid1 in bucketA 1249 long blame1B = 0; // Blame for uid1 in bucketB 1250 1251 final int uid2 = 10501; 1252 long blame2A = 0; // Blame for uid2 in bucketA 1253 long blame2B = 0; // Blame for uid2 in bucketB 1254 1255 final SparseLongArray newChargesA = new SparseLongArray(2); 1256 final SparseLongArray newChargesB = new SparseLongArray(2); 1257 1258 1259 // ----- Case A: battery off (so blame does not increase) 1260 bi.setOnBatteryInternal(false); 1261 1262 newChargesA.put(uid1, 20_000); 1263 // Implicit newChargesA.put(uid2, 0); 1264 bi.updateCustomMeasuredEnergyStatsLocked(bucketA, 500_000, newChargesA); 1265 1266 newChargesB.put(uid1, 60_000); 1267 // Implicit newChargesB.put(uid2, 0); 1268 bi.updateCustomMeasuredEnergyStatsLocked(bucketB, 700_000, newChargesB); 1269 1270 checkCustomBatteryConsumption( 1271 "A", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi); 1272 1273 1274 // ----- Case B: battery on 1275 bi.setOnBatteryInternal(true); 1276 1277 newChargesA.put(uid1, 7_000); blame1A += 7_000; 1278 // Implicit newChargesA.put(uid2, 0); blame2A += 0; 1279 bi.updateCustomMeasuredEnergyStatsLocked(bucketA, 310_000, newChargesA); 1280 totalBlameA += 310_000; 1281 1282 newChargesB.put(uid1, 63_000); blame1B += 63_000; 1283 newChargesB.put(uid2, 15_000); blame2B += 15_000; 1284 bi.updateCustomMeasuredEnergyStatsLocked(bucketB, 790_000, newChargesB); 1285 totalBlameB += 790_000; 1286 1287 checkCustomBatteryConsumption( 1288 "B", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi); 1289 1290 1291 // ----- Case C: battery still on 1292 newChargesA.delete(uid1); blame1A += 0; 1293 newChargesA.put(uid2, 16_000); blame2A += 16_000; 1294 bi.updateCustomMeasuredEnergyStatsLocked(bucketA, 560_000, newChargesA); 1295 totalBlameA += 560_000; 1296 1297 bi.updateCustomMeasuredEnergyStatsLocked(bucketB, 10_000, null); 1298 totalBlameB += 10_000; 1299 1300 checkCustomBatteryConsumption( 1301 "C", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi); 1302 1303 1304 // ----- Case D: battery still on 1305 bi.updateCustomMeasuredEnergyStatsLocked(bucketA, 0, newChargesA); 1306 bi.updateCustomMeasuredEnergyStatsLocked(bucketB, 15_000, new SparseLongArray(1)); 1307 totalBlameB += 15_000; 1308 checkCustomBatteryConsumption( 1309 "D", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi); 1310 } 1311 1312 @SmallTest testGetPerStateActiveRadioDurationMs_noModemActivity()1313 public void testGetPerStateActiveRadioDurationMs_noModemActivity() { 1314 final MockClock clock = new MockClock(); // holds realtime and uptime in ms 1315 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock); 1316 final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT; 1317 final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1; 1318 final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels(); 1319 1320 final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount]; 1321 final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount]; 1322 final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount]; 1323 for (int rat = 0; rat < ratCount; rat++) { 1324 for (int freq = 0; freq < frequencyCount; freq++) { 1325 // Should have no RX data without Modem Activity Info 1326 expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE; 1327 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) { 1328 expectedDurationsMs[rat][freq][txLvl] = 0; 1329 // Should have no TX data without Modem Activity Info 1330 expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE; 1331 } 1332 } 1333 } 1334 1335 final ModemAndBatteryState state = new ModemAndBatteryState(bi, null, null); 1336 1337 IntConsumer incrementTime = inc -> { 1338 state.currentTimeMs += inc; 1339 clock.realtime = clock.uptime = state.currentTimeMs; 1340 1341 // If the device is not on battery, no timers should increment. 1342 if (!state.onBattery) return; 1343 // If the modem is not active, no timers should increment. 1344 if (!state.modemActive) return; 1345 1346 final int currentRat = state.currentRat; 1347 final int currentFrequencyRange = 1348 currentRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0; 1349 int currentSignalStrength = state.currentSignalStrengths.get(currentRat); 1350 expectedDurationsMs[currentRat][currentFrequencyRange][currentSignalStrength] += inc; 1351 }; 1352 1353 1354 state.setOnBattery(false); 1355 state.setModemActive(false); 1356 state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN, 1357 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER); 1358 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN); 1359 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER, 1360 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN); 1361 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1362 expectedTxDurationsMs, bi, state.currentTimeMs); 1363 1364 // While not on battery, the timers should not increase. 1365 state.setModemActive(true); 1366 incrementTime.accept(100); 1367 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1368 expectedTxDurationsMs, bi, state.currentTimeMs); 1369 1370 state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR); 1371 incrementTime.accept(200); 1372 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1373 expectedTxDurationsMs, bi, state.currentTimeMs); 1374 1375 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR, 1376 CellSignalStrength.SIGNAL_STRENGTH_GOOD); 1377 incrementTime.accept(500); 1378 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1379 expectedTxDurationsMs, bi, state.currentTimeMs); 1380 1381 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE); 1382 incrementTime.accept(300); 1383 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1384 expectedTxDurationsMs, bi, state.currentTimeMs); 1385 1386 state.setRatType(TelephonyManager.NETWORK_TYPE_LTE, 1387 BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE); 1388 incrementTime.accept(400); 1389 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1390 expectedTxDurationsMs, bi, state.currentTimeMs); 1391 1392 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1393 CellSignalStrength.SIGNAL_STRENGTH_MODERATE); 1394 incrementTime.accept(500); 1395 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1396 expectedTxDurationsMs, bi, state.currentTimeMs); 1397 1398 // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should 1399 // start counting up. 1400 state.setOnBattery(true); 1401 incrementTime.accept(600); 1402 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1403 expectedTxDurationsMs, bi, state.currentTimeMs); 1404 // Changing LTE signal strength should be tracked. 1405 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1406 CellSignalStrength.SIGNAL_STRENGTH_POOR); 1407 incrementTime.accept(700); 1408 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1409 expectedTxDurationsMs, bi, state.currentTimeMs); 1410 1411 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1412 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN); 1413 incrementTime.accept(800); 1414 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1415 expectedTxDurationsMs, bi, state.currentTimeMs); 1416 1417 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1418 CellSignalStrength.SIGNAL_STRENGTH_GOOD); 1419 incrementTime.accept(900); 1420 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1421 expectedTxDurationsMs, bi, state.currentTimeMs); 1422 1423 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1424 CellSignalStrength.SIGNAL_STRENGTH_GREAT); 1425 incrementTime.accept(1000); 1426 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1427 expectedTxDurationsMs, bi, state.currentTimeMs); 1428 1429 // Change in the signal strength of nonactive RAT should not affect anything. 1430 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER, 1431 CellSignalStrength.SIGNAL_STRENGTH_POOR); 1432 incrementTime.accept(1100); 1433 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1434 expectedTxDurationsMs, bi, state.currentTimeMs); 1435 1436 // Changing to OTHER Rat should start tracking the poor signal strength. 1437 state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA, 1438 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER); 1439 incrementTime.accept(1200); 1440 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1441 expectedTxDurationsMs, bi, state.currentTimeMs); 1442 1443 // Noting frequency change should not affect non NR Rat. 1444 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH); 1445 incrementTime.accept(1300); 1446 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1447 expectedTxDurationsMs, bi, state.currentTimeMs); 1448 1449 // Now the NR Rat, HIGH frequency range, good signal strength should start counting. 1450 state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR); 1451 incrementTime.accept(1400); 1452 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1453 expectedTxDurationsMs, bi, state.currentTimeMs); 1454 1455 // Noting frequency change should not affect non NR Rat. 1456 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW); 1457 incrementTime.accept(1500); 1458 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1459 expectedTxDurationsMs, bi, state.currentTimeMs); 1460 1461 // Modem no longer active, should not be tracking any more. 1462 state.setModemActive(false); 1463 incrementTime.accept(1500); 1464 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1465 expectedTxDurationsMs, bi, state.currentTimeMs); 1466 } 1467 1468 @SmallTest testGetPerStateActiveRadioDurationMs_withModemActivity()1469 public void testGetPerStateActiveRadioDurationMs_withModemActivity() { 1470 final MockClock clock = new MockClock(); // holds realtime and uptime in ms 1471 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock); 1472 bi.setPowerProfile(mock(PowerProfile.class)); 1473 final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT; 1474 final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1; 1475 final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels(); 1476 1477 final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount]; 1478 final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount]; 1479 final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount]; 1480 for (int rat = 0; rat < ratCount; rat++) { 1481 for (int freq = 0; freq < frequencyCount; freq++) { 1482 expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE; 1483 1484 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) { 1485 expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE; 1486 } 1487 } 1488 } 1489 1490 final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L); 1491 final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, null); 1492 1493 IntConsumer incrementTime = inc -> { 1494 state.currentTimeMs += inc; 1495 clock.realtime = clock.uptime = state.currentTimeMs; 1496 1497 // If the device is not on battery, no timers should increment. 1498 if (!state.onBattery) return; 1499 // If the modem is not active, no timers should increment. 1500 if (!state.modemActive) return; 1501 1502 final int currRat = state.currentRat; 1503 final int currFreqRange = 1504 currRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0; 1505 int currSignalStrength = state.currentSignalStrengths.get(currRat); 1506 1507 expectedDurationsMs[currRat][currFreqRange][currSignalStrength] += inc; 1508 1509 // Evaluate the HAL provided time in states. 1510 switch (state.modemState) { 1511 case SLEEP: 1512 long sleepMs = state.modemActivityInfo.getSleepTimeMillis(); 1513 state.modemActivityInfo.setSleepTimeMillis(sleepMs + inc); 1514 break; 1515 case IDLE: 1516 long idleMs = state.modemActivityInfo.getIdleTimeMillis(); 1517 state.modemActivityInfo.setIdleTimeMillis(idleMs + inc); 1518 break; 1519 case RECEIVING: 1520 long rxMs = state.modemActivityInfo.getReceiveTimeMillis(); 1521 state.modemActivityInfo.setReceiveTimeMillis(rxMs + inc); 1522 expectedRxDurationsMs[currRat][currFreqRange] += inc; 1523 break; 1524 case TRANSMITTING: 1525 int[] txMs = state.modemActivityInfo.getTransmitTimeMillis(); 1526 txMs[currSignalStrength] += inc; 1527 state.modemActivityInfo.setTransmitTimeMillis(txMs); 1528 expectedTxDurationsMs[currRat][currFreqRange][currSignalStrength] += inc; 1529 break; 1530 } 1531 }; 1532 1533 state.setOnBattery(false); 1534 state.setModemActive(false); 1535 state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN, 1536 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER); 1537 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN); 1538 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER, 1539 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN); 1540 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1541 expectedTxDurationsMs, bi, state.currentTimeMs); 1542 1543 // While not on battery, the timers should not increase. 1544 state.setModemActive(true); 1545 incrementTime.accept(100); 1546 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1547 expectedTxDurationsMs, bi, state.currentTimeMs); 1548 1549 state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR); 1550 incrementTime.accept(200); 1551 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1552 expectedTxDurationsMs, bi, state.currentTimeMs); 1553 1554 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR, 1555 CellSignalStrength.SIGNAL_STRENGTH_GOOD); 1556 incrementTime.accept(500); 1557 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1558 expectedTxDurationsMs, bi, state.currentTimeMs); 1559 1560 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE); 1561 incrementTime.accept(300); 1562 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1563 expectedTxDurationsMs, bi, state.currentTimeMs); 1564 1565 state.setRatType(TelephonyManager.NETWORK_TYPE_LTE, 1566 BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE); 1567 incrementTime.accept(400); 1568 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1569 expectedTxDurationsMs, bi, state.currentTimeMs); 1570 1571 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1572 CellSignalStrength.SIGNAL_STRENGTH_MODERATE); 1573 incrementTime.accept(500); 1574 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1575 expectedTxDurationsMs, bi, state.currentTimeMs); 1576 1577 // Data will now be available. 1578 for (int rat = 0; rat < ratCount; rat++) { 1579 for (int freq = 0; freq < frequencyCount; freq++) { 1580 if (rat == RADIO_ACCESS_TECHNOLOGY_NR 1581 || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 1582 // Only the NR RAT should have per frequency data. 1583 expectedRxDurationsMs[rat][freq] = 0; 1584 } 1585 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) { 1586 if (rat == RADIO_ACCESS_TECHNOLOGY_NR 1587 || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 1588 // Only the NR RAT should have per frequency data. 1589 expectedTxDurationsMs[rat][freq][txLvl] = 0; 1590 } 1591 } 1592 } 1593 } 1594 1595 // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should 1596 // start counting up. 1597 state.setOnBattery(true); 1598 incrementTime.accept(300); 1599 state.setModemState(ModemState.RECEIVING); 1600 incrementTime.accept(500); 1601 state.setModemState(ModemState.TRANSMITTING); 1602 incrementTime.accept(600); 1603 state.noteModemControllerActivity(); 1604 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1605 expectedTxDurationsMs, bi, state.currentTimeMs); 1606 // Changing LTE signal strength should be tracked. 1607 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1608 CellSignalStrength.SIGNAL_STRENGTH_POOR); 1609 incrementTime.accept(300); 1610 state.setModemState(ModemState.SLEEP); 1611 incrementTime.accept(1000); 1612 state.setModemState(ModemState.RECEIVING); 1613 incrementTime.accept(700); 1614 state.noteModemControllerActivity(); 1615 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1616 expectedTxDurationsMs, bi, state.currentTimeMs); 1617 1618 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1619 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN); 1620 incrementTime.accept(800); 1621 state.setModemState(ModemState.TRANSMITTING); 1622 incrementTime.accept(222); 1623 state.setModemState(ModemState.IDLE); 1624 incrementTime.accept(111); 1625 state.setModemState(ModemState.RECEIVING); 1626 incrementTime.accept(7777); 1627 state.noteModemControllerActivity(); 1628 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1629 expectedTxDurationsMs, bi, state.currentTimeMs); 1630 1631 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1632 CellSignalStrength.SIGNAL_STRENGTH_GOOD); 1633 incrementTime.accept(88); 1634 state.setModemState(ModemState.TRANSMITTING); 1635 incrementTime.accept(900); 1636 state.noteModemControllerActivity(); 1637 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1638 expectedTxDurationsMs, bi, state.currentTimeMs); 1639 1640 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1641 CellSignalStrength.SIGNAL_STRENGTH_GREAT); 1642 incrementTime.accept(123); 1643 state.setModemState(ModemState.RECEIVING); 1644 incrementTime.accept(333); 1645 state.setModemState(ModemState.TRANSMITTING); 1646 incrementTime.accept(1000); 1647 state.setModemState(ModemState.RECEIVING); 1648 incrementTime.accept(555); 1649 state.noteModemControllerActivity(); 1650 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1651 expectedTxDurationsMs, bi, state.currentTimeMs); 1652 1653 // Change in the signal strength of nonactive RAT should not affect anything. 1654 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER, 1655 CellSignalStrength.SIGNAL_STRENGTH_POOR); 1656 incrementTime.accept(631); 1657 state.setModemState(ModemState.TRANSMITTING); 1658 incrementTime.accept(321); 1659 state.setModemState(ModemState.RECEIVING); 1660 incrementTime.accept(99); 1661 state.noteModemControllerActivity(); 1662 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1663 expectedTxDurationsMs, bi, state.currentTimeMs); 1664 1665 // Changing to OTHER Rat should start tracking the poor signal strength. 1666 state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA, 1667 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER); 1668 incrementTime.accept(1200); 1669 state.noteModemControllerActivity(); 1670 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1671 expectedTxDurationsMs, bi, state.currentTimeMs); 1672 1673 // Noting frequency change should not affect non NR Rat. 1674 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH); 1675 incrementTime.accept(444); 1676 state.setModemState(ModemState.TRANSMITTING); 1677 incrementTime.accept(1300); 1678 state.noteModemControllerActivity(); 1679 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1680 expectedTxDurationsMs, bi, state.currentTimeMs); 1681 1682 // Now the NR Rat, HIGH frequency range, good signal strength should start counting. 1683 state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR); 1684 incrementTime.accept(1400); 1685 state.noteModemControllerActivity(); 1686 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1687 expectedTxDurationsMs, bi, state.currentTimeMs); 1688 1689 // Frequency changed to low. 1690 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW); 1691 incrementTime.accept(852); 1692 state.setModemState(ModemState.RECEIVING); 1693 incrementTime.accept(157); 1694 state.setModemState(ModemState.TRANSMITTING); 1695 incrementTime.accept(1500); 1696 state.noteModemControllerActivity(); 1697 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1698 expectedTxDurationsMs, bi, state.currentTimeMs); 1699 1700 // Modem no longer active, should not be tracking any more. 1701 state.setModemActive(false); 1702 incrementTime.accept(1500); 1703 state.noteModemControllerActivity(); 1704 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1705 expectedTxDurationsMs, bi, state.currentTimeMs); 1706 } 1707 1708 @SmallTest testGetPerStateActiveRadioDurationMs_withSpecificInfoModemActivity()1709 public void testGetPerStateActiveRadioDurationMs_withSpecificInfoModemActivity() { 1710 final MockClock clock = new MockClock(); // holds realtime and uptime in ms 1711 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock); 1712 bi.setPowerProfile(mock(PowerProfile.class)); 1713 final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT; 1714 final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1; 1715 final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels(); 1716 1717 List<ActivityStatsTechSpecificInfo> specificInfoList = new ArrayList(); 1718 1719 final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount]; 1720 final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount]; 1721 final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount]; 1722 for (int rat = 0; rat < ratCount; rat++) { 1723 for (int freq = 0; freq < frequencyCount; freq++) { 1724 if (rat == RADIO_ACCESS_TECHNOLOGY_NR 1725 || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 1726 // Initialize available specific Modem info 1727 specificInfoList.add( 1728 new ActivityStatsTechSpecificInfo(rat, freq, new int[txLevelCount], 0)); 1729 } 1730 expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE; 1731 1732 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) { 1733 expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE; 1734 } 1735 } 1736 } 1737 1738 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.UNKNOWN, 1739 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0)); 1740 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.GERAN, 1741 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0)); 1742 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.UTRAN, 1743 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0)); 1744 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.EUTRAN, 1745 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0)); 1746 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.CDMA2000, 1747 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0)); 1748 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.IWLAN, 1749 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0)); 1750 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN, 1751 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0)); 1752 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN, 1753 ServiceState.FREQUENCY_RANGE_LOW, new int[txLevelCount], 0)); 1754 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN, 1755 ServiceState.FREQUENCY_RANGE_MID, new int[txLevelCount], 0)); 1756 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN, 1757 ServiceState.FREQUENCY_RANGE_HIGH, new int[txLevelCount], 0)); 1758 specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN, 1759 ServiceState.FREQUENCY_RANGE_MMWAVE, new int[txLevelCount], 0)); 1760 1761 final ActivityStatsTechSpecificInfo[] specificInfos = specificInfoList.toArray( 1762 new ActivityStatsTechSpecificInfo[specificInfoList.size()]); 1763 final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, specificInfos); 1764 final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, specificInfos); 1765 1766 IntConsumer incrementTime = inc -> { 1767 state.currentTimeMs += inc; 1768 clock.realtime = clock.uptime = state.currentTimeMs; 1769 1770 // If the device is not on battery, no timers should increment. 1771 if (!state.onBattery) return; 1772 // If the modem is not active, no timers should increment. 1773 if (!state.modemActive) return; 1774 1775 final int currRat = state.currentRat; 1776 final int currRant = state.currentRadioAccessNetworkType; 1777 final int currFreqRange = 1778 currRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0; 1779 int currSignalStrength = state.currentSignalStrengths.get(currRat); 1780 1781 expectedDurationsMs[currRat][currFreqRange][currSignalStrength] += inc; 1782 1783 // Evaluate the HAL provided time in states. 1784 final ActivityStatsTechSpecificInfo info = state.getSpecificInfo(currRant, 1785 currFreqRange); 1786 switch (state.modemState) { 1787 case SLEEP: 1788 long sleepMs = state.modemActivityInfo.getSleepTimeMillis(); 1789 state.modemActivityInfo.setSleepTimeMillis(sleepMs + inc); 1790 break; 1791 case IDLE: 1792 long idleMs = state.modemActivityInfo.getIdleTimeMillis(); 1793 state.modemActivityInfo.setIdleTimeMillis(idleMs + inc); 1794 break; 1795 case RECEIVING: 1796 long rxMs = info.getReceiveTimeMillis(); 1797 info.setReceiveTimeMillis(rxMs + inc); 1798 expectedRxDurationsMs[currRat][currFreqRange] += inc; 1799 break; 1800 case TRANSMITTING: 1801 int[] txMs = info.getTransmitTimeMillis().clone(); 1802 txMs[currSignalStrength] += inc; 1803 info.setTransmitTimeMillis(txMs); 1804 expectedTxDurationsMs[currRat][currFreqRange][currSignalStrength] += inc; 1805 break; 1806 } 1807 }; 1808 1809 state.setOnBattery(false); 1810 state.setModemActive(false); 1811 state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN, 1812 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER, 1813 AccessNetworkConstants.AccessNetworkType.UNKNOWN); 1814 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN); 1815 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER, 1816 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN); 1817 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1818 expectedTxDurationsMs, bi, state.currentTimeMs); 1819 1820 // While not on battery, the timers should not increase. 1821 state.setModemActive(true); 1822 incrementTime.accept(100); 1823 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1824 expectedTxDurationsMs, bi, state.currentTimeMs); 1825 1826 state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR, 1827 AccessNetworkConstants.AccessNetworkType.NGRAN); 1828 incrementTime.accept(200); 1829 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1830 expectedTxDurationsMs, bi, state.currentTimeMs); 1831 1832 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR, 1833 CellSignalStrength.SIGNAL_STRENGTH_GOOD); 1834 incrementTime.accept(500); 1835 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1836 expectedTxDurationsMs, bi, state.currentTimeMs); 1837 1838 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE); 1839 incrementTime.accept(300); 1840 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1841 expectedTxDurationsMs, bi, state.currentTimeMs); 1842 1843 state.setRatType(TelephonyManager.NETWORK_TYPE_LTE, 1844 BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1845 AccessNetworkConstants.AccessNetworkType.EUTRAN); 1846 incrementTime.accept(400); 1847 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1848 expectedTxDurationsMs, bi, state.currentTimeMs); 1849 1850 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1851 CellSignalStrength.SIGNAL_STRENGTH_MODERATE); 1852 incrementTime.accept(500); 1853 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1854 expectedTxDurationsMs, bi, state.currentTimeMs); 1855 1856 // Data will now be available. 1857 for (int rat = 0; rat < ratCount; rat++) { 1858 for (int freq = 0; freq < frequencyCount; freq++) { 1859 if (rat == RADIO_ACCESS_TECHNOLOGY_NR 1860 || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 1861 // Only the NR RAT should have per frequency data. 1862 expectedRxDurationsMs[rat][freq] = 0; 1863 } 1864 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) { 1865 if (rat == RADIO_ACCESS_TECHNOLOGY_NR 1866 || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) { 1867 // Only the NR RAT should have per frequency data. 1868 expectedTxDurationsMs[rat][freq][txLvl] = 0; 1869 } 1870 } 1871 } 1872 } 1873 1874 // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should 1875 // start counting up. 1876 state.setOnBattery(true); 1877 state.noteModemControllerActivity(); 1878 incrementTime.accept(300); 1879 state.setModemState(ModemState.RECEIVING); 1880 incrementTime.accept(500); 1881 state.setModemState(ModemState.TRANSMITTING); 1882 incrementTime.accept(600); 1883 state.noteModemControllerActivity(); 1884 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1885 expectedTxDurationsMs, bi, state.currentTimeMs); 1886 // Changing LTE signal strength should be tracked. 1887 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1888 CellSignalStrength.SIGNAL_STRENGTH_POOR); 1889 incrementTime.accept(300); 1890 state.setModemState(ModemState.SLEEP); 1891 incrementTime.accept(1000); 1892 state.setModemState(ModemState.RECEIVING); 1893 incrementTime.accept(700); 1894 state.noteModemControllerActivity(); 1895 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1896 expectedTxDurationsMs, bi, state.currentTimeMs); 1897 1898 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1899 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN); 1900 incrementTime.accept(800); 1901 state.setModemState(ModemState.TRANSMITTING); 1902 incrementTime.accept(222); 1903 state.setModemState(ModemState.IDLE); 1904 incrementTime.accept(111); 1905 state.setModemState(ModemState.RECEIVING); 1906 incrementTime.accept(7777); 1907 state.noteModemControllerActivity(); 1908 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1909 expectedTxDurationsMs, bi, state.currentTimeMs); 1910 1911 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1912 CellSignalStrength.SIGNAL_STRENGTH_GOOD); 1913 incrementTime.accept(88); 1914 state.setModemState(ModemState.TRANSMITTING); 1915 incrementTime.accept(900); 1916 state.noteModemControllerActivity(); 1917 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1918 expectedTxDurationsMs, bi, state.currentTimeMs); 1919 1920 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE, 1921 CellSignalStrength.SIGNAL_STRENGTH_GREAT); 1922 incrementTime.accept(123); 1923 state.setModemState(ModemState.RECEIVING); 1924 incrementTime.accept(333); 1925 state.setModemState(ModemState.TRANSMITTING); 1926 incrementTime.accept(1000); 1927 state.setModemState(ModemState.RECEIVING); 1928 incrementTime.accept(555); 1929 state.noteModemControllerActivity(); 1930 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1931 expectedTxDurationsMs, bi, state.currentTimeMs); 1932 1933 // Change in the signal strength of nonactive RAT should not affect anything. 1934 state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER, 1935 CellSignalStrength.SIGNAL_STRENGTH_POOR); 1936 incrementTime.accept(631); 1937 state.setModemState(ModemState.TRANSMITTING); 1938 incrementTime.accept(321); 1939 state.setModemState(ModemState.RECEIVING); 1940 incrementTime.accept(99); 1941 state.noteModemControllerActivity(); 1942 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1943 expectedTxDurationsMs, bi, state.currentTimeMs); 1944 1945 // Changing to OTHER Rat should start tracking the poor signal strength. 1946 state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA, 1947 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER, 1948 AccessNetworkConstants.AccessNetworkType.CDMA2000); 1949 incrementTime.accept(1200); 1950 state.noteModemControllerActivity(); 1951 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1952 expectedTxDurationsMs, bi, state.currentTimeMs); 1953 1954 // Noting frequency change should not affect non NR Rat. 1955 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH); 1956 incrementTime.accept(444); 1957 state.setModemState(ModemState.TRANSMITTING); 1958 incrementTime.accept(1300); 1959 state.noteModemControllerActivity(); 1960 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1961 expectedTxDurationsMs, bi, state.currentTimeMs); 1962 1963 // Now the NR Rat, HIGH frequency range, good signal strength should start counting. 1964 state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR, 1965 AccessNetworkConstants.AccessNetworkType.NGRAN); 1966 incrementTime.accept(1400); 1967 state.noteModemControllerActivity(); 1968 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1969 expectedTxDurationsMs, bi, state.currentTimeMs); 1970 1971 // Frequency changed to low. 1972 state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW); 1973 incrementTime.accept(852); 1974 state.setModemState(ModemState.RECEIVING); 1975 incrementTime.accept(157); 1976 state.setModemState(ModemState.TRANSMITTING); 1977 incrementTime.accept(1500); 1978 state.noteModemControllerActivity(); 1979 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1980 expectedTxDurationsMs, bi, state.currentTimeMs); 1981 1982 // Modem no longer active, should not be tracking any more. 1983 state.setModemActive(false); 1984 incrementTime.accept(1500); 1985 state.noteModemControllerActivity(); 1986 checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs, 1987 expectedTxDurationsMs, bi, state.currentTimeMs); 1988 } 1989 1990 @SmallTest 1991 @SuppressWarnings("GuardedBy") testProcStateSyncScheduling_mobileRadioActiveState()1992 public void testProcStateSyncScheduling_mobileRadioActiveState() { 1993 final MockClock clock = new MockClock(); // holds realtime and uptime in ms 1994 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock); 1995 final MutableInt lastProcStateChangeFlags = new MutableInt(0); 1996 1997 MockBatteryStatsImpl.DummyExternalStatsSync externalStatsSync = 1998 new MockBatteryStatsImpl.DummyExternalStatsSync() { 1999 @Override 2000 public void scheduleSyncDueToProcessStateChange(int flags, 2001 long delayMillis) { 2002 lastProcStateChangeFlags.value = flags; 2003 } 2004 }; 2005 2006 bi.setDummyExternalStatsSync(externalStatsSync); 2007 2008 bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 2009 2010 // Note mobile radio is on. 2011 long curr = 1000L * (clock.realtime = clock.uptime = 1001); 2012 bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr, 2013 UID); 2014 2015 lastProcStateChangeFlags.value = 0; 2016 clock.realtime = clock.uptime = 2002; 2017 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND); 2018 2019 final int allProcFlags = BatteryStatsImpl.ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE; 2020 assertEquals(allProcFlags, lastProcStateChangeFlags.value); 2021 2022 // Note mobile radio is off. 2023 curr = 1000L * (clock.realtime = clock.uptime = 3003); 2024 bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW, curr, 2025 UID); 2026 2027 lastProcStateChangeFlags.value = 0; 2028 clock.realtime = clock.uptime = 4004; 2029 bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2030 2031 final int noRadioProcFlags = BatteryStatsImpl.ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE 2032 & ~BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO; 2033 assertEquals( 2034 "An inactive radio should not be queried on proc state change", 2035 noRadioProcFlags, lastProcStateChangeFlags.value); 2036 } 2037 2038 2039 2040 @SmallTest testNoteMobileRadioPowerStateLocked()2041 public void testNoteMobileRadioPowerStateLocked() { 2042 long curr; 2043 boolean update; 2044 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 2045 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 2046 bi.setOnBatteryInternal(true); 2047 2048 // Note mobile radio is on. 2049 curr = 1000L * (clocks.realtime = clocks.uptime = 1001); 2050 bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr, 2051 UID); 2052 2053 // Note mobile radio is still on. 2054 curr = 1000L * (clocks.realtime = clocks.uptime = 2001); 2055 update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, 2056 curr, UID); 2057 assertFalse( 2058 "noteMobileRadioPowerStateLocked should not request an update when the power " 2059 + "state does not change from HIGH.", 2060 update); 2061 2062 // Note mobile radio is off. 2063 curr = 1000L * (clocks.realtime = clocks.uptime = 3001); 2064 update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW, 2065 curr, UID); 2066 assertTrue( 2067 "noteMobileRadioPowerStateLocked should request an update when the power state " 2068 + "changes from HIGH to LOW.", 2069 update); 2070 2071 // Note mobile radio is still off. 2072 curr = 1000L * (clocks.realtime = clocks.uptime = 4001); 2073 update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW, 2074 curr, UID); 2075 assertFalse( 2076 "noteMobileRadioPowerStateLocked should not request an update when the power " 2077 + "state does not change from LOW.", 2078 update); 2079 2080 // Note mobile radio is on. 2081 curr = 1000L * (clocks.realtime = clocks.uptime = 5001); 2082 update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, 2083 curr, UID); 2084 assertFalse( 2085 "noteMobileRadioPowerStateLocked should not request an update when the power " 2086 + "state changes from LOW to HIGH.", 2087 update); 2088 } 2089 2090 @SmallTest testNoteMobileRadioPowerStateLocked_rateLimited()2091 public void testNoteMobileRadioPowerStateLocked_rateLimited() { 2092 long curr; 2093 boolean update; 2094 final MockClock clocks = new MockClock(); // holds realtime and uptime in ms 2095 final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks); 2096 bi.setPowerProfile(mock(PowerProfile.class)); 2097 2098 final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels(); 2099 final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L); 2100 2101 final long rateLimit = bi.getMobileRadioPowerStateUpdateRateLimit(); 2102 if (rateLimit < 0) { 2103 Log.w(TAG, "Skipping testNoteMobileRadioPowerStateLocked_rateLimited, rateLimit = " 2104 + rateLimit); 2105 return; 2106 } 2107 bi.setOnBatteryInternal(true); 2108 2109 // Note mobile radio is on. 2110 curr = 1000L * (clocks.realtime = clocks.uptime = 1001); 2111 bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr, 2112 UID); 2113 2114 clocks.realtime = clocks.uptime = 2001; 2115 mai.setTimestamp(clocks.realtime); 2116 bi.noteModemControllerActivity(mai, POWER_DATA_UNAVAILABLE, 2117 clocks.realtime, clocks.uptime, mNetworkStatsManager); 2118 2119 // Note mobile radio is off within the rate limit duration. 2120 clocks.realtime = clocks.uptime = clocks.realtime + (long) (rateLimit * 0.7); 2121 curr = 1000L * clocks.realtime; 2122 update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW, 2123 curr, UID); 2124 assertFalse( 2125 "noteMobileRadioPowerStateLocked should not request an update when the power " 2126 + "state so soon after a noteModemControllerActivity", 2127 update); 2128 2129 // Note mobile radio is on. 2130 clocks.realtime = clocks.uptime = clocks.realtime + (long) (rateLimit * 0.7); 2131 curr = 1000L * clocks.realtime; 2132 bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr, 2133 UID); 2134 2135 // Note mobile radio is off much later 2136 clocks.realtime = clocks.uptime = clocks.realtime + rateLimit; 2137 curr = 1000L * clocks.realtime; 2138 update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW, 2139 curr, UID); 2140 assertTrue( 2141 "noteMobileRadioPowerStateLocked should request an update when the power state " 2142 + "changes from HIGH to LOW much later after a " 2143 + "noteModemControllerActivity.", 2144 update); 2145 } 2146 setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi)2147 private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) { 2148 // Note that noteUidProcessStateLocked uses ActivityManager process states. 2149 if (fgOn) { 2150 bi.noteActivityResumedLocked(uid); 2151 bi.noteUidProcessStateLocked(uid, ActivityManager.PROCESS_STATE_TOP); 2152 } else { 2153 bi.noteActivityPausedLocked(uid); 2154 bi.noteUidProcessStateLocked(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY); 2155 } 2156 } 2157 checkMeasuredCharge(String caseName, int uid1, long blame1, int uid2, long blame2, long globalDoze, MockBatteryStatsImpl bi)2158 private void checkMeasuredCharge(String caseName, int uid1, long blame1, int uid2, long blame2, 2159 long globalDoze, MockBatteryStatsImpl bi) { 2160 final int bucket = MeasuredEnergyStats.POWER_BUCKET_SCREEN_ON; 2161 2162 assertEquals("Wrong uid1 blame for Case " + caseName, blame1, 2163 bi.getUidStatsLocked(uid1).getMeasuredBatteryConsumptionUC(bucket)); 2164 2165 assertEquals("Wrong uid2 blame for Case " + caseName, blame2, 2166 bi.getUidStatsLocked(uid2).getMeasuredBatteryConsumptionUC(bucket)); 2167 2168 assertEquals("Wrong total blame for Case " + caseName, blame1 + blame2, 2169 bi.getScreenOnMeasuredBatteryConsumptionUC()); 2170 2171 assertEquals("Wrong doze for Case " + caseName, globalDoze, 2172 bi.getScreenDozeMeasuredBatteryConsumptionUC()); 2173 } 2174 checkCustomBatteryConsumption(String caseName, long totalBlameA, long totalBlameB, int uid1, long blame1A, long blame1B, int uid2, long blame2A, long blame2B, MockBatteryStatsImpl bi)2175 private void checkCustomBatteryConsumption(String caseName, 2176 long totalBlameA, long totalBlameB, 2177 int uid1, long blame1A, long blame1B, 2178 int uid2, long blame2A, long blame2B, 2179 MockBatteryStatsImpl bi) { 2180 2181 final long[] actualTotal = bi.getCustomConsumerMeasuredBatteryConsumptionUC(); 2182 final long[] actualUid1 = 2183 bi.getUidStatsLocked(uid1).getCustomConsumerMeasuredBatteryConsumptionUC(); 2184 final long[] actualUid2 = 2185 bi.getUidStatsLocked(uid2).getCustomConsumerMeasuredBatteryConsumptionUC(); 2186 2187 assertNotNull(actualTotal); 2188 assertNotNull(actualUid1); 2189 assertNotNull(actualUid2); 2190 2191 assertEquals("Wrong total blame in bucket 0 for Case " + caseName, totalBlameA, 2192 actualTotal[0]); 2193 2194 assertEquals("Wrong total blame in bucket 1 for Case " + caseName, totalBlameB, 2195 actualTotal[1]); 2196 2197 assertEquals("Wrong uid1 blame in bucket 0 for Case " + caseName, blame1A, actualUid1[0]); 2198 2199 assertEquals("Wrong uid1 blame in bucket 1 for Case " + caseName, blame1B, actualUid1[1]); 2200 2201 assertEquals("Wrong uid2 blame in bucket 0 for Case " + caseName, blame2A, actualUid2[0]); 2202 2203 assertEquals("Wrong uid2 blame in bucket 1 for Case " + caseName, blame2B, actualUid2[1]); 2204 } 2205 checkScreenBrightnesses(long[] overallExpected, long[][] perDisplayExpected, BatteryStatsImpl bi, long currentTimeMs)2206 private void checkScreenBrightnesses(long[] overallExpected, long[][] perDisplayExpected, 2207 BatteryStatsImpl bi, long currentTimeMs) { 2208 final int numDisplay = bi.getDisplayCount(); 2209 for (int bin = 0; bin < NUM_SCREEN_BRIGHTNESS_BINS; bin++) { 2210 for (int display = 0; display < numDisplay; display++) { 2211 assertEquals("Failure for display " + display + " screen brightness bin " + bin, 2212 perDisplayExpected[display][bin] * 1000, 2213 bi.getDisplayScreenBrightnessTime(display, bin, currentTimeMs * 1000)); 2214 } 2215 assertEquals("Failure for overall screen brightness bin " + bin, 2216 overallExpected[bin] * 1000, 2217 bi.getScreenBrightnessTime(bin, currentTimeMs * 1000, STATS_SINCE_CHARGED)); 2218 } 2219 } 2220 checkPerStateActiveRadioDurations(long[][][] expectedDurationsMs, long[][] expectedRxDurationsMs, long[][][] expectedTxDurationsMs, BatteryStatsImpl bi, long currentTimeMs)2221 private void checkPerStateActiveRadioDurations(long[][][] expectedDurationsMs, 2222 long[][] expectedRxDurationsMs, long[][][] expectedTxDurationsMs, 2223 BatteryStatsImpl bi, long currentTimeMs) { 2224 for (int rat = 0; rat < expectedDurationsMs.length; rat++) { 2225 final long[][] expectedRatDurationsMs = expectedDurationsMs[rat]; 2226 for (int freq = 0; freq < expectedRatDurationsMs.length; freq++) { 2227 final long expectedRxDurationMs = expectedRxDurationsMs[rat][freq]; 2228 2229 // Build a verbose fail message, just in case. 2230 final StringBuilder rxFailSb = new StringBuilder(); 2231 rxFailSb.append("Wrong time in Rx state for RAT:"); 2232 rxFailSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]); 2233 rxFailSb.append(", frequency:"); 2234 rxFailSb.append(ServiceState.frequencyRangeToString(freq)); 2235 assertEquals(rxFailSb.toString(), expectedRxDurationMs, 2236 bi.getActiveRxRadioDurationMs(rat, freq, currentTimeMs)); 2237 2238 final long[] expectedFreqDurationsMs = expectedRatDurationsMs[freq]; 2239 for (int strength = 0; strength < expectedFreqDurationsMs.length; strength++) { 2240 final long expectedSignalStrengthDurationMs = expectedFreqDurationsMs[strength]; 2241 final long expectedTxDurationMs = expectedTxDurationsMs[rat][freq][strength]; 2242 final long actualDurationMs = bi.getActiveRadioDurationMs(rat, freq, 2243 strength, currentTimeMs); 2244 2245 final StringBuilder failSb = new StringBuilder(); 2246 failSb.append("Wrong time in state for RAT:"); 2247 failSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]); 2248 failSb.append(", frequency:"); 2249 failSb.append(ServiceState.frequencyRangeToString(freq)); 2250 failSb.append(", strength:"); 2251 failSb.append(strength); 2252 assertEquals(failSb.toString(), expectedSignalStrengthDurationMs, 2253 actualDurationMs); 2254 2255 final StringBuilder txFailSb = new StringBuilder(); 2256 txFailSb.append("Wrong time in Tx state for RAT:"); 2257 txFailSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]); 2258 txFailSb.append(", frequency:"); 2259 txFailSb.append(ServiceState.frequencyRangeToString(freq)); 2260 txFailSb.append(", strength:"); 2261 txFailSb.append(strength); 2262 assertEquals(txFailSb.toString(), expectedTxDurationMs, 2263 bi.getActiveTxRadioDurationMs(rat, freq, strength, currentTimeMs)); 2264 } 2265 } 2266 } 2267 } 2268 2269 private class ModemAndBatteryState { 2270 public long currentTimeMs = 100; 2271 public boolean onBattery = false; 2272 public boolean modemActive = false; 2273 @Annotation.NetworkType 2274 public int currentNetworkDataType = TelephonyManager.NETWORK_TYPE_UNKNOWN; 2275 @BatteryStats.RadioAccessTechnology 2276 public int currentRat = BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER; 2277 @AccessNetworkConstants.RadioAccessNetworkType 2278 public int currentRadioAccessNetworkType = AccessNetworkConstants.AccessNetworkType.UNKNOWN; 2279 @ServiceState.FrequencyRange 2280 public int currentFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN; 2281 public SparseIntArray currentSignalStrengths = new SparseIntArray(); 2282 public ModemState modemState = ModemState.SLEEP; 2283 public ModemActivityInfo modemActivityInfo; 2284 public ActivityStatsTechSpecificInfo[] specificInfo; 2285 2286 private final MockBatteryStatsImpl mBsi; 2287 ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai, ActivityStatsTechSpecificInfo[] astsi)2288 ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai, 2289 ActivityStatsTechSpecificInfo[] astsi) { 2290 mBsi = bsi; 2291 modemActivityInfo = mai; 2292 specificInfo = astsi; 2293 } 2294 setOnBattery(boolean onBattery)2295 void setOnBattery(boolean onBattery) { 2296 this.onBattery = onBattery; 2297 mBsi.updateTimeBasesLocked(onBattery, Display.STATE_OFF, currentTimeMs * 1000, 2298 currentTimeMs * 1000); 2299 mBsi.setOnBatteryInternal(onBattery); 2300 noteModemControllerActivity(); 2301 } 2302 setModemActive(boolean active)2303 void setModemActive(boolean active) { 2304 modemActive = active; 2305 final int state = active ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH 2306 : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW; 2307 mBsi.noteMobileRadioPowerStateLocked(state, currentTimeMs * 1000_000L, UID); 2308 noteModemControllerActivity(); 2309 } 2310 setRatType(@nnotation.NetworkType int dataType, @BatteryStats.RadioAccessTechnology int rat, @AccessNetworkConstants.RadioAccessNetworkType int halDataType)2311 void setRatType(@Annotation.NetworkType int dataType, 2312 @BatteryStats.RadioAccessTechnology int rat, 2313 @AccessNetworkConstants.RadioAccessNetworkType int halDataType) { 2314 currentRadioAccessNetworkType = halDataType; 2315 setRatType(dataType, rat); 2316 } 2317 setRatType(@nnotation.NetworkType int dataType, @BatteryStats.RadioAccessTechnology int rat)2318 void setRatType(@Annotation.NetworkType int dataType, 2319 @BatteryStats.RadioAccessTechnology int rat) { 2320 currentNetworkDataType = dataType; 2321 currentRat = rat; 2322 mBsi.notePhoneDataConnectionStateLocked(dataType, true, ServiceState.STATE_IN_SERVICE, 2323 currentFrequencyRange); 2324 } 2325 setFrequencyRange(@erviceState.FrequencyRange int frequency)2326 void setFrequencyRange(@ServiceState.FrequencyRange int frequency) { 2327 currentFrequencyRange = frequency; 2328 mBsi.notePhoneDataConnectionStateLocked(currentNetworkDataType, true, 2329 ServiceState.STATE_IN_SERVICE, frequency); 2330 } 2331 setSignalStrength(@atteryStats.RadioAccessTechnology int rat, int strength)2332 void setSignalStrength(@BatteryStats.RadioAccessTechnology int rat, int strength) { 2333 currentSignalStrengths.put(rat, strength); 2334 final int size = currentSignalStrengths.size(); 2335 final int newestGenSignalStrength = currentSignalStrengths.valueAt(size - 1); 2336 mBsi.notePhoneSignalStrengthLocked(newestGenSignalStrength, currentSignalStrengths); 2337 } 2338 setModemState(ModemState state)2339 void setModemState(ModemState state) { 2340 modemState = state; 2341 } 2342 getSpecificInfo(@atteryStats.RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequency)2343 ActivityStatsTechSpecificInfo getSpecificInfo(@BatteryStats.RadioAccessTechnology int rat, 2344 @ServiceState.FrequencyRange int frequency) { 2345 if (specificInfo == null) return null; 2346 for (ActivityStatsTechSpecificInfo info : specificInfo) { 2347 if (info.getRat() == rat && info.getFrequencyRange() == frequency) { 2348 return info; 2349 } 2350 } 2351 return null; 2352 } 2353 noteModemControllerActivity()2354 void noteModemControllerActivity() { 2355 if (modemActivityInfo == null) return; 2356 modemActivityInfo.setTimestamp(currentTimeMs); 2357 final ModemActivityInfo copy; 2358 if (specificInfo == null) { 2359 copy = new ModemActivityInfo( 2360 modemActivityInfo.getTimestampMillis(), 2361 modemActivityInfo.getSleepTimeMillis(), 2362 modemActivityInfo.getIdleTimeMillis(), 2363 modemActivityInfo.getTransmitTimeMillis().clone(), 2364 modemActivityInfo.getReceiveTimeMillis()); 2365 } else { 2366 // Deep copy specificInfo 2367 final ActivityStatsTechSpecificInfo[] infoCopies = 2368 new ActivityStatsTechSpecificInfo[specificInfo.length]; 2369 for (int i = 0; i < specificInfo.length; i++) { 2370 final ActivityStatsTechSpecificInfo info = specificInfo[i]; 2371 infoCopies[i] = new ActivityStatsTechSpecificInfo(info.getRat(), 2372 info.getFrequencyRange(), info.getTransmitTimeMillis().clone(), 2373 (int) info.getReceiveTimeMillis()); 2374 } 2375 2376 copy = new ModemActivityInfo( 2377 modemActivityInfo.getTimestampMillis(), 2378 modemActivityInfo.getSleepTimeMillis(), 2379 modemActivityInfo.getIdleTimeMillis(), 2380 infoCopies); 2381 } 2382 mBsi.noteModemControllerActivity(copy, POWER_DATA_UNAVAILABLE, 2383 currentTimeMs, currentTimeMs, mNetworkStatsManager); 2384 } 2385 } 2386 } 2387