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