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