blob: e375af3f7b0ef095da7a96a75d97dc9ae6c3decb [file] [log] [blame]
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -07001/*
2 * Copyright (C) 2018 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
17package com.android.internal.os;
18
Olivier Gaillard94e6fe62018-08-06 16:43:47 +010019import static org.junit.Assert.assertEquals;
Marcin Oczeretko772e8f22018-11-21 13:00:32 +000020import static org.junit.Assert.assertTrue;
Olivier Gaillard94e6fe62018-08-06 16:43:47 +010021
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070022import android.os.Binder;
Olivier Gaillard28109b52018-12-14 15:14:14 +000023import android.os.SystemClock;
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070024import android.platform.test.annotations.Presubmit;
Olivier Gaillardf82d2e732018-06-07 11:45:35 +010025import android.util.ArrayMap;
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070026import android.util.SparseArray;
27
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090028import androidx.test.filters.SmallTest;
29import androidx.test.runner.AndroidJUnit4;
30
Olivier Gaillard289ba402018-07-24 18:50:13 +010031import com.android.internal.os.BinderInternal.CallSession;
32
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070033import org.junit.Assert;
34import org.junit.Test;
35import org.junit.runner.RunWith;
36
Olivier Gaillardf82d2e732018-06-07 11:45:35 +010037import java.io.PrintWriter;
38import java.io.StringWriter;
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +010039import java.util.ArrayList;
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070040import java.util.Arrays;
Olivier Gaillardf82d2e732018-06-07 11:45:35 +010041import java.util.HashMap;
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070042import java.util.List;
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +010043import java.util.Random;
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070044
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070045@SmallTest
46@RunWith(AndroidJUnit4.class)
47@Presubmit
48public class BinderCallsStatsTest {
Olivier Gaillard88de48f2018-10-18 10:21:21 +010049 private static final int WORKSOURCE_UID = 1;
50 private static final int CALLING_UID = 2;
Olivier Gaillard58b56e32018-06-01 16:18:43 +010051 private static final int REQUEST_SIZE = 2;
52 private static final int REPLY_SIZE = 3;
Marcin Oczeretkoc80c81a2018-08-30 20:15:52 +010053 private final CachedDeviceState mDeviceState = new CachedDeviceState(false, true);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070054
55 @Test
56 public void testDetailedOff() {
Olivier Gaillard1d7f6152018-07-03 13:57:58 +010057 TestBinderCallsStats bcs = new TestBinderCallsStats();
58 bcs.setDetailedTracking(false);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +010059 bcs.setSamplingInterval(5);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +010060
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070061 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +000062 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070063 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +000064 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070065
66 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
67 assertEquals(1, uidEntries.size());
Olivier Gaillard88de48f2018-10-18 10:21:21 +010068 BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070069 Assert.assertNotNull(uidEntry);
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +010070 List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070071 assertEquals(1, uidEntry.callCount);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +010072 assertEquals(1, uidEntry.recordedCallCount);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070073 assertEquals(10, uidEntry.cpuTimeMicros);
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +010074 assertEquals(binder.getClass(), callStatsList.get(0).binderClass);
Olivier Gaillard289ba402018-07-24 18:50:13 +010075 assertEquals(1, callStatsList.get(0).transactionCode);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070076
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +010077 // CPU usage is sampled, should not be tracked here.
Olivier Gaillard76c231d2018-12-05 12:52:08 +000078 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070079 bcs.time += 20;
Olivier Gaillard76c231d2018-12-05 12:52:08 +000080 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070081 assertEquals(2, uidEntry.callCount);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +010082 assertEquals(1, uidEntry.recordedCallCount);
83 assertEquals(10, uidEntry.cpuTimeMicros);
84 assertEquals(1, callStatsList.size());
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070085
Olivier Gaillard76c231d2018-12-05 12:52:08 +000086 callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070087 bcs.time += 50;
Olivier Gaillard76c231d2018-12-05 12:52:08 +000088 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard88de48f2018-10-18 10:21:21 +010089 uidEntry = bcs.getUidEntries().get(WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070090 assertEquals(3, uidEntry.callCount);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +010091 assertEquals(1, uidEntry.recordedCallCount);
92 // Still sampled even for another API.
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +010093 callStatsList = new ArrayList(uidEntry.getCallStatsList());
Olivier Gaillard34ad8af2018-08-06 15:55:03 +010094 assertEquals(1, callStatsList.size());
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -070095 }
96
97 @Test
98 public void testDetailedOn() {
Olivier Gaillard1d7f6152018-07-03 13:57:58 +010099 TestBinderCallsStats bcs = new TestBinderCallsStats();
100 bcs.setDetailedTracking(true);
101
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700102 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000103 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700104 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000105 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700106
107 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
108 assertEquals(1, uidEntries.size());
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100109 BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700110 Assert.assertNotNull(uidEntry);
111 assertEquals(1, uidEntry.callCount);
112 assertEquals(10, uidEntry.cpuTimeMicros);
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +0100113 assertEquals(1, new ArrayList(uidEntry.getCallStatsList()).size());
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700114
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +0100115 List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700116 assertEquals(1, callStatsList.get(0).callCount);
117 assertEquals(10, callStatsList.get(0).cpuTimeMicros);
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +0100118 assertEquals(binder.getClass(), callStatsList.get(0).binderClass);
Olivier Gaillard289ba402018-07-24 18:50:13 +0100119 assertEquals(1, callStatsList.get(0).transactionCode);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700120
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000121 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700122 bcs.time += 20;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000123 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700124
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100125 uidEntry = bcs.getUidEntries().get(WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700126 assertEquals(2, uidEntry.callCount);
127 assertEquals(30, uidEntry.cpuTimeMicros);
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +0100128 callStatsList = new ArrayList(uidEntry.getCallStatsList());
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700129 assertEquals(1, callStatsList.size());
130
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000131 callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700132 bcs.time += 50;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000133 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100134 uidEntry = bcs.getUidEntries().get(WORKSOURCE_UID);
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700135 assertEquals(3, uidEntry.callCount);
136
137 // This is the first transaction of a new type, so the real CPU time will be measured
138 assertEquals(80, uidEntry.cpuTimeMicros);
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +0100139 callStatsList = new ArrayList(uidEntry.getCallStatsList());
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700140 assertEquals(2, callStatsList.size());
141 }
142
143 @Test
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100144 public void testEnableInBetweenCall() {
145 TestBinderCallsStats bcs = new TestBinderCallsStats();
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100146 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000147 bcs.callEnded(null, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard289ba402018-07-24 18:50:13 +0100148
149 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
150 assertEquals(0, uidEntries.size());
151 }
152
153 @Test
154 public void testInBetweenCallWhenExceptionThrown() {
155 TestBinderCallsStats bcs = new TestBinderCallsStats();
156 Binder binder = new Binder();
157 bcs.callThrewException(null, new IllegalStateException());
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000158 bcs.callEnded(null, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100159
160 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
161 assertEquals(0, uidEntries.size());
162 }
163
164 @Test
165 public void testSampling() {
166 TestBinderCallsStats bcs = new TestBinderCallsStats();
167 bcs.setDetailedTracking(false);
168 bcs.setSamplingInterval(2);
169
170 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000171 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100172 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000173 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100174
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000175 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100176 bcs.time += 1000; // shoud be ignored.
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000177 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100178
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000179 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100180 bcs.time += 50;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000181 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100182
183 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
184 assertEquals(1, uidEntries.size());
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100185 BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100186 Assert.assertNotNull(uidEntry);
187 assertEquals(3, uidEntry.callCount);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100188 assertEquals(60 /* 10 + 50 */, uidEntry.cpuTimeMicros);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100189
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +0100190 List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100191 assertEquals(1, callStatsList.size());
192 BinderCallsStats.CallStat callStats = callStatsList.get(0);
193 assertEquals(3, callStats.callCount);
194 assertEquals(2, callStats.recordedCallCount);
195 assertEquals(60, callStats.cpuTimeMicros);
196 assertEquals(50, callStats.maxCpuTimeMicros);
197 assertEquals(0, callStats.maxRequestSizeBytes);
198 assertEquals(0, callStats.maxReplySizeBytes);
199 }
200
201 @Test
202 public void testSamplingWithDifferentApis() {
203 TestBinderCallsStats bcs = new TestBinderCallsStats();
204 bcs.setDetailedTracking(false);
205 bcs.setSamplingInterval(2);
206
207 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000208 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100209 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000210 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100211
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000212 callSession = bcs.callStarted(binder, 2 /* another method */, WORKSOURCE_UID);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100213 bcs.time += 1000; // shoud be ignored.
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000214 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100215
216
217 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
218 assertEquals(1, uidEntries.size());
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100219 BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100220 assertEquals(2, uidEntry.callCount);
221 assertEquals(1, uidEntry.recordedCallCount);
222 assertEquals(10, uidEntry.cpuTimeMicros);
223
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +0100224 List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
Olivier Gaillard34ad8af2018-08-06 15:55:03 +0100225 assertEquals(1, callStatsList.size());
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100226
227 BinderCallsStats.CallStat callStats = callStatsList.get(0);
228 assertEquals(1, callStats.callCount);
229 assertEquals(1, callStats.recordedCallCount);
230 assertEquals(10, callStats.cpuTimeMicros);
231 assertEquals(10, callStats.maxCpuTimeMicros);
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100232 }
233
Olivier Gaillard1f93a772018-07-30 14:09:22 +0100234 private static class BinderWithGetTransactionName extends Binder {
235 public static String getDefaultTransactionName(int code) {
236 return "resolved";
237 }
238 }
239
Olivier Gaillardf31dfb92018-07-31 12:59:20 +0100240 private static class AnotherBinderWithGetTransactionName extends Binder {
241 public static String getDefaultTransactionName(int code) {
242 return "foo" + code;
243 }
244 }
245
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100246 @Test
Olivier Gaillard103aae22018-06-07 18:20:10 +0100247 public void testTransactionCodeResolved() {
248 TestBinderCallsStats bcs = new TestBinderCallsStats();
249 bcs.setDetailedTracking(true);
Olivier Gaillard1f93a772018-07-30 14:09:22 +0100250 Binder binder = new BinderWithGetTransactionName();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000251 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard103aae22018-06-07 18:20:10 +0100252 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000253 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard103aae22018-06-07 18:20:10 +0100254
Olivier Gaillard1f93a772018-07-30 14:09:22 +0100255 List<BinderCallsStats.ExportedCallStat> callStatsList =
256 bcs.getExportedCallStats();
Olivier Gaillard103aae22018-06-07 18:20:10 +0100257 assertEquals("resolved", callStatsList.get(0).methodName);
258 }
259
260 @Test
Olivier Gaillardf31dfb92018-07-31 12:59:20 +0100261 public void testMultipleTransactionCodeResolved() {
262 TestBinderCallsStats bcs = new TestBinderCallsStats();
263 bcs.setDetailedTracking(true);
264
265 Binder binder = new AnotherBinderWithGetTransactionName();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000266 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillardf31dfb92018-07-31 12:59:20 +0100267 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000268 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillardf31dfb92018-07-31 12:59:20 +0100269
270 Binder binder2 = new BinderWithGetTransactionName();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000271 callSession = bcs.callStarted(binder2, 1, WORKSOURCE_UID);
Olivier Gaillardf31dfb92018-07-31 12:59:20 +0100272 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000273 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillardf31dfb92018-07-31 12:59:20 +0100274
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000275 callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID);
Olivier Gaillardf31dfb92018-07-31 12:59:20 +0100276 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000277 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillardf31dfb92018-07-31 12:59:20 +0100278
279 List<BinderCallsStats.ExportedCallStat> callStatsList =
280 bcs.getExportedCallStats();
281 assertEquals("foo1", callStatsList.get(0).methodName);
282 assertEquals(AnotherBinderWithGetTransactionName.class.getName(),
283 callStatsList.get(0).className);
284 assertEquals("foo2", callStatsList.get(1).methodName);
285 assertEquals(AnotherBinderWithGetTransactionName.class.getName(),
286 callStatsList.get(1).className);
287 assertEquals("resolved", callStatsList.get(2).methodName);
288 assertEquals(BinderWithGetTransactionName.class.getName(),
289 callStatsList.get(2).className);
290 }
291
292 @Test
Olivier Gaillard1f93a772018-07-30 14:09:22 +0100293 public void testResolvingCodeDoesNotThrowWhenMethodNotPresent() {
294 TestBinderCallsStats bcs = new TestBinderCallsStats();
295 bcs.setDetailedTracking(true);
296 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000297 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard1f93a772018-07-30 14:09:22 +0100298 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000299 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard1f93a772018-07-30 14:09:22 +0100300
301 List<BinderCallsStats.ExportedCallStat> callStatsList =
302 bcs.getExportedCallStats();
303 assertEquals("1", callStatsList.get(0).methodName);
304 }
305
306 @Test
Olivier Gaillard58b56e32018-06-01 16:18:43 +0100307 public void testParcelSize() {
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100308 TestBinderCallsStats bcs = new TestBinderCallsStats();
309 bcs.setDetailedTracking(true);
Olivier Gaillard58b56e32018-06-01 16:18:43 +0100310 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000311 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard58b56e32018-06-01 16:18:43 +0100312 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000313 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard58b56e32018-06-01 16:18:43 +0100314
315 List<BinderCallsStats.CallStat> callStatsList =
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100316 new ArrayList(bcs.getUidEntries().get(WORKSOURCE_UID).getCallStatsList());
Olivier Gaillard58b56e32018-06-01 16:18:43 +0100317
318 assertEquals(REQUEST_SIZE, callStatsList.get(0).maxRequestSizeBytes);
319 assertEquals(REPLY_SIZE, callStatsList.get(0).maxReplySizeBytes);
320 }
321
322 @Test
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100323 public void testMaxCpu() {
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100324 TestBinderCallsStats bcs = new TestBinderCallsStats();
325 bcs.setDetailedTracking(true);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100326 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000327 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100328 bcs.time += 50;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000329 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100330
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000331 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100332 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000333 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100334
335 List<BinderCallsStats.CallStat> callStatsList =
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100336 new ArrayList(bcs.getUidEntries().get(WORKSOURCE_UID).getCallStatsList());
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100337
338 assertEquals(50, callStatsList.get(0).maxCpuTimeMicros);
339 }
340
341 @Test
342 public void testMaxLatency() {
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100343 TestBinderCallsStats bcs = new TestBinderCallsStats();
344 bcs.setDetailedTracking(true);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100345 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000346 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100347 bcs.elapsedTime += 5;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000348 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100349
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000350 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100351 bcs.elapsedTime += 1;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000352 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100353
354 List<BinderCallsStats.CallStat> callStatsList =
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100355 new ArrayList(bcs.getUidEntries().get(WORKSOURCE_UID).getCallStatsList());
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100356
357 assertEquals(5, callStatsList.get(0).maxLatencyMicros);
358 }
359
360 @Test
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700361 public void testGetHighestValues() {
362 List<Integer> list = Arrays.asList(1, 2, 3, 4);
363 List<Integer> highestValues = BinderCallsStats
364 .getHighestValues(list, value -> value, 0.8);
365 assertEquals(Arrays.asList(4, 3, 2), highestValues);
366 }
367
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100368 @Test
369 public void testExceptionCount() {
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100370 TestBinderCallsStats bcs = new TestBinderCallsStats();
371 bcs.setDetailedTracking(true);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100372 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000373 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100374 bcs.callThrewException(callSession, new IllegalStateException());
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000375 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100376
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000377 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100378 bcs.callThrewException(callSession, new IllegalStateException());
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000379 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100380
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000381 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100382 bcs.callThrewException(callSession, new RuntimeException());
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000383 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100384
385 ArrayMap<String, Integer> expected = new ArrayMap<>();
386 expected.put("java.lang.IllegalStateException", 2);
387 expected.put("java.lang.RuntimeException", 1);
388 assertEquals(expected, bcs.getExceptionCounts());
389 }
390
391 @Test
Marcin Oczeretkoc80c81a2018-08-30 20:15:52 +0100392 public void testNoDataCollectedBeforeInitialDeviceStateSet() {
Marcin Oczeretko6a2e5242018-11-28 11:08:50 +0000393 TestBinderCallsStats bcs = new TestBinderCallsStats(null);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100394 bcs.setDetailedTracking(true);
395 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000396 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100397 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000398 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100399
Marcin Oczeretkoc80c81a2018-08-30 20:15:52 +0100400 bcs.setDeviceState(mDeviceState.getReadonlyClient());
Olivier Gaillard86714d12018-08-01 15:05:36 +0100401
402 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
403 assertEquals(0, uidEntries.size());
404 }
405
406 @Test
Olivier Gaillard86714d12018-08-01 15:05:36 +0100407 public void testNoDataCollectedOnCharger() {
408 TestBinderCallsStats bcs = new TestBinderCallsStats();
409 bcs.setDetailedTracking(true);
Marcin Oczeretkoc80c81a2018-08-30 20:15:52 +0100410 mDeviceState.setCharging(true);
411
Olivier Gaillard86714d12018-08-01 15:05:36 +0100412 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000413 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
414 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100415
416 assertEquals(0, bcs.getUidEntries().size());
417 }
418
419 @Test
420 public void testScreenOff() {
421 TestBinderCallsStats bcs = new TestBinderCallsStats();
422 bcs.setDetailedTracking(true);
Marcin Oczeretkoc80c81a2018-08-30 20:15:52 +0100423 mDeviceState.setScreenInteractive(false);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100424 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000425 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
426 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100427
428 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
429 assertEquals(1, uidEntries.size());
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100430 BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100431 Assert.assertNotNull(uidEntry);
432 List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
433 assertEquals(false, callStatsList.get(0).screenInteractive);
434 }
435
436 @Test
437 public void testScreenOn() {
438 TestBinderCallsStats bcs = new TestBinderCallsStats();
439 bcs.setDetailedTracking(true);
Marcin Oczeretkoc80c81a2018-08-30 20:15:52 +0100440 mDeviceState.setScreenInteractive(true);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100441 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000442 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
443 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100444
445 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
446 assertEquals(1, uidEntries.size());
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100447 BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100448 Assert.assertNotNull(uidEntry);
449 List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
450 assertEquals(true, callStatsList.get(0).screenInteractive);
451 }
452
453 @Test
454 public void testOnCharger() {
455 TestBinderCallsStats bcs = new TestBinderCallsStats();
456 bcs.setDetailedTracking(true);
Marcin Oczeretkoc80c81a2018-08-30 20:15:52 +0100457 mDeviceState.setCharging(true);
458
Olivier Gaillard86714d12018-08-01 15:05:36 +0100459 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000460 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
461 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100462
463 assertEquals(0, bcs.getExportedCallStats().size());
464 }
465
466 @Test
467 public void testOnBattery() {
468 TestBinderCallsStats bcs = new TestBinderCallsStats();
469 bcs.setDetailedTracking(true);
Marcin Oczeretkoc80c81a2018-08-30 20:15:52 +0100470 mDeviceState.setCharging(false);
471
Olivier Gaillard86714d12018-08-01 15:05:36 +0100472 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000473 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
474 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100475
476 assertEquals(1, bcs.getExportedCallStats().size());
477 }
478
479 @Test
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100480 public void testDumpDoesNotThrowException() {
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100481 TestBinderCallsStats bcs = new TestBinderCallsStats();
482 bcs.setDetailedTracking(true);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100483 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000484 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100485 bcs.callThrewException(callSession, new IllegalStateException());
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000486 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100487
488 PrintWriter pw = new PrintWriter(new StringWriter());
Marcin Oczeretkoc4c45a82018-12-06 15:09:49 +0000489 bcs.dump(pw, new AppIdToPackageMap(new HashMap<>()), true);
Olivier Gaillardf82d2e732018-06-07 11:45:35 +0100490 }
491
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100492 @Test
493 public void testGetExportedStatsWhenDetailedTrackingDisabled() {
494 TestBinderCallsStats bcs = new TestBinderCallsStats();
495 bcs.setDetailedTracking(false);
496 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000497 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
498 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100499
500 assertEquals(0, bcs.getExportedCallStats().size());
501 }
502
503 @Test
504 public void testGetExportedStatsWhenDetailedTrackingEnabled() {
505 TestBinderCallsStats bcs = new TestBinderCallsStats();
506 bcs.setDetailedTracking(true);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100507
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100508 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000509 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100510 bcs.time += 10;
511 bcs.elapsedTime += 20;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000512 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100513
514 assertEquals(1, bcs.getExportedCallStats().size());
515 BinderCallsStats.ExportedCallStat stat = bcs.getExportedCallStats().get(0);
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100516 assertEquals(WORKSOURCE_UID, stat.workSourceUid);
517 assertEquals(CALLING_UID, stat.callingUid);
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100518 assertEquals("android.os.Binder", stat.className);
519 assertEquals("1", stat.methodName);
Olivier Gaillard86714d12018-08-01 15:05:36 +0100520 assertEquals(true, stat.screenInteractive);
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100521 assertEquals(10, stat.cpuTimeMicros);
522 assertEquals(10, stat.maxCpuTimeMicros);
523 assertEquals(20, stat.latencyMicros);
524 assertEquals(20, stat.maxLatencyMicros);
525 assertEquals(1, stat.callCount);
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100526 assertEquals(1, stat.recordedCallCount);
Olivier Gaillard00bfb1b2018-07-10 11:25:09 +0100527 assertEquals(REQUEST_SIZE, stat.maxRequestSizeBytes);
528 assertEquals(REPLY_SIZE, stat.maxReplySizeBytes);
529 assertEquals(0, stat.exceptionCount);
530 }
531
Olivier Gaillard7a2a98b2018-07-26 13:29:16 +0100532 @Test
533 public void testGetExportedStatsWithoutCalls() {
534 TestBinderCallsStats bcs = new TestBinderCallsStats();
535 Binder binder = new Binder();
536 assertEquals(0, bcs.getExportedCallStats().size());
537 }
538
539 @Test
540 public void testGetExportedExceptionsWithoutCalls() {
541 TestBinderCallsStats bcs = new TestBinderCallsStats();
542 Binder binder = new Binder();
543 assertEquals(0, bcs.getExceptionCounts().size());
544 }
545
Olivier Gaillard79490612018-11-30 16:22:23 +0000546 @Test
547 public void testOverflow_sameEntry() {
548 TestBinderCallsStats bcs = new TestBinderCallsStats();
549 bcs.setDetailedTracking(true);
550 bcs.setSamplingInterval(1);
551 bcs.setMaxBinderCallStats(2);
552
553 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000554 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard79490612018-11-30 16:22:23 +0000555 bcs.time += 10;
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000556 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard79490612018-11-30 16:22:23 +0000557
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000558 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
559 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard79490612018-11-30 16:22:23 +0000560
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000561 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
562 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard79490612018-11-30 16:22:23 +0000563
564 BinderCallsStats.UidEntry uidEntry = bcs.getUidEntries().get(WORKSOURCE_UID);
565 List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
566 assertEquals(1, callStatsList.size());
567 BinderCallsStats.CallStat callStats = callStatsList.get(0);
568 assertEquals(3, callStats.callCount);
569 }
570
571 @Test
572 public void testOverflow_overflowEntry() {
573 TestBinderCallsStats bcs = new TestBinderCallsStats();
574 bcs.setDetailedTracking(true);
575 bcs.setSamplingInterval(1);
576 bcs.setMaxBinderCallStats(1);
577
578 Binder binder = new Binder();
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000579 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000580 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard79490612018-11-30 16:22:23 +0000581
Olivier Gaillard76c231d2018-12-05 12:52:08 +0000582 callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID);
583 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
Olivier Gaillard79490612018-11-30 16:22:23 +0000584
Olivier Gaillarda3686dd2018-12-07 11:28:07 +0000585 // Should use the same overflow entry.
586 callSession = bcs.callStarted(binder, 3, WORKSOURCE_UID);
587 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
588
Olivier Gaillard79490612018-11-30 16:22:23 +0000589 List<BinderCallsStats.ExportedCallStat> callStatsList = bcs.getExportedCallStats();
590 assertEquals(2, callStatsList.size());
591 BinderCallsStats.ExportedCallStat callStats = callStatsList.get(0);
592 assertEquals(1, callStats.callCount);
593 assertEquals("1", callStats.methodName);
594 assertEquals("android.os.Binder", callStats.className);
595 assertEquals(CALLING_UID, callStats.callingUid);
596
597 callStats = callStatsList.get(1);
Olivier Gaillarda3686dd2018-12-07 11:28:07 +0000598 assertEquals(2, callStats.callCount);
Olivier Gaillard79490612018-11-30 16:22:23 +0000599 assertEquals("-1", callStats.methodName);
600 assertEquals("com.android.internal.os.BinderCallsStats$OverflowBinder",
601 callStats.className);
Olivier Gaillarda3686dd2018-12-07 11:28:07 +0000602 assertEquals(false , callStats.screenInteractive);
603 assertEquals(-1 , callStats.callingUid);
604 }
605
606 @Test
607 public void testOverflow_oneOverflowEntryPerUid() {
608 TestBinderCallsStats bcs = new TestBinderCallsStats();
609 bcs.setDetailedTracking(true);
610 bcs.setSamplingInterval(1);
611 bcs.setMaxBinderCallStats(1);
612
613 Binder binder = new Binder();
614 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
615 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
616
617 callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID + 1);
618 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID + 1);
619
620 // Different uids have different overflow entries.
621 callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID + 2);
622 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID + 2);
623
624 List<BinderCallsStats.ExportedCallStat> callStatsList = bcs.getExportedCallStats();
625 assertEquals(3, callStatsList.size());
626
627 BinderCallsStats.ExportedCallStat callStats = callStatsList.get(1);
628 assertEquals(WORKSOURCE_UID + 1, callStats.workSourceUid);
629 assertEquals(1, callStats.callCount);
630 assertEquals("com.android.internal.os.BinderCallsStats$OverflowBinder",
631 callStats.className);
632
633 callStats = callStatsList.get(2);
634 assertEquals(WORKSOURCE_UID + 2, callStats.workSourceUid);
635 assertEquals(1, callStats.callCount);
636 assertEquals("com.android.internal.os.BinderCallsStats$OverflowBinder",
637 callStats.className);
Olivier Gaillard79490612018-11-30 16:22:23 +0000638 }
639
Marcin Oczeretko772e8f22018-11-21 13:00:32 +0000640 @Test
641 public void testAddsDebugEntries() {
Olivier Gaillard28109b52018-12-14 15:14:14 +0000642 long startTime = SystemClock.elapsedRealtime();
Marcin Oczeretko772e8f22018-11-21 13:00:32 +0000643 TestBinderCallsStats bcs = new TestBinderCallsStats();
644 bcs.setAddDebugEntries(true);
645 ArrayList<BinderCallsStats.ExportedCallStat> callStats = bcs.getExportedCallStats();
Marcin Oczeretko6a2e5242018-11-28 11:08:50 +0000646 assertEquals(3, callStats.size());
Marcin Oczeretko772e8f22018-11-21 13:00:32 +0000647 BinderCallsStats.ExportedCallStat debugEntry1 = callStats.get(0);
648 assertEquals("", debugEntry1.className);
649 assertEquals("__DEBUG_start_time_millis", debugEntry1.methodName);
Marcin Oczeretko8d861742018-12-06 11:13:29 +0000650 assertTrue(startTime <= debugEntry1.latencyMicros);
Marcin Oczeretko772e8f22018-11-21 13:00:32 +0000651 BinderCallsStats.ExportedCallStat debugEntry2 = callStats.get(1);
652 assertEquals("", debugEntry2.className);
653 assertEquals("__DEBUG_end_time_millis", debugEntry2.methodName);
Marcin Oczeretko8d861742018-12-06 11:13:29 +0000654 assertTrue(debugEntry1.latencyMicros <= debugEntry2.latencyMicros);
Marcin Oczeretko6a2e5242018-11-28 11:08:50 +0000655 BinderCallsStats.ExportedCallStat debugEntry3 = callStats.get(2);
656 assertEquals("", debugEntry3.className);
657 assertEquals("__DEBUG_battery_time_millis", debugEntry3.methodName);
Marcin Oczeretko8d861742018-12-06 11:13:29 +0000658 assertTrue(debugEntry3.latencyMicros >= 0);
Marcin Oczeretko772e8f22018-11-21 13:00:32 +0000659 }
660
Olivier Gaillard36b80ca2019-02-11 11:41:39 +0000661 @Test
662 public void testTrackScreenInteractiveDisabled() {
663 TestBinderCallsStats bcs = new TestBinderCallsStats();
664 bcs.setTrackScreenInteractive(false);
665 Binder binder = new Binder();
666
667 mDeviceState.setScreenInteractive(false);
668 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
669 bcs.time += 10;
670 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
671
672 mDeviceState.setScreenInteractive(true);
673 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
674 bcs.time += 1000; // shoud be ignored.
675 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
676
677 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
678 assertEquals(1, uidEntries.size());
679 BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
680 Assert.assertNotNull(uidEntry);
681 assertEquals(2, uidEntry.callCount);
682
683 List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
684 assertEquals(1, callStatsList.size());
685 BinderCallsStats.CallStat callStats = callStatsList.get(0);
686 assertEquals(false, callStats.screenInteractive);
687 assertEquals(2, callStats.callCount);
688 assertEquals(2, callStats.recordedCallCount);
689 }
690
691 @Test
692 public void testTrackCallingUidDisabled() {
693 TestBinderCallsStats bcs = new TestBinderCallsStats();
694 bcs.setTrackDirectCallerUid(false);
695 Binder binder = new Binder();
696
697 bcs.setCallingUid(1);
698 CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
699 bcs.time += 10;
700 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
701
702 bcs.setCallingUid(2);
703 callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
704 bcs.time += 1000; // shoud be ignored.
705 bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
706
707 SparseArray<BinderCallsStats.UidEntry> uidEntries = bcs.getUidEntries();
708 assertEquals(1, uidEntries.size());
709 BinderCallsStats.UidEntry uidEntry = uidEntries.get(WORKSOURCE_UID);
710 Assert.assertNotNull(uidEntry);
711 assertEquals(2, uidEntry.callCount);
712
713 List<BinderCallsStats.CallStat> callStatsList = new ArrayList(uidEntry.getCallStatsList());
714 assertEquals(1, callStatsList.size());
715 BinderCallsStats.CallStat callStats = callStatsList.get(0);
716 assertEquals(-1, callStats.callingUid);
717 assertEquals(2, callStats.callCount);
718 assertEquals(2, callStats.recordedCallCount);
719 }
720
721
Marcin Oczeretkoc80c81a2018-08-30 20:15:52 +0100722 class TestBinderCallsStats extends BinderCallsStats {
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100723 public int callingUid = CALLING_UID;
Olivier Gaillard88de48f2018-10-18 10:21:21 +0100724 public long time = 1234;
725 public long elapsedTime = 0;
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700726
Olivier Gaillard1d7f6152018-07-03 13:57:58 +0100727 TestBinderCallsStats() {
Marcin Oczeretko6a2e5242018-11-28 11:08:50 +0000728 this(mDeviceState);
729 }
730
731 TestBinderCallsStats(CachedDeviceState deviceState) {
Olivier Gaillard289ba402018-07-24 18:50:13 +0100732 // Make random generator not random.
Olivier Gaillard86714d12018-08-01 15:05:36 +0100733 super(new Injector() {
734 public Random getRandomGenerator() {
735 return new Random() {
736 int mCallCount = 0;
Olivier Gaillard2c13c6f2018-07-16 16:55:58 +0100737
Olivier Gaillard86714d12018-08-01 15:05:36 +0100738 public int nextInt() {
739 return mCallCount++;
740 }
741 };
Olivier Gaillard289ba402018-07-24 18:50:13 +0100742 }
743 });
Olivier Gaillard34ad8af2018-08-06 15:55:03 +0100744 setSamplingInterval(1);
Marcin Oczeretko772e8f22018-11-21 13:00:32 +0000745 setAddDebugEntries(false);
Olivier Gaillard36b80ca2019-02-11 11:41:39 +0000746 setTrackScreenInteractive(true);
747 setTrackDirectCallerUid(true);
Marcin Oczeretko6a2e5242018-11-28 11:08:50 +0000748 if (deviceState != null) {
749 setDeviceState(deviceState.getReadonlyClient());
750 }
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700751 }
752
753 @Override
754 protected long getThreadTimeMicro() {
755 return time;
756 }
757
758 @Override
Olivier Gaillard11965ed2018-06-04 14:14:04 +0100759 protected long getElapsedRealtimeMicro() {
760 return elapsedTime;
761 }
762
763 @Override
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700764 protected int getCallingUid() {
765 return callingUid;
766 }
Olivier Gaillard36b80ca2019-02-11 11:41:39 +0000767
768 protected void setCallingUid(int uid) {
769 callingUid = uid;
770 }
Fyodor Kupolovcf0fe2d2018-05-22 18:50:04 -0700771 }
772
773}