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 package android.cts.statsd.atom; 17 18 import static com.google.common.truth.Truth.assertThat; 19 20 import android.os.BatteryPluggedStateEnum; 21 import android.os.BatteryStatusEnum; 22 import android.platform.test.annotations.RestrictedBuildTest; 23 import android.server.DeviceIdleModeEnum; 24 import android.view.DisplayStateEnum; 25 26 import com.android.internal.os.StatsdConfigProto.StatsdConfig; 27 import com.android.os.AtomsProto.AppBreadcrumbReported; 28 import com.android.os.AtomsProto.Atom; 29 import com.android.os.AtomsProto.BatterySaverModeStateChanged; 30 import com.android.os.AtomsProto.BuildInformation; 31 import com.android.os.AtomsProto.ConnectivityStateChanged; 32 import com.android.os.StatsLog.ConfigMetricsReportList; 33 import com.android.os.StatsLog.EventMetricData; 34 35 import java.util.Arrays; 36 import java.util.HashSet; 37 import java.util.List; 38 import java.util.Set; 39 40 /** 41 * Statsd atom tests that are done via adb (hostside). 42 */ 43 public class HostAtomTests extends AtomTestCase { 44 45 private static final String TAG = "Statsd.HostAtomTests"; 46 47 // Either file must exist to read kernel wake lock stats. 48 private static final String WAKE_LOCK_FILE = "/proc/wakelocks"; 49 private static final String WAKE_SOURCES_FILE = "/d/wakeup_sources"; 50 51 @Override setUp()52 protected void setUp() throws Exception { 53 super.setUp(); 54 } 55 testScreenStateChangedAtom()56 public void testScreenStateChangedAtom() throws Exception { 57 if (statsdDisabled()) { 58 return; 59 } 60 // Setup, make sure the screen is off and turn off AoD if it is on. 61 // AoD needs to be turned off because the screen should go into an off state. But, if AoD is 62 // on and the device doesn't support STATE_DOZE, the screen sadly goes back to STATE_ON. 63 String aodState = getAodState(); 64 setAodState("0"); 65 turnScreenOn(); 66 Thread.sleep(WAIT_TIME_SHORT); 67 turnScreenOff(); 68 Thread.sleep(WAIT_TIME_SHORT); 69 70 final int atomTag = Atom.SCREEN_STATE_CHANGED_FIELD_NUMBER; 71 72 Set<Integer> screenOnStates = new HashSet<>( 73 Arrays.asList(DisplayStateEnum.DISPLAY_STATE_ON_VALUE, 74 DisplayStateEnum.DISPLAY_STATE_ON_SUSPEND_VALUE, 75 DisplayStateEnum.DISPLAY_STATE_VR_VALUE)); 76 Set<Integer> screenOffStates = new HashSet<>( 77 Arrays.asList(DisplayStateEnum.DISPLAY_STATE_OFF_VALUE, 78 DisplayStateEnum.DISPLAY_STATE_DOZE_VALUE, 79 DisplayStateEnum.DISPLAY_STATE_DOZE_SUSPEND_VALUE, 80 DisplayStateEnum.DISPLAY_STATE_UNKNOWN_VALUE)); 81 82 // Add state sets to the list in order. 83 List<Set<Integer>> stateSet = Arrays.asList(screenOnStates, screenOffStates); 84 85 createAndUploadConfig(atomTag); 86 Thread.sleep(WAIT_TIME_SHORT); 87 88 // Trigger events in same order. 89 turnScreenOn(); 90 Thread.sleep(WAIT_TIME_LONG); 91 turnScreenOff(); 92 Thread.sleep(WAIT_TIME_LONG); 93 94 // Sorted list of events in order in which they occurred. 95 List<EventMetricData> data = getEventMetricDataList(); 96 // reset screen to on 97 turnScreenOn(); 98 // Restores AoD to initial state. 99 setAodState(aodState); 100 // Assert that the events happened in the expected order. 101 assertStatesOccurred(stateSet, data, WAIT_TIME_LONG, 102 atom -> atom.getScreenStateChanged().getState().getNumber()); 103 } 104 testChargingStateChangedAtom()105 public void testChargingStateChangedAtom() throws Exception { 106 if (statsdDisabled()) { 107 return; 108 } 109 if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return; 110 // Setup, set charging state to full. 111 setChargingState(5); 112 Thread.sleep(WAIT_TIME_SHORT); 113 114 final int atomTag = Atom.CHARGING_STATE_CHANGED_FIELD_NUMBER; 115 116 Set<Integer> batteryUnknownStates = new HashSet<>( 117 Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_UNKNOWN_VALUE)); 118 Set<Integer> batteryChargingStates = new HashSet<>( 119 Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_CHARGING_VALUE)); 120 Set<Integer> batteryDischargingStates = new HashSet<>( 121 Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_DISCHARGING_VALUE)); 122 Set<Integer> batteryNotChargingStates = new HashSet<>( 123 Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_NOT_CHARGING_VALUE)); 124 Set<Integer> batteryFullStates = new HashSet<>( 125 Arrays.asList(BatteryStatusEnum.BATTERY_STATUS_FULL_VALUE)); 126 127 // Add state sets to the list in order. 128 List<Set<Integer>> stateSet = Arrays.asList(batteryUnknownStates, batteryChargingStates, 129 batteryDischargingStates, batteryNotChargingStates, batteryFullStates); 130 131 createAndUploadConfig(atomTag); 132 Thread.sleep(WAIT_TIME_SHORT); 133 134 // Trigger events in same order. 135 setChargingState(1); 136 Thread.sleep(WAIT_TIME_SHORT); 137 setChargingState(2); 138 Thread.sleep(WAIT_TIME_SHORT); 139 setChargingState(3); 140 Thread.sleep(WAIT_TIME_SHORT); 141 setChargingState(4); 142 Thread.sleep(WAIT_TIME_SHORT); 143 setChargingState(5); 144 Thread.sleep(WAIT_TIME_SHORT); 145 146 // Sorted list of events in order in which they occurred. 147 List<EventMetricData> data = getEventMetricDataList(); 148 149 // Unfreeze battery state after test 150 resetBatteryStatus(); 151 Thread.sleep(WAIT_TIME_SHORT); 152 153 // Assert that the events happened in the expected order. 154 assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT, 155 atom -> atom.getChargingStateChanged().getState().getNumber()); 156 } 157 testPluggedStateChangedAtom()158 public void testPluggedStateChangedAtom() throws Exception { 159 if (statsdDisabled()) { 160 return; 161 } 162 if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return; 163 // Setup, unplug device. 164 unplugDevice(); 165 Thread.sleep(WAIT_TIME_SHORT); 166 167 final int atomTag = Atom.PLUGGED_STATE_CHANGED_FIELD_NUMBER; 168 169 Set<Integer> unpluggedStates = new HashSet<>( 170 Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_NONE_VALUE)); 171 Set<Integer> acStates = new HashSet<>( 172 Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_AC_VALUE)); 173 Set<Integer> usbStates = new HashSet<>( 174 Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_USB_VALUE)); 175 Set<Integer> wirelessStates = new HashSet<>( 176 Arrays.asList(BatteryPluggedStateEnum.BATTERY_PLUGGED_WIRELESS_VALUE)); 177 178 // Add state sets to the list in order. 179 List<Set<Integer>> stateSet = Arrays.asList(acStates, unpluggedStates, usbStates, 180 unpluggedStates, wirelessStates, unpluggedStates); 181 182 createAndUploadConfig(atomTag); 183 Thread.sleep(WAIT_TIME_SHORT); 184 185 // Trigger events in same order. 186 plugInAc(); 187 Thread.sleep(WAIT_TIME_SHORT); 188 unplugDevice(); 189 Thread.sleep(WAIT_TIME_SHORT); 190 plugInUsb(); 191 Thread.sleep(WAIT_TIME_SHORT); 192 unplugDevice(); 193 Thread.sleep(WAIT_TIME_SHORT); 194 plugInWireless(); 195 Thread.sleep(WAIT_TIME_SHORT); 196 unplugDevice(); 197 Thread.sleep(WAIT_TIME_SHORT); 198 199 // Sorted list of events in order in which they occurred. 200 List<EventMetricData> data = getEventMetricDataList(); 201 202 // Unfreeze battery state after test 203 resetBatteryStatus(); 204 Thread.sleep(WAIT_TIME_SHORT); 205 206 // Assert that the events happened in the expected order. 207 assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT, 208 atom -> atom.getPluggedStateChanged().getState().getNumber()); 209 } 210 testBatteryLevelChangedAtom()211 public void testBatteryLevelChangedAtom() throws Exception { 212 if (statsdDisabled()) { 213 return; 214 } 215 if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return; 216 // Setup, set battery level to full. 217 setBatteryLevel(100); 218 Thread.sleep(WAIT_TIME_SHORT); 219 220 final int atomTag = Atom.BATTERY_LEVEL_CHANGED_FIELD_NUMBER; 221 222 Set<Integer> batteryLow = new HashSet<>(Arrays.asList(2)); 223 Set<Integer> battery25p = new HashSet<>(Arrays.asList(25)); 224 Set<Integer> battery50p = new HashSet<>(Arrays.asList(50)); 225 Set<Integer> battery75p = new HashSet<>(Arrays.asList(75)); 226 Set<Integer> batteryFull = new HashSet<>(Arrays.asList(100)); 227 228 // Add state sets to the list in order. 229 List<Set<Integer>> stateSet = Arrays.asList(batteryLow, battery25p, battery50p, 230 battery75p, batteryFull); 231 232 createAndUploadConfig(atomTag); 233 Thread.sleep(WAIT_TIME_SHORT); 234 235 // Trigger events in same order. 236 setBatteryLevel(2); 237 Thread.sleep(WAIT_TIME_SHORT); 238 setBatteryLevel(25); 239 Thread.sleep(WAIT_TIME_SHORT); 240 setBatteryLevel(50); 241 Thread.sleep(WAIT_TIME_SHORT); 242 setBatteryLevel(75); 243 Thread.sleep(WAIT_TIME_SHORT); 244 setBatteryLevel(100); 245 Thread.sleep(WAIT_TIME_SHORT); 246 247 // Sorted list of events in order in which they occurred. 248 List<EventMetricData> data = getEventMetricDataList(); 249 250 // Unfreeze battery state after test 251 resetBatteryStatus(); 252 Thread.sleep(WAIT_TIME_SHORT); 253 254 // Assert that the events happened in the expected order. 255 assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT, 256 atom -> atom.getBatteryLevelChanged().getBatteryLevel()); 257 } 258 testDeviceIdleModeStateChangedAtom()259 public void testDeviceIdleModeStateChangedAtom() throws Exception { 260 if (statsdDisabled()) { 261 return; 262 } 263 // Setup, leave doze mode. 264 leaveDozeMode(); 265 Thread.sleep(WAIT_TIME_SHORT); 266 267 final int atomTag = Atom.DEVICE_IDLE_MODE_STATE_CHANGED_FIELD_NUMBER; 268 269 Set<Integer> dozeOff = new HashSet<>( 270 Arrays.asList(DeviceIdleModeEnum.DEVICE_IDLE_MODE_OFF_VALUE)); 271 Set<Integer> dozeLight = new HashSet<>( 272 Arrays.asList(DeviceIdleModeEnum.DEVICE_IDLE_MODE_LIGHT_VALUE)); 273 Set<Integer> dozeDeep = new HashSet<>( 274 Arrays.asList(DeviceIdleModeEnum.DEVICE_IDLE_MODE_DEEP_VALUE)); 275 276 // Add state sets to the list in order. 277 List<Set<Integer>> stateSet = Arrays.asList(dozeLight, dozeDeep, dozeOff); 278 279 createAndUploadConfig(atomTag); 280 Thread.sleep(WAIT_TIME_SHORT); 281 282 // Trigger events in same order. 283 enterDozeModeLight(); 284 Thread.sleep(WAIT_TIME_SHORT); 285 enterDozeModeDeep(); 286 Thread.sleep(WAIT_TIME_SHORT); 287 leaveDozeMode(); 288 Thread.sleep(WAIT_TIME_SHORT); 289 290 // Sorted list of events in order in which they occurred. 291 List<EventMetricData> data = getEventMetricDataList();; 292 293 // Assert that the events happened in the expected order. 294 assertStatesOccurred(stateSet, data, WAIT_TIME_SHORT, 295 atom -> atom.getDeviceIdleModeStateChanged().getState().getNumber()); 296 } 297 testBatterySaverModeStateChangedAtom()298 public void testBatterySaverModeStateChangedAtom() throws Exception { 299 if (statsdDisabled()) { 300 return; 301 } 302 if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return; 303 // Setup, turn off battery saver. 304 turnBatterySaverOff(); 305 Thread.sleep(WAIT_TIME_SHORT); 306 307 final int atomTag = Atom.BATTERY_SAVER_MODE_STATE_CHANGED_FIELD_NUMBER; 308 309 Set<Integer> batterySaverOn = new HashSet<>( 310 Arrays.asList(BatterySaverModeStateChanged.State.ON_VALUE)); 311 Set<Integer> batterySaverOff = new HashSet<>( 312 Arrays.asList(BatterySaverModeStateChanged.State.OFF_VALUE)); 313 314 // Add state sets to the list in order. 315 List<Set<Integer>> stateSet = Arrays.asList(batterySaverOn, batterySaverOff); 316 317 createAndUploadConfig(atomTag); 318 Thread.sleep(WAIT_TIME_SHORT); 319 320 // Trigger events in same order. 321 turnBatterySaverOn(); 322 Thread.sleep(WAIT_TIME_LONG); 323 turnBatterySaverOff(); 324 Thread.sleep(WAIT_TIME_LONG); 325 326 // Sorted list of events in order in which they occurred. 327 List<EventMetricData> data = getEventMetricDataList(); 328 329 // Assert that the events happened in the expected order. 330 assertStatesOccurred(stateSet, data, WAIT_TIME_LONG, 331 atom -> atom.getBatterySaverModeStateChanged().getState().getNumber()); 332 } 333 334 @RestrictedBuildTest testRemainingBatteryCapacity()335 public void testRemainingBatteryCapacity() throws Exception { 336 if (statsdDisabled()) { 337 return; 338 } 339 if (!hasFeature(FEATURE_WATCH, false)) return; 340 if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return; 341 StatsdConfig.Builder config = getPulledConfig(); 342 addGaugeAtomWithDimensions(config, Atom.REMAINING_BATTERY_CAPACITY_FIELD_NUMBER, null); 343 344 uploadConfig(config); 345 346 Thread.sleep(WAIT_TIME_LONG); 347 setAppBreadcrumbPredicate(); 348 Thread.sleep(WAIT_TIME_LONG); 349 350 List<Atom> data = getGaugeMetricDataList(); 351 352 assertTrue(data.size() > 0); 353 Atom atom = data.get(0); 354 assertTrue(atom.getRemainingBatteryCapacity().hasChargeMicroAmpereHour()); 355 if (hasBattery()) { 356 assertTrue(atom.getRemainingBatteryCapacity().getChargeMicroAmpereHour() > 0); 357 } 358 } 359 360 @RestrictedBuildTest testFullBatteryCapacity()361 public void testFullBatteryCapacity() throws Exception { 362 if (statsdDisabled()) { 363 return; 364 } 365 if (!hasFeature(FEATURE_WATCH, false)) return; 366 if (!hasFeature(FEATURE_AUTOMOTIVE, false)) return; 367 StatsdConfig.Builder config = getPulledConfig(); 368 addGaugeAtomWithDimensions(config, Atom.FULL_BATTERY_CAPACITY_FIELD_NUMBER, null); 369 370 uploadConfig(config); 371 372 Thread.sleep(WAIT_TIME_LONG); 373 setAppBreadcrumbPredicate(); 374 Thread.sleep(WAIT_TIME_LONG); 375 376 List<Atom> data = getGaugeMetricDataList(); 377 378 assertTrue(data.size() > 0); 379 Atom atom = data.get(0); 380 assertTrue(atom.getFullBatteryCapacity().hasCapacityMicroAmpereHour()); 381 if (hasBattery()) { 382 assertTrue(atom.getFullBatteryCapacity().getCapacityMicroAmpereHour() > 0); 383 } 384 } 385 testBatteryVoltage()386 public void testBatteryVoltage() throws Exception { 387 if (statsdDisabled()) { 388 return; 389 } 390 if (!hasFeature(FEATURE_WATCH, false)) return; 391 StatsdConfig.Builder config = getPulledConfig(); 392 addGaugeAtomWithDimensions(config, Atom.BATTERY_VOLTAGE_FIELD_NUMBER, null); 393 394 uploadConfig(config); 395 396 Thread.sleep(WAIT_TIME_LONG); 397 setAppBreadcrumbPredicate(); 398 Thread.sleep(WAIT_TIME_LONG); 399 400 List<Atom> data = getGaugeMetricDataList(); 401 402 assertTrue(data.size() > 0); 403 Atom atom = data.get(0); 404 assertTrue(atom.getBatteryVoltage().hasVoltageMillivolt()); 405 if (hasBattery()) { 406 assertTrue(atom.getBatteryVoltage().getVoltageMillivolt() > 0); 407 } 408 } 409 410 // This test is for the pulled battery level atom. testBatteryLevel()411 public void testBatteryLevel() throws Exception { 412 if (statsdDisabled()) { 413 return; 414 } 415 if (!hasFeature(FEATURE_WATCH, false)) return; 416 StatsdConfig.Builder config = getPulledConfig(); 417 addGaugeAtomWithDimensions(config, Atom.BATTERY_LEVEL_FIELD_NUMBER, null); 418 419 uploadConfig(config); 420 421 Thread.sleep(WAIT_TIME_LONG); 422 setAppBreadcrumbPredicate(); 423 Thread.sleep(WAIT_TIME_LONG); 424 425 List<Atom> data = getGaugeMetricDataList(); 426 427 assertTrue(data.size() > 0); 428 Atom atom = data.get(0); 429 assertTrue(atom.getBatteryLevel().hasBatteryLevel()); 430 if (hasBattery()) { 431 assertTrue(atom.getBatteryLevel().getBatteryLevel() > 0); 432 assertTrue(atom.getBatteryLevel().getBatteryLevel() <= 100); 433 } 434 } 435 436 // This test is for the pulled battery charge count atom. testBatteryCycleCount()437 public void testBatteryCycleCount() throws Exception { 438 if (statsdDisabled()) { 439 return; 440 } 441 if (!hasFeature(FEATURE_WATCH, false)) return; 442 StatsdConfig.Builder config = getPulledConfig(); 443 addGaugeAtomWithDimensions(config, Atom.BATTERY_CYCLE_COUNT_FIELD_NUMBER, null); 444 445 uploadConfig(config); 446 447 Thread.sleep(WAIT_TIME_LONG); 448 setAppBreadcrumbPredicate(); 449 Thread.sleep(WAIT_TIME_LONG); 450 451 List<Atom> data = getGaugeMetricDataList(); 452 453 assertTrue(data.size() > 0); 454 Atom atom = data.get(0); 455 assertTrue(atom.getBatteryCycleCount().hasCycleCount()); 456 if (hasBattery()) { 457 assertTrue(atom.getBatteryCycleCount().getCycleCount() >= 0); 458 } 459 } 460 testKernelWakelock()461 public void testKernelWakelock() throws Exception { 462 if (statsdDisabled() || !kernelWakelockStatsExist()) { 463 return; 464 } 465 StatsdConfig.Builder config = getPulledConfig(); 466 addGaugeAtomWithDimensions(config, Atom.KERNEL_WAKELOCK_FIELD_NUMBER, null); 467 468 uploadConfig(config); 469 470 Thread.sleep(WAIT_TIME_LONG); 471 setAppBreadcrumbPredicate(); 472 Thread.sleep(WAIT_TIME_LONG); 473 474 List<Atom> data = getGaugeMetricDataList(); 475 476 Atom atom = data.get(0); 477 assertTrue(!atom.getKernelWakelock().getName().equals("")); 478 assertTrue(atom.getKernelWakelock().hasCount()); 479 assertTrue(atom.getKernelWakelock().hasVersion()); 480 assertTrue(atom.getKernelWakelock().getVersion() > 0); 481 assertTrue(atom.getKernelWakelock().hasTimeMicros()); 482 } 483 484 // Returns true iff either |WAKE_LOCK_FILE| or |WAKE_SOURCES_FILE| exists. kernelWakelockStatsExist()485 private boolean kernelWakelockStatsExist() { 486 try { 487 return doesFileExist(WAKE_LOCK_FILE) || doesFileExist(WAKE_SOURCES_FILE); 488 } catch(Exception e) { 489 return false; 490 } 491 } 492 testWifiActivityInfo()493 public void testWifiActivityInfo() throws Exception { 494 if (statsdDisabled()) { 495 return; 496 } 497 if (!hasFeature(FEATURE_WIFI, true)) return; 498 if (!hasFeature(FEATURE_WATCH, false)) return; 499 if (!checkDeviceFor("checkWifiEnhancedPowerReportingSupported")) return; 500 501 StatsdConfig.Builder config = getPulledConfig(); 502 addGaugeAtomWithDimensions(config, Atom.WIFI_ACTIVITY_INFO_FIELD_NUMBER, null); 503 504 uploadConfig(config); 505 506 Thread.sleep(WAIT_TIME_LONG); 507 setAppBreadcrumbPredicate(); 508 Thread.sleep(WAIT_TIME_LONG); 509 510 List<Atom> dataList = getGaugeMetricDataList(); 511 512 for (Atom atom: dataList) { 513 assertTrue(atom.getWifiActivityInfo().getTimestampMillis() > 0); 514 assertTrue(atom.getWifiActivityInfo().getStackState() >= 0); 515 assertTrue(atom.getWifiActivityInfo().getControllerIdleTimeMillis() > 0); 516 assertTrue(atom.getWifiActivityInfo().getControllerTxTimeMillis() >= 0); 517 assertTrue(atom.getWifiActivityInfo().getControllerRxTimeMillis() >= 0); 518 assertTrue(atom.getWifiActivityInfo().getControllerEnergyUsed() >= 0); 519 } 520 } 521 testBuildInformation()522 public void testBuildInformation() throws Exception { 523 if (statsdDisabled()) { 524 return; 525 } 526 527 StatsdConfig.Builder config = getPulledConfig(); 528 addGaugeAtomWithDimensions(config, Atom.BUILD_INFORMATION_FIELD_NUMBER, null); 529 uploadConfig(config); 530 531 Thread.sleep(WAIT_TIME_LONG); 532 setAppBreadcrumbPredicate(); 533 Thread.sleep(WAIT_TIME_LONG); 534 535 List<Atom> data = getGaugeMetricDataList(); 536 assertTrue(data.size() > 0); 537 BuildInformation atom = data.get(0).getBuildInformation(); 538 assertEquals(getProperty("ro.product.brand"), atom.getBrand()); 539 assertEquals(getProperty("ro.product.name"), atom.getProduct()); 540 assertEquals(getProperty("ro.product.device"), atom.getDevice()); 541 assertEquals(getProperty("ro.build.version.release"), atom.getVersionRelease()); 542 assertEquals(getProperty("ro.build.id"), atom.getId()); 543 assertEquals(getProperty("ro.build.version.incremental"), atom.getVersionIncremental()); 544 assertEquals(getProperty("ro.build.type"), atom.getType()); 545 assertEquals(getProperty("ro.build.tags"), atom.getTags()); 546 } 547 testOnDevicePowerMeasurement()548 public void testOnDevicePowerMeasurement() throws Exception { 549 if (!OPTIONAL_TESTS_ENABLED) return; 550 if (statsdDisabled()) { 551 return; 552 } 553 554 StatsdConfig.Builder config = getPulledConfig(); 555 addGaugeAtomWithDimensions(config, Atom.ON_DEVICE_POWER_MEASUREMENT_FIELD_NUMBER, null); 556 557 uploadConfig(config); 558 559 Thread.sleep(WAIT_TIME_LONG); 560 setAppBreadcrumbPredicate(); 561 Thread.sleep(WAIT_TIME_LONG); 562 563 List<Atom> dataList = getGaugeMetricDataList(); 564 565 for (Atom atom: dataList) { 566 assertTrue(atom.getOnDevicePowerMeasurement().getMeasurementTimestampMillis() >= 0); 567 assertTrue(atom.getOnDevicePowerMeasurement().getEnergyMicrowattSecs() >= 0); 568 } 569 } 570 571 // Explicitly tests if the adb command to log a breadcrumb is working. testBreadcrumbAdb()572 public void testBreadcrumbAdb() throws Exception { 573 if (statsdDisabled()) { 574 return; 575 } 576 final int atomTag = Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER; 577 createAndUploadConfig(atomTag); 578 Thread.sleep(WAIT_TIME_SHORT); 579 580 doAppBreadcrumbReportedStart(1); 581 Thread.sleep(WAIT_TIME_SHORT); 582 583 List<EventMetricData> data = getEventMetricDataList(); 584 AppBreadcrumbReported atom = data.get(0).getAtom().getAppBreadcrumbReported(); 585 assertTrue(atom.getLabel() == 1); 586 assertTrue(atom.getState().getNumber() == AppBreadcrumbReported.State.START_VALUE); 587 } 588 589 // Test dumpsys stats --proto. testDumpsysStats()590 public void testDumpsysStats() throws Exception { 591 if (statsdDisabled()) { 592 return; 593 } 594 final int atomTag = Atom.APP_BREADCRUMB_REPORTED_FIELD_NUMBER; 595 createAndUploadConfig(atomTag); 596 Thread.sleep(WAIT_TIME_SHORT); 597 598 doAppBreadcrumbReportedStart(1); 599 Thread.sleep(WAIT_TIME_SHORT); 600 601 // Get the stats incident section. 602 List<ConfigMetricsReportList> listList = getReportsFromStatsDataDumpProto(); 603 assertTrue(listList.size() > 0); 604 605 // Extract the relevent report from the incident section. 606 ConfigMetricsReportList ourList = null; 607 int hostUid = getHostUid(); 608 for (ConfigMetricsReportList list : listList) { 609 ConfigMetricsReportList.ConfigKey configKey = list.getConfigKey(); 610 if (configKey.getUid() == hostUid && configKey.getId() == CONFIG_ID) { 611 ourList = list; 612 break; 613 } 614 } 615 assertNotNull("Could not find list for uid=" + hostUid 616 + " id=" + CONFIG_ID, ourList); 617 618 // Make sure that the report is correct. 619 List<EventMetricData> data = getEventMetricDataList(ourList); 620 AppBreadcrumbReported atom = data.get(0).getAtom().getAppBreadcrumbReported(); 621 assertTrue(atom.getLabel() == 1); 622 assertTrue(atom.getState().getNumber() == AppBreadcrumbReported.State.START_VALUE); 623 } 624 testConnectivityStateChange()625 public void testConnectivityStateChange() throws Exception { 626 if (statsdDisabled()) { 627 return; 628 } 629 if (!hasFeature(FEATURE_WIFI, true)) return; 630 if (!hasFeature(FEATURE_WATCH, false)) return; 631 if (!hasFeature(FEATURE_LEANBACK_ONLY, false)) return; 632 633 final int atomTag = Atom.CONNECTIVITY_STATE_CHANGED_FIELD_NUMBER; 634 createAndUploadConfig(atomTag); 635 Thread.sleep(WAIT_TIME_SHORT); 636 637 turnOnAirplaneMode(); 638 // wait long enough for airplane mode events to propagate. 639 Thread.sleep(1_200); 640 turnOffAirplaneMode(); 641 // wait long enough for the device to restore connection 642 Thread.sleep(13_000); 643 644 List<EventMetricData> data = getEventMetricDataList(); 645 // at least 1 disconnect and 1 connect 646 assertThat(data.size()).isAtLeast(2); 647 boolean foundDisconnectEvent = false; 648 boolean foundConnectEvent = false; 649 for (EventMetricData d : data) { 650 ConnectivityStateChanged atom = d.getAtom().getConnectivityStateChanged(); 651 if(atom.getState().getNumber() 652 == ConnectivityStateChanged.State.DISCONNECTED_VALUE) { 653 foundDisconnectEvent = true; 654 } 655 if(atom.getState().getNumber() 656 == ConnectivityStateChanged.State.CONNECTED_VALUE) { 657 foundConnectEvent = true; 658 } 659 } 660 assertTrue(foundConnectEvent && foundDisconnectEvent); 661 } 662 } 663