blob: 793d6b0639a8ff4e4ed877f313919f470bc08992 [file] [log] [blame]
Amith Yamasani62ec27e92018-03-11 14:42:06 -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.server.usage;
18
19import static org.junit.Assert.assertEquals;
20import static org.junit.Assert.assertFalse;
21import static org.junit.Assert.assertTrue;
22
23import android.app.PendingIntent;
24import android.os.HandlerThread;
25import android.os.Looper;
Brett Chabota26eda92018-07-23 13:08:30 -070026
27import androidx.test.filters.MediumTest;
28import androidx.test.runner.AndroidJUnit4;
Amith Yamasani62ec27e92018-03-11 14:42:06 -070029
30import org.junit.After;
31import org.junit.Before;
32import org.junit.Test;
33import org.junit.runner.RunWith;
34
35import java.util.concurrent.CountDownLatch;
36import java.util.concurrent.TimeUnit;
37
38@RunWith(AndroidJUnit4.class)
39@MediumTest
40public class AppTimeLimitControllerTests {
41
42 private static final String PKG_SOC1 = "package.soc1";
43 private static final String PKG_SOC2 = "package.soc2";
44 private static final String PKG_GAME1 = "package.game1";
45 private static final String PKG_GAME2 = "package.game2";
46 private static final String PKG_PROD = "package.prod";
47
48 private static final int UID = 10100;
49 private static final int USER_ID = 10;
50 private static final int OBS_ID1 = 1;
51 private static final int OBS_ID2 = 2;
52 private static final int OBS_ID3 = 3;
Michael Wachenschwanzc8703092018-05-01 16:02:45 -070053 private static final int OBS_ID4 = 4;
54 private static final int OBS_ID5 = 5;
55 private static final int OBS_ID6 = 6;
56 private static final int OBS_ID7 = 7;
57 private static final int OBS_ID8 = 8;
58 private static final int OBS_ID9 = 9;
59 private static final int OBS_ID10 = 10;
60 private static final int OBS_ID11 = 11;
Amith Yamasani62ec27e92018-03-11 14:42:06 -070061
Michael Wachenschwanzc8703092018-05-01 16:02:45 -070062 private static final long TIME_30_MIN = 30 * 60_000L;
63 private static final long TIME_10_MIN = 10 * 60_000L;
Michael Wachenschwanz0f472842018-10-23 23:02:48 -070064 private static final long TIME_1_MIN = 10 * 60_000L;
Michael Wachenschwanzc8703092018-05-01 16:02:45 -070065
66 private static final long MAX_OBSERVER_PER_UID = 10;
67 private static final long MIN_TIME_LIMIT = 4_000L;
Amith Yamasani62ec27e92018-03-11 14:42:06 -070068
69 private static final String[] GROUP1 = {
70 PKG_SOC1, PKG_GAME1, PKG_PROD
71 };
72
73 private static final String[] GROUP_SOC = {
74 PKG_SOC1, PKG_SOC2
75 };
76
77 private static final String[] GROUP_GAME = {
78 PKG_GAME1, PKG_GAME2
79 };
80
Michael Wachenschwanz0f472842018-10-23 23:02:48 -070081 private CountDownLatch mLimitReachedLatch = new CountDownLatch(1);
82 private CountDownLatch mSessionEndLatch = new CountDownLatch(1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -070083
84 private AppTimeLimitController mController;
85
86 private HandlerThread mThread;
87
88 private long mUptimeMillis;
89
Michael Wachenschwanz0f472842018-10-23 23:02:48 -070090 AppTimeLimitController.TimeLimitCallbackListener mListener =
91 new AppTimeLimitController.TimeLimitCallbackListener() {
92 @Override
93 public void onLimitReached(int observerId, int userId, long timeLimit,
94 long timeElapsed,
95 PendingIntent callbackIntent) {
96 mLimitReachedLatch.countDown();
97 }
Amith Yamasani62ec27e92018-03-11 14:42:06 -070098
Michael Wachenschwanz0f472842018-10-23 23:02:48 -070099 @Override
100 public void onSessionEnd(int observerId, int userId, long timeElapsed,
101 PendingIntent callbackIntent) {
102 mSessionEndLatch.countDown();
103 }
104 };
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700105
106 class MyAppTimeLimitController extends AppTimeLimitController {
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700107 MyAppTimeLimitController(AppTimeLimitController.TimeLimitCallbackListener listener,
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700108 Looper looper) {
109 super(listener, looper);
110 }
111
112 @Override
113 protected long getUptimeMillis() {
114 return mUptimeMillis;
115 }
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700116
117 @Override
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700118 protected long getAppUsageObserverPerUidLimit() {
119 return MAX_OBSERVER_PER_UID;
120 }
121
122 @Override
123 protected long getUsageSessionObserverPerUidLimit() {
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700124 return MAX_OBSERVER_PER_UID;
125 }
126
127 @Override
128 protected long getMinTimeLimit() {
129 return MIN_TIME_LIMIT;
130 }
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700131 }
132
133 @Before
134 public void setUp() {
135 mThread = new HandlerThread("Test");
136 mThread.start();
137 mController = new MyAppTimeLimitController(mListener, mThread.getLooper());
138 }
139
140 @After
141 public void tearDown() {
142 mThread.quit();
143 }
144
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700145 /** Verify app usage observer is added */
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700146 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700147 public void testAppUsageObserver_AddObserver() {
148 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN);
149 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1));
150 addAppUsageObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN);
151 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID2));
152 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700153 }
154
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700155 /** Verify usage session observer is added */
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700156 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700157 public void testUsageSessionObserver_AddObserver() {
158 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN);
159 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1));
160 addUsageSessionObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_1_MIN);
161 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID2));
162 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1));
163 }
164
165 /** Verify app usage observer is removed */
166 @Test
167 public void testAppUsageObserver_RemoveObserver() {
168 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN);
169 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1));
170 mController.removeAppUsageObserver(UID, OBS_ID1, USER_ID);
171 assertFalse("Observer wasn't removed", hasAppUsageObserver(UID, OBS_ID1));
172 }
173
174 /** Verify usage session observer is removed */
175 @Test
176 public void testUsageSessionObserver_RemoveObserver() {
177 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN);
178 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1));
179 mController.removeUsageSessionObserver(UID, OBS_ID1, USER_ID);
180 assertFalse("Observer wasn't removed", hasUsageSessionObserver(UID, OBS_ID1));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700181 }
182
183 /** Re-adding an observer should result in only one copy */
184 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700185 public void testAppUsageObserver_ObserverReAdd() {
186 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN);
187 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1));
188 addAppUsageObserver(OBS_ID1, GROUP1, TIME_10_MIN);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700189 assertTrue("Observer wasn't added",
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700190 mController.getAppUsageGroup(UID, OBS_ID1).getTimeLimitMs() == TIME_10_MIN);
191 mController.removeAppUsageObserver(UID, OBS_ID1, USER_ID);
192 assertFalse("Observer wasn't removed", hasAppUsageObserver(UID, OBS_ID1));
193 }
194
195 /** Re-adding an observer should result in only one copy */
196 @Test
197 public void testUsageSessionObserver_ObserverReAdd() {
198 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN);
199 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1));
200 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_10_MIN, TIME_1_MIN);
201 assertTrue("Observer wasn't added",
202 mController.getSessionUsageGroup(UID, OBS_ID1).getTimeLimitMs() == TIME_10_MIN);
203 mController.removeUsageSessionObserver(UID, OBS_ID1, USER_ID);
204 assertFalse("Observer wasn't removed", hasUsageSessionObserver(UID, OBS_ID1));
205 }
206
207 /** Different type observers can be registered to the same observerId value */
208 @Test
209 public void testAllObservers_ExclusiveObserverIds() {
210 addAppUsageObserver(OBS_ID1, GROUP1, TIME_10_MIN);
211 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN);
212 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1));
213 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1));
214
215 AppTimeLimitController.UsageGroup appUsageGroup = mController.getAppUsageGroup(UID,
216 OBS_ID1);
217 AppTimeLimitController.UsageGroup sessionUsageGroup = mController.getSessionUsageGroup(UID,
218 OBS_ID1);
219
220 // Verify data still intact
221 assertEquals(TIME_10_MIN, appUsageGroup.getTimeLimitMs());
222 assertEquals(TIME_30_MIN, sessionUsageGroup.getTimeLimitMs());
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700223 }
224
225 /** Verify that usage across different apps within a group are added up */
226 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700227 public void testAppUsageObserver_Accumulation() throws Exception {
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700228 setTime(0L);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700229 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN);
230 startUsage(PKG_SOC1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700231 // Add 10 mins
232 setTime(TIME_10_MIN);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700233 stopUsage(PKG_SOC1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700234
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700235 AppTimeLimitController.UsageGroup group = mController.getAppUsageGroup(UID, OBS_ID1);
236
237 long timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs();
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700238 assertEquals(TIME_10_MIN * 2, timeRemaining);
239
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700240 startUsage(PKG_SOC1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700241 setTime(TIME_10_MIN * 2);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700242 stopUsage(PKG_SOC1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700243
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700244 timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs();
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700245 assertEquals(TIME_10_MIN, timeRemaining);
246
247 setTime(TIME_30_MIN);
248
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700249 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700250
251 // Add a different package in the group
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700252 startUsage(PKG_GAME1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700253 setTime(TIME_30_MIN + TIME_10_MIN);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700254 stopUsage(PKG_GAME1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700255
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700256 assertEquals(0, group.getTimeLimitMs() - group.getUsageTimeMs());
257 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
258 }
259
260 /** Verify that usage across different apps within a group are added up */
261 @Test
262 public void testUsageSessionObserver_Accumulation() throws Exception {
263 setTime(0L);
264 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN);
265 startUsage(PKG_SOC1);
266 // Add 10 mins
267 setTime(TIME_10_MIN);
268 stopUsage(PKG_SOC1);
269
270 AppTimeLimitController.UsageGroup group = mController.getSessionUsageGroup(UID, OBS_ID1);
271
272 long timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs();
273 assertEquals(TIME_10_MIN * 2, timeRemaining);
274
275 startUsage(PKG_SOC1);
276 setTime(TIME_10_MIN * 2);
277 stopUsage(PKG_SOC1);
278
279 timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs();
280 assertEquals(TIME_10_MIN, timeRemaining);
281
282 setTime(TIME_30_MIN);
283
284 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
285
286 // Add a different package in the group
287 startUsage(PKG_GAME1);
288 setTime(TIME_30_MIN + TIME_10_MIN);
289 stopUsage(PKG_GAME1);
290
291 assertEquals(0, group.getTimeLimitMs() - group.getUsageTimeMs());
292 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700293 }
294
295 /** Verify that time limit does not get triggered due to a different app */
296 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700297 public void testAppUsageObserver_TimeoutOtherApp() throws Exception {
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700298 setTime(0L);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700299 addAppUsageObserver(OBS_ID1, GROUP1, 4_000L);
300 startUsage(PKG_SOC2);
301 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700302 setTime(6_000L);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700303 stopUsage(PKG_SOC2);
304 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
305 }
306
307 /** Verify that time limit does not get triggered due to a different app */
308 @Test
309 public void testUsageSessionObserver_TimeoutOtherApp() throws Exception {
310 setTime(0L);
311 addUsageSessionObserver(OBS_ID1, GROUP1, 4_000L, 1_000L);
312 startUsage(PKG_SOC2);
313 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS));
314 setTime(6_000L);
315 stopUsage(PKG_SOC2);
316 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
317
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700318 }
319
320 /** Verify the timeout message is delivered at the right time */
321 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700322 public void testAppUsageObserver_Timeout() throws Exception {
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700323 setTime(0L);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700324 addAppUsageObserver(OBS_ID1, GROUP1, 4_000L);
325 startUsage(PKG_SOC1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700326 setTime(6_000L);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700327 assertTrue(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS));
328 stopUsage(PKG_SOC1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700329 // Verify that the observer was removed
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700330 assertFalse(hasAppUsageObserver(UID, OBS_ID1));
331 }
332
333 /** Verify the timeout message is delivered at the right time */
334 @Test
335 public void testUsageSessionObserver_Timeout() throws Exception {
336 setTime(0L);
337 addUsageSessionObserver(OBS_ID1, GROUP1, 4_000L, 1_000L);
338 startUsage(PKG_SOC1);
339 setTime(6_000L);
340 assertTrue(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS));
341 stopUsage(PKG_SOC1);
342 // Usage has stopped, Session should end in a second. Verify session end occurs in a second
343 // (+/- 100ms, which is hopefully not too slim a margin)
344 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS));
345 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS));
346 // Verify that the observer was not removed
347 assertTrue(hasUsageSessionObserver(UID, OBS_ID1));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700348 }
349
350 /** If an app was already running, make sure it is partially counted towards the time limit */
351 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700352 public void testAppUsageObserver_AlreadyRunning() throws Exception {
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700353 setTime(TIME_10_MIN);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700354 startUsage(PKG_GAME1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700355 setTime(TIME_30_MIN);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700356 addAppUsageObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700357 setTime(TIME_30_MIN + TIME_10_MIN);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700358 stopUsage(PKG_GAME1);
359 assertFalse(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700360
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700361 startUsage(PKG_GAME2);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700362 setTime(TIME_30_MIN + TIME_30_MIN);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700363 stopUsage(PKG_GAME2);
364 assertTrue(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700365 // Verify that the observer was removed
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700366 assertFalse(hasAppUsageObserver(UID, OBS_ID2));
367 }
368
369 /** If an app was already running, make sure it is partially counted towards the time limit */
370 @Test
371 public void testUsageSessionObserver_AlreadyRunning() throws Exception {
372 setTime(TIME_10_MIN);
373 startUsage(PKG_GAME1);
374 setTime(TIME_30_MIN);
375 addUsageSessionObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_1_MIN);
376 setTime(TIME_30_MIN + TIME_10_MIN);
377 stopUsage(PKG_GAME1);
378 assertFalse(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS));
379
380 startUsage(PKG_GAME2);
381 setTime(TIME_30_MIN + TIME_30_MIN);
382 stopUsage(PKG_GAME2);
383 assertTrue(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS));
384 // Verify that the observer was removed
385 assertTrue(hasUsageSessionObserver(UID, OBS_ID2));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700386 }
387
388 /** If watched app is already running, verify the timeout callback happens at the right time */
389 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700390 public void testAppUsageObserver_AlreadyRunningTimeout() throws Exception {
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700391 setTime(0);
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700392 startUsage(PKG_SOC1);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700393 setTime(TIME_10_MIN);
394 // 10 second time limit
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700395 addAppUsageObserver(OBS_ID1, GROUP_SOC, 10_000L);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700396 setTime(TIME_10_MIN + 5_000L);
397 // Shouldn't call back in 6 seconds
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700398 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700399 setTime(TIME_10_MIN + 10_000L);
400 // Should call back by 11 seconds (6 earlier + 5 now)
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700401 assertTrue(mLimitReachedLatch.await(5_000L, TimeUnit.MILLISECONDS));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700402 // Verify that the observer was removed
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700403 assertFalse(hasAppUsageObserver(UID, OBS_ID1));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700404 }
405
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700406 /** If watched app is already running, verify the timeout callback happens at the right time */
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700407 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700408 public void testUsageSessionObserver_AlreadyRunningTimeout() throws Exception {
409 setTime(0);
410 startUsage(PKG_SOC1);
411 setTime(TIME_10_MIN);
412 // 10 second time limit
413 addUsageSessionObserver(OBS_ID1, GROUP_SOC, 10_000L, 1_000L);
414 setTime(TIME_10_MIN + 5_000L);
415 // Shouldn't call back in 6 seconds
416 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS));
417 setTime(TIME_10_MIN + 10_000L);
418 // Should call back by 11 seconds (6 earlier + 5 now)
419 assertTrue(mLimitReachedLatch.await(5_000L, TimeUnit.MILLISECONDS));
420 stopUsage(PKG_SOC1);
421 // Usage has stopped, Session should end in a second. Verify session end occurs in a second
422 // (+/- 100ms, which is hopefully not too slim a margin)
423 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS));
424 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS));
425 // Verify that the observer was removed
426 assertTrue(hasUsageSessionObserver(UID, OBS_ID1));
427 }
428
429 /**
430 * Verify that App Time Limit Controller will limit the number of observerIds for app usage
431 * observers
432 */
433 @Test
434 public void testAppUsageObserver_MaxObserverLimit() throws Exception {
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700435 boolean receivedException = false;
436 int ANOTHER_UID = UID + 1;
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700437 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN);
438 addAppUsageObserver(OBS_ID2, GROUP1, TIME_30_MIN);
439 addAppUsageObserver(OBS_ID3, GROUP1, TIME_30_MIN);
440 addAppUsageObserver(OBS_ID4, GROUP1, TIME_30_MIN);
441 addAppUsageObserver(OBS_ID5, GROUP1, TIME_30_MIN);
442 addAppUsageObserver(OBS_ID6, GROUP1, TIME_30_MIN);
443 addAppUsageObserver(OBS_ID7, GROUP1, TIME_30_MIN);
444 addAppUsageObserver(OBS_ID8, GROUP1, TIME_30_MIN);
445 addAppUsageObserver(OBS_ID9, GROUP1, TIME_30_MIN);
446 addAppUsageObserver(OBS_ID10, GROUP1, TIME_30_MIN);
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700447 // Readding an observer should not cause an IllegalStateException
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700448 addAppUsageObserver(OBS_ID5, GROUP1, TIME_30_MIN);
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700449 // Adding an observer for a different uid shouldn't cause an IllegalStateException
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700450 mController.addAppUsageObserver(ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, null, USER_ID);
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700451 try {
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700452 addAppUsageObserver(OBS_ID11, GROUP1, TIME_30_MIN);
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700453 } catch (IllegalStateException ise) {
454 receivedException = true;
455 }
456 assertTrue("Should have caused an IllegalStateException", receivedException);
457 }
458
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700459 /**
460 * Verify that App Time Limit Controller will limit the number of observerIds for usage session
461 * observers
462 */
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700463 @Test
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700464 public void testUsageSessionObserver_MaxObserverLimit() throws Exception {
465 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN);
466 boolean receivedException = false;
467 int ANOTHER_UID = UID + 1;
468 addUsageSessionObserver(OBS_ID2, GROUP1, TIME_30_MIN, TIME_1_MIN);
469 addUsageSessionObserver(OBS_ID3, GROUP1, TIME_30_MIN, TIME_1_MIN);
470 addUsageSessionObserver(OBS_ID4, GROUP1, TIME_30_MIN, TIME_1_MIN);
471 addUsageSessionObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_1_MIN);
472 addUsageSessionObserver(OBS_ID6, GROUP1, TIME_30_MIN, TIME_1_MIN);
473 addUsageSessionObserver(OBS_ID7, GROUP1, TIME_30_MIN, TIME_1_MIN);
474 addUsageSessionObserver(OBS_ID8, GROUP1, TIME_30_MIN, TIME_1_MIN);
475 addUsageSessionObserver(OBS_ID9, GROUP1, TIME_30_MIN, TIME_1_MIN);
476 addUsageSessionObserver(OBS_ID10, GROUP1, TIME_30_MIN, TIME_1_MIN);
477 // Readding an observer should not cause an IllegalStateException
478 addUsageSessionObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_1_MIN);
479 // Adding an observer for a different uid shouldn't cause an IllegalStateException
480 mController.addUsageSessionObserver(ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, TIME_1_MIN,
481 null, null, USER_ID);
482 try {
483 addUsageSessionObserver(OBS_ID11, GROUP1, TIME_30_MIN, TIME_1_MIN);
484 } catch (IllegalStateException ise) {
485 receivedException = true;
486 }
487 assertTrue("Should have caused an IllegalStateException", receivedException);
488 }
489
490 /** Verify that addAppUsageObserver minimum time limit is one minute */
491 @Test
492 public void testAppUsageObserver_MinimumTimeLimit() throws Exception {
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700493 boolean receivedException = false;
494 // adding an observer with a one minute time limit should not cause an exception
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700495 addAppUsageObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT);
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700496 try {
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700497 addAppUsageObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1);
Michael Wachenschwanzc8703092018-05-01 16:02:45 -0700498 } catch (IllegalArgumentException iae) {
499 receivedException = true;
500 }
501 assertTrue("Should have caused an IllegalArgumentException", receivedException);
502 }
503
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700504 /** Verify that addUsageSessionObserver minimum time limit is one minute */
505 @Test
506 public void testUsageSessionObserver_MinimumTimeLimit() throws Exception {
507 boolean receivedException = false;
508 // test also for session observers
509 addUsageSessionObserver(OBS_ID10, GROUP1, MIN_TIME_LIMIT, TIME_1_MIN);
510 try {
511 addUsageSessionObserver(OBS_ID10, GROUP1, MIN_TIME_LIMIT - 1, TIME_1_MIN);
512 } catch (IllegalArgumentException iae) {
513 receivedException = true;
514 }
515 assertTrue("Should have caused an IllegalArgumentException", receivedException);
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700516 }
517
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700518 /** Verify that concurrent usage from multiple apps in the same group will counted correctly */
519 @Test
520 public void testAppUsageObserver_ConcurrentUsage() throws Exception {
521 setTime(0L);
522 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN);
523 AppTimeLimitController.UsageGroup group = mController.getAppUsageGroup(UID, OBS_ID1);
524 startUsage(PKG_SOC1);
525 // Add 10 mins
526 setTime(TIME_10_MIN);
527
528 // Add a different package in the group will first package is still in use
529 startUsage(PKG_GAME1);
530 setTime(TIME_10_MIN * 2);
531 // Stop first package usage
532 stopUsage(PKG_SOC1);
533
534 setTime(TIME_30_MIN);
535 stopUsage(PKG_GAME1);
536
537 assertEquals(TIME_30_MIN, group.getUsageTimeMs());
538 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700539 }
540
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700541 /** Verify that concurrent usage from multiple apps in the same group will counted correctly */
542 @Test
543 public void testUsageSessionObserver_ConcurrentUsage() throws Exception {
544 setTime(0L);
545 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN);
546 AppTimeLimitController.UsageGroup group = mController.getSessionUsageGroup(UID, OBS_ID1);
547 startUsage(PKG_SOC1);
548 // Add 10 mins
549 setTime(TIME_10_MIN);
550
551 // Add a different package in the group will first package is still in use
552 startUsage(PKG_GAME1);
553 setTime(TIME_10_MIN * 2);
554 // Stop first package usage
555 stopUsage(PKG_SOC1);
556
557 setTime(TIME_30_MIN);
558 stopUsage(PKG_GAME1);
559
560 assertEquals(TIME_30_MIN, group.getUsageTimeMs());
561 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700562 }
563
Michael Wachenschwanz0f472842018-10-23 23:02:48 -0700564 /** Verify that a session will continue if usage starts again within the session threshold */
565 @Test
566 public void testUsageSessionObserver_ContinueSession() throws Exception {
567 setTime(0L);
568 addUsageSessionObserver(OBS_ID1, GROUP1, 10_000L, 2_000L);
569 startUsage(PKG_SOC1);
570 setTime(6_000L);
571 stopUsage(PKG_SOC1);
572 // Wait momentarily, Session should not end
573 assertFalse(mSessionEndLatch.await(1_000L, TimeUnit.MILLISECONDS));
574
575 setTime(7_000L);
576 startUsage(PKG_SOC1);
577 setTime(10_500L);
578 stopUsage(PKG_SOC1);
579 // Total usage time has not reached the limit. Time limit callback should not fire yet
580 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
581
582 setTime(10_600L);
583 startUsage(PKG_SOC1);
584 setTime(12_000L);
585 assertTrue(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS));
586 stopUsage(PKG_SOC1);
587 // Usage has stopped, Session should end in 2 seconds. Verify session end occurs
588 // (+/- 100ms, which is hopefully not too slim a margin)
589 assertFalse(mSessionEndLatch.await(1_900L, TimeUnit.MILLISECONDS));
590 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS));
591 // Verify that the observer was not removed
592 assertTrue(hasUsageSessionObserver(UID, OBS_ID1));
593 }
594
595 /** Verify that a new session will start if next usage starts after the session threshold */
596 @Test
597 public void testUsageSessionObserver_NewSession() throws Exception {
598 setTime(0L);
599 addUsageSessionObserver(OBS_ID1, GROUP1, 10_000L, 1_000L);
600 startUsage(PKG_SOC1);
601 setTime(6_000L);
602 stopUsage(PKG_SOC1);
603 // Wait for longer than the session threshold. Session end callback should not be triggered
604 // because the usage timelimit hasn't been triggered.
605 assertFalse(mSessionEndLatch.await(1_500L, TimeUnit.MILLISECONDS));
606
607 setTime(7_500L);
608 // This should be the start of a new session
609 startUsage(PKG_SOC1);
610 setTime(16_000L);
611 stopUsage(PKG_SOC1);
612 // Total usage has exceed the timelimit, but current session time has not
613 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS));
614
615 setTime(16_100L);
616 startUsage(PKG_SOC1);
617 setTime(18_000L);
618 assertTrue(mLimitReachedLatch.await(2000L, TimeUnit.MILLISECONDS));
619 stopUsage(PKG_SOC1);
620 // Usage has stopped, Session should end in 2 seconds. Verify session end occurs
621 // (+/- 100ms, which is hopefully not too slim a margin)
622 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS));
623 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS));
624 // Verify that the observer was not removed
625 assertTrue(hasUsageSessionObserver(UID, OBS_ID1));
626 }
627
628 /** Verify that the callbacks will be triggered for multiple sessions */
629 @Test
630 public void testUsageSessionObserver_RepeatSessions() throws Exception {
631 setTime(0L);
632 addUsageSessionObserver(OBS_ID1, GROUP1, 10_000L, 1_000L);
633 startUsage(PKG_SOC1);
634 setTime(9_000L);
635 stopUsage(PKG_SOC1);
636 // Stutter usage here, to reduce real world time needed trigger limit reached callback
637 startUsage(PKG_SOC1);
638 setTime(11_000L);
639 assertTrue(mLimitReachedLatch.await(2_000L, TimeUnit.MILLISECONDS));
640 stopUsage(PKG_SOC1);
641 // Usage has stopped, Session should end in 1 seconds. Verify session end occurs
642 // (+/- 100ms, which is hopefully not too slim a margin)
643 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS));
644 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS));
645
646 // Rearm the countdown latches
647 mLimitReachedLatch = new CountDownLatch(1);
648 mSessionEndLatch = new CountDownLatch(1);
649
650 // New session start
651 setTime(20_000L);
652 startUsage(PKG_SOC1);
653 setTime(29_000L);
654 stopUsage(PKG_SOC1);
655 startUsage(PKG_SOC1);
656 setTime(31_000L);
657 assertTrue(mLimitReachedLatch.await(2_000L, TimeUnit.MILLISECONDS));
658 stopUsage(PKG_SOC1);
659 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS));
660 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS));
661 assertTrue(hasUsageSessionObserver(UID, OBS_ID1));
662 }
663
664 private void startUsage(String packageName) {
665 mController.noteUsageStart(packageName, USER_ID);
666 }
667
668 private void stopUsage(String packageName) {
669 mController.noteUsageStop(packageName, USER_ID);
670 }
671
672 private void addAppUsageObserver(int observerId, String[] packages, long timeLimit) {
673 mController.addAppUsageObserver(UID, observerId, packages, timeLimit, null, USER_ID);
674 }
675
676 private void addUsageSessionObserver(int observerId, String[] packages, long timeLimit,
677 long sessionThreshold) {
678 mController.addUsageSessionObserver(UID, observerId, packages, timeLimit, sessionThreshold,
679 null, null, USER_ID);
680 }
681
682 /** Is there still an app usage observer by that id */
683 private boolean hasAppUsageObserver(int uid, int observerId) {
684 return mController.getAppUsageGroup(uid, observerId) != null;
685 }
686
687 /** Is there still an usage session observer by that id */
688 private boolean hasUsageSessionObserver(int uid, int observerId) {
689 return mController.getSessionUsageGroup(uid, observerId) != null;
Amith Yamasani62ec27e92018-03-11 14:42:06 -0700690 }
691
692 private void setTime(long time) {
693 mUptimeMillis = time;
694 }
695}