Home | History | Annotate | Download | only in cts
      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
     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      */
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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      */
    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 
    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 
    510     private void checkUid(String[] parts) {
    511         assertEquals(6, parts.length);
    512         assertInteger(parts[4]); // uid
    513         assertNotNull(parts[5]); // pkgName
    514     }
    515 
    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 
    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 
    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 
    542     private void checkVibrator(String[] parts) {
    543         assertEquals(6, parts.length);
    544         assertInteger(parts[4]); // totalTime
    545         assertInteger(parts[5]); // count
    546     }
    547 
    548     private void checkForeground(String[] parts) {
    549         assertEquals(6, parts.length);
    550         assertInteger(parts[4]); // totalTime
    551         assertInteger(parts[5]); // count
    552     }
    553 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    648     private void checkBatteryLevel(String[] parts) {
    649         assertEquals(6, parts.length);
    650         assertInteger(parts[4]); // startLevel
    651         assertInteger(parts[5]); // currentLevel
    652     }
    653 
    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 
    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 
    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 
    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 
    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 
    710     private void checkSignalScanningTime(String[] parts) {
    711         assertEquals(5, parts.length);
    712         assertInteger(parts[4]); // signalScanningTime
    713     }
    714 
    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 
    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 
    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 
    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 
    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 
    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 
    790     private void checkPowerUseItem(String[] parts) {
    791         assertEquals(6, parts.length);
    792         assertNotNull(parts[4]); // label
    793         assertDouble(parts[5]);  // mAh
    794     }
    795 
    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 
    807     private void checkDischargeTimeRemain(String[] parts) {
    808         assertEquals(5, parts.length);
    809         assertInteger(parts[4]); // batteryTimeRemaining
    810     }
    811 
    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      */
    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 
    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
    908     public void setBuild(IBuildInfo buildInfo) {
    909         mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo);
    910     }
    911 
    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 
    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 
    930     private static void assertSeenTag(Set<String> seenTags, String tag) {
    931         assertTrue("No line starting with \"" + tag + ",\"", seenTags.contains(tag));
    932     }
    933 }
    934