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.power.stats;
18 
19 import static android.os.BatteryStats.NUM_SCREEN_BRIGHTNESS_BINS;
20 import static android.os.BatteryStats.POWER_DATA_UNAVAILABLE;
21 import static android.os.BatteryStats.RADIO_ACCESS_TECHNOLOGY_COUNT;
22 import static android.os.BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR;
23 import static android.os.BatteryStats.STATS_SINCE_CHARGED;
24 import static android.os.BatteryStats.WAKE_TYPE_PARTIAL;
25 
26 import static com.android.server.power.stats.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
27 import static com.android.server.power.stats.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY;
28 
29 import static com.google.common.truth.Truth.assertThat;
30 
31 import static org.mockito.Mockito.mock;
32 
33 import android.app.ActivityManager;
34 import android.app.usage.NetworkStatsManager;
35 import android.hardware.radio.V1_5.AccessNetwork;
36 import android.os.BatteryStats;
37 import android.os.BatteryStats.HistoryItem;
38 import android.os.BatteryStats.Uid.Sensor;
39 import android.os.Process;
40 import android.os.UserHandle;
41 import android.os.WorkSource;
42 import android.telephony.AccessNetworkConstants;
43 import android.telephony.ActivityStatsTechSpecificInfo;
44 import android.telephony.Annotation;
45 import android.telephony.CellSignalStrength;
46 import android.telephony.DataConnectionRealTimeInfo;
47 import android.telephony.ModemActivityInfo;
48 import android.telephony.ServiceState;
49 import android.telephony.TelephonyManager;
50 import android.util.Log;
51 import android.util.MutableInt;
52 import android.util.SparseIntArray;
53 import android.util.SparseLongArray;
54 import android.view.Display;
55 
56 import androidx.test.filters.SmallTest;
57 
58 import com.android.internal.os.BatteryStatsHistoryIterator;
59 import com.android.internal.os.PowerProfile;
60 import com.android.internal.power.EnergyConsumerStats;
61 import com.android.server.power.stats.BatteryStatsImpl.DualTimer;
62 
63 import junit.framework.TestCase;
64 
65 import org.mockito.Mock;
66 
67 import java.util.ArrayList;
68 import java.util.Arrays;
69 import java.util.HashMap;
70 import java.util.List;
71 import java.util.Map;
72 import java.util.function.IntConsumer;
73 
74 /**
75  * Test various BatteryStatsImpl noteStart methods.
76  */
77 @SuppressWarnings("GuardedBy")
78 public class BatteryStatsNoteTest extends TestCase {
79     private static final String TAG = BatteryStatsNoteTest.class.getSimpleName();
80 
81     private static final int UID = 10500;
82     private static final int ISOLATED_APP_ID = Process.FIRST_ISOLATED_UID + 23;
83     private static final int ISOLATED_UID = UserHandle.getUid(0, ISOLATED_APP_ID);
84     private static final WorkSource WS = new WorkSource(UID);
85 
86     enum ModemState {
87         SLEEP, IDLE, RECEIVING, TRANSMITTING
88     }
89 
90     @Mock
91     NetworkStatsManager mNetworkStatsManager;
92 
93     /**
94      * Test BatteryStatsImpl.Uid.noteBluetoothScanResultLocked.
95      */
96     @SmallTest
testNoteBluetoothScanResultLocked()97     public void testNoteBluetoothScanResultLocked() throws Exception {
98         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(new MockClock());
99         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
100         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
101 
102         bi.noteBluetoothScanResultsFromSourceLocked(WS, 1);
103         bi.noteBluetoothScanResultsFromSourceLocked(WS, 100);
104         assertEquals(101,
105                 bi.getUidStats().get(UID).getBluetoothScanResultCounter()
106                         .getCountLocked(STATS_SINCE_CHARGED));
107         BatteryStats.Counter bgCntr = bi.getUidStats().get(UID).getBluetoothScanResultBgCounter();
108         if (bgCntr != null) {
109             assertEquals(0, bgCntr.getCountLocked(STATS_SINCE_CHARGED));
110         }
111 
112         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
113         bi.noteBluetoothScanResultsFromSourceLocked(WS, 17);
114         assertEquals(101 + 17,
115                 bi.getUidStats().get(UID).getBluetoothScanResultCounter()
116                         .getCountLocked(STATS_SINCE_CHARGED));
117         assertEquals(17,
118                 bi.getUidStats().get(UID).getBluetoothScanResultBgCounter()
119                         .getCountLocked(STATS_SINCE_CHARGED));
120     }
121 
122     /**
123      * Test BatteryStatsImpl.Uid.noteStartWakeLocked.
124      */
125     @SmallTest
testNoteStartWakeLocked()126     public void testNoteStartWakeLocked() throws Exception {
127         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
128         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
129 
130         int pid = 10;
131         String name = "name";
132 
133         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
134         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
135         bi.getUidStatsLocked(UID)
136                 .noteStartWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime);
137 
138         clocks.realtime = clocks.uptime = 100;
139         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
140 
141         clocks.realtime = clocks.uptime = 220;
142         bi.getUidStatsLocked(UID).noteStopWakeLocked(pid, name, WAKE_TYPE_PARTIAL, clocks.realtime);
143 
144         BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID)
145                 .getAggregatedPartialWakelockTimer();
146         long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
147         long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
148         assertEquals(220_000, actualTime);
149         assertEquals(120_000, bgTime);
150     }
151 
152     /**
153      * Test BatteryStatsImpl.Uid.noteStartWakeLocked for an isolated uid.
154      */
155     @SmallTest
testNoteStartWakeLocked_isolatedUid()156     public void testNoteStartWakeLocked_isolatedUid() throws Exception {
157         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
158         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
159 
160         int pid = 10;
161         String name = "name";
162         String historyName = "historyName";
163 
164         WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain();
165         isolatedWorkChain.addNode(ISOLATED_UID, name);
166 
167         // Map ISOLATED_UID to UID.
168         bi.addIsolatedUidLocked(ISOLATED_UID, UID);
169 
170         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
171         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
172         bi.noteStartWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName,
173                 WAKE_TYPE_PARTIAL, false);
174 
175         clocks.realtime = clocks.uptime = 100;
176         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
177 
178         clocks.realtime = clocks.uptime = 220;
179         bi.noteStopWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName,
180                 WAKE_TYPE_PARTIAL);
181 
182         // ISOLATED_UID wakelock time should be attributed to UID.
183         BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID)
184                 .getAggregatedPartialWakelockTimer();
185         long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
186         long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
187         assertEquals(220_000, actualTime);
188         assertEquals(120_000, bgTime);
189     }
190 
191     /**
192      * Test BatteryStatsImpl.Uid.noteStartWakeLocked for an isolated uid, with a race where the
193      * isolated uid is removed from batterystats before the wakelock has been stopped.
194      */
195     @SmallTest
testNoteStartWakeLocked_isolatedUidRace()196     public void testNoteStartWakeLocked_isolatedUidRace() throws Exception {
197         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
198         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
199 
200         int pid = 10;
201         String name = "name";
202         String historyName = "historyName";
203 
204         WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain();
205         isolatedWorkChain.addNode(ISOLATED_UID, name);
206 
207         // Map ISOLATED_UID to UID.
208         bi.addIsolatedUidLocked(ISOLATED_UID, UID);
209 
210         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
211         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
212         bi.noteStartWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName,
213                 WAKE_TYPE_PARTIAL, false);
214 
215         clocks.realtime = clocks.uptime = 100;
216         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
217 
218         clocks.realtime = clocks.uptime = 150;
219         bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime);
220 
221         clocks.realtime = clocks.uptime = 220;
222         bi.noteStopWakeLocked(ISOLATED_UID, pid, isolatedWorkChain, name, historyName,
223                 WAKE_TYPE_PARTIAL);
224 
225         // ISOLATED_UID wakelock time should be attributed to UID.
226         BatteryStats.Timer aggregTimer = bi.getUidStats().get(UID)
227                 .getAggregatedPartialWakelockTimer();
228         long actualTime = aggregTimer.getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
229         long bgTime = aggregTimer.getSubTimer().getTotalTimeLocked(300_000, STATS_SINCE_CHARGED);
230         assertEquals(220_000, actualTime);
231         assertEquals(120_000, bgTime);
232     }
233 
234     /**
235      * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid.
236      */
237     @SmallTest
testNoteLongPartialWakelockStart_isolatedUid()238     public void testNoteLongPartialWakelockStart_isolatedUid() throws Exception {
239         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
240         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
241 
242 
243         bi.setRecordAllHistoryLocked(true);
244         bi.forceRecordAllHistory();
245 
246         int pid = 10;
247         String name = "name";
248         String historyName = "historyName";
249 
250         WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain();
251         isolatedWorkChain.addNode(ISOLATED_UID, name);
252 
253         // Map ISOLATED_UID to UID.
254         bi.addIsolatedUidLocked(ISOLATED_UID, UID);
255 
256         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
257         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
258         bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID);
259 
260         clocks.realtime = clocks.uptime = 100;
261         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
262 
263         clocks.realtime = clocks.uptime = 220;
264         bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID);
265 
266         final BatteryStatsHistoryIterator iterator =  bi.iterateBatteryStatsHistory();
267 
268         BatteryStats.HistoryItem item;
269 
270         while ((item = iterator.next()) != null) {
271             if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break;
272         }
273         assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START);
274         assertThat(item.eventTag).isNotNull();
275         assertThat(item.eventTag.string).isEqualTo(historyName);
276         assertThat(item.eventTag.uid).isEqualTo(UID);
277 
278         while ((item = iterator.next()) != null) {
279             if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break;
280         }
281         assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH);
282         assertThat(item.eventTag).isNotNull();
283         assertThat(item.eventTag.string).isEqualTo(historyName);
284         assertThat(item.eventTag.uid).isEqualTo(UID);
285     }
286 
287     /**
288      * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid.
289      */
290     @SmallTest
testNoteLongPartialWakelockStart_isolatedUidRace()291     public void testNoteLongPartialWakelockStart_isolatedUidRace() throws Exception {
292         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
293         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
294 
295 
296         bi.setRecordAllHistoryLocked(true);
297         bi.forceRecordAllHistory();
298 
299         int pid = 10;
300         String name = "name";
301         String historyName = "historyName";
302 
303         WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain();
304         isolatedWorkChain.addNode(ISOLATED_UID, name);
305 
306         // Map ISOLATED_UID to UID.
307         bi.addIsolatedUidLocked(ISOLATED_UID, UID);
308 
309         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
310         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
311         bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID);
312 
313         clocks.realtime = clocks.uptime = 100;
314         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
315 
316         clocks.realtime = clocks.uptime = 150;
317         bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime);
318 
319         clocks.realtime = clocks.uptime = 220;
320         bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID);
321 
322         final BatteryStatsHistoryIterator iterator = bi.iterateBatteryStatsHistory();
323 
324         BatteryStats.HistoryItem item;
325 
326         while ((item = iterator.next()) != null) {
327             if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break;
328         }
329         assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START);
330         assertThat(item.eventTag).isNotNull();
331         assertThat(item.eventTag.string).isEqualTo(historyName);
332         assertThat(item.eventTag.uid).isEqualTo(UID);
333 
334         while ((item = iterator.next()) != null) {
335             if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break;
336         }
337         assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH);
338         assertThat(item.eventTag).isNotNull();
339         assertThat(item.eventTag.string).isEqualTo(historyName);
340         assertThat(item.eventTag.uid).isEqualTo(UID);
341     }
342 
343     /**
344      * Test BatteryStatsImpl.noteUidProcessStateLocked.
345      */
346     @SmallTest
testNoteUidProcessStateLocked()347     public void testNoteUidProcessStateLocked() throws Exception {
348         final MockClock clocks = new MockClock();
349         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
350 
351         // map of ActivityManager process states and how long to simulate run time in each state
352         Map<Integer, Integer> stateRuntimeMap = new HashMap<Integer, Integer>();
353         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP, 1111);
354         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BOUND_TOP, 7382);
355         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE, 1234);
356         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE, 2468);
357         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TOP_SLEEPING, 7531);
358         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND, 4455);
359         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND, 1337);
360         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_BACKUP, 90210);
361         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_HEAVY_WEIGHT, 911);
362         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_SERVICE, 404);
363         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_RECEIVER, 31459);
364         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_HOME, 1123);
365         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_LAST_ACTIVITY, 5813);
366         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY, 867);
367         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT, 5309);
368         stateRuntimeMap.put(ActivityManager.PROCESS_STATE_CACHED_EMPTY, 42);
369 
370         bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);
371 
372         for (Map.Entry<Integer, Integer> entry : stateRuntimeMap.entrySet()) {
373             bi.noteUidProcessStateLocked(UID, entry.getKey());
374             clocks.realtime += entry.getValue();
375             clocks.uptime = clocks.realtime;
376         }
377 
378         long actualRunTimeUs;
379         long expectedRunTimeMs;
380         long elapsedTimeUs = clocks.realtime * 1000;
381         BatteryStats.Uid uid = bi.getUidStats().get(UID);
382 
383         // compare runtime of process states to the Uid process states they map to
384         actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP, elapsedTimeUs,
385                 STATS_SINCE_CHARGED);
386         expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP);
387         assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
388 
389         actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE,
390                 elapsedTimeUs, STATS_SINCE_CHARGED);
391         expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE)
392                 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE);
393         assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
394 
395         actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING,
396                 elapsedTimeUs, STATS_SINCE_CHARGED);
397         expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TOP_SLEEPING);
398         assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
399 
400         actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_FOREGROUND,
401                 elapsedTimeUs, STATS_SINCE_CHARGED);
402         expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
403         assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
404 
405         actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_BACKGROUND,
406                 elapsedTimeUs, STATS_SINCE_CHARGED);
407         expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND)
408                 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BACKUP)
409                 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_SERVICE)
410                 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_RECEIVER)
411                 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_BOUND_TOP);
412         assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
413 
414         actualRunTimeUs = uid.getProcessStateTime(BatteryStats.Uid.PROCESS_STATE_CACHED,
415                 elapsedTimeUs, STATS_SINCE_CHARGED);
416         expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_HOME)
417                 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_LAST_ACTIVITY)
418                 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY)
419                 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT)
420                 + stateRuntimeMap.get(ActivityManager.PROCESS_STATE_CACHED_EMPTY);
421         assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
422 
423         // Special check for foreground service timer
424         actualRunTimeUs = uid.getForegroundServiceTimer().getTotalTimeLocked(elapsedTimeUs,
425                 STATS_SINCE_CHARGED);
426         expectedRunTimeMs = stateRuntimeMap.get(ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
427         assertEquals(expectedRunTimeMs * 1000, actualRunTimeUs);
428     }
429 
430     /**
431      * Test BatteryStatsImpl.updateTimeBasesLocked.
432      */
433     @SmallTest
testUpdateTimeBasesLocked()434     public void testUpdateTimeBasesLocked() throws Exception {
435         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
436         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
437 
438         bi.updateTimeBasesLocked(false, Display.STATE_OFF, 0, 0);
439         assertFalse(bi.getOnBatteryTimeBase().isRunning());
440         bi.updateTimeBasesLocked(false, Display.STATE_DOZE, 10, 10);
441         assertFalse(bi.getOnBatteryTimeBase().isRunning());
442         bi.updateTimeBasesLocked(false, Display.STATE_ON, 20, 20);
443         assertFalse(bi.getOnBatteryTimeBase().isRunning());
444 
445         bi.updateTimeBasesLocked(true, Display.STATE_ON, 30, 30);
446         assertTrue(bi.getOnBatteryTimeBase().isRunning());
447         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
448         bi.updateTimeBasesLocked(true, Display.STATE_DOZE, 40, 40);
449         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
450         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 40, 40);
451         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
452     }
453 
454     /**
455      * Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly.
456      */
457     @SmallTest
testNoteScreenStateLocked()458     public void testNoteScreenStateLocked() throws Exception {
459         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
460         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
461         bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"});
462 
463         bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);
464         bi.noteScreenStateLocked(0, Display.STATE_ON);
465 
466         bi.noteScreenStateLocked(0, Display.STATE_DOZE);
467         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
468         assertEquals(Display.STATE_DOZE, bi.getScreenState());
469         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
470 
471         bi.noteScreenStateLocked(0, Display.STATE_ON);
472         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
473         assertEquals(Display.STATE_ON, bi.getScreenState());
474         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
475 
476         bi.noteScreenStateLocked(0, Display.STATE_OFF);
477         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
478         assertEquals(Display.STATE_OFF, bi.getScreenState());
479         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
480 
481         bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND);
482         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
483         assertEquals(Display.STATE_DOZE_SUSPEND, bi.getScreenState());
484         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
485 
486         // STATE_VR note should map to STATE_ON.
487         bi.noteScreenStateLocked(0, Display.STATE_VR);
488         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
489         assertEquals(Display.STATE_ON, bi.getScreenState());
490         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
491 
492         // STATE_ON_SUSPEND note should map to STATE_ON.
493         bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND);
494         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
495         assertEquals(Display.STATE_ON, bi.getScreenState());
496         // Transition from ON to ON state should not cause an External Sync
497         assertEquals(0, bi.getAndClearExternalStatsSyncFlags());
498     }
499 
500     /**
501      * Test BatteryStatsImpl.noteScreenStateLocked sets timebases and screen states correctly for
502      * multi display devices
503      */
504     @SmallTest
testNoteScreenStateLocked_multiDisplay()505     public void testNoteScreenStateLocked_multiDisplay() throws Exception {
506         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
507         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
508         bi.setDisplayCountLocked(2);
509         bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"});
510 
511         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
512         bi.noteScreenStateLocked(0, Display.STATE_OFF);
513         bi.noteScreenStateLocked(1, Display.STATE_OFF);
514 
515         bi.noteScreenStateLocked(0, Display.STATE_DOZE);
516         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
517         assertEquals(Display.STATE_DOZE, bi.getScreenState());
518         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
519 
520         bi.noteScreenStateLocked(0, Display.STATE_ON);
521         assertEquals(Display.STATE_ON, bi.getScreenState());
522         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
523         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
524 
525         bi.noteScreenStateLocked(0, Display.STATE_OFF);
526         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
527         assertEquals(Display.STATE_OFF, bi.getScreenState());
528         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
529 
530         bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND);
531         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
532         assertEquals(Display.STATE_DOZE_SUSPEND, bi.getScreenState());
533         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
534 
535         // STATE_VR note should map to STATE_ON.
536         bi.noteScreenStateLocked(0, Display.STATE_VR);
537         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
538         assertEquals(Display.STATE_ON, bi.getScreenState());
539         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
540 
541         // STATE_ON_SUSPEND note should map to STATE_ON.
542         bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND);
543         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
544         assertEquals(Display.STATE_ON, bi.getScreenState());
545         // Transition from ON to ON state should not cause an External Sync
546         assertEquals(0, bi.getAndClearExternalStatsSyncFlags());
547 
548         bi.noteScreenStateLocked(1, Display.STATE_DOZE);
549         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
550         // Should remain STATE_ON since display0 is still on.
551         assertEquals(Display.STATE_ON, bi.getScreenState());
552         // Overall screen state did not change, so no need to sync CPU stats.
553         assertEquals(UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
554 
555         bi.noteScreenStateLocked(0, Display.STATE_DOZE);
556         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
557         assertEquals(Display.STATE_DOZE, bi.getScreenState());
558         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
559 
560         bi.noteScreenStateLocked(0, Display.STATE_ON);
561         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
562         assertEquals(Display.STATE_ON, bi.getScreenState());
563         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
564 
565         bi.noteScreenStateLocked(0, Display.STATE_OFF);
566         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
567         assertEquals(Display.STATE_DOZE, bi.getScreenState());
568         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
569 
570         bi.noteScreenStateLocked(0, Display.STATE_DOZE_SUSPEND);
571         assertTrue(bi.getOnBatteryScreenOffTimeBase().isRunning());
572         assertEquals(Display.STATE_DOZE, bi.getScreenState());
573         // Overall screen state did not change, so no need to sync CPU stats.
574         assertEquals(UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
575 
576         bi.noteScreenStateLocked(0, Display.STATE_VR);
577         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
578         assertEquals(Display.STATE_ON, bi.getScreenState());
579         assertEquals(UPDATE_CPU | UPDATE_DISPLAY, bi.getAndClearExternalStatsSyncFlags());
580 
581         bi.noteScreenStateLocked(0, Display.STATE_ON_SUSPEND);
582         assertFalse(bi.getOnBatteryScreenOffTimeBase().isRunning());
583         assertEquals(Display.STATE_ON, bi.getScreenState());
584         assertEquals(0, bi.getAndClearExternalStatsSyncFlags());
585     }
586 
587     /*
588      * Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly.
589      *
590      * Unknown and doze should both be subset of off state
591      *
592      * Timeline 0----100----200----310----400------------1000
593      * Unknown         -------
594      * On                     -------
595      * Off             -------       ----------------------
596      * Doze                                ----------------
597      */
598     @SmallTest
testNoteScreenStateTimersLocked()599     public void testNoteScreenStateTimersLocked() throws Exception {
600         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
601         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
602 
603         clocks.realtime = clocks.uptime = 100;
604         // Device startup, setOnBatteryLocked calls updateTimebases
605         bi.updateTimeBasesLocked(true, Display.STATE_UNKNOWN, 100_000, 100_000);
606         // Turn on display at 200us
607         clocks.realtime = clocks.uptime = 200;
608         bi.noteScreenStateLocked(0, Display.STATE_ON);
609         assertEquals(150_000, bi.computeBatteryRealtime(250_000, STATS_SINCE_CHARGED));
610         assertEquals(100_000, bi.computeBatteryScreenOffRealtime(250_000, STATS_SINCE_CHARGED));
611         assertEquals(50_000, bi.getScreenOnTime(250_000, STATS_SINCE_CHARGED));
612         assertEquals(0, bi.getScreenDozeTime(250_000, STATS_SINCE_CHARGED));
613         assertEquals(50_000, bi.getDisplayScreenOnTime(0, 250_000));
614         assertEquals(0, bi.getDisplayScreenDozeTime(0, 250_000));
615 
616         clocks.realtime = clocks.uptime = 310;
617         bi.noteScreenStateLocked(0, Display.STATE_OFF);
618         assertEquals(250_000, bi.computeBatteryRealtime(350_000, STATS_SINCE_CHARGED));
619         assertEquals(140_000, bi.computeBatteryScreenOffRealtime(350_000, STATS_SINCE_CHARGED));
620         assertEquals(110_000, bi.getScreenOnTime(350_000, STATS_SINCE_CHARGED));
621         assertEquals(0, bi.getScreenDozeTime(350_000, STATS_SINCE_CHARGED));
622         assertEquals(110_000, bi.getDisplayScreenOnTime(0, 350_000));
623         assertEquals(0, bi.getDisplayScreenDozeTime(0, 350_000));
624 
625         clocks.realtime = clocks.uptime = 400;
626         bi.noteScreenStateLocked(0, Display.STATE_DOZE);
627         assertEquals(400_000, bi.computeBatteryRealtime(500_000, STATS_SINCE_CHARGED));
628         assertEquals(290_000, bi.computeBatteryScreenOffRealtime(500_000, STATS_SINCE_CHARGED));
629         assertEquals(110_000, bi.getScreenOnTime(500_000, STATS_SINCE_CHARGED));
630         assertEquals(100_000, bi.getScreenDozeTime(500_000, STATS_SINCE_CHARGED));
631         assertEquals(110_000, bi.getDisplayScreenOnTime(0, 500_000));
632         assertEquals(100_000, bi.getDisplayScreenDozeTime(0, 500_000));
633 
634         clocks.realtime = clocks.uptime = 1000;
635         bi.noteScreenStateLocked(0, Display.STATE_OFF);
636         assertEquals(1400_000, bi.computeBatteryRealtime(1500_000, STATS_SINCE_CHARGED));
637         assertEquals(1290_000, bi.computeBatteryScreenOffRealtime(1500_000, STATS_SINCE_CHARGED));
638         assertEquals(110_000, bi.getScreenOnTime(1500_000, STATS_SINCE_CHARGED));
639         assertEquals(600_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED));
640         assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1500_000));
641         assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1500_000));
642     }
643 
644     /*
645      * Test BatteryStatsImpl.noteScreenStateLocked updates timers correctly for multi display
646      * devices.
647      */
648     @SmallTest
testNoteScreenStateTimersLocked_multiDisplay()649     public void testNoteScreenStateTimersLocked_multiDisplay() throws Exception {
650         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
651         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
652         bi.setDisplayCountLocked(2);
653 
654         clocks.realtime = clocks.uptime = 100;
655         // Device startup, setOnBatteryLocked calls updateTimebases
656         bi.updateTimeBasesLocked(true, Display.STATE_UNKNOWN, 100_000, 100_000);
657         // Turn on display at 200us
658         clocks.realtime = clocks.uptime = 200;
659         bi.noteScreenStateLocked(0, Display.STATE_ON);
660         bi.noteScreenStateLocked(1, Display.STATE_OFF);
661         assertEquals(150_000, bi.computeBatteryRealtime(250_000, STATS_SINCE_CHARGED));
662         assertEquals(100_000, bi.computeBatteryScreenOffRealtime(250_000, STATS_SINCE_CHARGED));
663         assertEquals(50_000, bi.getScreenOnTime(250_000, STATS_SINCE_CHARGED));
664         assertEquals(0, bi.getScreenDozeTime(250_000, STATS_SINCE_CHARGED));
665         assertEquals(50_000, bi.getDisplayScreenOnTime(0, 250_000));
666         assertEquals(0, bi.getDisplayScreenDozeTime(0, 250_000));
667         assertEquals(0, bi.getDisplayScreenOnTime(1, 250_000));
668         assertEquals(0, bi.getDisplayScreenDozeTime(1, 250_000));
669 
670         clocks.realtime = clocks.uptime = 310;
671         bi.noteScreenStateLocked(0, Display.STATE_OFF);
672         assertEquals(250_000, bi.computeBatteryRealtime(350_000, STATS_SINCE_CHARGED));
673         assertEquals(140_000, bi.computeBatteryScreenOffRealtime(350_000, STATS_SINCE_CHARGED));
674         assertEquals(110_000, bi.getScreenOnTime(350_000, STATS_SINCE_CHARGED));
675         assertEquals(0, bi.getScreenDozeTime(350_000, STATS_SINCE_CHARGED));
676         assertEquals(110_000, bi.getDisplayScreenOnTime(0, 350_000));
677         assertEquals(0, bi.getDisplayScreenDozeTime(0, 350_000));
678         assertEquals(0, bi.getDisplayScreenOnTime(1, 350_000));
679         assertEquals(0, bi.getDisplayScreenDozeTime(1, 350_000));
680 
681         clocks.realtime = clocks.uptime = 400;
682         bi.noteScreenStateLocked(0, Display.STATE_DOZE);
683         assertEquals(400_000, bi.computeBatteryRealtime(500_000, STATS_SINCE_CHARGED));
684         assertEquals(290_000, bi.computeBatteryScreenOffRealtime(500_000, STATS_SINCE_CHARGED));
685         assertEquals(110_000, bi.getScreenOnTime(500_000, STATS_SINCE_CHARGED));
686         assertEquals(100_000, bi.getScreenDozeTime(500_000, STATS_SINCE_CHARGED));
687         assertEquals(110_000, bi.getDisplayScreenOnTime(0, 500_000));
688         assertEquals(100_000, bi.getDisplayScreenDozeTime(0, 500_000));
689         assertEquals(0, bi.getDisplayScreenOnTime(1, 500_000));
690         assertEquals(0, bi.getDisplayScreenDozeTime(1, 500_000));
691 
692         clocks.realtime = clocks.uptime = 1000;
693         bi.noteScreenStateLocked(0, Display.STATE_OFF);
694         assertEquals(1000_000, bi.computeBatteryRealtime(1100_000, STATS_SINCE_CHARGED));
695         assertEquals(890_000, bi.computeBatteryScreenOffRealtime(1100_000, STATS_SINCE_CHARGED));
696         assertEquals(110_000, bi.getScreenOnTime(1100_000, STATS_SINCE_CHARGED));
697         assertEquals(600_000, bi.getScreenDozeTime(1100_000, STATS_SINCE_CHARGED));
698         assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1100_000));
699         assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1100_000));
700         assertEquals(0, bi.getDisplayScreenOnTime(1, 1100_000));
701         assertEquals(0, bi.getDisplayScreenDozeTime(1, 1100_000));
702 
703         clocks.realtime = clocks.uptime = 1200;
704         // Change state of second display to doze
705         bi.noteScreenStateLocked(1, Display.STATE_DOZE);
706         assertEquals(1150_000, bi.computeBatteryRealtime(1250_000, STATS_SINCE_CHARGED));
707         assertEquals(1040_000, bi.computeBatteryScreenOffRealtime(1250_000, STATS_SINCE_CHARGED));
708         assertEquals(110_000, bi.getScreenOnTime(1250_000, STATS_SINCE_CHARGED));
709         assertEquals(650_000, bi.getScreenDozeTime(1250_000, STATS_SINCE_CHARGED));
710         assertEquals(110_000, bi.getDisplayScreenOnTime(0, 1250_000));
711         assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1250_000));
712         assertEquals(0, bi.getDisplayScreenOnTime(1, 1250_000));
713         assertEquals(50_000, bi.getDisplayScreenDozeTime(1, 1250_000));
714 
715         clocks.realtime = clocks.uptime = 1310;
716         bi.noteScreenStateLocked(0, Display.STATE_ON);
717         assertEquals(1250_000, bi.computeBatteryRealtime(1350_000, STATS_SINCE_CHARGED));
718         assertEquals(1100_000, bi.computeBatteryScreenOffRealtime(1350_000, STATS_SINCE_CHARGED));
719         assertEquals(150_000, bi.getScreenOnTime(1350_000, STATS_SINCE_CHARGED));
720         assertEquals(710_000, bi.getScreenDozeTime(1350_000, STATS_SINCE_CHARGED));
721         assertEquals(150_000, bi.getDisplayScreenOnTime(0, 1350_000));
722         assertEquals(600_000, bi.getDisplayScreenDozeTime(0, 1350_000));
723         assertEquals(0, bi.getDisplayScreenOnTime(1, 1350_000));
724         assertEquals(150_000, bi.getDisplayScreenDozeTime(1, 1350_000));
725 
726         clocks.realtime = clocks.uptime = 1400;
727         bi.noteScreenStateLocked(0, Display.STATE_DOZE);
728         assertEquals(1400_000, bi.computeBatteryRealtime(1500_000, STATS_SINCE_CHARGED));
729         assertEquals(1200_000, bi.computeBatteryScreenOffRealtime(1500_000, STATS_SINCE_CHARGED));
730         assertEquals(200_000, bi.getScreenOnTime(1500_000, STATS_SINCE_CHARGED));
731         assertEquals(810_000, bi.getScreenDozeTime(1500_000, STATS_SINCE_CHARGED));
732         assertEquals(200_000, bi.getDisplayScreenOnTime(0, 1500_000));
733         assertEquals(700_000, bi.getDisplayScreenDozeTime(0, 1500_000));
734         assertEquals(0, bi.getDisplayScreenOnTime(1, 1500_000));
735         assertEquals(300_000, bi.getDisplayScreenDozeTime(1, 1500_000));
736 
737         clocks.realtime = clocks.uptime = 2000;
738         bi.noteScreenStateLocked(0, Display.STATE_OFF);
739         assertEquals(2000_000, bi.computeBatteryRealtime(2100_000, STATS_SINCE_CHARGED));
740         assertEquals(1800_000, bi.computeBatteryScreenOffRealtime(2100_000, STATS_SINCE_CHARGED));
741         assertEquals(200_000, bi.getScreenOnTime(2100_000, STATS_SINCE_CHARGED));
742         assertEquals(1410_000, bi.getScreenDozeTime(2100_000, STATS_SINCE_CHARGED));
743         assertEquals(200_000, bi.getDisplayScreenOnTime(0, 2100_000));
744         assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2100_000));
745         assertEquals(0, bi.getDisplayScreenOnTime(1, 2100_000));
746         assertEquals(900_000, bi.getDisplayScreenDozeTime(1, 2100_000));
747 
748 
749         clocks.realtime = clocks.uptime = 2200;
750         // Change state of second display to on
751         bi.noteScreenStateLocked(1, Display.STATE_ON);
752         assertEquals(2150_000, bi.computeBatteryRealtime(2250_000, STATS_SINCE_CHARGED));
753         assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2250_000, STATS_SINCE_CHARGED));
754         assertEquals(250_000, bi.getScreenOnTime(2250_000, STATS_SINCE_CHARGED));
755         assertEquals(1510_000, bi.getScreenDozeTime(2250_000, STATS_SINCE_CHARGED));
756         assertEquals(200_000, bi.getDisplayScreenOnTime(0, 2250_000));
757         assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2250_000));
758         assertEquals(50_000, bi.getDisplayScreenOnTime(1, 2250_000));
759         assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2250_000));
760 
761         clocks.realtime = clocks.uptime = 2310;
762         bi.noteScreenStateLocked(0, Display.STATE_ON);
763         assertEquals(2250_000, bi.computeBatteryRealtime(2350_000, STATS_SINCE_CHARGED));
764         assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2350_000, STATS_SINCE_CHARGED));
765         assertEquals(350_000, bi.getScreenOnTime(2350_000, STATS_SINCE_CHARGED));
766         assertEquals(1510_000, bi.getScreenDozeTime(2350_000, STATS_SINCE_CHARGED));
767         assertEquals(240_000, bi.getDisplayScreenOnTime(0, 2350_000));
768         assertEquals(1200_000, bi.getDisplayScreenDozeTime(0, 2350_000));
769         assertEquals(150_000, bi.getDisplayScreenOnTime(1, 2350_000));
770         assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2350_000));
771 
772         clocks.realtime = clocks.uptime = 2400;
773         bi.noteScreenStateLocked(0, Display.STATE_DOZE);
774         assertEquals(2400_000, bi.computeBatteryRealtime(2500_000, STATS_SINCE_CHARGED));
775         assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(2500_000, STATS_SINCE_CHARGED));
776         assertEquals(500_000, bi.getScreenOnTime(2500_000, STATS_SINCE_CHARGED));
777         assertEquals(1510_000, bi.getScreenDozeTime(2500_000, STATS_SINCE_CHARGED));
778         assertEquals(290_000, bi.getDisplayScreenOnTime(0, 2500_000));
779         assertEquals(1300_000, bi.getDisplayScreenDozeTime(0, 2500_000));
780         assertEquals(300_000, bi.getDisplayScreenOnTime(1, 2500_000));
781         assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 2500_000));
782 
783         clocks.realtime = clocks.uptime = 3000;
784         bi.noteScreenStateLocked(0, Display.STATE_OFF);
785         assertEquals(3000_000, bi.computeBatteryRealtime(3100_000, STATS_SINCE_CHARGED));
786         assertEquals(1900_000, bi.computeBatteryScreenOffRealtime(3100_000, STATS_SINCE_CHARGED));
787         assertEquals(1100_000, bi.getScreenOnTime(3100_000, STATS_SINCE_CHARGED));
788         assertEquals(1510_000, bi.getScreenDozeTime(3100_000, STATS_SINCE_CHARGED));
789         assertEquals(290_000, bi.getDisplayScreenOnTime(0, 3100_000));
790         assertEquals(1800_000, bi.getDisplayScreenDozeTime(0, 3100_000));
791         assertEquals(900_000, bi.getDisplayScreenOnTime(1, 3100_000));
792         assertEquals(1000_000, bi.getDisplayScreenDozeTime(1, 3100_000));
793     }
794 
795 
796     /**
797      * Test BatteryStatsImpl.noteScreenBrightnessLocked updates timers correctly.
798      */
799     @SmallTest
testScreenBrightnessLocked_multiDisplay()800     public void testScreenBrightnessLocked_multiDisplay() throws Exception {
801         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
802         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
803 
804         final int numDisplay = 2;
805         bi.setDisplayCountLocked(numDisplay);
806 
807 
808         final long[] overallExpected = new long[NUM_SCREEN_BRIGHTNESS_BINS];
809         final long[][] perDisplayExpected = new long[numDisplay][NUM_SCREEN_BRIGHTNESS_BINS];
810         class Bookkeeper {
811             public long currentTimeMs = 100;
812             public int overallActiveBin = -1;
813             public int[] perDisplayActiveBin = new int[numDisplay];
814         }
815         final Bookkeeper bk = new Bookkeeper();
816         Arrays.fill(bk.perDisplayActiveBin, -1);
817 
818         IntConsumer incrementTime = inc -> {
819             bk.currentTimeMs += inc;
820             if (bk.overallActiveBin >= 0) {
821                 overallExpected[bk.overallActiveBin] += inc;
822             }
823             for (int i = 0; i < numDisplay; i++) {
824                 final int bin = bk.perDisplayActiveBin[i];
825                 if (bin >= 0) {
826                     perDisplayExpected[i][bin] += inc;
827                 }
828             }
829             clocks.realtime = clocks.uptime = bk.currentTimeMs;
830         };
831 
832         bi.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);
833         bi.noteScreenStateLocked(0, Display.STATE_ON);
834         bi.noteScreenStateLocked(1, Display.STATE_ON);
835 
836         incrementTime.accept(100);
837         bi.noteScreenBrightnessLocked(0, 25);
838         bi.noteScreenBrightnessLocked(1, 25);
839         // floor(25/256*5) = bin 0
840         bk.overallActiveBin = 0;
841         bk.perDisplayActiveBin[0] = 0;
842         bk.perDisplayActiveBin[1] = 0;
843 
844         incrementTime.accept(50);
845         checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
846 
847         incrementTime.accept(13);
848         bi.noteScreenBrightnessLocked(0, 100);
849         // floor(25/256*5) = bin 1
850         bk.overallActiveBin = 1;
851         bk.perDisplayActiveBin[0] = 1;
852 
853         incrementTime.accept(44);
854         checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
855 
856         incrementTime.accept(22);
857         bi.noteScreenBrightnessLocked(1, 200);
858         // floor(200/256*5) = bin 3
859         bk.overallActiveBin = 3;
860         bk.perDisplayActiveBin[1] = 3;
861 
862         incrementTime.accept(33);
863         checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
864 
865         incrementTime.accept(77);
866         bi.noteScreenBrightnessLocked(0, 150);
867         // floor(150/256*5) = bin 2
868         // Overall active bin should not change
869         bk.perDisplayActiveBin[0] = 2;
870 
871         incrementTime.accept(88);
872         checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
873 
874         incrementTime.accept(11);
875         bi.noteScreenStateLocked(1, Display.STATE_OFF);
876         // Display 1 should timers should stop incrementing
877         // Overall active bin should fallback to display 0's bin
878         bk.overallActiveBin = 2;
879         bk.perDisplayActiveBin[1] = -1;
880 
881         incrementTime.accept(99);
882         checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
883 
884         incrementTime.accept(200);
885         bi.noteScreenBrightnessLocked(0, 255);
886         // floor(150/256*5) = bin 4
887         bk.overallActiveBin = 4;
888         bk.perDisplayActiveBin[0] = 4;
889 
890         incrementTime.accept(300);
891         checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
892 
893         incrementTime.accept(200);
894         bi.noteScreenStateLocked(0, Display.STATE_DOZE);
895         // No displays are on. No brightness timers should be active.
896         bk.overallActiveBin = -1;
897         bk.perDisplayActiveBin[0] = -1;
898 
899         incrementTime.accept(300);
900         checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
901 
902         incrementTime.accept(400);
903         bi.noteScreenStateLocked(1, Display.STATE_ON);
904         // Display 1 turned back on.
905         bk.overallActiveBin = 3;
906         bk.perDisplayActiveBin[1] = 3;
907 
908         incrementTime.accept(500);
909         checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
910 
911         incrementTime.accept(600);
912         bi.noteScreenStateLocked(0, Display.STATE_ON);
913         // Display 0 turned back on.
914         bk.overallActiveBin = 4;
915         bk.perDisplayActiveBin[0] = 4;
916 
917         incrementTime.accept(700);
918         checkScreenBrightnesses(overallExpected, perDisplayExpected, bi, bk.currentTimeMs);
919     }
920 
921     @SmallTest
testAlarmStartAndFinishLocked()922     public void testAlarmStartAndFinishLocked() throws Exception {
923         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
924         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
925         bi.setRecordAllHistoryLocked(true);
926         bi.forceRecordAllHistory();
927 
928         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
929         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
930 
931         clocks.realtime = clocks.uptime = 100;
932         bi.noteAlarmStartLocked("foo", null, UID);
933         clocks.realtime = clocks.uptime = 5000;
934         bi.noteAlarmFinishLocked("foo", null, UID);
935 
936         BatteryStatsHistoryIterator iterator = bi.iterateBatteryStatsHistory();
937         HistoryItem item;
938 
939         assertThat(item = iterator.next()).isNotNull();
940         assertEquals(HistoryItem.CMD_RESET, item.cmd);
941         assertEquals(HistoryItem.EVENT_NONE, item.eventCode);
942 
943         assertThat(item = iterator.next()).isNotNull();
944         assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode);
945         assertEquals("foo", item.eventTag.string);
946         assertEquals(UID, item.eventTag.uid);
947 
948         assertThat(item = iterator.next()).isNotNull();
949         assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode);
950         assertTrue(item.isDeltaData());
951         assertEquals("foo", item.eventTag.string);
952         assertEquals(UID, item.eventTag.uid);
953 
954         assertThat(iterator.hasNext()).isFalse();
955         assertThat(iterator.next()).isNull();
956     }
957 
958     @SmallTest
testAlarmStartAndFinishLocked_workSource()959     public void testAlarmStartAndFinishLocked_workSource() throws Exception {
960         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
961         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
962         bi.setRecordAllHistoryLocked(true);
963         bi.forceRecordAllHistory();
964 
965         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
966         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
967 
968         WorkSource ws = new WorkSource();
969         ws.add(100);
970         ws.createWorkChain().addNode(500, "tag");
971         bi.noteAlarmStartLocked("foo", ws, UID);
972         clocks.realtime = clocks.uptime = 5000;
973         bi.noteAlarmFinishLocked("foo", ws, UID);
974 
975         BatteryStatsHistoryIterator iterator = bi.iterateBatteryStatsHistory();
976         HistoryItem item;
977 
978         assertThat(item = iterator.next()).isNotNull();
979         assertEquals(HistoryItem.CMD_RESET, item.cmd);
980         assertEquals(HistoryItem.EVENT_NONE, item.eventCode);
981 
982         assertThat(item = iterator.next()).isNotNull();
983         assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode);
984         assertEquals("foo", item.eventTag.string);
985         assertEquals(100, item.eventTag.uid);
986 
987         assertThat(item = iterator.next()).isNotNull();
988         assertEquals(HistoryItem.EVENT_ALARM_START, item.eventCode);
989         assertEquals("foo", item.eventTag.string);
990         assertEquals(500, item.eventTag.uid);
991 
992         assertThat(item = iterator.next()).isNotNull();
993         assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode);
994         assertEquals("foo", item.eventTag.string);
995         assertEquals(100, item.eventTag.uid);
996 
997         assertThat(item = iterator.next()).isNotNull();
998         assertEquals(HistoryItem.EVENT_ALARM_FINISH, item.eventCode);
999         assertEquals("foo", item.eventTag.string);
1000         assertEquals(500, item.eventTag.uid);
1001     }
1002 
1003     @SmallTest
testNoteWakupAlarmLocked()1004     public void testNoteWakupAlarmLocked() {
1005         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
1006         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
1007         bi.setRecordAllHistoryLocked(true);
1008         bi.forceRecordAllHistory();
1009         bi.mForceOnBattery = true;
1010 
1011         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
1012         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
1013 
1014         bi.noteWakupAlarmLocked("com.foo.bar", UID, null, "tag");
1015 
1016         BatteryStats.Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar");
1017         assertEquals(1, pkg.getWakeupAlarmStats().get("tag").getCountLocked(STATS_SINCE_CHARGED));
1018         assertEquals(1, pkg.getWakeupAlarmStats().size());
1019     }
1020 
1021     @SmallTest
testNoteWakupAlarmLocked_workSource_uid()1022     public void testNoteWakupAlarmLocked_workSource_uid() {
1023         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
1024         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
1025         bi.setRecordAllHistoryLocked(true);
1026         bi.forceRecordAllHistory();
1027         bi.mForceOnBattery = true;
1028 
1029         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
1030         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
1031 
1032         WorkSource ws = new WorkSource();
1033         ws.add(100);
1034 
1035         // When a WorkSource is present, "UID" should not be used - only the uids present in the
1036         // WorkSource should be reported.
1037         bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag");
1038         BatteryStats.Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar");
1039         assertEquals(0, pkg.getWakeupAlarmStats().size());
1040         pkg = bi.getPackageStatsLocked(100, "com.foo.bar");
1041         assertEquals(1, pkg.getWakeupAlarmStats().size());
1042 
1043         // If the WorkSource contains a "name", it should be interpreted as a package name and
1044         // the packageName supplied as an argument must be ignored.
1045         ws = new WorkSource();
1046         ws.add(100, "com.foo.baz_alternate");
1047         bi.noteWakupAlarmLocked("com.foo.baz", UID, ws, "tag");
1048         pkg = bi.getPackageStatsLocked(100, "com.foo.baz");
1049         assertEquals(0, pkg.getWakeupAlarmStats().size());
1050         pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate");
1051         assertEquals(1, pkg.getWakeupAlarmStats().size());
1052     }
1053 
1054     @SmallTest
testNoteWakupAlarmLocked_workSource_workChain()1055     public void testNoteWakupAlarmLocked_workSource_workChain() {
1056         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
1057         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
1058         bi.setRecordAllHistoryLocked(true);
1059         bi.forceRecordAllHistory();
1060         bi.mForceOnBattery = true;
1061 
1062         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
1063         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
1064 
1065         WorkSource ws = new WorkSource();
1066         ws.createWorkChain().addNode(100, "com.foo.baz_alternate");
1067         bi.noteWakupAlarmLocked("com.foo.bar", UID, ws, "tag");
1068 
1069         // For WorkChains, again we must only attribute to the uids present in the WorkSource
1070         // (and not to "UID"). However, unlike the older "tags" we do not change the packagename
1071         // supplied as an argument, given that we're logging the entire attribution chain.
1072         BatteryStats.Uid.Pkg pkg = bi.getPackageStatsLocked(UID, "com.foo.bar");
1073         assertEquals(0, pkg.getWakeupAlarmStats().size());
1074         pkg = bi.getPackageStatsLocked(100, "com.foo.bar");
1075         assertEquals(1, pkg.getWakeupAlarmStats().size());
1076         pkg = bi.getPackageStatsLocked(100, "com.foo.baz_alternate");
1077         assertEquals(0, pkg.getWakeupAlarmStats().size());
1078     }
1079 
1080     @SmallTest
testNoteGpsChanged()1081     public void testNoteGpsChanged() {
1082         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
1083         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
1084         bi.setRecordAllHistoryLocked(true);
1085         bi.forceRecordAllHistory();
1086         bi.mForceOnBattery = true;
1087 
1088         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
1089         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
1090 
1091         WorkSource ws = new WorkSource();
1092         ws.add(UID);
1093 
1094         bi.noteGpsChangedLocked(new WorkSource(), ws);
1095         DualTimer t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false);
1096         assertNotNull(t);
1097         assertTrue(t.isRunningLocked());
1098 
1099         bi.noteGpsChangedLocked(ws, new WorkSource());
1100         t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false);
1101         assertFalse(t.isRunningLocked());
1102     }
1103 
1104     @SmallTest
testNoteGpsChanged_workSource()1105     public void testNoteGpsChanged_workSource() {
1106         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
1107         MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
1108         bi.setRecordAllHistoryLocked(true);
1109         bi.forceRecordAllHistory();
1110         bi.mForceOnBattery = true;
1111 
1112         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
1113         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
1114 
1115         WorkSource ws = new WorkSource();
1116         ws.createWorkChain().addNode(UID, "com.foo");
1117 
1118         bi.noteGpsChangedLocked(new WorkSource(), ws);
1119         DualTimer t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false);
1120         assertNotNull(t);
1121         assertTrue(t.isRunningLocked());
1122 
1123         bi.noteGpsChangedLocked(ws, new WorkSource());
1124         t = bi.getUidStatsLocked(UID).getSensorTimerLocked(Sensor.GPS, false);
1125         assertFalse(t.isRunningLocked());
1126     }
1127 
1128     @SmallTest
testUpdateDisplayMeasuredEnergyStatsLocked()1129     public void testUpdateDisplayMeasuredEnergyStatsLocked() {
1130         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
1131         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
1132         bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"});
1133 
1134         clocks.realtime = 0;
1135         int[] screen = new int[]{Display.STATE_OFF};
1136         boolean battery = false;
1137 
1138         final int uid1 = 10500;
1139         final int uid2 = 10501;
1140         long blame1 = 0;
1141         long blame2 = 0;
1142         long globalDoze = 0;
1143 
1144         // Case A: uid1 off, uid2 off, battery off, screen off
1145         bi.updateTimeBasesLocked(battery, screen[0], clocks.realtime * 1000, 0);
1146         bi.setOnBatteryInternal(battery);
1147         bi.updateDisplayEnergyConsumerStatsLocked(new long[]{500_000}, screen, clocks.realtime);
1148         checkMeasuredCharge("A", uid1, blame1, uid2, blame2, globalDoze, bi);
1149 
1150         // Case B: uid1 off, uid2 off, battery ON,  screen off
1151         clocks.realtime += 17;
1152         battery = true;
1153         bi.updateTimeBasesLocked(battery, screen[0], clocks.realtime * 1000, 0);
1154         bi.setOnBatteryInternal(battery);
1155         clocks.realtime += 19;
1156         bi.updateDisplayEnergyConsumerStatsLocked(new long[]{510_000}, screen, clocks.realtime);
1157         checkMeasuredCharge("B", uid1, blame1, uid2, blame2, globalDoze, bi);
1158 
1159         // Case C: uid1 ON,  uid2 off, battery on,  screen off
1160         clocks.realtime += 18;
1161         setFgState(uid1, true, bi);
1162         clocks.realtime += 18;
1163         bi.updateDisplayEnergyConsumerStatsLocked(new long[]{520_000}, screen, clocks.realtime);
1164         checkMeasuredCharge("C", uid1, blame1, uid2, blame2, globalDoze, bi);
1165 
1166         // Case D: uid1 on,  uid2 off, battery on,  screen ON
1167         clocks.realtime += 17;
1168         screen[0] = Display.STATE_ON;
1169         bi.updateDisplayEnergyConsumerStatsLocked(new long[]{521_000}, screen, clocks.realtime);
1170         blame1 += 0; // Screen had been off during the measurement period
1171         checkMeasuredCharge("D.1", uid1, blame1, uid2, blame2, globalDoze, bi);
1172         clocks.realtime += 101;
1173         bi.updateDisplayEnergyConsumerStatsLocked(new long[]{530_000}, screen, clocks.realtime);
1174         blame1 += 530_000;
1175         checkMeasuredCharge("D.2", uid1, blame1, uid2, blame2, globalDoze, bi);
1176 
1177         // Case E: uid1 on,  uid2 ON,  battery on,  screen on
1178         clocks.realtime += 20;
1179         setFgState(uid2, true, bi);
1180         clocks.realtime += 40;
1181         bi.updateDisplayEnergyConsumerStatsLocked(new long[]{540_000}, screen, clocks.realtime);
1182         // In the past 60ms, sum of fg is 20+40+40=100ms. uid1 is blamed for 60/100; uid2 for 40/100
1183         blame1 += 540_000 * (20 + 40) / (20 + 40 + 40);
1184         blame2 += 540_000 * (0 + 40) / (20 + 40 + 40);
1185         checkMeasuredCharge("E", uid1, blame1, uid2, blame2, globalDoze, bi);
1186 
1187         // Case F: uid1 on,  uid2 OFF, battery on,  screen on
1188         clocks.realtime += 40;
1189         setFgState(uid2, false, bi);
1190         clocks.realtime += 120;
1191         bi.updateDisplayEnergyConsumerStatsLocked(new long[]{550_000}, screen, clocks.realtime);
1192         // In the past 160ms, sum f fg is 200ms. uid1 is blamed for 40+120 of it; uid2 for 40 of it.
1193         blame1 += 550_000 * (40 + 120) / (40 + 40 + 120);
1194         blame2 += 550_000 * (40 + 0) / (40 + 40 + 120);
1195         checkMeasuredCharge("F", uid1, blame1, uid2, blame2, globalDoze, bi);
1196 
1197         // Case G: uid1 on,  uid2 off,  battery on, screen DOZE
1198         clocks.realtime += 5;
1199         screen[0] = Display.STATE_DOZE;
1200         bi.updateDisplayEnergyConsumerStatsLocked(new long[]{570_000}, screen, clocks.realtime);
1201         blame1 += 570_000; // All of this pre-doze time is blamed on uid1.
1202         checkMeasuredCharge("G", uid1, blame1, uid2, blame2, globalDoze, bi);
1203 
1204         // Case H: uid1 on,  uid2 off,  battery on, screen ON
1205         clocks.realtime += 6;
1206         screen[0] = Display.STATE_ON;
1207         bi.updateDisplayEnergyConsumerStatsLocked(new long[]{580_000}, screen, clocks.realtime);
1208         blame1 += 0; // The screen had been doze during the energy period
1209         globalDoze += 580_000;
1210         checkMeasuredCharge("H", uid1, blame1, uid2, blame2, globalDoze, bi);
1211     }
1212 
1213     @SmallTest
testUpdateCustomMeasuredEnergyStatsLocked_neverCalled()1214     public void testUpdateCustomMeasuredEnergyStatsLocked_neverCalled() {
1215         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
1216         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
1217         bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"});
1218         bi.setOnBatteryInternal(true);
1219 
1220         final int uid1 = 11500;
1221         final int uid2 = 11501;
1222 
1223         // Initially, all custom buckets report charge of 0.
1224         checkCustomBatteryConsumption("0", 0, 0, uid1, 0, 0, uid2, 0, 0, bi);
1225     }
1226 
1227     @SmallTest
testUpdateCustomMeasuredEnergyStatsLocked()1228     public void testUpdateCustomMeasuredEnergyStatsLocked() {
1229         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
1230         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
1231         bi.initMeasuredEnergyStats(new String[]{"FOO", "BAR"});
1232 
1233         final int bucketA = 0; // Custom bucket 0
1234         final int bucketB = 1; // Custom bucket 1
1235 
1236         long totalBlameA = 0; // Total charge consumption for bucketA (may exceed sum of uids)
1237         long totalBlameB = 0; // Total charge consumption for bucketB (may exceed sum of uids)
1238 
1239         final int uid1 = 10500;
1240         long blame1A = 0; // Blame for uid1 in bucketA
1241         long blame1B = 0; // Blame for uid1 in bucketB
1242 
1243         final int uid2 = 10501;
1244         long blame2A = 0; // Blame for uid2 in bucketA
1245         long blame2B = 0; // Blame for uid2 in bucketB
1246 
1247         final SparseLongArray newChargesA = new SparseLongArray(2);
1248         final SparseLongArray newChargesB = new SparseLongArray(2);
1249 
1250 
1251         // ----- Case A: battery off (so blame does not increase)
1252         bi.setOnBatteryInternal(false);
1253 
1254         newChargesA.put(uid1, 20_000);
1255         // Implicit newChargesA.put(uid2, 0);
1256         bi.updateCustomEnergyConsumerStatsLocked(bucketA, 500_000, newChargesA);
1257 
1258         newChargesB.put(uid1, 60_000);
1259         // Implicit newChargesB.put(uid2, 0);
1260         bi.updateCustomEnergyConsumerStatsLocked(bucketB, 700_000, newChargesB);
1261 
1262         checkCustomBatteryConsumption(
1263                 "A", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi);
1264 
1265 
1266         // ----- Case B: battery on
1267         bi.setOnBatteryInternal(true);
1268 
1269         newChargesA.put(uid1, 7_000); blame1A += 7_000;
1270         // Implicit newChargesA.put(uid2, 0); blame2A += 0;
1271         bi.updateCustomEnergyConsumerStatsLocked(bucketA, 310_000, newChargesA);
1272         totalBlameA += 310_000;
1273 
1274         newChargesB.put(uid1, 63_000); blame1B += 63_000;
1275         newChargesB.put(uid2, 15_000); blame2B += 15_000;
1276         bi.updateCustomEnergyConsumerStatsLocked(bucketB, 790_000, newChargesB);
1277         totalBlameB += 790_000;
1278 
1279         checkCustomBatteryConsumption(
1280                 "B", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi);
1281 
1282 
1283         // ----- Case C: battery still on
1284         newChargesA.delete(uid1); blame1A += 0;
1285         newChargesA.put(uid2, 16_000); blame2A += 16_000;
1286         bi.updateCustomEnergyConsumerStatsLocked(bucketA, 560_000, newChargesA);
1287         totalBlameA += 560_000;
1288 
1289         bi.updateCustomEnergyConsumerStatsLocked(bucketB, 10_000, null);
1290         totalBlameB += 10_000;
1291 
1292         checkCustomBatteryConsumption(
1293                 "C", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi);
1294 
1295 
1296         // ----- Case D: battery still on
1297         bi.updateCustomEnergyConsumerStatsLocked(bucketA, 0, newChargesA);
1298         bi.updateCustomEnergyConsumerStatsLocked(bucketB, 15_000, new SparseLongArray(1));
1299         totalBlameB += 15_000;
1300         checkCustomBatteryConsumption(
1301                 "D", totalBlameA, totalBlameB, uid1, blame1A, blame1B, uid2, blame2A, blame2B, bi);
1302     }
1303 
1304     @SmallTest
testGetPerStateActiveRadioDurationMs_noModemActivity()1305     public void testGetPerStateActiveRadioDurationMs_noModemActivity() {
1306         final MockClock clock = new MockClock(); // holds realtime and uptime in ms
1307         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
1308         final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
1309         final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
1310         final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
1311 
1312         final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
1313         final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
1314         final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
1315         for (int rat = 0; rat < ratCount; rat++) {
1316             for (int freq = 0; freq < frequencyCount; freq++) {
1317                 // Should have no RX data without Modem Activity Info
1318                 expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
1319                 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
1320                     expectedDurationsMs[rat][freq][txLvl] = 0;
1321                     // Should have no TX data without Modem Activity Info
1322                     expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
1323                 }
1324             }
1325         }
1326 
1327         final ModemAndBatteryState state = new ModemAndBatteryState(bi, null, null);
1328 
1329         IntConsumer incrementTime = inc -> {
1330             state.currentTimeMs += inc;
1331             clock.realtime = clock.uptime = state.currentTimeMs;
1332 
1333             // If the device is not on battery, no timers should increment.
1334             if (!state.onBattery) return;
1335             // If the modem is not active, no timers should increment.
1336             if (!state.modemActive) return;
1337 
1338             final int currentRat = state.currentRat;
1339             final int currentFrequencyRange =
1340                     currentRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0;
1341             int currentSignalStrength = state.currentSignalStrengths.get(currentRat);
1342             expectedDurationsMs[currentRat][currentFrequencyRange][currentSignalStrength] += inc;
1343         };
1344 
1345 
1346         state.setOnBattery(false);
1347         state.setModemActive(false);
1348         state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN,
1349                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
1350         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN);
1351         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
1352                 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
1353         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1354                 expectedTxDurationsMs, bi, state.currentTimeMs);
1355 
1356         // While not on battery, the timers should not increase.
1357         state.setModemActive(true);
1358         incrementTime.accept(100);
1359         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1360                 expectedTxDurationsMs, bi, state.currentTimeMs);
1361 
1362         state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
1363         incrementTime.accept(200);
1364         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1365                 expectedTxDurationsMs, bi, state.currentTimeMs);
1366 
1367         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
1368                 CellSignalStrength.SIGNAL_STRENGTH_GOOD);
1369         incrementTime.accept(500);
1370         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1371                 expectedTxDurationsMs, bi, state.currentTimeMs);
1372 
1373         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE);
1374         incrementTime.accept(300);
1375         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1376                 expectedTxDurationsMs, bi, state.currentTimeMs);
1377 
1378         state.setRatType(TelephonyManager.NETWORK_TYPE_LTE,
1379                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE);
1380         incrementTime.accept(400);
1381         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1382                 expectedTxDurationsMs, bi, state.currentTimeMs);
1383 
1384         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1385                 CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
1386         incrementTime.accept(500);
1387         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1388                 expectedTxDurationsMs, bi, state.currentTimeMs);
1389 
1390         // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should
1391         // start counting up.
1392         state.setOnBattery(true);
1393         incrementTime.accept(600);
1394         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1395                 expectedTxDurationsMs, bi, state.currentTimeMs);
1396         // Changing LTE signal strength should be tracked.
1397         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1398                 CellSignalStrength.SIGNAL_STRENGTH_POOR);
1399         incrementTime.accept(700);
1400         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1401                 expectedTxDurationsMs, bi, state.currentTimeMs);
1402 
1403         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1404                 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
1405         incrementTime.accept(800);
1406         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1407                 expectedTxDurationsMs, bi, state.currentTimeMs);
1408 
1409         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1410                 CellSignalStrength.SIGNAL_STRENGTH_GOOD);
1411         incrementTime.accept(900);
1412         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1413                 expectedTxDurationsMs, bi, state.currentTimeMs);
1414 
1415         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1416                 CellSignalStrength.SIGNAL_STRENGTH_GREAT);
1417         incrementTime.accept(1000);
1418         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1419                 expectedTxDurationsMs, bi, state.currentTimeMs);
1420 
1421         // Change in the signal strength of nonactive RAT should not affect anything.
1422         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
1423                 CellSignalStrength.SIGNAL_STRENGTH_POOR);
1424         incrementTime.accept(1100);
1425         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1426                 expectedTxDurationsMs, bi, state.currentTimeMs);
1427 
1428         // Changing to OTHER Rat should start tracking the poor signal strength.
1429         state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA,
1430                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
1431         incrementTime.accept(1200);
1432         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1433                 expectedTxDurationsMs, bi, state.currentTimeMs);
1434 
1435         // Noting frequency change should not affect non NR Rat.
1436         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH);
1437         incrementTime.accept(1300);
1438         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1439                 expectedTxDurationsMs, bi, state.currentTimeMs);
1440 
1441         // Now the NR Rat, HIGH frequency range, good signal strength should start counting.
1442         state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
1443         incrementTime.accept(1400);
1444         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1445                 expectedTxDurationsMs, bi, state.currentTimeMs);
1446 
1447         // Noting frequency change should not affect non NR Rat.
1448         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
1449         incrementTime.accept(1500);
1450         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1451                 expectedTxDurationsMs, bi, state.currentTimeMs);
1452 
1453         // Modem no longer active, should not be tracking any more.
1454         state.setModemActive(false);
1455         incrementTime.accept(1500);
1456         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1457                 expectedTxDurationsMs, bi, state.currentTimeMs);
1458     }
1459 
1460     @SmallTest
testGetPerStateActiveRadioDurationMs_initialModemActivity()1461     public void testGetPerStateActiveRadioDurationMs_initialModemActivity() {
1462         final MockClock clock = new MockClock(); // holds realtime and uptime in ms
1463         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
1464         bi.setPowerProfile(mock(PowerProfile.class));
1465 
1466         final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
1467         final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
1468         final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
1469 
1470         List<ActivityStatsTechSpecificInfo> specificInfoList = new ArrayList();
1471 
1472         final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
1473         final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
1474         final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
1475         for (int rat = 0; rat < ratCount; rat++) {
1476             for (int freq = 0; freq < frequencyCount; freq++) {
1477                 if (rat == RADIO_ACCESS_TECHNOLOGY_NR
1478                         || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
1479                     // Only the NR RAT should have per frequency data.
1480                     expectedRxDurationsMs[rat][freq] = 0;
1481                 } else {
1482                     expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
1483                 }
1484                 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
1485                     if (rat == RADIO_ACCESS_TECHNOLOGY_NR
1486                             || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
1487                         // Only the NR RAT should have per frequency data.
1488                         expectedTxDurationsMs[rat][freq][txLvl] = 0;
1489                     } else {
1490                         expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
1491                     }
1492                 }
1493             }
1494         }
1495 
1496         // The first modem activity pulled from modem with activity stats for each RATs.
1497         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1498                 AccessNetworkConstants.AccessNetworkType.UNKNOWN,
1499                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 101));
1500         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1501                 AccessNetworkConstants.AccessNetworkType.GERAN,
1502                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 202));
1503         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1504                 AccessNetworkConstants.AccessNetworkType.UTRAN,
1505                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 303));
1506         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1507                 AccessNetworkConstants.AccessNetworkType.EUTRAN,
1508                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[]{3, 9, 133, 48, 218}, 404));
1509         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1510                 AccessNetworkConstants.AccessNetworkType.CDMA2000,
1511                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 505));
1512         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1513                 AccessNetworkConstants.AccessNetworkType.IWLAN,
1514                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 606));
1515         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1516                 AccessNetworkConstants.AccessNetworkType.NGRAN,
1517                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 707));
1518         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1519                 AccessNetworkConstants.AccessNetworkType.NGRAN,
1520                 ServiceState.FREQUENCY_RANGE_LOW, new int[txLevelCount], 808));
1521         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1522                 AccessNetworkConstants.AccessNetworkType.NGRAN,
1523                 ServiceState.FREQUENCY_RANGE_MID, new int[txLevelCount], 909));
1524         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1525                 AccessNetworkConstants.AccessNetworkType.NGRAN,
1526                 ServiceState.FREQUENCY_RANGE_HIGH, new int[txLevelCount], 1010));
1527         specificInfoList.add(new ActivityStatsTechSpecificInfo(
1528                 AccessNetworkConstants.AccessNetworkType.NGRAN,
1529                 ServiceState.FREQUENCY_RANGE_MMWAVE, new int[txLevelCount], 1111));
1530 
1531 
1532         final ActivityStatsTechSpecificInfo[] specificInfos = specificInfoList.toArray(
1533                 new ActivityStatsTechSpecificInfo[specificInfoList.size()]);
1534         final ModemActivityInfo mai = new ModemActivityInfo(0L, 2002L, 3003L, specificInfos);
1535         final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, specificInfos);
1536 
1537 
1538         IntConsumer incrementTime = inc -> {
1539             state.currentTimeMs += inc;
1540             clock.realtime = clock.uptime = state.currentTimeMs;
1541 
1542             final int currRat = state.currentRat;
1543             final int currRant = state.currentRadioAccessNetworkType;
1544             final int currFreqRange =
1545                     currRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0;
1546             int currSignalStrength = state.currentSignalStrengths.get(currRat);
1547 
1548             if (state.modemActive) {
1549                 // Don't count the duration if the modem is not active
1550                 expectedDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
1551             }
1552 
1553             // Evaluate the HAL provided time in states.
1554             final ActivityStatsTechSpecificInfo info = state.getSpecificInfo(currRant,
1555                     currFreqRange);
1556             switch (state.modemState) {
1557                 case SLEEP:
1558                     long sleepMs = state.modemActivityInfo.getSleepTimeMillis();
1559                     state.modemActivityInfo.setSleepTimeMillis(sleepMs + inc);
1560                     break;
1561                 case IDLE:
1562                     long idleMs = state.modemActivityInfo.getIdleTimeMillis();
1563                     state.modemActivityInfo.setIdleTimeMillis(idleMs + inc);
1564                     break;
1565                 case RECEIVING:
1566                     long rxMs = info.getReceiveTimeMillis();
1567                     info.setReceiveTimeMillis(rxMs + inc);
1568                     expectedRxDurationsMs[currRat][currFreqRange] += inc;
1569                     break;
1570                 case TRANSMITTING:
1571                     int[] txMs = info.getTransmitTimeMillis().clone();
1572                     txMs[currSignalStrength] += inc;
1573                     info.setTransmitTimeMillis(txMs);
1574                     expectedTxDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
1575                     break;
1576             }
1577         };
1578 
1579         // On battery, but the modem is not active
1580         bi.updateTimeBasesLocked(true, Display.STATE_OFF, state.currentTimeMs * 1000,
1581                 state.currentTimeMs * 1000);
1582         bi.setOnBatteryInternal(true);
1583         state.noteModemControllerActivity();
1584         // Ensure the first modem activity should not be counted up.
1585         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1586                 expectedTxDurationsMs, bi, state.currentTimeMs);
1587         // Start counting.
1588         state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
1589                 AccessNetworkConstants.AccessNetworkType.NGRAN);
1590         // Frequency changed to low.
1591         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
1592         incrementTime.accept(300);
1593         state.setModemState(ModemState.RECEIVING);
1594         incrementTime.accept(500);
1595         state.setModemState(ModemState.TRANSMITTING);
1596         incrementTime.accept(600);
1597         state.noteModemControllerActivity();
1598         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1599                 expectedTxDurationsMs, bi, state.currentTimeMs);
1600     }
1601 
1602     @SmallTest
testGetPerStateActiveRadioDurationMs_withModemActivity()1603     public void testGetPerStateActiveRadioDurationMs_withModemActivity() {
1604         final MockClock clock = new MockClock(); // holds realtime and uptime in ms
1605         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
1606         bi.setPowerProfile(mock(PowerProfile.class));
1607         final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
1608         final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
1609         final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
1610 
1611         final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
1612         final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
1613         final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
1614         for (int rat = 0; rat < ratCount; rat++) {
1615             for (int freq = 0; freq < frequencyCount; freq++) {
1616                 expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
1617 
1618                 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
1619                     expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
1620                 }
1621             }
1622         }
1623 
1624         final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L);
1625         final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, null);
1626 
1627         IntConsumer incrementTime = inc -> {
1628             state.currentTimeMs += inc;
1629             clock.realtime = clock.uptime = state.currentTimeMs;
1630 
1631             // If the device is not on battery, no timers should increment.
1632             if (!state.onBattery) return;
1633             // If the modem is not active, no timers should increment.
1634             if (!state.modemActive) return;
1635 
1636             final int currRat = state.currentRat;
1637             final int currFreqRange =
1638                     currRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0;
1639             int currSignalStrength = state.currentSignalStrengths.get(currRat);
1640 
1641             expectedDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
1642 
1643             // Evaluate the HAL provided time in states.
1644             switch (state.modemState) {
1645                 case SLEEP:
1646                     long sleepMs = state.modemActivityInfo.getSleepTimeMillis();
1647                     state.modemActivityInfo.setSleepTimeMillis(sleepMs + inc);
1648                     break;
1649                 case IDLE:
1650                     long idleMs = state.modemActivityInfo.getIdleTimeMillis();
1651                     state.modemActivityInfo.setIdleTimeMillis(idleMs + inc);
1652                     break;
1653                 case RECEIVING:
1654                     long rxMs = state.modemActivityInfo.getReceiveTimeMillis();
1655                     state.modemActivityInfo.setReceiveTimeMillis(rxMs + inc);
1656                     expectedRxDurationsMs[currRat][currFreqRange] += inc;
1657                     break;
1658                 case TRANSMITTING:
1659                     int[] txMs = state.modemActivityInfo.getTransmitTimeMillis();
1660                     txMs[currSignalStrength] += inc;
1661                     state.modemActivityInfo.setTransmitTimeMillis(txMs);
1662                     expectedTxDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
1663                     break;
1664             }
1665         };
1666 
1667         state.setOnBattery(false);
1668         state.setModemActive(false);
1669         state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN,
1670                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
1671         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN);
1672         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
1673                 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
1674         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1675                 expectedTxDurationsMs, bi, state.currentTimeMs);
1676 
1677         // While not on battery, the timers should not increase.
1678         state.setModemActive(true);
1679         incrementTime.accept(100);
1680         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1681                 expectedTxDurationsMs, bi, state.currentTimeMs);
1682 
1683         state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
1684         incrementTime.accept(200);
1685         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1686                 expectedTxDurationsMs, bi, state.currentTimeMs);
1687 
1688         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
1689                 CellSignalStrength.SIGNAL_STRENGTH_GOOD);
1690         incrementTime.accept(500);
1691         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1692                 expectedTxDurationsMs, bi, state.currentTimeMs);
1693 
1694         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE);
1695         incrementTime.accept(300);
1696         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1697                 expectedTxDurationsMs, bi, state.currentTimeMs);
1698 
1699         state.setRatType(TelephonyManager.NETWORK_TYPE_LTE,
1700                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE);
1701         incrementTime.accept(400);
1702         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1703                 expectedTxDurationsMs, bi, state.currentTimeMs);
1704 
1705         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1706                 CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
1707         incrementTime.accept(500);
1708         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1709                 expectedTxDurationsMs, bi, state.currentTimeMs);
1710 
1711         // Data will now be available.
1712         for (int rat = 0; rat < ratCount; rat++) {
1713             for (int freq = 0; freq < frequencyCount; freq++) {
1714                 if (rat == RADIO_ACCESS_TECHNOLOGY_NR
1715                         || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
1716                     // Only the NR RAT should have per frequency data.
1717                     expectedRxDurationsMs[rat][freq] = 0;
1718                 }
1719                 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
1720                     if (rat == RADIO_ACCESS_TECHNOLOGY_NR
1721                             || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
1722                         // Only the NR RAT should have per frequency data.
1723                         expectedTxDurationsMs[rat][freq][txLvl] = 0;
1724                     }
1725                 }
1726             }
1727         }
1728 
1729         // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should
1730         // start counting up.
1731         state.setOnBattery(true);
1732         incrementTime.accept(300);
1733         state.setModemState(ModemState.RECEIVING);
1734         incrementTime.accept(500);
1735         state.setModemState(ModemState.TRANSMITTING);
1736         incrementTime.accept(600);
1737         state.noteModemControllerActivity();
1738         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1739                 expectedTxDurationsMs, bi, state.currentTimeMs);
1740         // Changing LTE signal strength should be tracked.
1741         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1742                 CellSignalStrength.SIGNAL_STRENGTH_POOR);
1743         incrementTime.accept(300);
1744         state.setModemState(ModemState.SLEEP);
1745         incrementTime.accept(1000);
1746         state.setModemState(ModemState.RECEIVING);
1747         incrementTime.accept(700);
1748         state.noteModemControllerActivity();
1749         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1750                 expectedTxDurationsMs, bi, state.currentTimeMs);
1751 
1752         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1753                 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
1754         incrementTime.accept(800);
1755         state.setModemState(ModemState.TRANSMITTING);
1756         incrementTime.accept(222);
1757         state.setModemState(ModemState.IDLE);
1758         incrementTime.accept(111);
1759         state.setModemState(ModemState.RECEIVING);
1760         incrementTime.accept(7777);
1761         state.noteModemControllerActivity();
1762         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1763                 expectedTxDurationsMs, bi, state.currentTimeMs);
1764 
1765         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1766                 CellSignalStrength.SIGNAL_STRENGTH_GOOD);
1767         incrementTime.accept(88);
1768         state.setModemState(ModemState.TRANSMITTING);
1769         incrementTime.accept(900);
1770         state.noteModemControllerActivity();
1771         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1772                 expectedTxDurationsMs, bi, state.currentTimeMs);
1773 
1774         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1775                 CellSignalStrength.SIGNAL_STRENGTH_GREAT);
1776         incrementTime.accept(123);
1777         state.setModemState(ModemState.RECEIVING);
1778         incrementTime.accept(333);
1779         state.setModemState(ModemState.TRANSMITTING);
1780         incrementTime.accept(1000);
1781         state.setModemState(ModemState.RECEIVING);
1782         incrementTime.accept(555);
1783         state.noteModemControllerActivity();
1784         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1785                 expectedTxDurationsMs, bi, state.currentTimeMs);
1786 
1787         // Change in the signal strength of nonactive RAT should not affect anything.
1788         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
1789                 CellSignalStrength.SIGNAL_STRENGTH_POOR);
1790         incrementTime.accept(631);
1791         state.setModemState(ModemState.TRANSMITTING);
1792         incrementTime.accept(321);
1793         state.setModemState(ModemState.RECEIVING);
1794         incrementTime.accept(99);
1795         state.noteModemControllerActivity();
1796         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1797                 expectedTxDurationsMs, bi, state.currentTimeMs);
1798 
1799         // Changing to OTHER Rat should start tracking the poor signal strength.
1800         state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA,
1801                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER);
1802         incrementTime.accept(1200);
1803         state.noteModemControllerActivity();
1804         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1805                 expectedTxDurationsMs, bi, state.currentTimeMs);
1806 
1807         // Noting frequency change should not affect non NR Rat.
1808         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH);
1809         incrementTime.accept(444);
1810         state.setModemState(ModemState.TRANSMITTING);
1811         incrementTime.accept(1300);
1812         state.noteModemControllerActivity();
1813         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1814                 expectedTxDurationsMs, bi, state.currentTimeMs);
1815 
1816         // Now the NR Rat, HIGH frequency range, good signal strength should start counting.
1817         state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR);
1818         incrementTime.accept(1400);
1819         state.noteModemControllerActivity();
1820         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1821                 expectedTxDurationsMs, bi, state.currentTimeMs);
1822 
1823         // Frequency changed to low.
1824         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
1825         incrementTime.accept(852);
1826         state.setModemState(ModemState.RECEIVING);
1827         incrementTime.accept(157);
1828         state.setModemState(ModemState.TRANSMITTING);
1829         incrementTime.accept(1500);
1830         state.noteModemControllerActivity();
1831         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1832                 expectedTxDurationsMs, bi, state.currentTimeMs);
1833 
1834         // Modem no longer active, should not be tracking any more.
1835         state.setModemActive(false);
1836         incrementTime.accept(1500);
1837         state.noteModemControllerActivity();
1838         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1839                 expectedTxDurationsMs, bi, state.currentTimeMs);
1840     }
1841 
1842     @SmallTest
testGetPerStateActiveRadioDurationMs_withSpecificInfoModemActivity()1843     public void testGetPerStateActiveRadioDurationMs_withSpecificInfoModemActivity() {
1844         final MockClock clock = new MockClock(); // holds realtime and uptime in ms
1845         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
1846         bi.setPowerProfile(mock(PowerProfile.class));
1847         final int ratCount = RADIO_ACCESS_TECHNOLOGY_COUNT;
1848         final int frequencyCount = ServiceState.FREQUENCY_RANGE_MMWAVE + 1;
1849         final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
1850 
1851         List<ActivityStatsTechSpecificInfo> specificInfoList = new ArrayList();
1852 
1853         final long[][][] expectedDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
1854         final long[][] expectedRxDurationsMs = new long[ratCount][frequencyCount];
1855         final long[][][] expectedTxDurationsMs = new long[ratCount][frequencyCount][txLevelCount];
1856         for (int rat = 0; rat < ratCount; rat++) {
1857             for (int freq = 0; freq < frequencyCount; freq++) {
1858                 if (rat == RADIO_ACCESS_TECHNOLOGY_NR
1859                         || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
1860                     // Initialize available specific Modem info
1861                     specificInfoList.add(
1862                             new ActivityStatsTechSpecificInfo(rat, freq, new int[txLevelCount], 0));
1863                 }
1864                 expectedRxDurationsMs[rat][freq] = POWER_DATA_UNAVAILABLE;
1865 
1866                 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
1867                     expectedTxDurationsMs[rat][freq][txLvl] = POWER_DATA_UNAVAILABLE;
1868                 }
1869             }
1870         }
1871 
1872         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.UNKNOWN,
1873                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
1874         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.GERAN,
1875                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
1876         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.UTRAN,
1877                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
1878         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.EUTRAN,
1879                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
1880         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.CDMA2000,
1881                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
1882         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.IWLAN,
1883                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
1884         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
1885                 ServiceState.FREQUENCY_RANGE_UNKNOWN, new int[txLevelCount], 0));
1886         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
1887                 ServiceState.FREQUENCY_RANGE_LOW, new int[txLevelCount], 0));
1888         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
1889                 ServiceState.FREQUENCY_RANGE_MID, new int[txLevelCount], 0));
1890         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
1891                 ServiceState.FREQUENCY_RANGE_HIGH, new int[txLevelCount], 0));
1892         specificInfoList.add(new ActivityStatsTechSpecificInfo(AccessNetwork.NGRAN,
1893                 ServiceState.FREQUENCY_RANGE_MMWAVE, new int[txLevelCount], 0));
1894 
1895         final ActivityStatsTechSpecificInfo[] specificInfos = specificInfoList.toArray(
1896                 new ActivityStatsTechSpecificInfo[specificInfoList.size()]);
1897         final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, specificInfos);
1898         final ModemAndBatteryState state = new ModemAndBatteryState(bi, mai, specificInfos);
1899 
1900         IntConsumer incrementTime = inc -> {
1901             state.currentTimeMs += inc;
1902             clock.realtime = clock.uptime = state.currentTimeMs;
1903 
1904             // If the device is not on battery, no timers should increment.
1905             if (!state.onBattery) return;
1906             // If the modem is not active, no timers should increment.
1907             if (!state.modemActive) return;
1908 
1909             final int currRat = state.currentRat;
1910             final int currRant = state.currentRadioAccessNetworkType;
1911             final int currFreqRange =
1912                     currRat == RADIO_ACCESS_TECHNOLOGY_NR ? state.currentFrequencyRange : 0;
1913             int currSignalStrength = state.currentSignalStrengths.get(currRat);
1914 
1915             expectedDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
1916 
1917             // Evaluate the HAL provided time in states.
1918             final ActivityStatsTechSpecificInfo info = state.getSpecificInfo(currRant,
1919                     currFreqRange);
1920             switch (state.modemState) {
1921                 case SLEEP:
1922                     long sleepMs = state.modemActivityInfo.getSleepTimeMillis();
1923                     state.modemActivityInfo.setSleepTimeMillis(sleepMs + inc);
1924                     break;
1925                 case IDLE:
1926                     long idleMs = state.modemActivityInfo.getIdleTimeMillis();
1927                     state.modemActivityInfo.setIdleTimeMillis(idleMs + inc);
1928                     break;
1929                 case RECEIVING:
1930                     long rxMs = info.getReceiveTimeMillis();
1931                     info.setReceiveTimeMillis(rxMs + inc);
1932                     expectedRxDurationsMs[currRat][currFreqRange] += inc;
1933                     break;
1934                 case TRANSMITTING:
1935                     int[] txMs = info.getTransmitTimeMillis().clone();
1936                     txMs[currSignalStrength] += inc;
1937                     info.setTransmitTimeMillis(txMs);
1938                     expectedTxDurationsMs[currRat][currFreqRange][currSignalStrength] += inc;
1939                     break;
1940             }
1941         };
1942 
1943         state.setOnBattery(false);
1944         state.setModemActive(false);
1945         state.setRatType(TelephonyManager.NETWORK_TYPE_UNKNOWN,
1946                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
1947                 AccessNetworkConstants.AccessNetworkType.UNKNOWN);
1948         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_UNKNOWN);
1949         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
1950                 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
1951         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1952                 expectedTxDurationsMs, bi, state.currentTimeMs);
1953 
1954         // While not on battery, the timers should not increase.
1955         state.setModemActive(true);
1956         incrementTime.accept(100);
1957         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1958                 expectedTxDurationsMs, bi, state.currentTimeMs);
1959 
1960         state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
1961                 AccessNetworkConstants.AccessNetworkType.NGRAN);
1962         incrementTime.accept(200);
1963         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1964                 expectedTxDurationsMs, bi, state.currentTimeMs);
1965 
1966         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
1967                 CellSignalStrength.SIGNAL_STRENGTH_GOOD);
1968         incrementTime.accept(500);
1969         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1970                 expectedTxDurationsMs, bi, state.currentTimeMs);
1971 
1972         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_MMWAVE);
1973         incrementTime.accept(300);
1974         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1975                 expectedTxDurationsMs, bi, state.currentTimeMs);
1976 
1977         state.setRatType(TelephonyManager.NETWORK_TYPE_LTE,
1978                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1979                 AccessNetworkConstants.AccessNetworkType.EUTRAN);
1980         incrementTime.accept(400);
1981         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1982                 expectedTxDurationsMs, bi, state.currentTimeMs);
1983 
1984         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
1985                 CellSignalStrength.SIGNAL_STRENGTH_MODERATE);
1986         incrementTime.accept(500);
1987         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
1988                 expectedTxDurationsMs, bi, state.currentTimeMs);
1989 
1990         // Data will now be available.
1991         for (int rat = 0; rat < ratCount; rat++) {
1992             for (int freq = 0; freq < frequencyCount; freq++) {
1993                 if (rat == RADIO_ACCESS_TECHNOLOGY_NR
1994                         || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
1995                     // Only the NR RAT should have per frequency data.
1996                     expectedRxDurationsMs[rat][freq] = 0;
1997                 }
1998                 for (int txLvl = 0; txLvl < txLevelCount; txLvl++) {
1999                     if (rat == RADIO_ACCESS_TECHNOLOGY_NR
2000                             || freq == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
2001                         // Only the NR RAT should have per frequency data.
2002                         expectedTxDurationsMs[rat][freq][txLvl] = 0;
2003                     }
2004                 }
2005             }
2006         }
2007 
2008         // When set on battery, currently active state (RAT:LTE, Signal Strength:Moderate) should
2009         // start counting up.
2010         state.setOnBattery(true);
2011         state.noteModemControllerActivity();
2012         incrementTime.accept(300);
2013         state.setModemState(ModemState.RECEIVING);
2014         incrementTime.accept(500);
2015         state.setModemState(ModemState.TRANSMITTING);
2016         incrementTime.accept(600);
2017         state.noteModemControllerActivity();
2018         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2019                 expectedTxDurationsMs, bi, state.currentTimeMs);
2020         // Changing LTE signal strength should be tracked.
2021         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
2022                 CellSignalStrength.SIGNAL_STRENGTH_POOR);
2023         incrementTime.accept(300);
2024         state.setModemState(ModemState.SLEEP);
2025         incrementTime.accept(1000);
2026         state.setModemState(ModemState.RECEIVING);
2027         incrementTime.accept(700);
2028         state.noteModemControllerActivity();
2029         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2030                 expectedTxDurationsMs, bi, state.currentTimeMs);
2031 
2032         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
2033                 CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN);
2034         incrementTime.accept(800);
2035         state.setModemState(ModemState.TRANSMITTING);
2036         incrementTime.accept(222);
2037         state.setModemState(ModemState.IDLE);
2038         incrementTime.accept(111);
2039         state.setModemState(ModemState.RECEIVING);
2040         incrementTime.accept(7777);
2041         state.noteModemControllerActivity();
2042         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2043                 expectedTxDurationsMs, bi, state.currentTimeMs);
2044 
2045         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
2046                 CellSignalStrength.SIGNAL_STRENGTH_GOOD);
2047         incrementTime.accept(88);
2048         state.setModemState(ModemState.TRANSMITTING);
2049         incrementTime.accept(900);
2050         state.noteModemControllerActivity();
2051         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2052                 expectedTxDurationsMs, bi, state.currentTimeMs);
2053 
2054         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_LTE,
2055                 CellSignalStrength.SIGNAL_STRENGTH_GREAT);
2056         incrementTime.accept(123);
2057         state.setModemState(ModemState.RECEIVING);
2058         incrementTime.accept(333);
2059         state.setModemState(ModemState.TRANSMITTING);
2060         incrementTime.accept(1000);
2061         state.setModemState(ModemState.RECEIVING);
2062         incrementTime.accept(555);
2063         state.noteModemControllerActivity();
2064         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2065                 expectedTxDurationsMs, bi, state.currentTimeMs);
2066 
2067         // Change in the signal strength of nonactive RAT should not affect anything.
2068         state.setSignalStrength(BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
2069                 CellSignalStrength.SIGNAL_STRENGTH_POOR);
2070         incrementTime.accept(631);
2071         state.setModemState(ModemState.TRANSMITTING);
2072         incrementTime.accept(321);
2073         state.setModemState(ModemState.RECEIVING);
2074         incrementTime.accept(99);
2075         state.noteModemControllerActivity();
2076         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2077                 expectedTxDurationsMs, bi, state.currentTimeMs);
2078 
2079         // Changing to OTHER Rat should start tracking the poor signal strength.
2080         state.setRatType(TelephonyManager.NETWORK_TYPE_CDMA,
2081                 BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER,
2082                 AccessNetworkConstants.AccessNetworkType.CDMA2000);
2083         incrementTime.accept(1200);
2084         state.noteModemControllerActivity();
2085         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2086                 expectedTxDurationsMs, bi, state.currentTimeMs);
2087 
2088         // Noting frequency change should not affect non NR Rat.
2089         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_HIGH);
2090         incrementTime.accept(444);
2091         state.setModemState(ModemState.TRANSMITTING);
2092         incrementTime.accept(1300);
2093         state.noteModemControllerActivity();
2094         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2095                 expectedTxDurationsMs, bi, state.currentTimeMs);
2096 
2097         // Now the NR Rat, HIGH frequency range, good signal strength should start counting.
2098         state.setRatType(TelephonyManager.NETWORK_TYPE_NR, BatteryStats.RADIO_ACCESS_TECHNOLOGY_NR,
2099                 AccessNetworkConstants.AccessNetworkType.NGRAN);
2100         incrementTime.accept(1400);
2101         state.noteModemControllerActivity();
2102         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2103                 expectedTxDurationsMs, bi, state.currentTimeMs);
2104 
2105         // Frequency changed to low.
2106         state.setFrequencyRange(ServiceState.FREQUENCY_RANGE_LOW);
2107         incrementTime.accept(852);
2108         state.setModemState(ModemState.RECEIVING);
2109         incrementTime.accept(157);
2110         state.setModemState(ModemState.TRANSMITTING);
2111         incrementTime.accept(1500);
2112         state.noteModemControllerActivity();
2113         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2114                 expectedTxDurationsMs, bi, state.currentTimeMs);
2115 
2116         // Modem no longer active, should not be tracking any more.
2117         state.setModemActive(false);
2118         incrementTime.accept(1500);
2119         state.noteModemControllerActivity();
2120         checkPerStateActiveRadioDurations(expectedDurationsMs, expectedRxDurationsMs,
2121                 expectedTxDurationsMs, bi, state.currentTimeMs);
2122     }
2123 
2124     @SmallTest
2125     @SuppressWarnings("GuardedBy")
testProcStateSyncScheduling_mobileRadioActiveState()2126     public void testProcStateSyncScheduling_mobileRadioActiveState() {
2127         final MockClock clock = new MockClock(); // holds realtime and uptime in ms
2128         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clock);
2129         final MutableInt lastProcStateChangeFlags = new MutableInt(0);
2130 
2131         MockBatteryStatsImpl.DummyExternalStatsSync externalStatsSync =
2132                 new MockBatteryStatsImpl.DummyExternalStatsSync() {
2133                     @Override
2134                     public void scheduleSyncDueToProcessStateChange(int flags,
2135                             long delayMillis) {
2136                         lastProcStateChangeFlags.value = flags;
2137                     }
2138                 };
2139 
2140         bi.setDummyExternalStatsSync(externalStatsSync);
2141 
2142         bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
2143 
2144         // Note mobile radio is on.
2145         long curr = 1000L * (clock.realtime = clock.uptime = 1001);
2146         bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr,
2147                 UID);
2148 
2149         lastProcStateChangeFlags.value = 0;
2150         clock.realtime = clock.uptime = 2002;
2151         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND);
2152 
2153         final int allProcFlags = BatteryStatsImpl.ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE;
2154         assertEquals(allProcFlags, lastProcStateChangeFlags.value);
2155 
2156         // Note mobile radio is off.
2157         curr = 1000L * (clock.realtime = clock.uptime = 3003);
2158         bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW, curr,
2159                 UID);
2160 
2161         lastProcStateChangeFlags.value = 0;
2162         clock.realtime = clock.uptime = 4004;
2163         bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2164 
2165         final int noRadioProcFlags = BatteryStatsImpl.ExternalStatsSync.UPDATE_ON_PROC_STATE_CHANGE
2166                 & ~BatteryStatsImpl.ExternalStatsSync.UPDATE_RADIO;
2167         assertEquals(
2168                 "An inactive radio should not be queried on proc state change",
2169                 noRadioProcFlags, lastProcStateChangeFlags.value);
2170     }
2171 
2172     @SmallTest
testNoteMobileRadioPowerStateLocked()2173     public void testNoteMobileRadioPowerStateLocked() {
2174         long curr;
2175         boolean update;
2176         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
2177         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
2178         bi.setOnBatteryInternal(true);
2179 
2180         // Note mobile radio is on.
2181         curr = 1000L * (clocks.realtime = clocks.uptime = 1001);
2182         bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr,
2183                 UID);
2184 
2185         // Note mobile radio is still on.
2186         curr = 1000L * (clocks.realtime = clocks.uptime = 2001);
2187         update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH,
2188                 curr, UID);
2189         assertFalse(
2190                 "noteMobileRadioPowerStateLocked should not request an update when the power "
2191                         + "state does not change from HIGH.",
2192                 update);
2193 
2194         // Note mobile radio is off.
2195         curr = 1000L * (clocks.realtime = clocks.uptime = 3001);
2196         update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW,
2197                 curr, UID);
2198         assertTrue(
2199                 "noteMobileRadioPowerStateLocked should request an update when the power state "
2200                         + "changes from HIGH to LOW.",
2201                 update);
2202 
2203         // Note mobile radio is still off.
2204         curr = 1000L * (clocks.realtime = clocks.uptime = 4001);
2205         update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW,
2206                 curr, UID);
2207         assertFalse(
2208                 "noteMobileRadioPowerStateLocked should not request an update when the power "
2209                         + "state does not change from LOW.",
2210                 update);
2211 
2212         // Note mobile radio is on.
2213         curr = 1000L * (clocks.realtime = clocks.uptime = 5001);
2214         update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH,
2215                 curr, UID);
2216         assertFalse(
2217                 "noteMobileRadioPowerStateLocked should not request an update when the power "
2218                         + "state changes from LOW to HIGH.",
2219                 update);
2220     }
2221 
2222     @SmallTest
testNoteMobileRadioPowerStateLocked_rateLimited()2223     public void testNoteMobileRadioPowerStateLocked_rateLimited() {
2224         long curr;
2225         boolean update;
2226         final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
2227         final MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
2228         bi.setPowerProfile(mock(PowerProfile.class));
2229 
2230         final int txLevelCount = CellSignalStrength.getNumSignalStrengthLevels();
2231         final ModemActivityInfo mai = new ModemActivityInfo(0L, 0L, 0L, new int[txLevelCount], 0L);
2232 
2233         final long rateLimit = bi.getMobileRadioPowerStateUpdateRateLimit();
2234         if (rateLimit < 0) {
2235             Log.w(TAG, "Skipping testNoteMobileRadioPowerStateLocked_rateLimited, rateLimit = "
2236                     + rateLimit);
2237             return;
2238         }
2239         bi.setOnBatteryInternal(true);
2240 
2241         // Note mobile radio is on.
2242         curr = 1000L * (clocks.realtime = clocks.uptime = 1001);
2243         bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr,
2244                 UID);
2245 
2246         clocks.realtime = clocks.uptime = 2001;
2247         mai.setTimestamp(clocks.realtime);
2248         bi.noteModemControllerActivity(mai, POWER_DATA_UNAVAILABLE,
2249                 clocks.realtime, clocks.uptime, mNetworkStatsManager);
2250 
2251         // Note mobile radio is off within the rate limit duration.
2252         clocks.realtime = clocks.uptime = clocks.realtime + (long) (rateLimit * 0.7);
2253         curr = 1000L * clocks.realtime;
2254         update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW,
2255                 curr, UID);
2256         assertFalse(
2257                 "noteMobileRadioPowerStateLocked should not request an update when the power "
2258                         + "state so soon after a noteModemControllerActivity",
2259                 update);
2260 
2261         // Note mobile radio is on.
2262         clocks.realtime = clocks.uptime = clocks.realtime + (long) (rateLimit * 0.7);
2263         curr = 1000L * clocks.realtime;
2264         bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH, curr,
2265                 UID);
2266 
2267         // Note mobile radio is off much later
2268         clocks.realtime = clocks.uptime = clocks.realtime + rateLimit;
2269         curr = 1000L * clocks.realtime;
2270         update = bi.noteMobileRadioPowerStateLocked(DataConnectionRealTimeInfo.DC_POWER_STATE_LOW,
2271                 curr, UID);
2272         assertTrue(
2273                 "noteMobileRadioPowerStateLocked should request an update when the power state "
2274                         + "changes from HIGH to LOW much later after a "
2275                         + "noteModemControllerActivity.",
2276                 update);
2277     }
2278 
setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi)2279     private void setFgState(int uid, boolean fgOn, MockBatteryStatsImpl bi) {
2280         // Note that noteUidProcessStateLocked uses ActivityManager process states.
2281         if (fgOn) {
2282             bi.noteActivityResumedLocked(uid);
2283             bi.noteUidProcessStateLocked(uid, ActivityManager.PROCESS_STATE_TOP);
2284         } else {
2285             bi.noteActivityPausedLocked(uid);
2286             bi.noteUidProcessStateLocked(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
2287         }
2288     }
2289 
checkMeasuredCharge(String caseName, int uid1, long blame1, int uid2, long blame2, long globalDoze, MockBatteryStatsImpl bi)2290     private void checkMeasuredCharge(String caseName, int uid1, long blame1, int uid2, long blame2,
2291             long globalDoze, MockBatteryStatsImpl bi) {
2292         final int bucket = EnergyConsumerStats.POWER_BUCKET_SCREEN_ON;
2293 
2294         assertEquals("Wrong uid1 blame for Case " + caseName, blame1,
2295                 bi.getUidStatsLocked(uid1).getEnergyConsumptionUC(bucket));
2296 
2297         assertEquals("Wrong uid2 blame for Case " + caseName, blame2,
2298                 bi.getUidStatsLocked(uid2).getEnergyConsumptionUC(bucket));
2299 
2300         assertEquals("Wrong total blame for Case " + caseName, blame1 + blame2,
2301                 bi.getScreenOnEnergyConsumptionUC());
2302 
2303         assertEquals("Wrong doze for Case " + caseName, globalDoze,
2304                 bi.getScreenDozeEnergyConsumptionUC());
2305     }
2306 
checkCustomBatteryConsumption(String caseName, long totalBlameA, long totalBlameB, int uid1, long blame1A, long blame1B, int uid2, long blame2A, long blame2B, MockBatteryStatsImpl bi)2307     private void checkCustomBatteryConsumption(String caseName,
2308             long totalBlameA, long totalBlameB,
2309             int uid1, long blame1A, long blame1B,
2310             int uid2, long blame2A, long blame2B,
2311             MockBatteryStatsImpl bi) {
2312 
2313         final long[] actualTotal = bi.getCustomEnergyConsumerBatteryConsumptionUC();
2314         final long[] actualUid1 =
2315                 bi.getUidStatsLocked(uid1).getCustomEnergyConsumerBatteryConsumptionUC();
2316         final long[] actualUid2 =
2317                 bi.getUidStatsLocked(uid2).getCustomEnergyConsumerBatteryConsumptionUC();
2318 
2319         assertNotNull(actualTotal);
2320         assertNotNull(actualUid1);
2321         assertNotNull(actualUid2);
2322 
2323         assertEquals("Wrong total blame in bucket 0 for Case " + caseName, totalBlameA,
2324                 actualTotal[0]);
2325 
2326         assertEquals("Wrong total blame in bucket 1 for Case " + caseName, totalBlameB,
2327                 actualTotal[1]);
2328 
2329         assertEquals("Wrong uid1 blame in bucket 0 for Case " + caseName, blame1A, actualUid1[0]);
2330 
2331         assertEquals("Wrong uid1 blame in bucket 1 for Case " + caseName, blame1B, actualUid1[1]);
2332 
2333         assertEquals("Wrong uid2 blame in bucket 0 for Case " + caseName, blame2A, actualUid2[0]);
2334 
2335         assertEquals("Wrong uid2 blame in bucket 1 for Case " + caseName, blame2B, actualUid2[1]);
2336     }
2337 
checkScreenBrightnesses(long[] overallExpected, long[][] perDisplayExpected, BatteryStatsImpl bi, long currentTimeMs)2338     private void checkScreenBrightnesses(long[] overallExpected, long[][] perDisplayExpected,
2339             BatteryStatsImpl bi, long currentTimeMs) {
2340         final int numDisplay = bi.getDisplayCount();
2341         for (int bin = 0; bin < NUM_SCREEN_BRIGHTNESS_BINS; bin++) {
2342             for (int display = 0; display < numDisplay; display++) {
2343                 assertEquals("Failure for display " + display + " screen brightness bin " + bin,
2344                         perDisplayExpected[display][bin] * 1000,
2345                         bi.getDisplayScreenBrightnessTime(display, bin, currentTimeMs * 1000));
2346             }
2347             assertEquals("Failure for overall screen brightness bin " + bin,
2348                     overallExpected[bin] * 1000,
2349                     bi.getScreenBrightnessTime(bin, currentTimeMs * 1000, STATS_SINCE_CHARGED));
2350         }
2351     }
2352 
checkPerStateActiveRadioDurations(long[][][] expectedDurationsMs, long[][] expectedRxDurationsMs, long[][][] expectedTxDurationsMs, BatteryStatsImpl bi, long currentTimeMs)2353     private void checkPerStateActiveRadioDurations(long[][][] expectedDurationsMs,
2354             long[][] expectedRxDurationsMs, long[][][] expectedTxDurationsMs,
2355             BatteryStatsImpl bi, long currentTimeMs) {
2356         for (int rat = 0; rat < expectedDurationsMs.length; rat++) {
2357             final long[][] expectedRatDurationsMs = expectedDurationsMs[rat];
2358             for (int freq = 0; freq < expectedRatDurationsMs.length; freq++) {
2359                 final long expectedRxDurationMs = expectedRxDurationsMs[rat][freq];
2360 
2361                 // Build a verbose fail message, just in case.
2362                 final StringBuilder rxFailSb = new StringBuilder();
2363                 rxFailSb.append("Wrong time in Rx state for RAT:");
2364                 rxFailSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
2365                 rxFailSb.append(", frequency:");
2366                 rxFailSb.append(ServiceState.frequencyRangeToString(freq));
2367                 assertEquals(rxFailSb.toString(), expectedRxDurationMs,
2368                         bi.getActiveRxRadioDurationMs(rat, freq, currentTimeMs));
2369 
2370                 final long[] expectedFreqDurationsMs = expectedRatDurationsMs[freq];
2371                 for (int strength = 0; strength < expectedFreqDurationsMs.length; strength++) {
2372                     final long expectedSignalStrengthDurationMs = expectedFreqDurationsMs[strength];
2373                     final long expectedTxDurationMs = expectedTxDurationsMs[rat][freq][strength];
2374                     final long actualDurationMs = bi.getActiveRadioDurationMs(rat, freq,
2375                             strength, currentTimeMs);
2376 
2377                     final StringBuilder failSb = new StringBuilder();
2378                     failSb.append("Wrong time in state for RAT:");
2379                     failSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
2380                     failSb.append(", frequency:");
2381                     failSb.append(ServiceState.frequencyRangeToString(freq));
2382                     failSb.append(", strength:");
2383                     failSb.append(strength);
2384                     assertEquals(failSb.toString(), expectedSignalStrengthDurationMs,
2385                             actualDurationMs);
2386 
2387                     final StringBuilder txFailSb = new StringBuilder();
2388                     txFailSb.append("Wrong time in Tx state for RAT:");
2389                     txFailSb.append(BatteryStats.RADIO_ACCESS_TECHNOLOGY_NAMES[rat]);
2390                     txFailSb.append(", frequency:");
2391                     txFailSb.append(ServiceState.frequencyRangeToString(freq));
2392                     txFailSb.append(", strength:");
2393                     txFailSb.append(strength);
2394                     assertEquals(txFailSb.toString(), expectedTxDurationMs,
2395                             bi.getActiveTxRadioDurationMs(rat, freq, strength, currentTimeMs));
2396                 }
2397             }
2398         }
2399     }
2400 
2401     private class ModemAndBatteryState {
2402         public long currentTimeMs = 100;
2403         public boolean onBattery = false;
2404         public boolean modemActive = false;
2405         @Annotation.NetworkType
2406         public int currentNetworkDataType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
2407         @BatteryStats.RadioAccessTechnology
2408         public int currentRat = BatteryStats.RADIO_ACCESS_TECHNOLOGY_OTHER;
2409         @AccessNetworkConstants.RadioAccessNetworkType
2410         public int currentRadioAccessNetworkType = AccessNetworkConstants.AccessNetworkType.UNKNOWN;
2411         @ServiceState.FrequencyRange
2412         public int currentFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
2413         public SparseIntArray currentSignalStrengths = new SparseIntArray();
2414         public ModemState modemState = ModemState.SLEEP;
2415         public ModemActivityInfo modemActivityInfo;
2416         public ActivityStatsTechSpecificInfo[] specificInfo;
2417 
2418         private final MockBatteryStatsImpl mBsi;
2419 
ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai, ActivityStatsTechSpecificInfo[] astsi)2420         ModemAndBatteryState(MockBatteryStatsImpl bsi, ModemActivityInfo mai,
2421                 ActivityStatsTechSpecificInfo[] astsi) {
2422             mBsi = bsi;
2423             modemActivityInfo = mai;
2424             specificInfo = astsi;
2425         }
2426 
setOnBattery(boolean onBattery)2427         void setOnBattery(boolean onBattery) {
2428             this.onBattery = onBattery;
2429             mBsi.updateTimeBasesLocked(onBattery, Display.STATE_OFF, currentTimeMs * 1000,
2430                     currentTimeMs * 1000);
2431             mBsi.setOnBatteryInternal(onBattery);
2432             noteModemControllerActivity();
2433         }
2434 
setModemActive(boolean active)2435         void setModemActive(boolean active) {
2436             modemActive = active;
2437             final int state = active ? DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH
2438                     : DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
2439             mBsi.noteMobileRadioPowerStateLocked(state, currentTimeMs * 1000_000L, UID);
2440             noteModemControllerActivity();
2441         }
2442 
setRatType(@nnotation.NetworkType int dataType, @BatteryStats.RadioAccessTechnology int rat, @AccessNetworkConstants.RadioAccessNetworkType int halDataType)2443         void setRatType(@Annotation.NetworkType int dataType,
2444                 @BatteryStats.RadioAccessTechnology int rat,
2445                 @AccessNetworkConstants.RadioAccessNetworkType int halDataType) {
2446             currentRadioAccessNetworkType = halDataType;
2447             setRatType(dataType, rat);
2448         }
2449 
setRatType(@nnotation.NetworkType int dataType, @BatteryStats.RadioAccessTechnology int rat)2450         void setRatType(@Annotation.NetworkType int dataType,
2451                 @BatteryStats.RadioAccessTechnology int rat) {
2452             currentNetworkDataType = dataType;
2453             currentRat = rat;
2454             mBsi.notePhoneDataConnectionStateLocked(dataType, true, ServiceState.STATE_IN_SERVICE,
2455                     currentFrequencyRange);
2456         }
2457 
setFrequencyRange(@erviceState.FrequencyRange int frequency)2458         void setFrequencyRange(@ServiceState.FrequencyRange int frequency) {
2459             currentFrequencyRange = frequency;
2460             mBsi.notePhoneDataConnectionStateLocked(currentNetworkDataType, true,
2461                     ServiceState.STATE_IN_SERVICE, frequency);
2462         }
2463 
setSignalStrength(@atteryStats.RadioAccessTechnology int rat, int strength)2464         void setSignalStrength(@BatteryStats.RadioAccessTechnology int rat, int strength) {
2465             currentSignalStrengths.put(rat, strength);
2466             final int size = currentSignalStrengths.size();
2467             final int newestGenSignalStrength = currentSignalStrengths.valueAt(size - 1);
2468             mBsi.notePhoneSignalStrengthLocked(newestGenSignalStrength, currentSignalStrengths);
2469         }
2470 
setModemState(ModemState state)2471         void setModemState(ModemState state) {
2472             modemState = state;
2473         }
2474 
getSpecificInfo(@atteryStats.RadioAccessTechnology int rat, @ServiceState.FrequencyRange int frequency)2475         ActivityStatsTechSpecificInfo getSpecificInfo(@BatteryStats.RadioAccessTechnology int rat,
2476                 @ServiceState.FrequencyRange int frequency) {
2477             if (specificInfo == null) return null;
2478             for (ActivityStatsTechSpecificInfo info : specificInfo) {
2479                 if (info.getRat() == rat && info.getFrequencyRange() == frequency) {
2480                     return info;
2481                 }
2482             }
2483             return null;
2484         }
2485 
noteModemControllerActivity()2486         void noteModemControllerActivity() {
2487             if (modemActivityInfo == null) return;
2488             modemActivityInfo.setTimestamp(currentTimeMs);
2489             final ModemActivityInfo copy;
2490             if (specificInfo == null) {
2491                 copy = new ModemActivityInfo(
2492                         modemActivityInfo.getTimestampMillis(),
2493                         modemActivityInfo.getSleepTimeMillis(),
2494                         modemActivityInfo.getIdleTimeMillis(),
2495                         modemActivityInfo.getTransmitTimeMillis().clone(),
2496                         modemActivityInfo.getReceiveTimeMillis());
2497             } else {
2498                 // Deep copy specificInfo
2499                 final ActivityStatsTechSpecificInfo[] infoCopies =
2500                         new ActivityStatsTechSpecificInfo[specificInfo.length];
2501                 for (int i = 0; i < specificInfo.length; i++) {
2502                     final ActivityStatsTechSpecificInfo info = specificInfo[i];
2503                     infoCopies[i] = new ActivityStatsTechSpecificInfo(info.getRat(),
2504                             info.getFrequencyRange(), info.getTransmitTimeMillis().clone(),
2505                             (int) info.getReceiveTimeMillis());
2506                 }
2507 
2508                 copy = new ModemActivityInfo(
2509                         modemActivityInfo.getTimestampMillis(),
2510                         modemActivityInfo.getSleepTimeMillis(),
2511                         modemActivityInfo.getIdleTimeMillis(),
2512                         infoCopies);
2513             }
2514             mBsi.noteModemControllerActivity(copy, POWER_DATA_UNAVAILABLE,
2515                     currentTimeMs, currentTimeMs, mNetworkStatsManager);
2516         }
2517     }
2518 }
2519