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.Uid.NUM_PROCESS_STATE; 20 import static android.os.BatteryStats.Uid.PROCESS_STATE_BACKGROUND; 21 import static android.os.BatteryStats.Uid.PROCESS_STATE_CACHED; 22 import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE; 23 import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP; 24 25 import static com.google.common.truth.Truth.assertThat; 26 27 import static org.junit.Assert.assertArrayEquals; 28 import static org.junit.Assert.assertEquals; 29 import static org.junit.Assert.assertFalse; 30 import static org.junit.Assert.assertNotNull; 31 import static org.junit.Assert.assertTrue; 32 import static org.mockito.ArgumentMatchers.any; 33 import static org.mockito.ArgumentMatchers.anyLong; 34 import static org.mockito.ArgumentMatchers.eq; 35 import static org.mockito.Mockito.doAnswer; 36 import static org.mockito.Mockito.when; 37 38 import android.app.ActivityManager; 39 import android.bluetooth.BluetoothActivityEnergyInfo; 40 import android.bluetooth.UidTraffic; 41 import android.os.BatteryStats; 42 import android.os.BluetoothBatteryStats; 43 import android.os.Parcel; 44 import android.os.WakeLockStats; 45 import android.os.WorkSource; 46 import android.util.SparseArray; 47 import android.view.Display; 48 49 import androidx.test.filters.LargeTest; 50 import androidx.test.runner.AndroidJUnit4; 51 52 import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader; 53 import com.android.internal.os.KernelSingleUidTimeReader; 54 import com.android.internal.os.LongArrayMultiStateCounter; 55 import com.android.internal.os.PowerProfile; 56 57 import com.google.common.collect.ImmutableList; 58 59 import org.junit.Before; 60 import org.junit.Test; 61 import org.junit.runner.RunWith; 62 import org.mockito.Mock; 63 import org.mockito.MockitoAnnotations; 64 65 import java.util.List; 66 67 @LargeTest 68 @RunWith(AndroidJUnit4.class) 69 @SuppressWarnings("GuardedBy") 70 public class BatteryStatsImplTest { 71 private static final long[] CPU_FREQS = {1, 2, 3, 4, 5}; 72 private static final int NUM_CPU_FREQS = CPU_FREQS.length; 73 74 @Mock 75 private KernelCpuUidFreqTimeReader mKernelUidCpuFreqTimeReader; 76 @Mock 77 private KernelSingleUidTimeReader mKernelSingleUidTimeReader; 78 @Mock 79 private PowerProfile mPowerProfile; 80 81 private final MockClock mMockClock = new MockClock(); 82 private MockBatteryStatsImpl mBatteryStatsImpl; 83 84 @Before setUp()85 public void setUp() { 86 MockitoAnnotations.initMocks(this); 87 88 when(mKernelUidCpuFreqTimeReader.isFastCpuTimesReader()).thenReturn(true); 89 when(mKernelUidCpuFreqTimeReader.readFreqs(any())).thenReturn(CPU_FREQS); 90 when(mKernelUidCpuFreqTimeReader.allUidTimesAvailable()).thenReturn(true); 91 when(mKernelSingleUidTimeReader.singleUidCpuTimesAvailable()).thenReturn(true); 92 mBatteryStatsImpl = new MockBatteryStatsImpl(mMockClock) 93 .setPowerProfile(mPowerProfile) 94 .setKernelCpuUidFreqTimeReader(mKernelUidCpuFreqTimeReader) 95 .setKernelSingleUidTimeReader(mKernelSingleUidTimeReader); 96 } 97 98 @Test testUpdateProcStateCpuTimes()99 public void testUpdateProcStateCpuTimes() { 100 mBatteryStatsImpl.setOnBatteryInternal(true); 101 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); 102 103 final int[] testUids = {10032, 10048, 10145, 10139}; 104 final int[] activityManagerProcStates = { 105 ActivityManager.PROCESS_STATE_RECEIVER, 106 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 107 ActivityManager.PROCESS_STATE_TOP, 108 ActivityManager.PROCESS_STATE_CACHED_EMPTY 109 }; 110 final int[] testProcStates = { 111 PROCESS_STATE_BACKGROUND, 112 PROCESS_STATE_FOREGROUND_SERVICE, 113 PROCESS_STATE_TOP, 114 PROCESS_STATE_CACHED 115 }; 116 117 // Initialize time-in-freq counters 118 mMockClock.realtime = 1000; 119 mMockClock.uptime = 1000; 120 for (int i = 0; i < testUids.length; ++i) { 121 mockKernelSingleUidTimeReader(testUids[i], new long[5]); 122 mBatteryStatsImpl.noteUidProcessStateLocked(testUids[i], activityManagerProcStates[i]); 123 } 124 125 final long[] timeInFreqs = new long[NUM_CPU_FREQS]; 126 127 // Verify there are no cpu times initially. 128 for (int i = 0; i < testUids.length; ++i) { 129 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUids[i]); 130 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { 131 assertFalse(u.getCpuFreqTimes(timeInFreqs, procState)); 132 assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); 133 } 134 } 135 136 // Obtain initial CPU time-in-freq counts 137 final long[][] cpuTimes = { 138 {349734983, 394982394832L, 909834, 348934, 9838}, 139 {7498, 1239890, 988, 13298, 98980}, 140 {989834, 384098, 98483, 23809, 4984}, 141 {4859048, 348903, 4578967, 5973894, 298549} 142 }; 143 144 mMockClock.realtime += 1000; 145 mMockClock.uptime += 1000; 146 147 for (int i = 0; i < testUids.length; ++i) { 148 mockKernelSingleUidTimeReader(testUids[i], cpuTimes[i]); 149 mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], 150 mMockClock.realtime, mMockClock.uptime); 151 } 152 153 for (int i = 0; i < testUids.length; ++i) { 154 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); 155 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { 156 final boolean hasTimeInFreq = u.getCpuFreqTimes(timeInFreqs, procState); 157 if (procState == testProcStates[i]) { 158 assertArrayEquals("Uid=" + testUids[i], cpuTimes[i], timeInFreqs); 159 } else { 160 assertFalse(hasTimeInFreq); 161 } 162 assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); 163 } 164 } 165 166 // Accumulate CPU time-in-freq deltas 167 final long[][] delta1 = { 168 {9589, 148934, 309894, 3098493, 98754}, 169 {21983, 94983, 4983, 9878493, 84854}, 170 {945894, 9089432, 19478, 3834, 7845}, 171 {843895, 43948, 949582, 99, 384} 172 }; 173 174 mMockClock.realtime += 1000; 175 mMockClock.uptime += 1000; 176 177 for (int i = 0; i < testUids.length; ++i) { 178 long[] newCpuTimes = new long[cpuTimes[i].length]; 179 for (int j = 0; j < cpuTimes[i].length; j++) { 180 newCpuTimes[j] = cpuTimes[i][j] + delta1[i][j]; 181 } 182 mockKernelSingleUidTimeReader(testUids[i], newCpuTimes); 183 mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], 184 mMockClock.realtime, mMockClock.uptime); 185 } 186 187 for (int i = 0; i < testUids.length; ++i) { 188 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); 189 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { 190 if (procState == testProcStates[i]) { 191 long[] expectedCpuTimes = cpuTimes[i].clone(); 192 for (int j = 0; j < expectedCpuTimes.length; ++j) { 193 expectedCpuTimes[j] += delta1[i][j]; 194 } 195 assertTrue(u.getCpuFreqTimes(timeInFreqs, procState)); 196 assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes, timeInFreqs); 197 } else { 198 assertFalse(u.getCpuFreqTimes(timeInFreqs, procState)); 199 } 200 assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); 201 } 202 } 203 204 // Validate the on-battery-screen-off counter 205 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, mMockClock.uptime * 1000, 206 mMockClock.realtime * 1000); 207 208 final long[][] delta2 = { 209 {95932, 2943, 49834, 89034, 139}, 210 {349, 89605, 5896, 845, 98444}, 211 {678, 7498, 9843, 889, 4894}, 212 {488, 998, 8498, 394, 574} 213 }; 214 215 mMockClock.realtime += 1000; 216 mMockClock.uptime += 1000; 217 218 for (int i = 0; i < testUids.length; ++i) { 219 long[] newCpuTimes = new long[cpuTimes[i].length]; 220 for (int j = 0; j < cpuTimes[i].length; j++) { 221 newCpuTimes[j] = cpuTimes[i][j] + delta1[i][j] + delta2[i][j]; 222 } 223 mockKernelSingleUidTimeReader(testUids[i], newCpuTimes); 224 mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], 225 mMockClock.realtime, mMockClock.uptime); 226 } 227 228 for (int i = 0; i < testUids.length; ++i) { 229 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); 230 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { 231 if (procState == testProcStates[i]) { 232 long[] expectedCpuTimes = cpuTimes[i].clone(); 233 for (int j = 0; j < expectedCpuTimes.length; ++j) { 234 expectedCpuTimes[j] += delta1[i][j] + delta2[i][j]; 235 } 236 assertTrue(u.getCpuFreqTimes(timeInFreqs, procState)); 237 assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes, timeInFreqs); 238 assertTrue(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); 239 assertArrayEquals("Uid=" + testUids[i], delta2[i], timeInFreqs); 240 } else { 241 assertFalse(u.getCpuFreqTimes(timeInFreqs, procState)); 242 assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); 243 } 244 } 245 } 246 247 // Verify handling of isolated UIDs - their time-in-freq must be directly 248 // added to that of the parent UID's. The proc state of the isolated UID is 249 // assumed to be the same as that of the parent UID, so there is no per-state 250 // data for isolated UIDs. 251 final long[][] delta3 = { 252 {98545, 95768795, 76586, 548945, 57846}, 253 {788876, 586, 578459, 8776984, 9578923}, 254 {3049509483598l, 4597834, 377654, 94589035, 7854}, 255 {9493, 784, 99895, 8974893, 9879843} 256 }; 257 258 mMockClock.realtime += 1000; 259 mMockClock.uptime += 1000; 260 261 final int parentUid = testUids[1]; 262 final int childUid = 99099; 263 addIsolatedUid(parentUid, childUid); 264 final long[] isolatedUidCpuTimes = {495784, 398473, 4895, 4905, 30984093}; 265 mockKernelSingleUidTimeReader(childUid, isolatedUidCpuTimes, isolatedUidCpuTimes); 266 267 for (int i = 0; i < testUids.length; ++i) { 268 long[] newCpuTimes = new long[cpuTimes[i].length]; 269 for (int j = 0; j < cpuTimes[i].length; j++) { 270 newCpuTimes[j] = cpuTimes[i][j] + delta1[i][j] + delta2[i][j] + delta3[i][j]; 271 } 272 mockKernelSingleUidTimeReader(testUids[i], newCpuTimes); 273 mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], 274 mMockClock.realtime, mMockClock.uptime); 275 } 276 277 for (int i = 0; i < testUids.length; ++i) { 278 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); 279 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { 280 if (procState == testProcStates[i]) { 281 long[] expectedCpuTimes = cpuTimes[i].clone(); 282 for (int j = 0; j < expectedCpuTimes.length; ++j) { 283 expectedCpuTimes[j] += delta1[i][j] + delta2[i][j] + delta3[i][j] 284 + (testUids[i] == parentUid ? isolatedUidCpuTimes[j] : 0); 285 } 286 assertTrue(u.getCpuFreqTimes(timeInFreqs, procState)); 287 assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes, timeInFreqs); 288 long[] expectedScreenOffTimes = delta2[i].clone(); 289 for (int j = 0; j < expectedScreenOffTimes.length; ++j) { 290 expectedScreenOffTimes[j] += delta3[i][j] 291 + (testUids[i] == parentUid ? isolatedUidCpuTimes[j] : 0); 292 } 293 assertTrue(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); 294 assertArrayEquals("Uid=" + testUids[i], expectedScreenOffTimes, timeInFreqs); 295 } else { 296 assertFalse(u.getCpuFreqTimes(timeInFreqs, procState)); 297 assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); 298 } 299 } 300 } 301 } 302 303 @Test testUpdateCpuTimesForAllUids()304 public void testUpdateCpuTimesForAllUids() { 305 mBatteryStatsImpl.setOnBatteryInternal(false); 306 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0); 307 308 mMockClock.realtime = 1000; 309 mMockClock.uptime = 1000; 310 311 final int[] testUids = {10032, 10048, 10145, 10139}; 312 final int[] testProcStates = { 313 PROCESS_STATE_BACKGROUND, 314 PROCESS_STATE_FOREGROUND_SERVICE, 315 PROCESS_STATE_TOP, 316 PROCESS_STATE_CACHED 317 }; 318 319 for (int i = 0; i < testUids.length; ++i) { 320 BatteryStatsImpl.Uid uid = mBatteryStatsImpl.getUidStatsLocked(testUids[i]); 321 uid.setProcessStateForTest(testProcStates[i], mMockClock.elapsedRealtime()); 322 mockKernelSingleUidTimeReader(testUids[i], new long[NUM_CPU_FREQS]); 323 mBatteryStatsImpl.updateProcStateCpuTimesLocked(testUids[i], 324 mMockClock.elapsedRealtime(), mMockClock.uptime); 325 } 326 327 final SparseArray<long[]> allUidCpuTimes = new SparseArray<>(); 328 long[][] allCpuTimes = { 329 {938483, 4985984, 439893}, 330 {499, 94904, 27694}, 331 {302949085, 39789473, 34792839}, 332 {9809485, 9083475, 347889834}, 333 }; 334 for (int i = 0; i < testUids.length; ++i) { 335 allUidCpuTimes.put(testUids[i], allCpuTimes[i]); 336 } 337 when(mKernelUidCpuFreqTimeReader.getAllUidCpuFreqTimeMs()).thenReturn(allUidCpuTimes); 338 long[][] expectedCpuTimes = { 339 {843598745, 397843, 32749, 99854, 23454}, 340 {9834, 5885, 487589, 394, 93933}, 341 {203984, 439, 9859, 30948, 49494}, 342 {9389, 858, 239, 349, 50505} 343 }; 344 for (int i = 0; i < testUids.length; ++i) { 345 mockKernelSingleUidTimeReader(testUids[i], expectedCpuTimes[i]); 346 } 347 348 mMockClock.realtime += 1000; 349 mMockClock.uptime += 1000; 350 351 mBatteryStatsImpl.updateCpuTimesForAllUids(); 352 353 final long[] timeInFreqs = new long[NUM_CPU_FREQS]; 354 355 for (int i = 0; i < testUids.length; ++i) { 356 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]); 357 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) { 358 if (procState == testProcStates[i]) { 359 assertTrue(u.getCpuFreqTimes(timeInFreqs, procState)); 360 assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes[i], timeInFreqs); 361 } else { 362 assertFalse(u.getCpuFreqTimes(timeInFreqs, procState)); 363 } 364 assertFalse(u.getScreenOffCpuFreqTimes(timeInFreqs, procState)); 365 } 366 } 367 } 368 mockKernelSingleUidTimeReader(int testUid, long[] cpuTimes)369 private void mockKernelSingleUidTimeReader(int testUid, long[] cpuTimes) { 370 doAnswer(invocation -> { 371 LongArrayMultiStateCounter counter = invocation.getArgument(1); 372 long timestampMs = invocation.getArgument(2); 373 LongArrayMultiStateCounter.LongArrayContainer container = 374 new LongArrayMultiStateCounter.LongArrayContainer(NUM_CPU_FREQS); 375 container.setValues(cpuTimes); 376 counter.updateValues(container, timestampMs); 377 return null; 378 }).when(mKernelSingleUidTimeReader).addDelta(eq(testUid), 379 any(LongArrayMultiStateCounter.class), anyLong()); 380 } 381 mockKernelSingleUidTimeReader(int testUid, long[] cpuTimes, long[] delta)382 private void mockKernelSingleUidTimeReader(int testUid, long[] cpuTimes, long[] delta) { 383 doAnswer(invocation -> { 384 LongArrayMultiStateCounter counter = invocation.getArgument(1); 385 long timestampMs = invocation.getArgument(2); 386 LongArrayMultiStateCounter.LongArrayContainer deltaContainer = 387 invocation.getArgument(3); 388 389 LongArrayMultiStateCounter.LongArrayContainer container = 390 new LongArrayMultiStateCounter.LongArrayContainer(NUM_CPU_FREQS); 391 container.setValues(cpuTimes); 392 counter.updateValues(container, timestampMs); 393 if (deltaContainer != null) { 394 deltaContainer.setValues(delta); 395 } 396 return null; 397 }).when(mKernelSingleUidTimeReader).addDelta(eq(testUid), 398 any(LongArrayMultiStateCounter.class), anyLong(), 399 any(LongArrayMultiStateCounter.LongArrayContainer.class)); 400 } 401 402 @Test testMulticastWakelockAcqRel()403 public void testMulticastWakelockAcqRel() { 404 final int testUid = 10032; 405 final int acquireTimeMs = 1000; 406 final int releaseTimeMs = 1005; 407 final int currentTimeMs = 1011; 408 409 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 410 411 // Create a Uid Object 412 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); 413 assertNotNull(u); 414 415 // Acquire and release the lock 416 u.noteWifiMulticastEnabledLocked(acquireTimeMs); 417 u.noteWifiMulticastDisabledLocked(releaseTimeMs); 418 419 // Get the total acquisition time 420 long totalTime = u.getWifiMulticastTime(currentTimeMs * 1000, 421 BatteryStats.STATS_SINCE_CHARGED); 422 assertEquals("Miscalculations of Multicast wakelock acquisition time", 423 (releaseTimeMs - acquireTimeMs) * 1000, totalTime); 424 } 425 426 @Test testMulticastWakelockAcqNoRel()427 public void testMulticastWakelockAcqNoRel() { 428 final int testUid = 10032; 429 final int acquireTimeMs = 1000; 430 final int currentTimeMs = 1011; 431 432 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 433 434 // Create a Uid Object 435 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); 436 assertNotNull(u); 437 438 // Acquire the lock 439 u.noteWifiMulticastEnabledLocked(acquireTimeMs); 440 441 // Get the total acquisition time 442 long totalTime = u.getWifiMulticastTime(currentTimeMs * 1000, 443 BatteryStats.STATS_SINCE_CHARGED); 444 assertEquals("Miscalculations of Multicast wakelock acquisition time", 445 (currentTimeMs - acquireTimeMs) * 1000, totalTime); 446 } 447 448 @Test testMulticastWakelockAcqAcqRelRel()449 public void testMulticastWakelockAcqAcqRelRel() { 450 final int testUid = 10032; 451 final int acquireTimeMs_1 = 1000; 452 final int acquireTimeMs_2 = 1002; 453 454 final int releaseTimeMs_1 = 1005; 455 final int releaseTimeMs_2 = 1009; 456 final int currentTimeMs = 1011; 457 458 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 459 460 // Create a Uid Object 461 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); 462 assertNotNull(u); 463 464 // Acquire and release the lock (twice in nested way) 465 u.noteWifiMulticastEnabledLocked(acquireTimeMs_1); 466 u.noteWifiMulticastEnabledLocked(acquireTimeMs_2); 467 468 u.noteWifiMulticastDisabledLocked(releaseTimeMs_1); 469 u.noteWifiMulticastDisabledLocked(releaseTimeMs_2); 470 471 // Get the total acquisition time 472 long totalTime = u.getWifiMulticastTime(currentTimeMs * 1000, 473 BatteryStats.STATS_SINCE_CHARGED); 474 assertEquals("Miscalculations of Multicast wakelock acquisition time", 475 (releaseTimeMs_2 - acquireTimeMs_1) * 1000, totalTime); 476 } 477 478 @Test testMulticastWakelockAcqRelAcqRel()479 public void testMulticastWakelockAcqRelAcqRel() { 480 final int testUid = 10032; 481 final int acquireTimeMs_1 = 1000; 482 final int acquireTimeMs_2 = 1005; 483 484 final int releaseTimeMs_1 = 1002; 485 final int releaseTimeMs_2 = 1009; 486 final int currentTimeMs = 1011; 487 488 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 489 490 // Create a Uid Object 491 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUid); 492 assertNotNull(u); 493 494 // Acquire and release the lock (twice) 495 u.noteWifiMulticastEnabledLocked(acquireTimeMs_1); 496 u.noteWifiMulticastDisabledLocked(releaseTimeMs_1); 497 498 u.noteWifiMulticastEnabledLocked(acquireTimeMs_2); 499 u.noteWifiMulticastDisabledLocked(releaseTimeMs_2); 500 501 // Get the total acquisition time 502 long totalTime = u.getWifiMulticastTime(currentTimeMs * 1000, 503 BatteryStats.STATS_SINCE_CHARGED); 504 assertEquals("Miscalculations of Multicast wakelock acquisition time", 505 ((releaseTimeMs_1 - acquireTimeMs_1) + (releaseTimeMs_2 - acquireTimeMs_2)) 506 * 1000, totalTime); 507 } 508 addIsolatedUid(int parentUid, int childUid)509 private void addIsolatedUid(int parentUid, int childUid) { 510 final BatteryStatsImpl.Uid u = mBatteryStatsImpl.getUidStatsLocked(parentUid); 511 u.addIsolatedUid(childUid); 512 } 513 514 @Test testGetWakeLockStats()515 public void testGetWakeLockStats() { 516 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 517 518 // First wakelock, acquired once, not currently held 519 mMockClock.realtime = 1000; 520 mBatteryStatsImpl.noteStartWakeLocked(10100, 100, null, "wakeLock1", null, 521 BatteryStats.WAKE_TYPE_PARTIAL, false); 522 523 mMockClock.realtime = 3000; 524 mBatteryStatsImpl.noteStopWakeLocked(10100, 100, null, "wakeLock1", null, 525 BatteryStats.WAKE_TYPE_PARTIAL); 526 527 // Second wakelock, acquired twice, still held 528 mMockClock.realtime = 4000; 529 mBatteryStatsImpl.noteStartWakeLocked(10200, 101, null, "wakeLock2", null, 530 BatteryStats.WAKE_TYPE_PARTIAL, false); 531 532 mMockClock.realtime = 5000; 533 mBatteryStatsImpl.noteStopWakeLocked(10200, 101, null, "wakeLock2", null, 534 BatteryStats.WAKE_TYPE_PARTIAL); 535 536 mMockClock.realtime = 6000; 537 mBatteryStatsImpl.noteStartWakeLocked(10200, 101, null, "wakeLock2", null, 538 BatteryStats.WAKE_TYPE_PARTIAL, false); 539 540 mMockClock.realtime = 9000; 541 542 List<WakeLockStats.WakeLock> wakeLockStats = 543 mBatteryStatsImpl.getWakeLockStats().getWakeLocks(); 544 assertThat(wakeLockStats).hasSize(2); 545 546 WakeLockStats.WakeLock wakeLock1 = wakeLockStats.stream() 547 .filter(wl -> wl.uid == 10100 && wl.name.equals("wakeLock1")).findFirst().get(); 548 549 assertThat(wakeLock1.timesAcquired).isEqualTo(1); 550 assertThat(wakeLock1.timeHeldMs).isEqualTo(0); // Not currently held 551 assertThat(wakeLock1.totalTimeHeldMs).isEqualTo(2000); // 3000-1000 552 553 WakeLockStats.WakeLock wakeLock2 = wakeLockStats.stream() 554 .filter(wl -> wl.uid == 10200 && wl.name.equals("wakeLock2")).findFirst().get(); 555 556 assertThat(wakeLock2.timesAcquired).isEqualTo(2); 557 assertThat(wakeLock2.timeHeldMs).isEqualTo(3000); // 9000-6000 558 assertThat(wakeLock2.totalTimeHeldMs).isEqualTo(4000); // (5000-4000) + (9000-6000) 559 } 560 561 @Test testGetBluetoothBatteryStats()562 public void testGetBluetoothBatteryStats() { 563 when(mPowerProfile.getAveragePower( 564 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE)).thenReturn(3.0); 565 mBatteryStatsImpl.setOnBatteryInternal(true); 566 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 567 568 final WorkSource ws = new WorkSource(10042); 569 mBatteryStatsImpl.noteBluetoothScanStartedFromSourceLocked(ws, false, 1000, 1000); 570 mBatteryStatsImpl.noteBluetoothScanStoppedFromSourceLocked(ws, false, 5000, 5000); 571 mBatteryStatsImpl.noteBluetoothScanStartedFromSourceLocked(ws, true, 6000, 6000); 572 mBatteryStatsImpl.noteBluetoothScanStoppedFromSourceLocked(ws, true, 9000, 9000); 573 mBatteryStatsImpl.noteBluetoothScanResultsFromSourceLocked(ws, 42, 9000, 9000); 574 575 BluetoothActivityEnergyInfo info = createBluetoothActivityEnergyInfo( 576 /* timestamp= */ 1000, 577 /* controllerTxTimeMs= */ 9000, 578 /* controllerRxTimeMs= */ 8000, 579 /* controllerIdleTimeMs= */ 12000, 580 /* controllerEnergyUsed= */ 0, 581 createUidTraffic(/* appUid= */ 10042, /* rxBytes= */ 3000, /* txBytes= */ 4000), 582 createUidTraffic(/* appUid= */ 10043, /* rxBytes= */ 5000, /* txBytes= */ 8000)); 583 584 mBatteryStatsImpl.updateBluetoothStateLocked(info, -1, 1000, 1000); 585 586 BluetoothBatteryStats stats = 587 mBatteryStatsImpl.getBluetoothBatteryStats(); 588 assertThat(stats.getUidStats()).hasSize(2); 589 590 final BluetoothBatteryStats.UidStats uidStats = 591 stats.getUidStats().stream().filter(u -> u.uid == 10042).findFirst().get(); 592 assertThat(uidStats.scanTimeMs).isEqualTo(7000); // 4000+3000 593 assertThat(uidStats.unoptimizedScanTimeMs).isEqualTo(3000); 594 assertThat(uidStats.scanResultCount).isEqualTo(42); 595 assertThat(uidStats.rxTimeMs).isEqualTo(7375); // Some scan time is treated as RX 596 assertThat(uidStats.txTimeMs).isEqualTo(7666); // Some scan time is treated as TX 597 } 598 599 /** A regression test for b/266128651 */ 600 @Test testGetNetworkActivityBytes_multipleUpdates()601 public void testGetNetworkActivityBytes_multipleUpdates() { 602 when(mPowerProfile.getAveragePower( 603 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE)).thenReturn(3.0); 604 mBatteryStatsImpl.setOnBatteryInternal(true); 605 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0); 606 607 BluetoothActivityEnergyInfo info1 = createBluetoothActivityEnergyInfo( 608 /* timestamp= */ 10000, 609 /* controllerTxTimeMs= */ 9000, 610 /* controllerRxTimeMs= */ 8000, 611 /* controllerIdleTimeMs= */ 2000, 612 /* controllerEnergyUsed= */ 0, 613 createUidTraffic(/* appUid= */ 10042, /* rxBytes= */ 3000, /* txBytes= */ 4000), 614 createUidTraffic(/* appUid= */ 10043, /* rxBytes= */ 5000, /* txBytes= */ 8000)); 615 616 mBatteryStatsImpl.updateBluetoothStateLocked(info1, -1, 1000, 1000); 617 618 long totalRx1 = mBatteryStatsImpl.getNetworkActivityBytes( 619 BatteryStats.NETWORK_BT_RX_DATA, BatteryStats.STATS_SINCE_CHARGED); 620 long totalTx1 = mBatteryStatsImpl.getNetworkActivityBytes( 621 BatteryStats.NETWORK_BT_TX_DATA, BatteryStats.STATS_SINCE_CHARGED); 622 623 assertThat(totalRx1).isEqualTo(8000); // 3000 + 5000 624 assertThat(totalTx1).isEqualTo(12000); // 4000 + 8000 625 626 BluetoothActivityEnergyInfo info2 = createBluetoothActivityEnergyInfo( 627 /* timestamp= */ 20000, 628 /* controllerTxTimeMs= */ 19000, 629 /* controllerRxTimeMs= */ 18000, 630 /* controllerIdleTimeMs= */ 3000, 631 /* controllerEnergyUsed= */ 0, 632 createUidTraffic(/* appUid= */ 10043, /* rxBytes= */ 6000, /* txBytes= */ 9500), 633 createUidTraffic(/* appUid= */ 10044, /* rxBytes= */ 7000, /* txBytes= */ 9000)); 634 635 mBatteryStatsImpl.updateBluetoothStateLocked(info2, -1, 2000, 2000); 636 637 long totalRx2 = mBatteryStatsImpl.getNetworkActivityBytes( 638 BatteryStats.NETWORK_BT_RX_DATA, BatteryStats.STATS_SINCE_CHARGED); 639 long totalTx2 = mBatteryStatsImpl.getNetworkActivityBytes( 640 BatteryStats.NETWORK_BT_TX_DATA, BatteryStats.STATS_SINCE_CHARGED); 641 642 assertThat(totalRx2).isEqualTo(16000); // 3000 + 6000 (updated) + 7000 (new) 643 assertThat(totalTx2).isEqualTo(22500); // 4000 + 9500 (updated) + 9000 (new) 644 645 BluetoothActivityEnergyInfo info3 = createBluetoothActivityEnergyInfo( 646 /* timestamp= */ 30000, 647 /* controllerTxTimeMs= */ 20000, 648 /* controllerRxTimeMs= */ 20000, 649 /* controllerIdleTimeMs= */ 4000, 650 /* controllerEnergyUsed= */ 0, 651 createUidTraffic(/* appUid= */ 10043, /* rxBytes= */ 7000, /* txBytes= */ 9900), 652 createUidTraffic(/* appUid= */ 10044, /* rxBytes= */ 8000, /* txBytes= */ 10000)); 653 654 mBatteryStatsImpl.updateBluetoothStateLocked(info3, -1, 2000, 2000); 655 656 long totalRx3 = mBatteryStatsImpl.getNetworkActivityBytes( 657 BatteryStats.NETWORK_BT_RX_DATA, BatteryStats.STATS_SINCE_CHARGED); 658 long totalTx3 = mBatteryStatsImpl.getNetworkActivityBytes( 659 BatteryStats.NETWORK_BT_TX_DATA, BatteryStats.STATS_SINCE_CHARGED); 660 661 assertThat(totalRx3).isEqualTo(18000); // 3000 + 7000 (updated) + 8000 (updated) 662 assertThat(totalTx3).isEqualTo(23900); // 4000 + 9900 (updated) + 10000 (updated) 663 } 664 createUidTraffic(int appUid, long rxBytes, long txBytes)665 private UidTraffic createUidTraffic(int appUid, long rxBytes, long txBytes) { 666 final Parcel parcel = Parcel.obtain(); 667 parcel.writeInt(appUid); // mAppUid 668 parcel.writeLong(rxBytes); // mRxBytes 669 parcel.writeLong(txBytes); // mTxBytes 670 parcel.setDataPosition(0); 671 UidTraffic uidTraffic = UidTraffic.CREATOR.createFromParcel(parcel); 672 parcel.recycle(); 673 return uidTraffic; 674 } 675 createBluetoothActivityEnergyInfo( long timestamp, long controllerTxTimeMs, long controllerRxTimeMs, long controllerIdleTimeMs, long controllerEnergyUsed, UidTraffic... uidTraffic)676 private BluetoothActivityEnergyInfo createBluetoothActivityEnergyInfo( 677 long timestamp, 678 long controllerTxTimeMs, 679 long controllerRxTimeMs, 680 long controllerIdleTimeMs, 681 long controllerEnergyUsed, 682 UidTraffic... uidTraffic) { 683 Parcel parcel = Parcel.obtain(); 684 parcel.writeLong(timestamp); // mTimestamp 685 parcel.writeInt( 686 BluetoothActivityEnergyInfo.BT_STACK_STATE_STATE_ACTIVE); // mBluetoothStackState 687 parcel.writeLong(controllerTxTimeMs); // mControllerTxTimeMs; 688 parcel.writeLong(controllerRxTimeMs); // mControllerRxTimeMs; 689 parcel.writeLong(controllerIdleTimeMs); // mControllerIdleTimeMs; 690 parcel.writeLong(controllerEnergyUsed); // mControllerEnergyUsed; 691 parcel.writeTypedList(ImmutableList.copyOf(uidTraffic)); // mUidTraffic 692 parcel.setDataPosition(0); 693 694 BluetoothActivityEnergyInfo info = 695 BluetoothActivityEnergyInfo.CREATOR.createFromParcel(parcel); 696 parcel.recycle(); 697 return info; 698 } 699 } 700