1 /* 2 * Copyright (C) 2014 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 android.dumpsys.cts; 18 19 import com.android.cts.tradefed.build.CtsBuildHelper; 20 import com.android.tradefed.build.IBuildInfo; 21 import com.android.tradefed.device.ITestDevice; 22 import com.android.tradefed.testtype.DeviceTestCase; 23 import com.android.tradefed.testtype.IBuildReceiver; 24 25 import java.io.BufferedReader; 26 import java.io.File; 27 import java.io.IOException; 28 import java.io.StringReader; 29 import java.util.HashSet; 30 import java.util.Set; 31 32 /** 33 * Test to check the format of the dumps of various services (currently only procstats is tested). 34 */ 35 public class DumpsysHostTest extends DeviceTestCase implements IBuildReceiver { 36 private static final String TAG = "DumpsysHostTest"; 37 private static final String TEST_APK = "CtsFramestatsTestApp.apk"; 38 private static final String TEST_PKG = "com.android.cts.framestatstestapp"; 39 40 /** 41 * A reference to the device under test. 42 */ 43 private ITestDevice mDevice; 44 45 @Override setUp()46 protected void setUp() throws Exception { 47 super.setUp(); 48 mDevice = getDevice(); 49 } 50 51 /** 52 * Tests the output of "dumpsys procstats -c". This is a proxy for testing "dumpsys procstats 53 * --checkin", since the latter is not idempotent. 54 * 55 * @throws Exception 56 */ testProcstatsOutput()57 public void testProcstatsOutput() throws Exception { 58 String procstats = mDevice.executeShellCommand("dumpsys procstats -c"); 59 assertNotNull(procstats); 60 assertTrue(procstats.length() > 0); 61 62 Set<String> seenTags = new HashSet<>(); 63 int version = -1; 64 65 try (BufferedReader reader = new BufferedReader( 66 new StringReader(procstats))) { 67 68 String line; 69 while ((line = reader.readLine()) != null) { 70 if (line.isEmpty()) { 71 continue; 72 } 73 74 // extra space to make sure last column shows up. 75 if (line.endsWith(",")) { 76 line = line + " "; 77 } 78 String[] parts = line.split(","); 79 seenTags.add(parts[0]); 80 81 switch (parts[0]) { 82 case "vers": 83 assertEquals(2, parts.length); 84 version = Integer.parseInt(parts[1]); 85 break; 86 case "period": 87 checkPeriod(parts); 88 break; 89 case "pkgproc": 90 checkPkgProc(parts, version); 91 break; 92 case "pkgpss": 93 checkPkgPss(parts, version); 94 break; 95 case "pkgsvc-bound": 96 case "pkgsvc-exec": 97 case "pkgsvc-run": 98 case "pkgsvc-start": 99 checkPkgSvc(parts, version); 100 break; 101 case "pkgkills": 102 checkPkgKills(parts, version); 103 break; 104 case "proc": 105 checkProc(parts); 106 break; 107 case "pss": 108 checkPss(parts); 109 break; 110 case "kills": 111 checkKills(parts); 112 break; 113 case "total": 114 checkTotal(parts); 115 break; 116 default: 117 break; 118 } 119 } 120 } 121 122 // spot check a few tags 123 assertSeenTag(seenTags, "pkgproc"); 124 assertSeenTag(seenTags, "proc"); 125 assertSeenTag(seenTags, "pss"); 126 assertSeenTag(seenTags, "total"); 127 } 128 checkPeriod(String[] parts)129 private void checkPeriod(String[] parts) { 130 assertEquals(5, parts.length); 131 assertNotNull(parts[1]); // date 132 assertInteger(parts[2]); // start time (msec) 133 assertInteger(parts[3]); // end time (msec) 134 assertNotNull(parts[4]); // status 135 } 136 checkPkgProc(String[] parts, int version)137 private void checkPkgProc(String[] parts, int version) { 138 int statesStartIndex; 139 140 if (version < 4) { 141 assertTrue(parts.length >= 4); 142 assertNotNull(parts[1]); // package name 143 assertInteger(parts[2]); // uid 144 assertNotNull(parts[3]); // process 145 statesStartIndex = 4; 146 } else { 147 assertTrue(parts.length >= 5); 148 assertNotNull(parts[1]); // package name 149 assertInteger(parts[2]); // uid 150 assertInteger(parts[3]); // app version 151 assertNotNull(parts[4]); // process 152 statesStartIndex = 5; 153 } 154 155 for (int i = statesStartIndex; i < parts.length; i++) { 156 String[] subparts = parts[i].split(":"); 157 assertEquals(2, subparts.length); 158 checkTag(subparts[0], true); // tag 159 assertInteger(subparts[1]); // duration (msec) 160 } 161 } 162 checkTag(String tag, boolean hasProcess)163 private void checkTag(String tag, boolean hasProcess) { 164 assertEquals(hasProcess ? 3 : 2, tag.length()); 165 166 // screen: 0 = off, 1 = on 167 char s = tag.charAt(0); 168 if (s != '0' && s != '1') { 169 fail("malformed tag: " + tag); 170 } 171 172 // memory: n = normal, m = moderate, l = low, c = critical 173 char m = tag.charAt(1); 174 if (m != 'n' && m != 'm' && m != 'l' && m != 'c') { 175 fail("malformed tag: " + tag); 176 } 177 178 if (hasProcess) { 179 char p = tag.charAt(2); 180 assertTrue("malformed tag: " + tag, p >= 'a' && p <= 'z'); 181 } 182 } 183 checkPkgPss(String[] parts, int version)184 private void checkPkgPss(String[] parts, int version) { 185 int statesStartIndex; 186 187 if (version < 4) { 188 assertTrue(parts.length >= 4); 189 assertNotNull(parts[1]); // package name 190 assertInteger(parts[2]); // uid 191 assertNotNull(parts[3]); // process 192 statesStartIndex = 4; 193 } else { 194 assertTrue(parts.length >= 5); 195 assertNotNull(parts[1]); // package name 196 assertInteger(parts[2]); // uid 197 assertInteger(parts[3]); // app version 198 assertNotNull(parts[4]); // process 199 statesStartIndex = 5; 200 } 201 202 for (int i = statesStartIndex; i < parts.length; i++) { 203 String[] subparts = parts[i].split(":"); 204 assertEquals(8, subparts.length); 205 checkTag(subparts[0], true); // tag 206 assertInteger(subparts[1]); // sample size 207 assertInteger(subparts[2]); // pss min 208 assertInteger(subparts[3]); // pss avg 209 assertInteger(subparts[4]); // pss max 210 assertInteger(subparts[5]); // uss min 211 assertInteger(subparts[6]); // uss avg 212 assertInteger(subparts[7]); // uss max 213 } 214 } 215 checkPkgSvc(String[] parts, int version)216 private void checkPkgSvc(String[] parts, int version) { 217 int statesStartIndex; 218 219 if (version < 4) { 220 assertTrue(parts.length >= 5); 221 assertNotNull(parts[1]); // package name 222 assertInteger(parts[2]); // uid 223 assertNotNull(parts[3]); // service name 224 assertInteger(parts[4]); // count 225 statesStartIndex = 5; 226 } else { 227 assertTrue(parts.length >= 6); 228 assertNotNull(parts[1]); // package name 229 assertInteger(parts[2]); // uid 230 assertInteger(parts[3]); // app version 231 assertNotNull(parts[4]); // service name 232 assertInteger(parts[5]); // count 233 statesStartIndex = 6; 234 } 235 236 for (int i = statesStartIndex; i < parts.length; i++) { 237 String[] subparts = parts[i].split(":"); 238 assertEquals(2, subparts.length); 239 checkTag(subparts[0], false); // tag 240 assertInteger(subparts[1]); // duration (msec) 241 } 242 } 243 checkPkgKills(String[] parts, int version)244 private void checkPkgKills(String[] parts, int version) { 245 String pssStr; 246 247 if (version < 4) { 248 assertEquals(8, parts.length); 249 assertNotNull(parts[1]); // package name 250 assertInteger(parts[2]); // uid 251 assertNotNull(parts[3]); // process 252 assertInteger(parts[4]); // wakes 253 assertInteger(parts[5]); // cpu 254 assertInteger(parts[6]); // cached 255 pssStr = parts[7]; 256 } else { 257 assertEquals(9, parts.length); 258 assertNotNull(parts[1]); // package name 259 assertInteger(parts[2]); // uid 260 assertInteger(parts[3]); // app version 261 assertNotNull(parts[4]); // process 262 assertInteger(parts[5]); // wakes 263 assertInteger(parts[6]); // cpu 264 assertInteger(parts[7]); // cached 265 pssStr = parts[8]; 266 } 267 268 String[] subparts = pssStr.split(":"); 269 assertEquals(3, subparts.length); 270 assertInteger(subparts[0]); // pss min 271 assertInteger(subparts[1]); // pss avg 272 assertInteger(subparts[2]); // pss max 273 } 274 checkProc(String[] parts)275 private void checkProc(String[] parts) { 276 assertTrue(parts.length >= 3); 277 assertNotNull(parts[1]); // package name 278 assertInteger(parts[2]); // uid 279 280 for (int i = 3; i < parts.length; i++) { 281 String[] subparts = parts[i].split(":"); 282 assertEquals(2, subparts.length); 283 checkTag(subparts[0], true); // tag 284 assertInteger(subparts[1]); // duration (msec) 285 } 286 } 287 checkPss(String[] parts)288 private void checkPss(String[] parts) { 289 assertTrue(parts.length >= 3); 290 assertNotNull(parts[1]); // package name 291 assertInteger(parts[2]); // uid 292 293 for (int i = 3; i < parts.length; i++) { 294 String[] subparts = parts[i].split(":"); 295 assertEquals(8, subparts.length); 296 checkTag(subparts[0], true); // tag 297 assertInteger(subparts[1]); // sample size 298 assertInteger(subparts[2]); // pss min 299 assertInteger(subparts[3]); // pss avg 300 assertInteger(subparts[4]); // pss max 301 assertInteger(subparts[5]); // uss min 302 assertInteger(subparts[6]); // uss avg 303 assertInteger(subparts[7]); // uss max 304 } 305 } 306 checkKills(String[] parts)307 private void checkKills(String[] parts) { 308 assertEquals(7, parts.length); 309 assertNotNull(parts[1]); // package name 310 assertInteger(parts[2]); // uid 311 assertInteger(parts[3]); // wakes 312 assertInteger(parts[4]); // cpu 313 assertInteger(parts[5]); // cached 314 String pssStr = parts[6]; 315 316 String[] subparts = pssStr.split(":"); 317 assertEquals(3, subparts.length); 318 assertInteger(subparts[0]); // pss min 319 assertInteger(subparts[1]); // pss avg 320 assertInteger(subparts[2]); // pss max 321 } 322 checkTotal(String[] parts)323 private void checkTotal(String[] parts) { 324 assertTrue(parts.length >= 2); 325 for (int i = 1; i < parts.length; i++) { 326 String[] subparts = parts[i].split(":"); 327 checkTag(subparts[0], false); // tag 328 329 if (subparts[1].contains("sysmemusage")) { 330 break; // see b/18340771 331 } 332 assertInteger(subparts[1]); // duration (msec) 333 } 334 } 335 336 /** 337 * Tests the output of "dumpsys batterystats --checkin". 338 * 339 * @throws Exception 340 */ testBatterystatsOutput()341 public void testBatterystatsOutput() throws Exception { 342 String batterystats = mDevice.executeShellCommand("dumpsys batterystats --checkin"); 343 assertNotNull(batterystats); 344 assertTrue(batterystats.length() > 0); 345 346 Set<String> seenTags = new HashSet<>(); 347 int version = -1; 348 349 try (BufferedReader reader = new BufferedReader( 350 new StringReader(batterystats))) { 351 352 String line; 353 while ((line = reader.readLine()) != null) { 354 if (line.isEmpty()) { 355 continue; 356 } 357 358 359 // With a default limit of 0, empty strings at the end are discarded. 360 // We still consider the empty string as a valid value in some cases. 361 // Using any negative number for the limit will preserve a trailing empty string. 362 // @see String#split(String, int) 363 String[] parts = line.split(",", -1); 364 assertInteger(parts[0]); // old version 365 assertInteger(parts[1]); // UID 366 switch (parts[2]) { // aggregation type 367 case "i": 368 case "l": 369 case "c": 370 case "u": 371 break; 372 default: 373 fail("malformed stat: " + parts[2]); 374 } 375 assertNotNull(parts[3]); 376 seenTags.add(parts[3]); 377 378 // Note the time fields are measured in milliseconds by default. 379 switch (parts[3]) { 380 case "vers": 381 checkVersion(parts); 382 break; 383 case "uid": 384 checkUid(parts); 385 break; 386 case "apk": 387 checkApk(parts); 388 break; 389 case "pr": 390 checkProcess(parts); 391 break; 392 case "sr": 393 checkSensor(parts); 394 break; 395 case "vib": 396 checkVibrator(parts); 397 break; 398 case "fg": 399 checkForeground(parts); 400 break; 401 case "st": 402 checkStateTime(parts); 403 break; 404 case "wl": 405 checkWakelock(parts); 406 break; 407 case "sy": 408 checkSync(parts); 409 break; 410 case "jb": 411 checkJob(parts); 412 break; 413 case "kwl": 414 checkKernelWakelock(parts); 415 break; 416 case "wr": 417 checkWakeupReason(parts); 418 break; 419 case "nt": 420 checkNetwork(parts); 421 break; 422 case "ua": 423 checkUserActivity(parts); 424 break; 425 case "bt": 426 checkBattery(parts); 427 break; 428 case "dc": 429 checkBatteryDischarge(parts); 430 break; 431 case "lv": 432 checkBatteryLevel(parts); 433 break; 434 case "wfl": 435 checkWifi(parts); 436 break; 437 case "m": 438 checkMisc(parts); 439 break; 440 case "gn": 441 checkGlobalNetwork(parts); 442 break; 443 case "br": 444 checkScreenBrightness(parts); 445 break; 446 case "sgt": 447 case "sgc": 448 checkSignalStrength(parts); 449 break; 450 case "sst": 451 checkSignalScanningTime(parts); 452 break; 453 case "dct": 454 case "dcc": 455 checkDataConnection(parts); 456 break; 457 case "wst": 458 case "wsc": 459 checkWifiState(parts); 460 break; 461 case "wsst": 462 case "wssc": 463 checkWifiSupplState(parts); 464 break; 465 case "wsgt": 466 case "wsgc": 467 checkWifiSignalStrength(parts); 468 break; 469 case "bst": 470 case "bsc": 471 checkBluetoothState(parts); 472 break; 473 case "pws": 474 checkPowerUseSummary(parts); 475 break; 476 case "pwi": 477 checkPowerUseItem(parts); 478 break; 479 case "dsd": 480 case "csd": 481 checkChargeDischargeStep(parts); 482 break; 483 case "dtr": 484 checkDischargeTimeRemain(parts); 485 break; 486 case "ctr": 487 checkChargeTimeRemain(parts); 488 break; 489 default: 490 break; 491 } 492 } 493 } 494 495 // spot check a few tags 496 assertSeenTag(seenTags, "vers"); 497 assertSeenTag(seenTags, "bt"); 498 assertSeenTag(seenTags, "dc"); 499 assertSeenTag(seenTags, "m"); 500 } 501 checkVersion(String[] parts)502 private void checkVersion(String[] parts) { 503 assertEquals(8, parts.length); 504 assertInteger(parts[4]); // checkinVersion 505 assertInteger(parts[5]); // parcelVersion 506 assertNotNull(parts[6]); // startPlatformVersion 507 assertNotNull(parts[7]); // endPlatformVersion 508 } 509 checkUid(String[] parts)510 private void checkUid(String[] parts) { 511 assertEquals(6, parts.length); 512 assertInteger(parts[4]); // uid 513 assertNotNull(parts[5]); // pkgName 514 } 515 checkApk(String[] parts)516 private void checkApk(String[] parts) { 517 assertEquals(10, parts.length); 518 assertInteger(parts[4]); // wakeups 519 assertNotNull(parts[5]); // apk 520 assertNotNull(parts[6]); // service 521 assertInteger(parts[7]); // startTime 522 assertInteger(parts[8]); // starts 523 assertInteger(parts[9]); // launches 524 } 525 checkProcess(String[] parts)526 private void checkProcess(String[] parts) { 527 assertTrue(parts.length >= 9); 528 assertNotNull(parts[4]); // process 529 assertInteger(parts[5]); // userMillis 530 assertInteger(parts[6]); // systemMillis 531 assertInteger(parts[7]); // foregroundMillis 532 assertInteger(parts[8]); // starts 533 } 534 checkSensor(String[] parts)535 private void checkSensor(String[] parts) { 536 assertEquals(7, parts.length); 537 assertInteger(parts[4]); // sensorNumber 538 assertInteger(parts[5]); // totalTime 539 assertInteger(parts[6]); // count 540 } 541 checkVibrator(String[] parts)542 private void checkVibrator(String[] parts) { 543 assertEquals(6, parts.length); 544 assertInteger(parts[4]); // totalTime 545 assertInteger(parts[5]); // count 546 } 547 checkForeground(String[] parts)548 private void checkForeground(String[] parts) { 549 assertEquals(6, parts.length); 550 assertInteger(parts[4]); // totalTime 551 assertInteger(parts[5]); // count 552 } 553 checkStateTime(String[] parts)554 private void checkStateTime(String[] parts) { 555 assertEquals(7, parts.length); 556 assertInteger(parts[4]); // foreground 557 assertInteger(parts[5]); // active 558 assertInteger(parts[6]); // running 559 } 560 checkWakelock(String[] parts)561 private void checkWakelock(String[] parts) { 562 assertEquals(14, parts.length); 563 assertNotNull(parts[4]); // wakelock 564 assertInteger(parts[5]); // full totalTime 565 assertEquals("f", parts[6]); // full 566 assertInteger(parts[7]); // full count 567 assertInteger(parts[8]); // partial totalTime 568 assertEquals("p", parts[9]); // partial 569 assertInteger(parts[10]); // partial count 570 assertInteger(parts[11]); // window totalTime 571 assertEquals("w", parts[12]); // window 572 assertInteger(parts[13]); // window count 573 } 574 checkSync(String[] parts)575 private void checkSync(String[] parts) { 576 assertEquals(7, parts.length); 577 assertNotNull(parts[4]); // sync 578 assertInteger(parts[5]); // totalTime 579 assertInteger(parts[6]); // count 580 } 581 checkJob(String[] parts)582 private void checkJob(String[] parts) { 583 assertEquals(7, parts.length); 584 assertNotNull(parts[4]); // job 585 assertInteger(parts[5]); // totalTime 586 assertInteger(parts[6]); // count 587 } 588 checkKernelWakelock(String[] parts)589 private void checkKernelWakelock(String[] parts) { 590 assertTrue(parts.length >= 7); 591 assertNotNull(parts[4]); // Kernel wakelock 592 assertInteger(parts[parts.length-2]); // totalTime 593 assertInteger(parts[parts.length-1]); // count 594 } 595 checkWakeupReason(String[] parts)596 private void checkWakeupReason(String[] parts) { 597 assertTrue(parts.length >= 7); 598 for (int i = 4; i < parts.length-2; i++) { 599 assertNotNull(parts[i]); // part of wakeup 600 } 601 assertInteger(parts[parts.length-2]); // totalTime 602 assertInteger(parts[parts.length-1]); // count 603 } 604 checkNetwork(String[] parts)605 private void checkNetwork(String[] parts) { 606 assertEquals(14, parts.length); 607 assertInteger(parts[4]); // mobileBytesRx 608 assertInteger(parts[5]); // mobileBytesTx 609 assertInteger(parts[6]); // wifiBytesRx 610 assertInteger(parts[7]); // wifiBytesTx 611 assertInteger(parts[8]); // mobilePacketsRx 612 assertInteger(parts[9]); // mobilePacketsTx 613 assertInteger(parts[10]); // wifiPacketsRx 614 assertInteger(parts[11]); // wifiPacketsTx 615 assertInteger(parts[12]); // mobileActiveTime (usec) 616 assertInteger(parts[13]); // mobileActiveCount 617 } 618 checkUserActivity(String[] parts)619 private void checkUserActivity(String[] parts) { 620 assertEquals(7, parts.length); 621 assertInteger(parts[4]); // other 622 assertInteger(parts[5]); // button 623 assertInteger(parts[6]); // touch 624 } 625 checkBattery(String[] parts)626 private void checkBattery(String[] parts) { 627 assertEquals(12, parts.length); 628 if (!parts[4].equals("N/A")) { 629 assertInteger(parts[4]); // startCount 630 } 631 assertInteger(parts[5]); // batteryRealtime 632 assertInteger(parts[6]); // batteryUptime 633 assertInteger(parts[7]); // totalRealtime 634 assertInteger(parts[8]); // totalUptime 635 assertInteger(parts[9]); // startClockTime 636 assertInteger(parts[10]); // batteryScreenOffRealtime 637 assertInteger(parts[11]); // batteryScreenOffUptime 638 } 639 checkBatteryDischarge(String[] parts)640 private void checkBatteryDischarge(String[] parts) { 641 assertEquals(8, parts.length); 642 assertInteger(parts[4]); // low 643 assertInteger(parts[5]); // high 644 assertInteger(parts[6]); // screenOn 645 assertInteger(parts[7]); // screenOff 646 } 647 checkBatteryLevel(String[] parts)648 private void checkBatteryLevel(String[] parts) { 649 assertEquals(6, parts.length); 650 assertInteger(parts[4]); // startLevel 651 assertInteger(parts[5]); // currentLevel 652 } 653 checkWifi(String[] parts)654 private void checkWifi(String[] parts) { 655 assertEquals(7, parts.length); 656 assertInteger(parts[4]); // fullWifiLockOnTime (usec) 657 assertInteger(parts[5]); // wifiScanTime (usec) 658 assertInteger(parts[6]); // uidWifiRunningTime (usec) 659 } 660 checkMisc(String[] parts)661 private void checkMisc(String[] parts) { 662 assertTrue(parts.length >= 19); 663 assertInteger(parts[4]); // screenOnTime 664 assertInteger(parts[5]); // phoneOnTime 665 assertInteger(parts[6]); // fullWakeLockTimeTotal 666 assertInteger(parts[7]); // partialWakeLockTimeTotal 667 assertInteger(parts[8]); // mobileRadioActiveTime 668 assertInteger(parts[9]); // mobileRadioActiveAdjustedTime 669 assertInteger(parts[10]); // interactiveTime 670 assertInteger(parts[11]); // lowPowerModeEnabledTime 671 assertInteger(parts[12]); // connChanges 672 assertInteger(parts[13]); // deviceIdleModeEnabledTime 673 assertInteger(parts[14]); // deviceIdleModeEnabledCount 674 assertInteger(parts[15]); // deviceIdlingTime 675 assertInteger(parts[16]); // deviceIdlingCount 676 assertInteger(parts[17]); // mobileRadioActiveCount 677 assertInteger(parts[18]); // mobileRadioActiveUnknownTime 678 } 679 checkGlobalNetwork(String[] parts)680 private void checkGlobalNetwork(String[] parts) { 681 assertEquals(12, parts.length); 682 assertInteger(parts[4]); // mobileRxTotalBytes 683 assertInteger(parts[5]); // mobileTxTotalBytes 684 assertInteger(parts[6]); // wifiRxTotalBytes 685 assertInteger(parts[7]); // wifiTxTotalBytes 686 assertInteger(parts[8]); // mobileRxTotalPackets 687 assertInteger(parts[9]); // mobileTxTotalPackets 688 assertInteger(parts[10]); // wifiRxTotalPackets 689 assertInteger(parts[11]); // wifiTxTotalPackets 690 } 691 checkScreenBrightness(String[] parts)692 private void checkScreenBrightness(String[] parts) { 693 assertEquals(9, parts.length); 694 assertInteger(parts[4]); // dark 695 assertInteger(parts[5]); // dim 696 assertInteger(parts[6]); // medium 697 assertInteger(parts[7]); // light 698 assertInteger(parts[8]); // bright 699 } 700 checkSignalStrength(String[] parts)701 private void checkSignalStrength(String[] parts) { 702 assertTrue(parts.length >= 9); 703 assertInteger(parts[4]); // none 704 assertInteger(parts[5]); // poor 705 assertInteger(parts[6]); // moderate 706 assertInteger(parts[7]); // good 707 assertInteger(parts[8]); // great 708 } 709 checkSignalScanningTime(String[] parts)710 private void checkSignalScanningTime(String[] parts) { 711 assertEquals(5, parts.length); 712 assertInteger(parts[4]); // signalScanningTime 713 } 714 checkDataConnection(String[] parts)715 private void checkDataConnection(String[] parts) { 716 assertEquals(21, parts.length); 717 assertInteger(parts[4]); // none 718 assertInteger(parts[5]); // gprs 719 assertInteger(parts[6]); // edge 720 assertInteger(parts[7]); // umts 721 assertInteger(parts[8]); // cdma 722 assertInteger(parts[9]); // evdo_0 723 assertInteger(parts[10]); // evdo_A 724 assertInteger(parts[11]); // 1xrtt 725 assertInteger(parts[12]); // hsdpa 726 assertInteger(parts[13]); // hsupa 727 assertInteger(parts[14]); // hspa 728 assertInteger(parts[15]); // iden 729 assertInteger(parts[16]); // evdo_b 730 assertInteger(parts[17]); // lte 731 assertInteger(parts[18]); // ehrpd 732 assertInteger(parts[19]); // hspap 733 assertInteger(parts[20]); // other 734 } 735 checkWifiState(String[] parts)736 private void checkWifiState(String[] parts) { 737 assertEquals(12, parts.length); 738 assertInteger(parts[4]); // off 739 assertInteger(parts[5]); // scanning 740 assertInteger(parts[6]); // no_net 741 assertInteger(parts[7]); // disconn 742 assertInteger(parts[8]); // sta 743 assertInteger(parts[9]); // p2p 744 assertInteger(parts[10]); // sta_p2p 745 assertInteger(parts[11]); // soft_ap 746 } 747 checkWifiSupplState(String[] parts)748 private void checkWifiSupplState(String[] parts) { 749 assertEquals(17, parts.length); 750 assertInteger(parts[4]); // inv 751 assertInteger(parts[5]); // dsc 752 assertInteger(parts[6]); // dis 753 assertInteger(parts[7]); // inact 754 assertInteger(parts[8]); // scan 755 assertInteger(parts[9]); // auth 756 assertInteger(parts[10]); // ascing 757 assertInteger(parts[11]); // asced 758 assertInteger(parts[12]); // 4-way 759 assertInteger(parts[13]); // group 760 assertInteger(parts[14]); // compl 761 assertInteger(parts[15]); // dorm 762 assertInteger(parts[16]); // uninit 763 } 764 checkWifiSignalStrength(String[] parts)765 private void checkWifiSignalStrength(String[] parts) { 766 assertEquals(9, parts.length); 767 assertInteger(parts[4]); // none 768 assertInteger(parts[5]); // poor 769 assertInteger(parts[6]); // moderate 770 assertInteger(parts[7]); // good 771 assertInteger(parts[8]); // great 772 } 773 checkBluetoothState(String[] parts)774 private void checkBluetoothState(String[] parts) { 775 assertEquals(8, parts.length); 776 assertInteger(parts[4]); // inactive 777 assertInteger(parts[5]); // low 778 assertInteger(parts[6]); // med 779 assertInteger(parts[7]); // high 780 } 781 checkPowerUseSummary(String[] parts)782 private void checkPowerUseSummary(String[] parts) { 783 assertEquals(8, parts.length); 784 assertDouble(parts[4]); // batteryCapacity 785 assertDouble(parts[5]); // computedPower 786 assertDouble(parts[6]); // minDrainedPower 787 assertDouble(parts[7]); // maxDrainedPower 788 } 789 checkPowerUseItem(String[] parts)790 private void checkPowerUseItem(String[] parts) { 791 assertEquals(6, parts.length); 792 assertNotNull(parts[4]); // label 793 assertDouble(parts[5]); // mAh 794 } 795 checkChargeDischargeStep(String[] parts)796 private void checkChargeDischargeStep(String[] parts) { 797 assertEquals(9, parts.length); 798 assertInteger(parts[4]); // duration 799 if (!parts[5].equals("?")) { 800 assertInteger(parts[5]); // level 801 } 802 assertNotNull(parts[6]); // screen 803 assertNotNull(parts[7]); // power-save 804 assertNotNull(parts[8]); // device-idle 805 } 806 checkDischargeTimeRemain(String[] parts)807 private void checkDischargeTimeRemain(String[] parts) { 808 assertEquals(5, parts.length); 809 assertInteger(parts[4]); // batteryTimeRemaining 810 } 811 checkChargeTimeRemain(String[] parts)812 private void checkChargeTimeRemain(String[] parts) { 813 assertEquals(5, parts.length); 814 assertInteger(parts[4]); // chargeTimeRemaining 815 } 816 817 /** 818 * Tests the output of "dumpsys gfxinfo framestats". 819 * 820 * @throws Exception 821 */ testGfxinfoFramestats()822 public void testGfxinfoFramestats() throws Exception { 823 final String MARKER = "---PROFILEDATA---"; 824 825 try { 826 // cleanup test apps that might be installed from previous partial test run 827 getDevice().uninstallPackage(TEST_PKG); 828 829 // install the test app 830 File testAppFile = mCtsBuild.getTestApp(TEST_APK); 831 String installResult = getDevice().installPackage(testAppFile, false); 832 assertNull( 833 String.format("failed to install atrace test app. Reason: %s", installResult), 834 installResult); 835 836 getDevice().executeShellCommand("am start -W " + TEST_PKG); 837 838 String frameinfo = mDevice.executeShellCommand("dumpsys gfxinfo " + 839 TEST_PKG + " framestats"); 840 assertNotNull(frameinfo); 841 assertTrue(frameinfo.length() > 0); 842 int profileStart = frameinfo.indexOf(MARKER); 843 int profileEnd = frameinfo.indexOf(MARKER, profileStart + 1); 844 assertTrue(profileStart >= 0); 845 assertTrue(profileEnd > profileStart); 846 String profileData = frameinfo.substring(profileStart + MARKER.length(), profileEnd); 847 assertTrue(profileData.length() > 0); 848 validateProfileData(profileData); 849 } finally { 850 getDevice().uninstallPackage(TEST_PKG); 851 } 852 } 853 validateProfileData(String profileData)854 private void validateProfileData(String profileData) throws IOException { 855 final int TIMESTAMP_COUNT = 14; 856 boolean foundAtLeastOneRow = false; 857 try (BufferedReader reader = new BufferedReader( 858 new StringReader(profileData))) { 859 String line; 860 // First line needs to be the headers 861 while ((line = reader.readLine()) != null && line.isEmpty()) {} 862 863 assertNotNull(line); 864 assertTrue("First line was not the expected header", 865 line.startsWith("Flags,IntendedVsync,Vsync,OldestInputEvent" + 866 ",NewestInputEvent,HandleInputStart,AnimationStart" + 867 ",PerformTraversalsStart,DrawStart,SyncQueued,SyncStart" + 868 ",IssueDrawCommandsStart,SwapBuffers,FrameCompleted")); 869 870 long[] numparts = new long[TIMESTAMP_COUNT]; 871 while ((line = reader.readLine()) != null && !line.isEmpty()) { 872 873 String[] parts = line.split(","); 874 assertTrue(parts.length >= TIMESTAMP_COUNT); 875 for (int i = 0; i < TIMESTAMP_COUNT; i++) { 876 numparts[i] = assertInteger(parts[i]); 877 } 878 if (numparts[0] != 0) { 879 continue; 880 } 881 // assert VSYNC >= INTENDED_VSYNC 882 assertTrue(numparts[2] >= numparts[1]); 883 // assert time is flowing forwards, skipping index 3 & 4 884 // as those are input timestamps that may or may not be present 885 assertTrue(numparts[5] >= numparts[2]); 886 for (int i = 6; i < TIMESTAMP_COUNT; i++) { 887 assertTrue("Index " + i + " did not flow forward, " + 888 numparts[i] + " not larger than " + numparts[i - 1], 889 numparts[i] >= numparts[i-1]); 890 } 891 long totalDuration = numparts[13] - numparts[1]; 892 assertTrue("Frame did not take a positive amount of time to process", 893 totalDuration > 0); 894 assertTrue("Bogus frame duration, exceeds 100 seconds", 895 totalDuration < 100000000000L); 896 foundAtLeastOneRow = true; 897 } 898 } 899 assertTrue(foundAtLeastOneRow); 900 } 901 902 private CtsBuildHelper mCtsBuild; 903 904 /** 905 * {@inheritDoc} 906 */ 907 @Override setBuild(IBuildInfo buildInfo)908 public void setBuild(IBuildInfo buildInfo) { 909 mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo); 910 } 911 assertInteger(String input)912 private static long assertInteger(String input) { 913 try { 914 return Long.parseLong(input); 915 } catch (NumberFormatException e) { 916 fail("Expected an integer but found \"" + input + "\""); 917 // Won't be hit, above throws AssertException 918 return -1; 919 } 920 } 921 assertDouble(String input)922 private static void assertDouble(String input) { 923 try { 924 Double.parseDouble(input); 925 } catch (NumberFormatException e) { 926 fail("Expected a double but found \"" + input + "\""); 927 } 928 } 929 assertSeenTag(Set<String> seenTags, String tag)930 private static void assertSeenTag(Set<String> seenTags, String tag) { 931 assertTrue("No line starting with \"" + tag + ",\"", seenTags.contains(tag)); 932 } 933 } 934