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 com.android.server.cts;
18 
19 import android.os.BatteryStatsProto;
20 import android.os.ControllerActivityProto;
21 import android.os.SystemProto;
22 import android.os.TimerProto;
23 import android.os.UidProto;
24 import android.service.batterystats.BatteryStatsServiceDumpProto;
25 import android.telephony.NetworkTypeEnum;
26 
27 /**
28  * Test to BatteryStats proto dump.
29  */
30 public class BatteryStatsIncidentTest extends ProtoDumpTestCase {
31 
32     @Override
tearDown()33     protected void tearDown() throws Exception {
34         batteryOffScreenOn();
35         super.tearDown();
36     }
37 
batteryOnScreenOff()38     protected void batteryOnScreenOff() throws Exception {
39         getDevice().executeShellCommand("dumpsys battery unplug");
40         getDevice().executeShellCommand("dumpsys batterystats enable pretend-screen-off");
41     }
42 
batteryOffScreenOn()43     protected void batteryOffScreenOn() throws Exception {
44         getDevice().executeShellCommand("dumpsys battery reset");
45         getDevice().executeShellCommand("dumpsys batterystats disable pretend-screen-off");
46     }
47 
48     /**
49      * Tests that batterystats is dumped to proto with sane values.
50      */
testBatteryStatsServiceDump()51     public void testBatteryStatsServiceDump() throws Exception {
52         batteryOnScreenOff();
53         Thread.sleep(5000); // Allow some time for battery data to accumulate.
54 
55         final BatteryStatsServiceDumpProto dump = getDump(BatteryStatsServiceDumpProto.parser(),
56                 "dumpsys batterystats --proto");
57 
58         verifyBatteryStatsServiceDumpProto(dump, PRIVACY_NONE);
59 
60         batteryOffScreenOn();
61     }
62 
verifyBatteryStatsServiceDumpProto(BatteryStatsServiceDumpProto dump, final int filterLevel)63     static void verifyBatteryStatsServiceDumpProto(BatteryStatsServiceDumpProto dump, final int filterLevel) throws Exception {
64         final BatteryStatsProto bs = dump.getBatterystats();
65         assertNotNull(bs);
66 
67         // Proto dumps were finalized when the batterystats report version was ~29 and the parcel
68         // version was ~172.
69         assertTrue(29 <= bs.getReportVersion());
70         assertTrue(172 <= bs.getParcelVersion());
71         assertNotNull(bs.getStartPlatformVersion());
72         assertFalse(bs.getStartPlatformVersion().isEmpty());
73         assertNotNull(bs.getEndPlatformVersion());
74         assertFalse(bs.getEndPlatformVersion().isEmpty());
75 
76         for (UidProto u : bs.getUidsList()) {
77             testUidProto(u, filterLevel);
78         }
79 
80         testSystemProto(bs.getSystem());
81     }
82 
testControllerActivityProto(ControllerActivityProto ca)83     private static void testControllerActivityProto(ControllerActivityProto ca) throws Exception {
84         assertNotNull(ca);
85 
86         assertTrue(0 <= ca.getIdleDurationMs());
87         assertTrue(0 <= ca.getRxDurationMs());
88         assertTrue(0 <= ca.getPowerMah());
89         for (ControllerActivityProto.TxLevel tx : ca.getTxList()) {
90             assertTrue(0 <= tx.getDurationMs());
91         }
92     }
93 
testBatteryLevelStep(SystemProto.BatteryLevelStep bls)94     private static void testBatteryLevelStep(SystemProto.BatteryLevelStep bls) throws Exception {
95         assertNotNull(bls);
96 
97         assertTrue(0 < bls.getDurationMs());
98         assertTrue(0 <= bls.getLevel());
99         assertTrue(100 >= bls.getLevel());
100 
101         assertTrue(SystemProto.BatteryLevelStep.DisplayState.getDescriptor().getValues()
102                 .contains(bls.getDisplayState().getValueDescriptor()));
103         assertTrue(SystemProto.BatteryLevelStep.PowerSaveMode.getDescriptor().getValues()
104                 .contains(bls.getPowerSaveMode().getValueDescriptor()));
105         assertTrue(SystemProto.BatteryLevelStep.IdleMode.getDescriptor().getValues()
106                 .contains(bls.getIdleMode().getValueDescriptor()));
107     }
108 
testSystemProto(SystemProto s)109     private static void testSystemProto(SystemProto s) throws Exception {
110         final long epsilon = 500; // Allow ~500 ms of error when comparing times.
111         assertNotNull(s);
112 
113         SystemProto.Battery b = s.getBattery();
114         assertTrue(0 < b.getStartClockTimeMs());
115         assertTrue(0 <= b.getStartCount());
116         long totalRealtimeMs = b.getTotalRealtimeMs();
117         long totalUptimeMs = b.getTotalUptimeMs();
118         assertTrue(0 <= totalUptimeMs);
119         assertTrue(totalUptimeMs <= totalRealtimeMs + epsilon);
120         long batteryRealtimeMs = b.getBatteryRealtimeMs();
121         long batteryUptimeMs = b.getBatteryUptimeMs();
122         assertTrue(0 <= batteryUptimeMs);
123         assertTrue(batteryUptimeMs <= batteryRealtimeMs + epsilon);
124         assertTrue("Battery realtime (" + batteryRealtimeMs + ") is greater than total realtime (" + totalRealtimeMs + ")",
125             batteryRealtimeMs <= totalRealtimeMs + epsilon);
126         assertTrue(batteryUptimeMs <= totalUptimeMs + epsilon);
127         long screenOffRealtimeMs = b.getScreenOffRealtimeMs();
128         long screenOffUptimeMs = b.getScreenOffUptimeMs();
129         assertTrue(0 <= screenOffUptimeMs);
130         assertTrue(screenOffUptimeMs <= screenOffRealtimeMs + epsilon);
131         assertTrue(screenOffRealtimeMs <= totalRealtimeMs + epsilon);
132         assertTrue(screenOffUptimeMs <= totalUptimeMs + epsilon);
133         long screenDozeDurationMs = b.getScreenDozeDurationMs();
134         assertTrue(0 <= screenDozeDurationMs);
135         assertTrue(screenDozeDurationMs <= screenOffRealtimeMs + epsilon);
136         assertTrue(0 < b.getEstimatedBatteryCapacityMah());
137         long minLearnedCapacityUah = b.getMinLearnedBatteryCapacityUah();
138         long maxLearnedCapacityUah = b.getMaxLearnedBatteryCapacityUah();
139         assertTrue(0 <= minLearnedCapacityUah);
140         assertTrue(minLearnedCapacityUah <= maxLearnedCapacityUah);
141 
142         SystemProto.BatteryDischarge bd = s.getBatteryDischarge();
143         int lowerBound = bd.getLowerBoundSinceCharge();
144         int upperBound = bd.getUpperBoundSinceCharge();
145         assertTrue(0 <= lowerBound);
146         assertTrue(lowerBound <= upperBound);
147         assertTrue(0 <= bd.getScreenOnSinceCharge());
148         int screenOff = bd.getScreenOffSinceCharge();
149         int screenDoze = bd.getScreenDozeSinceCharge();
150         assertTrue(0 <= screenDoze);
151         assertTrue(screenDoze <= screenOff);
152         long totalMah = bd.getTotalMah();
153         long totalMahScreenOff = bd.getTotalMahScreenOff();
154         long totalMahScreenDoze = bd.getTotalMahScreenDoze();
155         long totalMahLightDoze = bd.getTotalMahLightDoze();
156         long totalMahDeepDoze = bd.getTotalMahDeepDoze();
157         assertTrue(0 <= totalMahScreenDoze);
158         assertTrue(0 <= totalMahLightDoze);
159         assertTrue(0 <= totalMahDeepDoze);
160         assertTrue(totalMahScreenDoze <= totalMahScreenOff);
161         assertTrue(totalMahLightDoze <= totalMahScreenOff);
162         assertTrue(totalMahDeepDoze <= totalMahScreenOff);
163         assertTrue(totalMahScreenOff <= totalMah);
164 
165         assertTrue(-1 <= s.getChargeTimeRemainingMs());
166         assertTrue(-1 <= s.getDischargeTimeRemainingMs());
167 
168         for (SystemProto.BatteryLevelStep bls : s.getChargeStepList()) {
169             testBatteryLevelStep(bls);
170         }
171         for (SystemProto.BatteryLevelStep bls : s.getDischargeStepList()) {
172             testBatteryLevelStep(bls);
173         }
174 
175         for (SystemProto.DataConnection dc : s.getDataConnectionList()) {
176             // If isNone is not set, then the name will be a valid network type.
177             if (!dc.getIsNone()) {
178                 assertTrue(NetworkTypeEnum.getDescriptor().getValues()
179                         .contains(dc.getName().getValueDescriptor()));
180             }
181             testTimerProto(dc.getTotal());
182         }
183 
184         testControllerActivityProto(s.getGlobalBluetoothController());
185         testControllerActivityProto(s.getGlobalModemController());
186         testControllerActivityProto(s.getGlobalWifiController());
187 
188         SystemProto.GlobalNetwork gn = s.getGlobalNetwork();
189         assertTrue(0 <= gn.getMobileBytesRx());
190         assertTrue(0 <= gn.getMobileBytesTx());
191         assertTrue(0 <= gn.getWifiBytesRx());
192         assertTrue(0 <= gn.getWifiBytesTx());
193         assertTrue(0 <= gn.getMobilePacketsRx());
194         assertTrue(0 <= gn.getMobilePacketsTx());
195         assertTrue(0 <= gn.getWifiPacketsRx());
196         assertTrue(0 <= gn.getWifiPacketsTx());
197         assertTrue(0 <= gn.getBtBytesRx());
198         assertTrue(0 <= gn.getBtBytesTx());
199 
200         SystemProto.GlobalWifi gw = s.getGlobalWifi();
201         assertTrue(0 <= gw.getOnDurationMs());
202         assertTrue(0 <= gw.getRunningDurationMs());
203 
204         for (SystemProto.KernelWakelock kw : s.getKernelWakelockList()) {
205             testTimerProto(kw.getTotal());
206         }
207 
208         SystemProto.Misc m = s.getMisc();
209         assertTrue(0 <= m.getScreenOnDurationMs());
210         assertTrue(0 <= m.getPhoneOnDurationMs());
211         assertTrue(0 <= m.getFullWakelockTotalDurationMs());
212         assertTrue(0 <= m.getPartialWakelockTotalDurationMs());
213         assertTrue(0 <= m.getMobileRadioActiveDurationMs());
214         assertTrue(0 <= m.getMobileRadioActiveAdjustedTimeMs());
215         assertTrue(0 <= m.getMobileRadioActiveCount());
216         assertTrue(0 <= m.getMobileRadioActiveUnknownDurationMs());
217         assertTrue(0 <= m.getInteractiveDurationMs());
218         assertTrue(0 <= m.getBatterySaverModeEnabledDurationMs());
219         assertTrue(0 <= m.getNumConnectivityChanges());
220         assertTrue(0 <= m.getDeepDozeEnabledDurationMs());
221         assertTrue(0 <= m.getDeepDozeCount());
222         assertTrue(0 <= m.getDeepDozeIdlingDurationMs());
223         assertTrue(0 <= m.getDeepDozeIdlingCount());
224         assertTrue(0 <= m.getLongestDeepDozeDurationMs());
225         assertTrue(0 <= m.getLightDozeEnabledDurationMs());
226         assertTrue(0 <= m.getLightDozeCount());
227         assertTrue(0 <= m.getLightDozeIdlingDurationMs());
228         assertTrue(0 <= m.getLightDozeIdlingCount());
229         assertTrue(0 <= m.getLongestLightDozeDurationMs());
230 
231         for (SystemProto.PhoneSignalStrength pss : s.getPhoneSignalStrengthList()) {
232             testTimerProto(pss.getTotal());
233         }
234 
235         for (SystemProto.PowerUseItem pui : s.getPowerUseItemList()) {
236             assertTrue(SystemProto.PowerUseItem.Sipper.getDescriptor().getValues()
237                     .contains(pui.getName().getValueDescriptor()));
238             assertTrue(0 <= pui.getUid());
239             assertTrue(0 <= pui.getComputedPowerMah());
240             assertTrue(0 <= pui.getScreenPowerMah());
241             assertTrue(0 <= pui.getProportionalSmearMah());
242         }
243 
244         SystemProto.PowerUseSummary pus = s.getPowerUseSummary();
245         assertTrue(0 < pus.getBatteryCapacityMah());
246         assertTrue(0 <= pus.getComputedPowerMah());
247         double minDrained = pus.getMinDrainedPowerMah();
248         double maxDrained = pus.getMaxDrainedPowerMah();
249         assertTrue(0 <= minDrained);
250         assertTrue(minDrained <= maxDrained);
251 
252         for (SystemProto.ResourcePowerManager rpm : s.getResourcePowerManagerList()) {
253             assertNotNull(rpm.getName());
254             assertFalse(rpm.getName().isEmpty());
255             testTimerProto(rpm.getTotal());
256             testTimerProto(rpm.getScreenOff());
257         }
258 
259         for (SystemProto.ScreenBrightness sb : s.getScreenBrightnessList()) {
260             testTimerProto(sb.getTotal());
261         }
262 
263         testTimerProto(s.getSignalScanning());
264 
265         for (SystemProto.WakeupReason wr : s.getWakeupReasonList()) {
266             testTimerProto(wr.getTotal());
267         }
268 
269         SystemProto.WifiMulticastWakelockTotal wmwl = s.getWifiMulticastWakelockTotal();
270         assertTrue(0 <= wmwl.getDurationMs());
271         assertTrue(0 <= wmwl.getCount());
272 
273         for (SystemProto.WifiSignalStrength wss : s.getWifiSignalStrengthList()) {
274             testTimerProto(wss.getTotal());
275         }
276 
277         for (SystemProto.WifiState ws : s.getWifiStateList()) {
278             assertTrue(SystemProto.WifiState.Name.getDescriptor().getValues()
279                     .contains(ws.getName().getValueDescriptor()));
280             testTimerProto(ws.getTotal());
281         }
282 
283         for (SystemProto.WifiSupplicantState wss : s.getWifiSupplicantStateList()) {
284             assertTrue(SystemProto.WifiSupplicantState.Name.getDescriptor().getValues()
285                     .contains(wss.getName().getValueDescriptor()));
286             testTimerProto(wss.getTotal());
287         }
288     }
289 
testTimerProto(TimerProto t)290     private static void testTimerProto(TimerProto t) throws Exception {
291         assertNotNull(t);
292 
293         long duration = t.getDurationMs();
294         long curDuration = t.getCurrentDurationMs();
295         long maxDuration = t.getMaxDurationMs();
296         long totalDuration = t.getTotalDurationMs();
297         assertTrue(0 <= duration);
298         assertTrue(0 <= t.getCount());
299         // Not all TimerProtos will have max duration, current duration, or total duration
300         // populated, so must tread carefully. Regardless, they should never be negative.
301         assertTrue(0 <= curDuration);
302         assertTrue(0 <= maxDuration);
303         assertTrue(0 <= totalDuration);
304         if (maxDuration > 0) {
305             assertTrue(curDuration <= maxDuration);
306         }
307         if (totalDuration > 0) {
308             assertTrue(maxDuration <= totalDuration);
309             assertTrue("Duration " + duration + " is greater than totalDuration " + totalDuration,
310                     duration <= totalDuration);
311         }
312     }
313 
testByFrequency(UidProto.Cpu.ByFrequency bf)314     private static void testByFrequency(UidProto.Cpu.ByFrequency bf) throws Exception {
315         assertNotNull(bf);
316 
317         assertTrue(1 <= bf.getFrequencyIndex());
318         long total = bf.getTotalDurationMs();
319         long screenOff = bf.getScreenOffDurationMs();
320         assertTrue(0 <= screenOff);
321         assertTrue(screenOff <= total);
322     }
323 
testUidProto(UidProto u, final int filterLevel)324     private static void testUidProto(UidProto u, final int filterLevel) throws Exception {
325         assertNotNull(u);
326 
327         assertTrue(0 <= u.getUid());
328 
329         for (UidProto.Package p : u.getPackagesList()) {
330             assertNotNull(p.getName());
331             assertFalse(p.getName().isEmpty());
332 
333             for (UidProto.Package.Service s : p.getServicesList()) {
334                 assertNotNull(s.getName());
335                 assertFalse(s.getName().isEmpty());
336                 assertTrue(0 <= s.getStartDurationMs());
337                 assertTrue(0 <= s.getStartCount());
338                 assertTrue(0 <= s.getLaunchCount());
339             }
340         }
341 
342         testControllerActivityProto(u.getBluetoothController());
343         testControllerActivityProto(u.getModemController());
344         testControllerActivityProto(u.getWifiController());
345 
346         UidProto.BluetoothMisc bm = u.getBluetoothMisc();
347         testTimerProto(bm.getApportionedBleScan());
348         testTimerProto(bm.getBackgroundBleScan());
349         testTimerProto(bm.getUnoptimizedBleScan());
350         testTimerProto(bm.getBackgroundUnoptimizedBleScan());
351         assertTrue(0 <= bm.getBleScanResultCount());
352         assertTrue(0 <= bm.getBackgroundBleScanResultCount());
353 
354         UidProto.Cpu c = u.getCpu();
355         assertTrue(0 <= c.getUserDurationMs());
356         assertTrue(0 <= c.getSystemDurationMs());
357         for (UidProto.Cpu.ByFrequency bf : c.getByFrequencyList()) {
358             testByFrequency(bf);
359         }
360         for (UidProto.Cpu.ByProcessState bps : c.getByProcessStateList()) {
361             assertTrue(UidProto.Cpu.ProcessState.getDescriptor().getValues()
362                     .contains(bps.getProcessState().getValueDescriptor()));
363             for (UidProto.Cpu.ByFrequency bf : bps.getByFrequencyList()) {
364                 testByFrequency(bf);
365             }
366         }
367 
368         testTimerProto(u.getAudio());
369         testTimerProto(u.getCamera());
370         testTimerProto(u.getFlashlight());
371         testTimerProto(u.getForegroundActivity());
372         testTimerProto(u.getForegroundService());
373         testTimerProto(u.getVibrator());
374         testTimerProto(u.getVideo());
375 
376         for (UidProto.Job j : u.getJobsList()) {
377             assertNotNull(j.getName());
378             assertFalse(j.getName().isEmpty());
379 
380             testTimerProto(j.getTotal());
381             testTimerProto(j.getBackground());
382         }
383 
384         for (UidProto.JobCompletion jc : u.getJobCompletionList()) {
385             assertNotNull(jc.getName());
386             assertFalse(jc.getName().isEmpty());
387 
388             for (UidProto.JobCompletion.ReasonCount rc : jc.getReasonCountList()) {
389                 assertTrue(0 <= rc.getCount());
390             }
391         }
392 
393         UidProto.Network n = u.getNetwork();
394         assertTrue(0 <= n.getMobileBytesRx());
395         assertTrue(0 <= n.getMobileBytesTx());
396         assertTrue(0 <= n.getWifiBytesRx());
397         assertTrue(0 <= n.getWifiBytesTx());
398         assertTrue(0 <= n.getBtBytesRx());
399         assertTrue(0 <= n.getBtBytesTx());
400         assertTrue(0 <= n.getMobilePacketsRx());
401         assertTrue(0 <= n.getMobilePacketsTx());
402         assertTrue(0 <= n.getWifiPacketsRx());
403         assertTrue(0 <= n.getWifiPacketsTx());
404         assertTrue(0 <= n.getMobileActiveDurationMs());
405         assertTrue(0 <= n.getMobileActiveCount());
406         assertTrue(0 <= n.getMobileWakeupCount());
407         assertTrue(0 <= n.getWifiWakeupCount());
408         assertTrue(0 <= n.getMobileBytesBgRx());
409         assertTrue(0 <= n.getMobileBytesBgTx());
410         assertTrue(0 <= n.getWifiBytesBgRx());
411         assertTrue(0 <= n.getWifiBytesBgTx());
412         assertTrue(0 <= n.getMobilePacketsBgRx());
413         assertTrue(0 <= n.getMobilePacketsBgTx());
414         assertTrue(0 <= n.getWifiPacketsBgRx());
415         assertTrue(0 <= n.getWifiPacketsBgTx());
416 
417         UidProto.PowerUseItem pui = u.getPowerUseItem();
418         assertTrue(0 <= pui.getComputedPowerMah());
419         assertTrue(0 <= pui.getScreenPowerMah());
420         assertTrue(0 <= pui.getProportionalSmearMah());
421 
422         for (UidProto.Process p : u.getProcessList()) {
423             assertNotNull(p.getName());
424             assertFalse(p.getName().isEmpty());
425             assertTrue(0 <= p.getUserDurationMs());
426             assertTrue("Process system duration is negative: " + p.getSystemDurationMs(),
427                     0 <= p.getSystemDurationMs());
428             assertTrue(0 <= p.getForegroundDurationMs());
429             assertTrue(0 <= p.getStartCount());
430             assertTrue(0 <= p.getAnrCount());
431             assertTrue(0 <= p.getCrashCount());
432         }
433 
434         for (UidProto.StateTime st : u.getStatesList()) {
435             assertTrue(UidProto.StateTime.State.getDescriptor().getValues()
436                     .contains(st.getState().getValueDescriptor()));
437             assertTrue(0 <= st.getDurationMs());
438         }
439 
440         for (UidProto.Sensor s : u.getSensorsList()) {
441             testTimerProto(s.getApportioned());
442             testTimerProto(s.getBackground());
443         }
444 
445         for (UidProto.Sync s : u.getSyncsList()) {
446             assertFalse(s.getName().isEmpty());
447 
448             testTimerProto(s.getTotal());
449             testTimerProto(s.getBackground());
450         }
451 
452         for (UidProto.UserActivity ua : u.getUserActivityList()) {
453             assertTrue(0 <= ua.getCount());
454         }
455 
456         UidProto.AggregatedWakelock aw = u.getAggregatedWakelock();
457         long awPartial = aw.getPartialDurationMs();
458         long awBgPartial = aw.getBackgroundPartialDurationMs();
459         assertTrue(0 <= awBgPartial);
460         assertTrue(awBgPartial <= awPartial);
461 
462         for (UidProto.Wakelock w : u.getWakelocksList()) {
463             // Unfortunately, apps can legitimately pass an empty string as the wakelock name, so we
464             // can't guarantee that wakelock names will be non-empty.
465             testTimerProto(w.getFull());
466             testTimerProto(w.getPartial());
467             testTimerProto(w.getBackgroundPartial());
468             testTimerProto(w.getWindow());
469         }
470 
471         for (UidProto.WakeupAlarm wa : u.getWakeupAlarmList()) {
472             assertTrue(0 <= wa.getCount());
473         }
474 
475         UidProto.Wifi w = u.getWifi();
476         assertTrue(0 <= w.getFullWifiLockDurationMs());
477         assertTrue(0 <= w.getRunningDurationMs());
478         testTimerProto(w.getApportionedScan());
479         testTimerProto(w.getBackgroundScan());
480 
481         testTimerProto(u.getWifiMulticastWakelock());
482     }
483 }
484