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