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