1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.dumpsys.cts;
18 
19 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
20 import com.android.tradefed.log.LogUtil.CLog;
21 
22 import java.io.BufferedReader;
23 import java.io.File;
24 import java.io.IOException;
25 import java.io.StringReader;
26 import java.util.HashSet;
27 import java.util.Set;
28 
29 /**
30  * Test to check the format of the dumps of the batterystats test.
31  */
32 public class BatteryStatsDumpsysTest extends BaseDumpsysTest {
33    private static final String TEST_APK = "CtsFramestatsTestApp.apk";
34     private static final String TEST_PKG = "com.android.cts.framestatstestapp";
35 
36     /**
37      * Tests the output of "dumpsys batterystats --checkin".
38      *
39      * @throws Exception
40      */
testBatterystatsOutput()41     public void testBatterystatsOutput() throws Exception {
42         String batterystats = mDevice.executeShellCommand("dumpsys batterystats --checkin");
43         assertNotNull(batterystats);
44         assertTrue(batterystats.length() > 0);
45 
46         Set<String> seenTags = new HashSet<>();
47 
48         try (BufferedReader reader = new BufferedReader(
49                 new StringReader(batterystats))) {
50 
51             String line;
52             while ((line = reader.readLine()) != null) {
53                 if (line.isEmpty()) {
54                     continue;
55                 }
56 
57 
58                 try {
59                     // With a default limit of 0, empty strings at the end are discarded.
60                     // We still consider the empty string as a valid value in some cases.
61                     // Using any negative number for the limit will preserve a trailing empty string.
62                     // @see String#split(String, int)
63                     String[] parts = line.split(",", -1);
64                     assertInteger(parts[0]); // old version
65                     assertInteger(parts[1]); // UID
66                     switch (parts[2]) { // aggregation type
67                         case "i":
68                         case "l":
69                         case "c":
70                         case "u":
71                             break;
72                         default:
73                             fail("malformed stat: " + parts[2]);
74                     }
75                     assertNotNull(parts[3]);
76                     seenTags.add(parts[3]);
77 
78                     // Note the time fields are measured in milliseconds by default.
79                     switch (parts[3]) {
80                         case "vers":
81                             checkVersion(parts);
82                             break;
83                         case "uid":
84                             checkUid(parts);
85                             break;
86                         case "apk":
87                             checkApk(parts);
88                             break;
89                         case "pr":
90                             checkProcess(parts);
91                             break;
92                         case "sr":
93                             checkSensor(parts);
94                             break;
95                         case "vib":
96                             checkVibrator(parts);
97                             break;
98                         case "fg":
99                             checkForegroundActivity(parts);
100                             break;
101                         case "fgs":
102                             checkForegroundService(parts);
103                             break;
104                         case "st":
105                             checkStateTime(parts);
106                             break;
107                         case "wl":
108                             checkWakelock(parts);
109                             break;
110                         case "awl":
111                             checkAggregatedWakelock(parts);
112                             break;
113                         case "sy":
114                             checkSync(parts);
115                             break;
116                         case "jb":
117                             checkJob(parts);
118                             break;
119                         case "jbc":
120                             checkJobCompletion(parts);
121                             break;
122                         case "jbd":
123                             checkJobsDeferred(parts);
124                             break;
125                         case "kwl":
126                             checkKernelWakelock(parts);
127                             break;
128                         case "wr":
129                             checkWakeupReason(parts);
130                             break;
131                         case "nt":
132                             checkNetwork(parts);
133                             break;
134                         case "ua":
135                             checkUserActivity(parts);
136                             break;
137                         case "bt":
138                             checkBattery(parts);
139                             break;
140                         case "dc":
141                             checkBatteryDischarge(parts);
142                             break;
143                         case "lv":
144                             checkBatteryLevel(parts);
145                             break;
146                         case "wfl":
147                             checkWifi(parts);
148                             break;
149                         case "m":
150                             checkMisc(parts);
151                             break;
152                         case "gn":
153                             checkGlobalNetwork(parts);
154                             break;
155                         case "br":
156                             checkScreenBrightness(parts);
157                             break;
158                         case "sgt":
159                         case "sgc":
160                             checkSignalStrength(parts);
161                             break;
162                         case "sst":
163                             checkSignalScanningTime(parts);
164                             break;
165                         case "dct":
166                         case "dcc":
167                             checkDataConnection(parts);
168                             break;
169                         case "wst":
170                         case "wsc":
171                             checkWifiState(parts);
172                             break;
173                         case "wsst":
174                         case "wssc":
175                             checkWifiSupplState(parts);
176                             break;
177                         case "wsgt":
178                         case "wsgc":
179                             checkWifiSignalStrength(parts);
180                             break;
181                         case "bst":
182                         case "bsc":
183                             checkBluetoothState(parts);
184                             break;
185                         case "blem":
186                             checkBluetoothMisc(parts);
187                             break;
188                         case "pws":
189                             checkPowerUseSummary(parts);
190                             break;
191                         case "pwi":
192                             checkPowerUseItem(parts);
193                             break;
194                         case "dsd":
195                         case "csd":
196                             checkChargeDischargeStep(parts);
197                             break;
198                         case "dtr":
199                             checkDischargeTimeRemain(parts);
200                             break;
201                         case "ctr":
202                             checkChargeTimeRemain(parts);
203                             break;
204                         case "cpu":
205                             checkUidCpuUsage(parts);
206                             break;
207                         default:
208                             break;
209                     }
210                 } catch (AssertionError e) {
211                     CLog.e("Assert fail for line <" + line + ">");
212                     throw e;
213                 }
214             }
215         }
216 
217         // spot check a few tags
218         assertSeenTag(seenTags, "vers");
219         assertSeenTag(seenTags, "bt");
220         assertSeenTag(seenTags, "dc");
221         assertSeenTag(seenTags, "m");
222     }
223 
checkVersion(String[] parts)224     private void checkVersion(String[] parts) {
225         assertEquals(8, parts.length);
226         assertInteger(parts[4]); // checkinVersion
227         assertInteger(parts[5]); // parcelVersion
228         assertNotNull(parts[6]); // startPlatformVersion
229         assertNotNull(parts[7]); // endPlatformVersion
230     }
231 
checkUid(String[] parts)232     private void checkUid(String[] parts) {
233         assertEquals(6, parts.length);
234         assertInteger(parts[4]); // uid
235         assertNotNull(parts[5]); // pkgName
236     }
237 
checkApk(String[] parts)238     private void checkApk(String[] parts) {
239         assertEquals(10, parts.length);
240         long wakeup_count = assertInteger(parts[4]); // wakeups
241         assertNotNull(parts[5]); // apk
242         assertNotNull(parts[6]); // service
243         assertInteger(parts[7]); // startTime
244         assertInteger(parts[8]); // starts
245         assertInteger(parts[9]); // launches
246 
247         // Validation check.
248         assertTrue("wakeup count must be >= 0", wakeup_count >= 0);
249     }
250 
checkProcess(String[] parts)251     private void checkProcess(String[] parts) {
252         assertTrue(parts.length >= 9);
253         assertNotNull(parts[4]); // process
254         assertInteger(parts[5]); // userMillis
255         assertInteger(parts[6]); // systemMillis
256         assertInteger(parts[7]); // foregroundMillis
257         assertInteger(parts[8]); // starts
258     }
259 
checkSensor(String[] parts)260     private void checkSensor(String[] parts) {
261         assertEquals(10, parts.length);
262         assertInteger(parts[4]); // sensorNumber
263         assertInteger(parts[5]); // totalTime
264         assertInteger(parts[6]); // count
265         assertInteger(parts[7]); // backgroundCount
266         assertInteger(parts[8]); // actualTime
267         assertInteger(parts[9]); // backgroundActualTime
268     }
269 
checkVibrator(String[] parts)270     private void checkVibrator(String[] parts) {
271         assertEquals(6, parts.length);
272         assertInteger(parts[4]); // totalTime
273         assertInteger(parts[5]); // count
274     }
275 
checkForegroundActivity(String[] parts)276     private void checkForegroundActivity(String[] parts) {
277         assertEquals(6, parts.length);
278         assertInteger(parts[4]); // totalTime
279         assertInteger(parts[5]); // count
280     }
281 
checkForegroundService(String[] parts)282     private void checkForegroundService(String[] parts) {
283         assertEquals(6, parts.length);
284         assertInteger(parts[4]); // totalTime
285         assertInteger(parts[5]); // count
286     }
287 
checkStateTime(String[] parts)288     private void checkStateTime(String[] parts) {
289         assertEquals(11, parts.length);
290         assertInteger(parts[4]);  // top
291         assertInteger(parts[5]);  // foreground_service
292         assertInteger(parts[6]);  // foreground
293         assertInteger(parts[7]);  // background
294         assertInteger(parts[8]);  // top_sleeping
295         assertInteger(parts[9]);  // heavy_weight
296         assertInteger(parts[10]); // cached
297     }
298 
checkWakelock(String[] parts)299     private void checkWakelock(String[] parts) {
300         assertEquals(29, parts.length);
301         assertNotNull(parts[4]);      // wakelock
302 
303         assertInteger(parts[5]);      // full totalTime
304         assertEquals("f", parts[6]);  // full
305         long full_count = assertInteger(parts[7]);      // full count
306         assertInteger(parts[8]);      // current duration
307         assertInteger(parts[9]);      // max duration
308         assertInteger(parts[10]);     // total duration
309 
310         assertInteger(parts[11]);      // partial totalTime
311         assertEquals("p", parts[12]);  // partial
312         long partial_count = assertInteger(parts[13]);     // partial count
313         assertInteger(parts[14]);      // current duration
314         assertInteger(parts[15]);      // max duration
315         assertInteger(parts[16]);      // total duration
316 
317         assertInteger(parts[17]);      // background partial totalTime
318         assertEquals("bp", parts[18]); // background partial
319         long bg_partial_count = assertInteger(parts[19]);     // background partial count
320         assertInteger(parts[20]);      // current duration
321         assertInteger(parts[21]);      // max duration
322         assertInteger(parts[22]);      // total duration
323 
324         assertInteger(parts[23]);      // window totalTime
325         assertEquals("w", parts[24]);  // window
326         long window_count = assertInteger(parts[25]);     // window count
327         assertInteger(parts[26]);      // current duration
328         assertInteger(parts[27]);      // max duration
329         assertInteger(parts[28]);      // total duration
330 
331         // Validation checks.
332         assertTrue("full wakelock count must be >= 0", full_count >= 0);
333         assertTrue("partial wakelock count must be >= 0", partial_count >= 0);
334         assertTrue("background partial wakelock count must be >= 0", bg_partial_count >= 0);
335         assertTrue("window wakelock count must be >= 0", window_count >= 0);
336     }
337 
checkAggregatedWakelock(String[] parts)338     private void checkAggregatedWakelock(String[] parts) {
339         assertEquals(6, parts.length);
340         assertInteger(parts[4]); // total time
341         assertInteger(parts[5]); // background time
342     }
343 
checkSync(String[] parts)344     private void checkSync(String[] parts) {
345         assertEquals(9, parts.length);
346         assertNotNull(parts[4]); // sync
347         assertInteger(parts[5]); // totalTime
348         assertInteger(parts[6]); // count
349         assertInteger(parts[7]); // bgTime
350         assertInteger(parts[8]); // bgCount
351     }
352 
checkJob(String[] parts)353     private void checkJob(String[] parts) {
354         assertEquals(9, parts.length);
355         assertNotNull(parts[4]); // job
356         assertInteger(parts[5]); // totalTime
357         assertInteger(parts[6]); // count
358         assertInteger(parts[7]); // bgTime
359         assertInteger(parts[8]); // bgCount
360     }
361 
checkJobCompletion(String[] parts)362     private void checkJobCompletion(String[] parts) {
363         assertEquals(10, parts.length);
364         assertNotNull(parts[4]); // job
365         assertInteger(parts[5]); // reason_canceled
366         assertInteger(parts[6]); // reason_constraints_not_satisfied
367         assertInteger(parts[7]); // reason_preempt
368         assertInteger(parts[8]); // reason_timeout
369         assertInteger(parts[9]); // reason_device_idle
370     }
371 
checkJobsDeferred(String[] parts)372     private void checkJobsDeferred(String[] parts) {
373         assertEquals(12, parts.length);
374         assertInteger(parts[4]); // jobsDeferredEventCount
375         assertInteger(parts[5]); // jobsDeferredCount
376         assertInteger(parts[6]); // totalLatencyMillis
377         assertInteger(parts[7]); // count at latency < 1 hr
378         assertInteger(parts[8]); // count at latency 1-2 hrs
379         assertInteger(parts[9]); // count at latency 2-4 hrs
380         assertInteger(parts[10]); // count at latency 4-8 hrs
381         assertInteger(parts[11]); // count at latency 8+ hrs
382     }
383 
checkKernelWakelock(String[] parts)384     private void checkKernelWakelock(String[] parts) {
385         assertTrue(parts.length >= 7);
386 	assertNotNull(parts[4]); // Kernel wakelock
387 	assertInteger(parts[parts.length-2]); // totalTime
388         assertInteger(parts[parts.length-1]); // count
389     }
390 
checkWakeupReason(String[] parts)391     private void checkWakeupReason(String[] parts) {
392         assertTrue(parts.length >= 7);
393         for (int i = 4; i < parts.length-2; i++) {
394             assertNotNull(parts[i]); // part of wakeup
395         }
396         assertInteger(parts[parts.length-2]); // totalTime
397         assertInteger(parts[parts.length-1]); // count
398     }
399 
checkNetwork(String[] parts)400     private void checkNetwork(String[] parts) {
401         assertEquals(26, parts.length);
402         long mbRx = assertInteger(parts[4]);  // mobileBytesRx
403         long mbTx = assertInteger(parts[5]);  // mobileBytesTx
404         long wbRx = assertInteger(parts[6]);  // wifiBytesRx
405         long wbTx = assertInteger(parts[7]);  // wifiBytesTx
406         long mpRx = assertInteger(parts[8]);  // mobilePacketsRx
407         long mpTx = assertInteger(parts[9]);  // mobilePacketsTx
408         long wpRx = assertInteger(parts[10]); // wifiPacketsRx
409         long wpTx = assertInteger(parts[11]); // wifiPacketsTx
410         assertInteger(parts[12]); // mobileActiveTime (usec)
411         assertInteger(parts[13]); // mobileActiveCount
412         assertInteger(parts[14]); // btBytesRx
413         assertInteger(parts[15]); // btBytesTx
414         assertInteger(parts[16]); // mobileWakeup
415         assertInteger(parts[17]); // wifiWakeup
416         long mbBgRx = assertInteger(parts[18]);  // mobileBytesRx
417         long mbBgTx = assertInteger(parts[19]);  // mobileBytesTx
418         long wbBgRx = assertInteger(parts[20]);  // wifiBytesRx
419         long wbBgTx = assertInteger(parts[21]);  // wifiBytesTx
420         long mpBgRx = assertInteger(parts[22]);  // mobilePacketsRx
421         long mpBgTx = assertInteger(parts[23]);  // mobilePacketsTx
422         long wpBgRx = assertInteger(parts[24]); // wifiPacketsRx
423         long wpBgTx = assertInteger(parts[25]); // wifiPacketsTx
424 
425         // Assuming each packet contains some bytes, bytes >= packets >= 0.
426         assertTrue("mobileBytesRx must be >= mobilePacketsRx", mbRx >= mpRx);
427         assertTrue("mobilePacketsRx must be >= 0", mpRx >= 0);
428         assertTrue("mobileBytesTx must be >= mobilePacketsTx", mbTx >= mpTx);
429         assertTrue("mobilePacketsTx must be >= 0", mpTx >= 0);
430         assertTrue("wifiBytesRx must be >= wifiPacketsRx", wbRx >= wpRx);
431         assertTrue("wifiPacketsRx must be >= 0", wpRx >= 0);
432         assertTrue("wifiBytesTx must be >= wifiPacketsTx", wbTx >= wpTx);
433         assertTrue("wifiPacketsTx must be >= 0", wpTx >= 0);
434         // Totals should be greater than or equal to background data numbers
435         assertTrue("mobileBytesRx must be >= mobileBytesBgRx", mbRx >= mbBgRx);
436         assertTrue("mobilePacketsRx must be >= mobilePacketsBgRx", mpRx >= mpBgRx);
437         assertTrue("mobileBytesTx must be >= mobileBytesBgTx", mbTx >= mbBgTx);
438         assertTrue("mobilePacketsTx must be >= mobilePacketsBgTx", mpTx >= mpBgTx);
439         assertTrue("wifiBytesRx must be >= wifiBytesBgRx", wbRx >= wbBgRx);
440         assertTrue("wifiPacketsRx must be >= wifiPacketsBgRx", wpRx >= wpBgRx);
441         assertTrue("wifiBytesTx must be >= wifiBytesBgTx", wbTx >= wbBgTx);
442         assertTrue("wifiPacketsTx must be >= wifiPacketsBgTx", wpTx >= wpBgTx);
443     }
444 
checkUserActivity(String[] parts)445     private void checkUserActivity(String[] parts) {
446         assertEquals(9, parts.length);
447         assertInteger(parts[4]); // other
448         assertInteger(parts[5]); // button
449         assertInteger(parts[6]); // touch
450         assertInteger(parts[7]); // accessibility
451         assertInteger(parts[8]); // attention
452     }
453 
checkBattery(String[] parts)454     private void checkBattery(String[] parts) {
455         assertEquals(16, parts.length);
456         if (!parts[4].equals("N/A")) {
457             assertInteger(parts[4]);  // startCount
458         }
459         long bReal = assertInteger(parts[5]);  // batteryRealtime
460         long bUp = assertInteger(parts[6]);  // batteryUptime
461         long tReal = assertInteger(parts[7]);  // totalRealtime
462         long tUp = assertInteger(parts[8]);  // totalUptime
463         assertInteger(parts[9]);  // startClockTime
464         long bOffReal = assertInteger(parts[10]); // batteryScreenOffRealtime
465         long bOffUp = assertInteger(parts[11]); // batteryScreenOffUptime
466         long bEstCap = assertInteger(parts[12]); // batteryEstimatedCapacity
467         assertInteger(parts[13]); // minLearnedBatteryCapacity
468         assertInteger(parts[14]); // maxLearnedBatteryCapacity
469         long bDoze = assertInteger(parts[15]); // screenDozeTime
470 
471         // The device cannot be up more than there are real-world seconds.
472         assertTrue("batteryRealtime must be >= batteryUptime", bReal >= bUp);
473         assertTrue("totalRealtime must be >= totalUptime", tReal >= tUp);
474         assertTrue("batteryScreenOffRealtime must be >= batteryScreenOffUptime",
475                 bOffReal >= bOffUp);
476 
477         // total >= battery >= battery screen-off >= 0
478         assertTrue("totalRealtime must be >= batteryRealtime", tReal >= bReal);
479         assertTrue("batteryRealtime must be >= batteryScreenOffRealtime", bReal >= bOffReal);
480         assertTrue("batteryScreenOffRealtime must be >= 0", bOffReal >= 0);
481         assertTrue("totalUptime must be >= batteryUptime", tUp >= bUp);
482         assertTrue("batteryUptime must be >= batteryScreenOffUptime", bUp >= bOffUp);
483         assertTrue("batteryScreenOffUptime must be >= 0", bOffUp >= 0);
484         assertTrue("batteryEstimatedCapacity must be >= 0", bEstCap >= 0);
485         assertTrue("screenDozeTime must be >= 0", bDoze >= 0);
486         assertTrue("screenDozeTime must be <= batteryScreenOffRealtime", bDoze <= bOffReal);
487     }
488 
checkBatteryDischarge(String[] parts)489     private void checkBatteryDischarge(String[] parts) {
490         assertEquals(14, parts.length);
491         assertInteger(parts[4]); // low
492         assertInteger(parts[5]); // high
493         assertInteger(parts[6]); // screenOn
494         assertInteger(parts[7]); // screenOff
495         assertInteger(parts[8]); // dischargeMah
496         assertInteger(parts[9]); // dischargeScreenOffMah
497         assertInteger(parts[10]); // dischargeDozeCount
498         assertInteger(parts[11]); // dischargeDozeMah
499         assertInteger(parts[12]); // dischargeLightDozeMah
500         assertInteger(parts[13]); // dischargeDeepDozeMah
501     }
502 
checkBatteryLevel(String[] parts)503     private void checkBatteryLevel(String[] parts) {
504         assertEquals(6, parts.length);
505         assertInteger(parts[4]); // startLevel
506         assertInteger(parts[5]); // currentLevel
507     }
508 
checkWifi(String[] parts)509     private void checkWifi(String[] parts) {
510         assertEquals(14, parts.length);
511         assertInteger(parts[4]); // fullWifiLockOnTime (usec)
512         assertInteger(parts[5]); // wifiScanTime (usec)
513         assertInteger(parts[6]); // uidWifiRunningTime (usec)
514         assertInteger(parts[7]); // wifiScanCount
515         // Fields for parts[8 and 9 and 10] are deprecated.
516         assertInteger(parts[11]); // wifiScanCountBg
517         assertInteger(parts[12]); // wifiScanActualTimeMs (msec)
518         assertInteger(parts[13]); // wifiScanActualTimeMsBg (msec)
519     }
520 
checkMisc(String[] parts)521     private void checkMisc(String[] parts) {
522         assertTrue(parts.length >= 19);
523         assertInteger(parts[4]);      // screenOnTime
524         assertInteger(parts[5]);      // phoneOnTime
525         assertInteger(parts[6]);      // fullWakeLockTimeTotal
526         assertInteger(parts[7]);      // partialWakeLockTimeTotal
527         assertInteger(parts[8]);      // mobileRadioActiveTime
528         assertInteger(parts[9]);      // mobileRadioActiveAdjustedTime
529         assertInteger(parts[10]);     // interactiveTime
530         assertInteger(parts[11]);     // lowPowerModeEnabledTime
531         assertInteger(parts[12]);     // connChanges
532         assertInteger(parts[13]);     // deviceIdleModeEnabledTime
533         assertInteger(parts[14]);     // deviceIdleModeEnabledCount
534         assertInteger(parts[15]);     // deviceIdlingTime
535         assertInteger(parts[16]);     // deviceIdlingCount
536         assertInteger(parts[17]);     // mobileRadioActiveCount
537         assertInteger(parts[18]);     // mobileRadioActiveUnknownTime
538     }
539 
checkGlobalNetwork(String[] parts)540     private void checkGlobalNetwork(String[] parts) {
541         assertEquals(14, parts.length);
542         assertInteger(parts[4]);  // mobileRxTotalBytes
543         assertInteger(parts[5]);  // mobileTxTotalBytes
544         assertInteger(parts[6]);  // wifiRxTotalBytes
545         assertInteger(parts[7]);  // wifiTxTotalBytes
546         assertInteger(parts[8]);  // mobileRxTotalPackets
547         assertInteger(parts[9]);  // mobileTxTotalPackets
548         assertInteger(parts[10]); // wifiRxTotalPackets
549         assertInteger(parts[11]); // wifiTxTotalPackets
550         assertInteger(parts[12]); // btRxTotalBytes
551         assertInteger(parts[13]); // btTxTotalBytes
552     }
553 
checkScreenBrightness(String[] parts)554     private void checkScreenBrightness(String[] parts) {
555         assertEquals(9, parts.length);
556         assertInteger(parts[4]); // dark
557         assertInteger(parts[5]); // dim
558         assertInteger(parts[6]); // medium
559         assertInteger(parts[7]); // light
560         assertInteger(parts[8]); // bright
561     }
562 
checkSignalStrength(String[] parts)563     private void checkSignalStrength(String[] parts) {
564         assertTrue(parts.length >= 9);
565         assertInteger(parts[4]); // none
566         assertInteger(parts[5]); // poor
567         assertInteger(parts[6]); // moderate
568         assertInteger(parts[7]); // good
569         assertInteger(parts[8]); // great
570     }
571 
checkSignalScanningTime(String[] parts)572     private void checkSignalScanningTime(String[] parts) {
573         assertEquals(5, parts.length);
574         assertInteger(parts[4]); // signalScanningTime
575     }
576 
checkDataConnection(String[] parts)577     private void checkDataConnection(String[] parts) {
578         assertEquals(27, parts.length);
579         assertInteger(parts[4]);  // oos
580         assertInteger(parts[5]);  // gprs
581         assertInteger(parts[6]);  // edge
582         assertInteger(parts[7]);  // umts
583         assertInteger(parts[8]);  // cdma
584         assertInteger(parts[9]);  // evdo_0
585         assertInteger(parts[10]); // evdo_A
586         assertInteger(parts[11]); // 1xrtt
587         assertInteger(parts[12]); // hsdpa
588         assertInteger(parts[13]); // hsupa
589         assertInteger(parts[14]); // hspa
590         assertInteger(parts[15]); // iden
591         assertInteger(parts[16]); // evdo_b
592         assertInteger(parts[17]); // lte
593         assertInteger(parts[18]); // ehrpd
594         assertInteger(parts[19]); // hspap
595         assertInteger(parts[20]); // gsm
596         assertInteger(parts[21]); // td_scdma
597         assertInteger(parts[22]); // iwlan
598         assertInteger(parts[23]); // lte_ca
599         assertInteger(parts[24]); // nr
600         assertInteger(parts[25]); // emngcy
601         assertInteger(parts[26]); // other
602     }
603 
checkWifiState(String[] parts)604     private void checkWifiState(String[] parts) {
605         assertEquals(12, parts.length);
606         assertInteger(parts[4]);  // off
607         assertInteger(parts[5]);  // scanning
608         assertInteger(parts[6]);  // no_net
609         assertInteger(parts[7]);  // disconn
610         assertInteger(parts[8]);  // sta
611         assertInteger(parts[9]);  // p2p
612         assertInteger(parts[10]); // sta_p2p
613         assertInteger(parts[11]); // soft_ap
614     }
615 
checkWifiSupplState(String[] parts)616     private void checkWifiSupplState(String[] parts) {
617         assertEquals(17, parts.length);
618         assertInteger(parts[4]);  // inv
619         assertInteger(parts[5]);  // dsc
620         assertInteger(parts[6]);  // dis
621         assertInteger(parts[7]);  // inact
622         assertInteger(parts[8]);  // scan
623         assertInteger(parts[9]);  // auth
624         assertInteger(parts[10]); // ascing
625         assertInteger(parts[11]); // asced
626         assertInteger(parts[12]); // 4-way
627         assertInteger(parts[13]); // group
628         assertInteger(parts[14]); // compl
629         assertInteger(parts[15]); // dorm
630         assertInteger(parts[16]); // uninit
631     }
632 
checkWifiSignalStrength(String[] parts)633     private void checkWifiSignalStrength(String[] parts) {
634         assertEquals(9, parts.length);
635         assertInteger(parts[4]); // none
636         assertInteger(parts[5]); // poor
637         assertInteger(parts[6]); // moderate
638         assertInteger(parts[7]); // good
639         assertInteger(parts[8]); // great
640     }
641 
checkBluetoothState(String[] parts)642     private void checkBluetoothState(String[] parts) {
643         assertEquals(8, parts.length);
644         assertInteger(parts[4]); // inactive
645         assertInteger(parts[5]); // low
646         assertInteger(parts[6]); // med
647         assertInteger(parts[7]); // high
648     }
649 
checkPowerUseSummary(String[] parts)650     private void checkPowerUseSummary(String[] parts) {
651         assertEquals(8, parts.length);
652         assertDouble(parts[4]); // batteryCapacity
653         assertDouble(parts[5]); // computedPower
654         assertDouble(parts[6]); // minDrainedPower
655         assertDouble(parts[7]); // maxDrainedPower
656     }
657 
checkPowerUseItem(String[] parts)658     private void checkPowerUseItem(String[] parts) {
659         assertEquals(9, parts.length);
660         assertNotNull(parts[4]); // label
661         final double totalPowerMah = assertDouble(parts[5]);  // totalPowerMah
662         final long shouldHide = assertInteger(parts[6]);  // shouldHide (0 or 1)
663         final double screenPowerMah = assertDouble(parts[7]);  // screenPowerMah
664         final double proportionalSmearMah = assertDouble(parts[8]);  // proportionalSmearMah
665 
666         assertTrue("powerUseItem totalPowerMah must be >= 0", totalPowerMah >= 0);
667         assertTrue("powerUseItem screenPowerMah must be >= 0", screenPowerMah >= 0);
668         assertTrue("powerUseItem proportionalSmearMah must be >= 0", proportionalSmearMah >= 0);
669         assertTrue("powerUseItem shouldHide must be 0 or 1", shouldHide == 0 || shouldHide == 1);
670 
671         // Largest current Android battery is ~5K. 100K shouldn't get made for a while.
672         assertTrue("powerUseItem totalPowerMah is expected to be <= 100000", totalPowerMah <= 100000);
673     }
674 
checkChargeDischargeStep(String[] parts)675     private void checkChargeDischargeStep(String[] parts) {
676         assertEquals(9, parts.length);
677         assertInteger(parts[4]); // duration
678         if (!parts[5].equals("?")) {
679             assertInteger(parts[5]); // level
680         }
681         assertNotNull(parts[6]); // screen
682         assertNotNull(parts[7]); // power-save
683         assertNotNull(parts[8]); // device-idle
684     }
685 
checkDischargeTimeRemain(String[] parts)686     private void checkDischargeTimeRemain(String[] parts) {
687         assertEquals(5, parts.length);
688         assertInteger(parts[4]); // batteryTimeRemaining
689     }
690 
checkChargeTimeRemain(String[] parts)691     private void checkChargeTimeRemain(String[] parts) {
692         assertEquals(5, parts.length);
693         assertInteger(parts[4]); // chargeTimeRemaining
694     }
695 
checkUidCpuUsage(String[] parts)696     private void checkUidCpuUsage(String[] parts) {
697         assertTrue(parts.length >= 6);
698         assertInteger(parts[4]); // user time
699         assertInteger(parts[5]); // system time
700     }
701 
checkBluetoothMisc(String[] parts)702     private void checkBluetoothMisc(String[] parts) {
703         assertEquals(15, parts.length);
704         assertInteger(parts[4]); // totalTime
705         assertInteger(parts[5]); // count
706         assertInteger(parts[6]); // countBg
707         assertInteger(parts[7]); // actualTime
708         assertInteger(parts[8]); // actualTimeBg
709         assertInteger(parts[9]); // resultsCount
710         assertInteger(parts[10]); // resultsCountBg
711         assertInteger(parts[11]); // unoptimizedScanTotalTime
712         assertInteger(parts[12]); // unoptimizedScanTotalTimeBg
713         assertInteger(parts[13]); // unoptimizedScanMaxTime
714         assertInteger(parts[14]); // unoptimizedScanMaxTimeBg
715     }
716 
717     /**
718      * Tests the output of "dumpsys gfxinfo framestats".
719      *
720      * @throws Exception
721      */
testGfxinfoFramestats()722     public void testGfxinfoFramestats() throws Exception {
723         final String MARKER = "---PROFILEDATA---";
724 
725         try {
726             // cleanup test apps that might be installed from previous partial test run
727             getDevice().uninstallPackage(TEST_PKG);
728 
729             // install the test app
730             CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
731             File testAppFile = buildHelper.getTestFile(TEST_APK);
732             String installResult = getDevice().installPackage(testAppFile, false);
733             assertNull(
734                     String.format("failed to install atrace test app. Reason: %s", installResult),
735                     installResult);
736 
737             getDevice().executeShellCommand("am start -W " + TEST_PKG);
738 
739             String frameinfo = mDevice.executeShellCommand("dumpsys gfxinfo " +
740                     TEST_PKG + " framestats");
741             assertNotNull(frameinfo);
742             assertTrue(frameinfo.length() > 0);
743             int profileStart = frameinfo.indexOf(MARKER);
744             int profileEnd = frameinfo.indexOf(MARKER, profileStart + 1);
745             assertTrue(profileStart >= 0);
746             assertTrue(profileEnd > profileStart);
747             String profileData = frameinfo.substring(profileStart + MARKER.length(), profileEnd);
748             assertTrue(profileData.length() > 0);
749             validateProfileData(profileData);
750         } finally {
751             getDevice().uninstallPackage(TEST_PKG);
752         }
753     }
754 
validateProfileData(String profileData)755     private void validateProfileData(String profileData) throws IOException {
756         final int TIMESTAMP_COUNT = 14;
757         boolean foundAtLeastOneRow = false;
758         try (BufferedReader reader = new BufferedReader(
759                 new StringReader(profileData))) {
760             String line;
761             // First line needs to be the headers
762             while ((line = reader.readLine()) != null && line.isEmpty()) {}
763 
764             assertNotNull(line);
765             assertTrue("First line was not the expected header",
766                     line.startsWith("Flags,IntendedVsync,Vsync,OldestInputEvent" +
767                             ",NewestInputEvent,HandleInputStart,AnimationStart" +
768                             ",PerformTraversalsStart,DrawStart,SyncQueued,SyncStart" +
769                             ",IssueDrawCommandsStart,SwapBuffers,FrameCompleted"));
770 
771             long[] numparts = new long[TIMESTAMP_COUNT];
772             while ((line = reader.readLine()) != null && !line.isEmpty()) {
773 
774                 String[] parts = line.split(",");
775                 assertTrue(parts.length >= TIMESTAMP_COUNT);
776                 for (int i = 0; i < TIMESTAMP_COUNT; i++) {
777                     numparts[i] = assertInteger(parts[i]);
778                 }
779                 // Flags = 1 just means the first frame of the window
780                 if (numparts[0] != 0 && numparts[0] != 1) {
781                     continue;
782                 }
783                 // assert VSYNC >= INTENDED_VSYNC
784                 assertTrue(numparts[2] >= numparts[1]);
785                 // assert time is flowing forwards, skipping index 3 & 4
786                 // as those are input timestamps that may or may not be present
787                 assertTrue(numparts[5] >= numparts[2]);
788                 for (int i = 6; i < TIMESTAMP_COUNT; i++) {
789                     assertTrue("Index " + i + " did not flow forward, " +
790                             numparts[i] + " not larger than " + numparts[i - 1],
791                             numparts[i] >= numparts[i-1]);
792                 }
793                 long totalDuration = numparts[13] - numparts[1];
794                 assertTrue("Frame did not take a positive amount of time to process",
795                         totalDuration > 0);
796                 assertTrue("Bogus frame duration, exceeds 100 seconds",
797                         totalDuration < 100000000000L);
798                 foundAtLeastOneRow = true;
799             }
800         }
801         assertTrue(foundAtLeastOneRow);
802     }
803 }
804