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