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.cts; 18 19 import android.os.BatteryStatsProto; 20 import android.os.ControllerActivityProto; 21 import android.os.SystemProto; 22 import android.os.TimerProto; 23 import android.os.UidProto; 24 import android.service.batterystats.BatteryStatsServiceDumpProto; 25 import android.telephony.NetworkTypeEnum; 26 27 /** 28 * Test to BatteryStats proto dump. 29 */ 30 public class BatteryStatsIncidentTest extends ProtoDumpTestCase { 31 32 @Override tearDown()33 protected void tearDown() throws Exception { 34 batteryOffScreenOn(); 35 super.tearDown(); 36 } 37 batteryOnScreenOff()38 protected void batteryOnScreenOff() throws Exception { 39 getDevice().executeShellCommand("dumpsys battery unplug"); 40 getDevice().executeShellCommand("dumpsys batterystats enable pretend-screen-off"); 41 } 42 batteryOffScreenOn()43 protected void batteryOffScreenOn() throws Exception { 44 getDevice().executeShellCommand("dumpsys battery reset"); 45 getDevice().executeShellCommand("dumpsys batterystats disable pretend-screen-off"); 46 } 47 48 /** 49 * Tests that batterystats is dumped to proto with sane values. 50 */ testBatteryStatsServiceDump()51 public void testBatteryStatsServiceDump() throws Exception { 52 batteryOnScreenOff(); 53 Thread.sleep(5000); // Allow some time for battery data to accumulate. 54 55 final BatteryStatsServiceDumpProto dump = getDump(BatteryStatsServiceDumpProto.parser(), 56 "dumpsys batterystats --proto"); 57 58 verifyBatteryStatsServiceDumpProto(dump, PRIVACY_NONE); 59 60 batteryOffScreenOn(); 61 } 62 verifyBatteryStatsServiceDumpProto(BatteryStatsServiceDumpProto dump, final int filterLevel)63 static void verifyBatteryStatsServiceDumpProto(BatteryStatsServiceDumpProto dump, final int filterLevel) throws Exception { 64 final BatteryStatsProto bs = dump.getBatterystats(); 65 assertNotNull(bs); 66 67 // Proto dumps were finalized when the batterystats report version was ~29 and the parcel 68 // version was ~172. 69 assertTrue(29 <= bs.getReportVersion()); 70 assertTrue(172 <= bs.getParcelVersion()); 71 assertNotNull(bs.getStartPlatformVersion()); 72 assertFalse(bs.getStartPlatformVersion().isEmpty()); 73 assertNotNull(bs.getEndPlatformVersion()); 74 assertFalse(bs.getEndPlatformVersion().isEmpty()); 75 76 for (UidProto u : bs.getUidsList()) { 77 testUidProto(u, filterLevel); 78 } 79 80 testSystemProto(bs.getSystem()); 81 } 82 testControllerActivityProto(ControllerActivityProto ca)83 private static void testControllerActivityProto(ControllerActivityProto ca) throws Exception { 84 assertNotNull(ca); 85 86 assertTrue(0 <= ca.getIdleDurationMs()); 87 assertTrue(0 <= ca.getRxDurationMs()); 88 assertTrue(0 <= ca.getPowerMah()); 89 for (ControllerActivityProto.TxLevel tx : ca.getTxList()) { 90 assertTrue(0 <= tx.getDurationMs()); 91 } 92 } 93 testBatteryLevelStep(SystemProto.BatteryLevelStep bls)94 private static void testBatteryLevelStep(SystemProto.BatteryLevelStep bls) throws Exception { 95 assertNotNull(bls); 96 97 assertTrue(0 < bls.getDurationMs()); 98 assertTrue(0 <= bls.getLevel()); 99 assertTrue(100 >= bls.getLevel()); 100 101 assertTrue(SystemProto.BatteryLevelStep.DisplayState.getDescriptor().getValues() 102 .contains(bls.getDisplayState().getValueDescriptor())); 103 assertTrue(SystemProto.BatteryLevelStep.PowerSaveMode.getDescriptor().getValues() 104 .contains(bls.getPowerSaveMode().getValueDescriptor())); 105 assertTrue(SystemProto.BatteryLevelStep.IdleMode.getDescriptor().getValues() 106 .contains(bls.getIdleMode().getValueDescriptor())); 107 } 108 testSystemProto(SystemProto s)109 private static void testSystemProto(SystemProto s) throws Exception { 110 final long epsilon = 500; // Allow ~500 ms of error when comparing times. 111 assertNotNull(s); 112 113 SystemProto.Battery b = s.getBattery(); 114 assertTrue(0 < b.getStartClockTimeMs()); 115 assertTrue(0 <= b.getStartCount()); 116 long totalRealtimeMs = b.getTotalRealtimeMs(); 117 long totalUptimeMs = b.getTotalUptimeMs(); 118 assertTrue(0 <= totalUptimeMs); 119 assertTrue(totalUptimeMs <= totalRealtimeMs + epsilon); 120 long batteryRealtimeMs = b.getBatteryRealtimeMs(); 121 long batteryUptimeMs = b.getBatteryUptimeMs(); 122 assertTrue(0 <= batteryUptimeMs); 123 assertTrue(batteryUptimeMs <= batteryRealtimeMs + epsilon); 124 assertTrue("Battery realtime (" + batteryRealtimeMs + ") is greater than total realtime (" + totalRealtimeMs + ")", 125 batteryRealtimeMs <= totalRealtimeMs + epsilon); 126 assertTrue(batteryUptimeMs <= totalUptimeMs + epsilon); 127 long screenOffRealtimeMs = b.getScreenOffRealtimeMs(); 128 long screenOffUptimeMs = b.getScreenOffUptimeMs(); 129 assertTrue(0 <= screenOffUptimeMs); 130 assertTrue(screenOffUptimeMs <= screenOffRealtimeMs + epsilon); 131 assertTrue(screenOffRealtimeMs <= totalRealtimeMs + epsilon); 132 assertTrue(screenOffUptimeMs <= totalUptimeMs + epsilon); 133 long screenDozeDurationMs = b.getScreenDozeDurationMs(); 134 assertTrue(0 <= screenDozeDurationMs); 135 assertTrue(screenDozeDurationMs <= screenOffRealtimeMs + epsilon); 136 assertTrue(0 < b.getEstimatedBatteryCapacityMah()); 137 long minLearnedCapacityUah = b.getMinLearnedBatteryCapacityUah(); 138 long maxLearnedCapacityUah = b.getMaxLearnedBatteryCapacityUah(); 139 assertTrue(0 <= minLearnedCapacityUah); 140 assertTrue(minLearnedCapacityUah <= maxLearnedCapacityUah); 141 142 SystemProto.BatteryDischarge bd = s.getBatteryDischarge(); 143 int lowerBound = bd.getLowerBoundSinceCharge(); 144 int upperBound = bd.getUpperBoundSinceCharge(); 145 assertTrue(0 <= lowerBound); 146 assertTrue(lowerBound <= upperBound); 147 assertTrue(0 <= bd.getScreenOnSinceCharge()); 148 int screenOff = bd.getScreenOffSinceCharge(); 149 int screenDoze = bd.getScreenDozeSinceCharge(); 150 assertTrue(0 <= screenDoze); 151 assertTrue(screenDoze <= screenOff); 152 long totalMah = bd.getTotalMah(); 153 long totalMahScreenOff = bd.getTotalMahScreenOff(); 154 long totalMahScreenDoze = bd.getTotalMahScreenDoze(); 155 long totalMahLightDoze = bd.getTotalMahLightDoze(); 156 long totalMahDeepDoze = bd.getTotalMahDeepDoze(); 157 assertTrue(0 <= totalMahScreenDoze); 158 assertTrue(0 <= totalMahLightDoze); 159 assertTrue(0 <= totalMahDeepDoze); 160 assertTrue(totalMahScreenDoze <= totalMahScreenOff); 161 assertTrue(totalMahLightDoze <= totalMahScreenOff); 162 assertTrue(totalMahDeepDoze <= totalMahScreenOff); 163 assertTrue(totalMahScreenOff <= totalMah); 164 165 assertTrue(-1 <= s.getChargeTimeRemainingMs()); 166 assertTrue(-1 <= s.getDischargeTimeRemainingMs()); 167 168 for (SystemProto.BatteryLevelStep bls : s.getChargeStepList()) { 169 testBatteryLevelStep(bls); 170 } 171 for (SystemProto.BatteryLevelStep bls : s.getDischargeStepList()) { 172 testBatteryLevelStep(bls); 173 } 174 175 for (SystemProto.DataConnection dc : s.getDataConnectionList()) { 176 // If isNone is not set, then the name will be a valid network type. 177 if (!dc.getIsNone()) { 178 assertTrue(NetworkTypeEnum.getDescriptor().getValues() 179 .contains(dc.getName().getValueDescriptor())); 180 } 181 testTimerProto(dc.getTotal()); 182 } 183 184 testControllerActivityProto(s.getGlobalBluetoothController()); 185 testControllerActivityProto(s.getGlobalModemController()); 186 testControllerActivityProto(s.getGlobalWifiController()); 187 188 SystemProto.GlobalNetwork gn = s.getGlobalNetwork(); 189 assertTrue(0 <= gn.getMobileBytesRx()); 190 assertTrue(0 <= gn.getMobileBytesTx()); 191 assertTrue(0 <= gn.getWifiBytesRx()); 192 assertTrue(0 <= gn.getWifiBytesTx()); 193 assertTrue(0 <= gn.getMobilePacketsRx()); 194 assertTrue(0 <= gn.getMobilePacketsTx()); 195 assertTrue(0 <= gn.getWifiPacketsRx()); 196 assertTrue(0 <= gn.getWifiPacketsTx()); 197 assertTrue(0 <= gn.getBtBytesRx()); 198 assertTrue(0 <= gn.getBtBytesTx()); 199 200 SystemProto.GlobalWifi gw = s.getGlobalWifi(); 201 assertTrue(0 <= gw.getOnDurationMs()); 202 assertTrue(0 <= gw.getRunningDurationMs()); 203 204 for (SystemProto.KernelWakelock kw : s.getKernelWakelockList()) { 205 testTimerProto(kw.getTotal()); 206 } 207 208 SystemProto.Misc m = s.getMisc(); 209 assertTrue(0 <= m.getScreenOnDurationMs()); 210 assertTrue(0 <= m.getPhoneOnDurationMs()); 211 assertTrue(0 <= m.getFullWakelockTotalDurationMs()); 212 assertTrue(0 <= m.getPartialWakelockTotalDurationMs()); 213 assertTrue(0 <= m.getMobileRadioActiveDurationMs()); 214 assertTrue(0 <= m.getMobileRadioActiveAdjustedTimeMs()); 215 assertTrue(0 <= m.getMobileRadioActiveCount()); 216 assertTrue(0 <= m.getMobileRadioActiveUnknownDurationMs()); 217 assertTrue(0 <= m.getInteractiveDurationMs()); 218 assertTrue(0 <= m.getBatterySaverModeEnabledDurationMs()); 219 assertTrue(0 <= m.getNumConnectivityChanges()); 220 assertTrue(0 <= m.getDeepDozeEnabledDurationMs()); 221 assertTrue(0 <= m.getDeepDozeCount()); 222 assertTrue(0 <= m.getDeepDozeIdlingDurationMs()); 223 assertTrue(0 <= m.getDeepDozeIdlingCount()); 224 assertTrue(0 <= m.getLongestDeepDozeDurationMs()); 225 assertTrue(0 <= m.getLightDozeEnabledDurationMs()); 226 assertTrue(0 <= m.getLightDozeCount()); 227 assertTrue(0 <= m.getLightDozeIdlingDurationMs()); 228 assertTrue(0 <= m.getLightDozeIdlingCount()); 229 assertTrue(0 <= m.getLongestLightDozeDurationMs()); 230 231 for (SystemProto.PhoneSignalStrength pss : s.getPhoneSignalStrengthList()) { 232 testTimerProto(pss.getTotal()); 233 } 234 235 for (SystemProto.PowerUseItem pui : s.getPowerUseItemList()) { 236 assertTrue(SystemProto.PowerUseItem.Sipper.getDescriptor().getValues() 237 .contains(pui.getName().getValueDescriptor())); 238 assertTrue(0 <= pui.getUid()); 239 assertTrue(0 <= pui.getComputedPowerMah()); 240 assertTrue(0 <= pui.getScreenPowerMah()); 241 assertTrue(0 <= pui.getProportionalSmearMah()); 242 } 243 244 SystemProto.PowerUseSummary pus = s.getPowerUseSummary(); 245 assertTrue(0 < pus.getBatteryCapacityMah()); 246 assertTrue(0 <= pus.getComputedPowerMah()); 247 double minDrained = pus.getMinDrainedPowerMah(); 248 double maxDrained = pus.getMaxDrainedPowerMah(); 249 assertTrue(0 <= minDrained); 250 assertTrue(minDrained <= maxDrained); 251 252 for (SystemProto.ResourcePowerManager rpm : s.getResourcePowerManagerList()) { 253 assertNotNull(rpm.getName()); 254 assertFalse(rpm.getName().isEmpty()); 255 testTimerProto(rpm.getTotal()); 256 testTimerProto(rpm.getScreenOff()); 257 } 258 259 for (SystemProto.ScreenBrightness sb : s.getScreenBrightnessList()) { 260 testTimerProto(sb.getTotal()); 261 } 262 263 testTimerProto(s.getSignalScanning()); 264 265 for (SystemProto.WakeupReason wr : s.getWakeupReasonList()) { 266 testTimerProto(wr.getTotal()); 267 } 268 269 SystemProto.WifiMulticastWakelockTotal wmwl = s.getWifiMulticastWakelockTotal(); 270 assertTrue(0 <= wmwl.getDurationMs()); 271 assertTrue(0 <= wmwl.getCount()); 272 273 for (SystemProto.WifiSignalStrength wss : s.getWifiSignalStrengthList()) { 274 testTimerProto(wss.getTotal()); 275 } 276 277 for (SystemProto.WifiState ws : s.getWifiStateList()) { 278 assertTrue(SystemProto.WifiState.Name.getDescriptor().getValues() 279 .contains(ws.getName().getValueDescriptor())); 280 testTimerProto(ws.getTotal()); 281 } 282 283 for (SystemProto.WifiSupplicantState wss : s.getWifiSupplicantStateList()) { 284 assertTrue(SystemProto.WifiSupplicantState.Name.getDescriptor().getValues() 285 .contains(wss.getName().getValueDescriptor())); 286 testTimerProto(wss.getTotal()); 287 } 288 } 289 testTimerProto(TimerProto t)290 private static void testTimerProto(TimerProto t) throws Exception { 291 assertNotNull(t); 292 293 long duration = t.getDurationMs(); 294 long curDuration = t.getCurrentDurationMs(); 295 long maxDuration = t.getMaxDurationMs(); 296 long totalDuration = t.getTotalDurationMs(); 297 assertTrue(0 <= duration); 298 assertTrue(0 <= t.getCount()); 299 // Not all TimerProtos will have max duration, current duration, or total duration 300 // populated, so must tread carefully. Regardless, they should never be negative. 301 assertTrue(0 <= curDuration); 302 assertTrue(0 <= maxDuration); 303 assertTrue(0 <= totalDuration); 304 if (maxDuration > 0) { 305 assertTrue(curDuration <= maxDuration); 306 } 307 if (totalDuration > 0) { 308 assertTrue(maxDuration <= totalDuration); 309 assertTrue("Duration " + duration + " is greater than totalDuration " + totalDuration, 310 duration <= totalDuration); 311 } 312 } 313 testByFrequency(UidProto.Cpu.ByFrequency bf)314 private static void testByFrequency(UidProto.Cpu.ByFrequency bf) throws Exception { 315 assertNotNull(bf); 316 317 assertTrue(1 <= bf.getFrequencyIndex()); 318 long total = bf.getTotalDurationMs(); 319 long screenOff = bf.getScreenOffDurationMs(); 320 assertTrue(0 <= screenOff); 321 assertTrue(screenOff <= total); 322 } 323 testUidProto(UidProto u, final int filterLevel)324 private static void testUidProto(UidProto u, final int filterLevel) throws Exception { 325 assertNotNull(u); 326 327 assertTrue(0 <= u.getUid()); 328 329 for (UidProto.Package p : u.getPackagesList()) { 330 assertNotNull(p.getName()); 331 assertFalse(p.getName().isEmpty()); 332 333 for (UidProto.Package.Service s : p.getServicesList()) { 334 assertNotNull(s.getName()); 335 assertFalse(s.getName().isEmpty()); 336 assertTrue(0 <= s.getStartDurationMs()); 337 assertTrue(0 <= s.getStartCount()); 338 assertTrue(0 <= s.getLaunchCount()); 339 } 340 } 341 342 testControllerActivityProto(u.getBluetoothController()); 343 testControllerActivityProto(u.getModemController()); 344 testControllerActivityProto(u.getWifiController()); 345 346 UidProto.BluetoothMisc bm = u.getBluetoothMisc(); 347 testTimerProto(bm.getApportionedBleScan()); 348 testTimerProto(bm.getBackgroundBleScan()); 349 testTimerProto(bm.getUnoptimizedBleScan()); 350 testTimerProto(bm.getBackgroundUnoptimizedBleScan()); 351 assertTrue(0 <= bm.getBleScanResultCount()); 352 assertTrue(0 <= bm.getBackgroundBleScanResultCount()); 353 354 UidProto.Cpu c = u.getCpu(); 355 assertTrue(0 <= c.getUserDurationMs()); 356 assertTrue(0 <= c.getSystemDurationMs()); 357 for (UidProto.Cpu.ByFrequency bf : c.getByFrequencyList()) { 358 testByFrequency(bf); 359 } 360 for (UidProto.Cpu.ByProcessState bps : c.getByProcessStateList()) { 361 assertTrue(UidProto.Cpu.ProcessState.getDescriptor().getValues() 362 .contains(bps.getProcessState().getValueDescriptor())); 363 for (UidProto.Cpu.ByFrequency bf : bps.getByFrequencyList()) { 364 testByFrequency(bf); 365 } 366 } 367 368 testTimerProto(u.getAudio()); 369 testTimerProto(u.getCamera()); 370 testTimerProto(u.getFlashlight()); 371 testTimerProto(u.getForegroundActivity()); 372 testTimerProto(u.getForegroundService()); 373 testTimerProto(u.getVibrator()); 374 testTimerProto(u.getVideo()); 375 376 for (UidProto.Job j : u.getJobsList()) { 377 assertNotNull(j.getName()); 378 assertFalse(j.getName().isEmpty()); 379 380 testTimerProto(j.getTotal()); 381 testTimerProto(j.getBackground()); 382 } 383 384 for (UidProto.JobCompletion jc : u.getJobCompletionList()) { 385 assertNotNull(jc.getName()); 386 assertFalse(jc.getName().isEmpty()); 387 388 for (UidProto.JobCompletion.ReasonCount rc : jc.getReasonCountList()) { 389 assertTrue(0 <= rc.getCount()); 390 } 391 } 392 393 UidProto.Network n = u.getNetwork(); 394 assertTrue(0 <= n.getMobileBytesRx()); 395 assertTrue(0 <= n.getMobileBytesTx()); 396 assertTrue(0 <= n.getWifiBytesRx()); 397 assertTrue(0 <= n.getWifiBytesTx()); 398 assertTrue(0 <= n.getBtBytesRx()); 399 assertTrue(0 <= n.getBtBytesTx()); 400 assertTrue(0 <= n.getMobilePacketsRx()); 401 assertTrue(0 <= n.getMobilePacketsTx()); 402 assertTrue(0 <= n.getWifiPacketsRx()); 403 assertTrue(0 <= n.getWifiPacketsTx()); 404 assertTrue(0 <= n.getMobileActiveDurationMs()); 405 assertTrue(0 <= n.getMobileActiveCount()); 406 assertTrue(0 <= n.getMobileWakeupCount()); 407 assertTrue(0 <= n.getWifiWakeupCount()); 408 assertTrue(0 <= n.getMobileBytesBgRx()); 409 assertTrue(0 <= n.getMobileBytesBgTx()); 410 assertTrue(0 <= n.getWifiBytesBgRx()); 411 assertTrue(0 <= n.getWifiBytesBgTx()); 412 assertTrue(0 <= n.getMobilePacketsBgRx()); 413 assertTrue(0 <= n.getMobilePacketsBgTx()); 414 assertTrue(0 <= n.getWifiPacketsBgRx()); 415 assertTrue(0 <= n.getWifiPacketsBgTx()); 416 417 UidProto.PowerUseItem pui = u.getPowerUseItem(); 418 assertTrue(0 <= pui.getComputedPowerMah()); 419 assertTrue(0 <= pui.getScreenPowerMah()); 420 assertTrue(0 <= pui.getProportionalSmearMah()); 421 422 for (UidProto.Process p : u.getProcessList()) { 423 assertNotNull(p.getName()); 424 assertFalse(p.getName().isEmpty()); 425 assertTrue(0 <= p.getUserDurationMs()); 426 assertTrue("Process system duration is negative: " + p.getSystemDurationMs(), 427 0 <= p.getSystemDurationMs()); 428 assertTrue(0 <= p.getForegroundDurationMs()); 429 assertTrue(0 <= p.getStartCount()); 430 assertTrue(0 <= p.getAnrCount()); 431 assertTrue(0 <= p.getCrashCount()); 432 } 433 434 for (UidProto.StateTime st : u.getStatesList()) { 435 assertTrue(UidProto.StateTime.State.getDescriptor().getValues() 436 .contains(st.getState().getValueDescriptor())); 437 assertTrue(0 <= st.getDurationMs()); 438 } 439 440 for (UidProto.Sensor s : u.getSensorsList()) { 441 testTimerProto(s.getApportioned()); 442 testTimerProto(s.getBackground()); 443 } 444 445 for (UidProto.Sync s : u.getSyncsList()) { 446 assertFalse(s.getName().isEmpty()); 447 448 testTimerProto(s.getTotal()); 449 testTimerProto(s.getBackground()); 450 } 451 452 for (UidProto.UserActivity ua : u.getUserActivityList()) { 453 assertTrue(0 <= ua.getCount()); 454 } 455 456 UidProto.AggregatedWakelock aw = u.getAggregatedWakelock(); 457 long awPartial = aw.getPartialDurationMs(); 458 long awBgPartial = aw.getBackgroundPartialDurationMs(); 459 assertTrue(0 <= awBgPartial); 460 assertTrue(awBgPartial <= awPartial); 461 462 for (UidProto.Wakelock w : u.getWakelocksList()) { 463 // Unfortunately, apps can legitimately pass an empty string as the wakelock name, so we 464 // can't guarantee that wakelock names will be non-empty. 465 testTimerProto(w.getFull()); 466 testTimerProto(w.getPartial()); 467 testTimerProto(w.getBackgroundPartial()); 468 testTimerProto(w.getWindow()); 469 } 470 471 for (UidProto.WakeupAlarm wa : u.getWakeupAlarmList()) { 472 assertTrue(0 <= wa.getCount()); 473 } 474 475 UidProto.Wifi w = u.getWifi(); 476 assertTrue(0 <= w.getFullWifiLockDurationMs()); 477 assertTrue(0 <= w.getRunningDurationMs()); 478 testTimerProto(w.getApportionedScan()); 479 testTimerProto(w.getBackgroundScan()); 480 481 testTimerProto(u.getWifiMulticastWakelock()); 482 } 483 } 484