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