blob: 3794b5f61b5f8b6b738cd46d7fb9fcd656daf17e [file] [log] [blame]
Sudheer Shankab2f83c12017-11-13 19:25:01 -08001/*
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 */
16package com.android.internal.os;
17
18import static android.os.BatteryStats.STATS_SINCE_CHARGED;
19import static android.os.BatteryStats.Uid.NUM_PROCESS_STATE;
20import static android.os.BatteryStats.Uid.PROCESS_STATE_BACKGROUND;
21import static android.os.BatteryStats.Uid.PROCESS_STATE_CACHED;
22import static android.os.BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE;
23import static android.os.BatteryStats.Uid.PROCESS_STATE_TOP;
24
25import static org.junit.Assert.assertArrayEquals;
26import static org.junit.Assert.assertEquals;
27import static org.junit.Assert.assertNull;
28import static org.mockito.ArgumentMatchers.argThat;
29import static org.mockito.ArgumentMatchers.eq;
30import static org.mockito.Mockito.when;
31
32import android.os.BatteryStats;
33import android.support.test.filters.LargeTest;
34import android.support.test.runner.AndroidJUnit4;
35import android.util.SparseArray;
36import android.util.SparseIntArray;
37import android.view.Display;
38
39import com.android.internal.util.ArrayUtils;
40
41import org.junit.Before;
42import org.junit.Test;
43import org.junit.runner.RunWith;
44import org.mockito.ArgumentMatcher;
45import org.mockito.Mock;
46import org.mockito.MockitoAnnotations;
47
48import java.util.Arrays;
49
50@LargeTest
51@RunWith(AndroidJUnit4.class)
52public class BatteryStatsImplTest {
53 @Mock
54 private KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader;
55 @Mock
56 private KernelSingleUidTimeReader mKernelSingleUidTimeReader;
57
58 private MockBatteryStatsImpl mBatteryStatsImpl;
59
60 @Before
61 public void setUp() {
62 MockitoAnnotations.initMocks(this);
63
64 when(mKernelUidCpuFreqTimeReader.allUidTimesAvailable()).thenReturn(true);
65 when(mKernelSingleUidTimeReader.singleUidCpuTimesAvailable()).thenReturn(true);
66 mBatteryStatsImpl = new MockBatteryStatsImpl()
67 .setKernelUidCpuFreqTimeReader(mKernelUidCpuFreqTimeReader)
68 .setKernelSingleUidTimeReader(mKernelSingleUidTimeReader);
69 }
70
71 @Test
72 public void testUpdateProcStateCpuTimes() {
73 mBatteryStatsImpl.setOnBatteryInternal(true);
74 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);
75
76 final int[] testUids = {10032, 10048, 10145, 10139};
77 final int[] testProcStates = {
78 PROCESS_STATE_BACKGROUND,
79 PROCESS_STATE_FOREGROUND_SERVICE,
80 PROCESS_STATE_TOP,
81 PROCESS_STATE_CACHED
82 };
83 addPendingUids(testUids, testProcStates);
84 final long[][] cpuTimes = {
85 {349734983, 394982394832l, 909834, 348934, 9838},
86 {7498, 1239890, 988, 13298, 98980},
87 {989834, 384098, 98483, 23809, 4984},
88 {4859048, 348903, 4578967, 5973894, 298549}
89 };
90 for (int i = 0; i < testUids.length; ++i) {
91 when(mKernelSingleUidTimeReader.readDeltaMs(testUids[i])).thenReturn(cpuTimes[i]);
92
93 // Verify there are no cpu times initially.
94 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStatsLocked(testUids[i]);
95 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
96 assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
97 assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
98 }
99 }
100
101 mBatteryStatsImpl.updateProcStateCpuTimes();
102
103 verifyNoPendingUids();
104 for (int i = 0; i < testUids.length; ++i) {
105 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
106 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
107 if (procState == testProcStates[i]) {
108 assertArrayEquals("Uid=" + testUids[i], cpuTimes[i],
109 u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
110 } else {
111 assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
112 }
113 assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
114 }
115 }
116
117 final long[][] delta1 = {
118 {9589, 148934, 309894, 3098493, 98754},
119 {21983, 94983, 4983, 9878493, 84854},
120 {945894, 9089432, 19478, 3834, 7845},
121 {843895, 43948, 949582, 99, 384}
122 };
123 for (int i = 0; i < testUids.length; ++i) {
124 when(mKernelSingleUidTimeReader.readDeltaMs(testUids[i])).thenReturn(delta1[i]);
125 }
126 addPendingUids(testUids, testProcStates);
127
128 mBatteryStatsImpl.updateProcStateCpuTimes();
129
130 verifyNoPendingUids();
131 for (int i = 0; i < testUids.length; ++i) {
132 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
133 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
134 if (procState == testProcStates[i]) {
135 long[] expectedCpuTimes = cpuTimes[i].clone();
136 for (int j = 0; j < expectedCpuTimes.length; ++j) {
137 expectedCpuTimes[j] += delta1[i][j];
138 }
139 assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes,
140 u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
141 } else {
142 assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
143 }
144 assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
145 }
146 }
147
148 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
149 final long[][] delta2 = {
150 {95932, 2943, 49834, 89034, 139},
151 {349, 89605, 5896, 845, 98444},
152 {678, 7498, 9843, 889, 4894},
153 {488, 998, 8498, 394, 574}
154 };
155 for (int i = 0; i < testUids.length; ++i) {
156 when(mKernelSingleUidTimeReader.readDeltaMs(testUids[i])).thenReturn(delta2[i]);
157 }
158 addPendingUids(testUids, testProcStates);
159
160 mBatteryStatsImpl.updateProcStateCpuTimes();
161
162 verifyNoPendingUids();
163 for (int i = 0; i < testUids.length; ++i) {
164 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
165 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
166 if (procState == testProcStates[i]) {
167 long[] expectedCpuTimes = cpuTimes[i].clone();
168 for (int j = 0; j < expectedCpuTimes.length; ++j) {
169 expectedCpuTimes[j] += delta1[i][j] + delta2[i][j];
170 }
171 assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes,
172 u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
173 assertArrayEquals("Uid=" + testUids[i], delta2[i],
174 u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
175 } else {
176 assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
177 assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
178 }
179 }
180 }
181
182 final long[][] delta3 = {
183 {98545, 95768795, 76586, 548945, 57846},
184 {788876, 586, 578459, 8776984, 9578923},
185 {3049509483598l, 4597834, 377654, 94589035, 7854},
186 {9493, 784, 99895, 8974893, 9879843}
187 };
188 for (int i = 0; i < testUids.length; ++i) {
189 when(mKernelSingleUidTimeReader.readDeltaMs(testUids[i])).thenReturn(
190 delta3[i].clone());
191 }
192 addPendingUids(testUids, testProcStates);
193 final int parentUid = testUids[1];
194 final int childUid = 99099;
195 addIsolatedUid(parentUid, childUid);
196 final long[] isolatedUidCpuTimes = {495784, 398473, 4895, 4905, 30984093};
197 when(mKernelSingleUidTimeReader.readDeltaMs(childUid)).thenReturn(isolatedUidCpuTimes);
198
199 mBatteryStatsImpl.updateProcStateCpuTimes();
200
201 verifyNoPendingUids();
202 for (int i = 0; i < testUids.length; ++i) {
203 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
204 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
205 if (procState == testProcStates[i]) {
206 long[] expectedCpuTimes = cpuTimes[i].clone();
207 for (int j = 0; j < expectedCpuTimes.length; ++j) {
208 expectedCpuTimes[j] += delta1[i][j] + delta2[i][j] + delta3[i][j]
209 + (testUids[i] == parentUid ? isolatedUidCpuTimes[j] : 0);
210 }
211 assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes,
212 u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
213 long[] expectedScreenOffTimes = delta2[i].clone();
214 for (int j = 0; j < expectedScreenOffTimes.length; ++j) {
215 expectedScreenOffTimes[j] += delta3[i][j]
216 + (testUids[i] == parentUid ? isolatedUidCpuTimes[j] : 0);
217 }
218 assertArrayEquals("Uid=" + testUids[i], expectedScreenOffTimes,
219 u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
220 } else {
221 assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
222 assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
223 }
224 }
225 }
226 }
227
228 @Test
229 public void testCopyFromAllUidsCpuTimes() {
230 mBatteryStatsImpl.setOnBatteryInternal(true);
231 mBatteryStatsImpl.updateTimeBasesLocked(true, Display.STATE_ON, 0, 0);
232
233 final int[] testUids = {10032, 10048, 10145, 10139};
234 final int[] testProcStates = {
235 PROCESS_STATE_BACKGROUND,
236 PROCESS_STATE_FOREGROUND_SERVICE,
237 PROCESS_STATE_TOP,
238 PROCESS_STATE_CACHED
239 };
240 final int[] pendingUidIdx = {1, 2};
241 updateProcessStates(testUids, testProcStates, pendingUidIdx);
242
243 final SparseArray<long[]> allUidCpuTimes = new SparseArray<>();
244 long[][] allCpuTimes = {
245 {938483, 4985984, 439893},
246 {499, 94904, 27694},
247 {302949085, 39789473, 34792839},
248 {9809485, 9083475, 347889834},
249 };
250 for (int i = 0; i < testUids.length; ++i) {
251 allUidCpuTimes.put(testUids[i], allCpuTimes[i]);
252 }
253 when(mKernelUidCpuFreqTimeReader.getAllUidCpuFreqTimeMs()).thenReturn(allUidCpuTimes);
254 long[][] expectedCpuTimes = {
255 {843598745, 397843, 32749, 99854},
256 {9834, 5885, 487589, 394},
257 {203984, 439, 9859, 30948},
258 {9389, 858, 239, 349}
259 };
260 for (int i = 0; i < testUids.length; ++i) {
261 final int idx = i;
262 final ArgumentMatcher<long[]> matcher = times -> Arrays.equals(times, allCpuTimes[idx]);
263 when(mKernelSingleUidTimeReader.computeDelta(eq(testUids[i]), argThat(matcher)))
264 .thenReturn(expectedCpuTimes[i]);
265 }
266
267 mBatteryStatsImpl.copyFromAllUidsCpuTimes();
268
269 verifyNoPendingUids();
270 for (int i = 0; i < testUids.length; ++i) {
271 final BatteryStats.Uid u = mBatteryStatsImpl.getUidStats().get(testUids[i]);
272 for (int procState = 0; procState < NUM_PROCESS_STATE; ++procState) {
273 if (procState == testProcStates[i]) {
274 assertArrayEquals("Uid=" + testUids[i], expectedCpuTimes[i],
275 u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
276 } else {
277 assertNull(u.getCpuFreqTimes(STATS_SINCE_CHARGED, procState));
278 }
279 assertNull(u.getScreenOffCpuFreqTimes(STATS_SINCE_CHARGED, procState));
280 }
281 }
282 }
283
284 @Test
285 public void testAddCpuTimes() {
286 long[] timesA = null;
287 long[] timesB = null;
288 assertNull(mBatteryStatsImpl.addCpuTimes(timesA, timesB));
289
290 timesA = new long[] {34, 23, 45, 24};
291 assertArrayEquals(timesA, mBatteryStatsImpl.addCpuTimes(timesA, timesB));
292
293 timesB = timesA;
294 timesA = null;
295 assertArrayEquals(timesB, mBatteryStatsImpl.addCpuTimes(timesA, timesB));
296
297 final long[] expected = {434, 6784, 34987, 9984};
298 timesA = new long[timesB.length];
299 for (int i = 0; i < timesA.length; ++i) {
300 timesA[i] = expected[i] - timesB[i];
301 }
302 assertArrayEquals(expected, mBatteryStatsImpl.addCpuTimes(timesA, timesB));
303 }
304
305 private void addIsolatedUid(int parentUid, int childUid) {
306 final BatteryStatsImpl.Uid u = mBatteryStatsImpl.getUidStatsLocked(parentUid);
307 u.addIsolatedUid(childUid);
308 }
309
310 private void addPendingUids(int[] uids, int[] procStates) {
311 final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids();
312 for (int i = 0; i < uids.length; ++i) {
313 pendingUids.put(uids[i], procStates[i]);
314 }
315 }
316
317 private void updateProcessStates(int[] uids, int[] procStates,
318 int[] pendingUidsIdx) {
319 final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids();
320 for (int i = 0; i < uids.length; ++i) {
321 final BatteryStatsImpl.Uid u = mBatteryStatsImpl.getUidStatsLocked(uids[i]);
322 if (ArrayUtils.contains(pendingUidsIdx, i)) {
323 u.setProcessStateForTest(PROCESS_STATE_TOP);
324 pendingUids.put(uids[i], procStates[i]);
325 } else {
326 u.setProcessStateForTest(procStates[i]);
327 }
328 }
329 }
330
331 private void verifyNoPendingUids() {
332 final SparseIntArray pendingUids = mBatteryStatsImpl.getPendingUids();
333 assertEquals("There shouldn't be any pending uids left: " + pendingUids,
334 0, pendingUids.size());
335 }
336}