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.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
     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      */
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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      */
    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 
    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 
    517     private void checkUid(String[] parts) {
    518         assertEquals(6, parts.length);
    519         assertInteger(parts[4]); // uid
    520         assertNotNull(parts[5]); // pkgName
    521     }
    522 
    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 
    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 
    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 
    552     private void checkVibrator(String[] parts) {
    553         assertEquals(6, parts.length);
    554         assertInteger(parts[4]); // totalTime
    555         assertInteger(parts[5]); // count
    556     }
    557 
    558     private void checkForeground(String[] parts) {
    559         assertEquals(6, parts.length);
    560         assertInteger(parts[4]); // totalTime
    561         assertInteger(parts[5]); // count
    562     }
    563 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    687     private void checkBatteryLevel(String[] parts) {
    688         assertEquals(6, parts.length);
    689         assertInteger(parts[4]); // startLevel
    690         assertInteger(parts[5]); // currentLevel
    691     }
    692 
    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 
    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 
    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 
    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 
    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 
    749     private void checkSignalScanningTime(String[] parts) {
    750         assertEquals(5, parts.length);
    751         assertInteger(parts[4]); // signalScanningTime
    752     }
    753 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    850     private void checkDischargeTimeRemain(String[] parts) {
    851         assertEquals(5, parts.length);
    852         assertInteger(parts[4]); // batteryTimeRemaining
    853     }
    854 
    855     private void checkChargeTimeRemain(String[] parts) {
    856         assertEquals(5, parts.length);
    857         assertInteger(parts[4]); // chargeTimeRemaining
    858     }
    859 
    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      */
    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 
    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
    957     public void setBuild(IBuildInfo buildInfo) {
    958         mCtsBuild = buildInfo;
    959     }
    960 
    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 
    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 
    980     private static void assertSeenTag(Set<String> seenTags, String tag) {
    981         assertTrue("No line starting with \"" + tag + ",\"", seenTags.contains(tag));
    982     }
    983 }
    984