1 /* 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 17 package com.android.server.usage; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertNotNull; 22 import static org.junit.Assert.assertTrue; 23 import static org.junit.Assert.fail; 24 import static org.mockito.ArgumentMatchers.any; 25 import static org.mockito.ArgumentMatchers.anyLong; 26 import static org.mockito.ArgumentMatchers.anyString; 27 import static org.mockito.ArgumentMatchers.eq; 28 import static org.mockito.Mockito.times; 29 import static org.mockito.Mockito.verify; 30 31 import android.app.AlarmManager; 32 import android.app.PendingIntent; 33 import android.app.usage.UsageStatsManagerInternal; 34 import android.os.HandlerThread; 35 import android.os.Looper; 36 import android.os.UserHandle; 37 38 import androidx.test.InstrumentationRegistry; 39 import androidx.test.filters.LargeTest; 40 import androidx.test.runner.AndroidJUnit4; 41 42 import org.junit.After; 43 import org.junit.Before; 44 import org.junit.Test; 45 import org.junit.runner.RunWith; 46 import org.mockito.ArgumentCaptor; 47 import org.mockito.Mock; 48 import org.mockito.MockitoAnnotations; 49 50 import java.io.PrintWriter; 51 import java.io.StringWriter; 52 import java.util.concurrent.CountDownLatch; 53 import java.util.concurrent.TimeUnit; 54 55 @RunWith(AndroidJUnit4.class) 56 @LargeTest 57 public class AppTimeLimitControllerTests { 58 59 private static final String PKG_SOC1 = "package.soc1"; 60 private static final String PKG_SOC2 = "package.soc2"; 61 private static final String PKG_GAME1 = "package.game1"; 62 private static final String PKG_GAME2 = "package.game2"; 63 private static final String PKG_PROD = "package.prod"; 64 65 private static final int UID = 10100; 66 private static final int USER_ID = 10; 67 private static final int OBS_ID1 = 1; 68 private static final int OBS_ID2 = 2; 69 private static final int OBS_ID3 = 3; 70 private static final int OBS_ID4 = 4; 71 private static final int OBS_ID5 = 5; 72 private static final int OBS_ID6 = 6; 73 private static final int OBS_ID7 = 7; 74 private static final int OBS_ID8 = 8; 75 private static final int OBS_ID9 = 9; 76 private static final int OBS_ID10 = 10; 77 private static final int OBS_ID11 = 11; 78 79 private static final long TIME_30_MIN = 30 * 60_000L; 80 private static final long TIME_10_MIN = 10 * 60_000L; 81 private static final long TIME_1_MIN = 1 * 60_000L; 82 83 private static final long MAX_OBSERVER_PER_UID = 10; 84 private static final long MIN_TIME_LIMIT = 4_000L; 85 86 private static final String[] GROUP1 = { 87 PKG_SOC1, PKG_GAME1, PKG_PROD 88 }; 89 90 private static final String[] GROUP_SOC = { 91 PKG_SOC1, PKG_SOC2 92 }; 93 94 private static final String[] GROUP_GAME = { 95 PKG_GAME1, PKG_GAME2 96 }; 97 98 private CountDownLatch mLimitReachedLatch = new CountDownLatch(1); 99 private CountDownLatch mSessionEndLatch = new CountDownLatch(1); 100 101 private AppTimeLimitController mController; 102 103 @Mock private AlarmManager mMockAlarmManager; 104 105 private HandlerThread mThread; 106 107 private long mElapsedTime; 108 109 AppTimeLimitController.TimeLimitCallbackListener mListener = 110 new AppTimeLimitController.TimeLimitCallbackListener() { 111 @Override 112 public void onLimitReached(int observerId, int userId, long timeLimit, 113 long timeElapsed, 114 PendingIntent callbackIntent) { 115 mLimitReachedLatch.countDown(); 116 } 117 118 @Override 119 public void onSessionEnd(int observerId, int userId, long timeElapsed, 120 PendingIntent callbackIntent) { 121 mSessionEndLatch.countDown(); 122 } 123 }; 124 125 class MyAppTimeLimitController extends AppTimeLimitController { MyAppTimeLimitController(AppTimeLimitController.TimeLimitCallbackListener listener, Looper looper)126 MyAppTimeLimitController(AppTimeLimitController.TimeLimitCallbackListener listener, 127 Looper looper) { 128 super(InstrumentationRegistry.getContext(), listener, looper); 129 } 130 131 @Override getAlarmManager()132 protected AlarmManager getAlarmManager() { 133 return mMockAlarmManager; 134 } 135 136 @Override getElapsedRealtime()137 protected long getElapsedRealtime() { 138 return mElapsedTime; 139 } 140 141 @Override getAppUsageObserverPerUidLimit()142 protected long getAppUsageObserverPerUidLimit() { 143 return MAX_OBSERVER_PER_UID; 144 } 145 146 @Override getUsageSessionObserverPerUidLimit()147 protected long getUsageSessionObserverPerUidLimit() { 148 return MAX_OBSERVER_PER_UID; 149 } 150 151 @Override getAppUsageLimitObserverPerUidLimit()152 protected long getAppUsageLimitObserverPerUidLimit() { 153 return MAX_OBSERVER_PER_UID; 154 } 155 156 @Override getMinTimeLimit()157 protected long getMinTimeLimit() { 158 return MIN_TIME_LIMIT; 159 } 160 } 161 162 @Before setUp()163 public void setUp() { 164 mThread = new HandlerThread("Test"); 165 mThread.start(); 166 mController = new MyAppTimeLimitController(mListener, mThread.getLooper()); 167 168 MockitoAnnotations.initMocks(this); 169 } 170 171 @After tearDown()172 public void tearDown() { 173 mThread.quit(); 174 } 175 176 /** Verify app usage observer is added */ 177 @Test testAppUsageObserver_AddObserver()178 public void testAppUsageObserver_AddObserver() { 179 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN); 180 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1)); 181 addAppUsageObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN); 182 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID2)); 183 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1)); 184 } 185 186 /** Verify usage session observer is added */ 187 @Test testUsageSessionObserver_AddObserver()188 public void testUsageSessionObserver_AddObserver() { 189 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN); 190 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1)); 191 addUsageSessionObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_1_MIN); 192 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID2)); 193 } 194 195 /** Verify app usage limit observer is added */ 196 @Test testAppUsageLimitObserver_AddObserver()197 public void testAppUsageLimitObserver_AddObserver() { 198 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 199 assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); 200 addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, 0); 201 assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID2)); 202 assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); 203 } 204 205 /** Verify app usage observer is removed */ 206 @Test testAppUsageObserver_RemoveObserver()207 public void testAppUsageObserver_RemoveObserver() { 208 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN); 209 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1)); 210 mController.removeAppUsageObserver(UID, OBS_ID1, USER_ID); 211 assertFalse("Observer wasn't removed", hasAppUsageObserver(UID, OBS_ID1)); 212 } 213 214 /** Verify usage session observer is removed */ 215 @Test testUsageSessionObserver_RemoveObserver()216 public void testUsageSessionObserver_RemoveObserver() { 217 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN); 218 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1)); 219 mController.removeUsageSessionObserver(UID, OBS_ID1, USER_ID); 220 assertFalse("Observer wasn't removed", hasUsageSessionObserver(UID, OBS_ID1)); 221 } 222 223 /** Verify app usage limit observer is removed */ 224 @Test testAppUsageLimitObserver_RemoveObserver()225 public void testAppUsageLimitObserver_RemoveObserver() { 226 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 227 assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); 228 mController.removeAppUsageLimitObserver(UID, OBS_ID1, USER_ID); 229 assertFalse("Observer wasn't removed", hasAppUsageLimitObserver(UID, OBS_ID1)); 230 } 231 232 /** Verify nothing happens when a nonexistent app usage observer is removed */ 233 @Test testAppUsageObserver_RemoveMissingObserver()234 public void testAppUsageObserver_RemoveMissingObserver() { 235 assertFalse("Observer should not exist", hasAppUsageObserver(UID, OBS_ID1)); 236 try { 237 mController.removeAppUsageObserver(UID, OBS_ID1, USER_ID); 238 } catch (Exception e) { 239 StringWriter sw = new StringWriter(); 240 sw.write("Hit exception trying to remove nonexistent observer:\n"); 241 sw.write(e.toString()); 242 PrintWriter pw = new PrintWriter(sw); 243 e.printStackTrace(pw); 244 sw.write("\nTest Failed!"); 245 fail(sw.toString()); 246 } 247 assertFalse("Observer should not exist", hasAppUsageObserver(UID, OBS_ID1)); 248 } 249 250 /** Verify nothing happens when a nonexistent usage session observer is removed */ 251 @Test testUsageSessionObserver_RemoveMissingObserver()252 public void testUsageSessionObserver_RemoveMissingObserver() { 253 assertFalse("Observer should not exist", hasUsageSessionObserver(UID, OBS_ID1)); 254 try { 255 mController.removeUsageSessionObserver(UID, OBS_ID1, USER_ID); 256 } catch (Exception e) { 257 StringWriter sw = new StringWriter(); 258 sw.write("Hit exception trying to remove nonexistent observer:"); 259 sw.write(e.toString()); 260 PrintWriter pw = new PrintWriter(sw); 261 e.printStackTrace(pw); 262 sw.write("\nTest Failed!"); 263 fail(sw.toString()); 264 } 265 assertFalse("Observer should not exist", hasUsageSessionObserver(UID, OBS_ID1)); 266 } 267 268 /** Verify nothing happens when a nonexistent app usage limit observer is removed */ 269 @Test testAppUsageLimitObserver_RemoveMissingObserver()270 public void testAppUsageLimitObserver_RemoveMissingObserver() { 271 assertFalse("Observer should not exist", hasAppUsageLimitObserver(UID, OBS_ID1)); 272 try { 273 mController.removeAppUsageLimitObserver(UID, OBS_ID1, USER_ID); 274 } catch (Exception e) { 275 StringWriter sw = new StringWriter(); 276 sw.write("Hit exception trying to remove nonexistent observer:\n"); 277 sw.write(e.toString()); 278 PrintWriter pw = new PrintWriter(sw); 279 e.printStackTrace(pw); 280 sw.write("\nTest Failed!"); 281 fail(sw.toString()); 282 } 283 assertFalse("Observer should not exist", hasAppUsageLimitObserver(UID, OBS_ID1)); 284 } 285 286 /** Re-adding an observer should result in only one copy */ 287 @Test testAppUsageObserver_ObserverReAdd()288 public void testAppUsageObserver_ObserverReAdd() { 289 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN); 290 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1)); 291 addAppUsageObserver(OBS_ID1, GROUP1, TIME_10_MIN); 292 assertTrue("Observer wasn't added", 293 mController.getAppUsageGroup(UID, OBS_ID1).getTimeLimitMs() == TIME_10_MIN); 294 mController.removeAppUsageObserver(UID, OBS_ID1, USER_ID); 295 assertFalse("Observer wasn't removed", hasAppUsageObserver(UID, OBS_ID1)); 296 } 297 298 /** Re-adding an observer should result in only one copy */ 299 @Test testUsageSessionObserver_ObserverReAdd()300 public void testUsageSessionObserver_ObserverReAdd() { 301 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN); 302 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1)); 303 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_10_MIN, TIME_1_MIN); 304 assertTrue("Observer wasn't added", 305 mController.getSessionUsageGroup(UID, OBS_ID1).getTimeLimitMs() == TIME_10_MIN); 306 mController.removeUsageSessionObserver(UID, OBS_ID1, USER_ID); 307 assertFalse("Observer wasn't removed", hasUsageSessionObserver(UID, OBS_ID1)); 308 } 309 310 /** Re-adding an observer should result in only one copy */ 311 @Test testAppUsageLimitObserver_ObserverReAdd()312 public void testAppUsageLimitObserver_ObserverReAdd() { 313 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 314 assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); 315 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, 0); 316 assertTrue("Observer wasn't added", 317 getAppUsageLimitObserver(UID, OBS_ID1).getTimeLimitMs() == TIME_10_MIN); 318 mController.removeAppUsageLimitObserver(UID, OBS_ID1, USER_ID); 319 assertFalse("Observer wasn't removed", hasAppUsageLimitObserver(UID, OBS_ID1)); 320 } 321 322 /** Different type observers can be registered to the same observerId value */ 323 @Test testAllObservers_ExclusiveObserverIds()324 public void testAllObservers_ExclusiveObserverIds() { 325 addAppUsageObserver(OBS_ID1, GROUP1, TIME_10_MIN); 326 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN); 327 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_10_MIN, 0); 328 assertTrue("Observer wasn't added", hasAppUsageObserver(UID, OBS_ID1)); 329 assertTrue("Observer wasn't added", hasUsageSessionObserver(UID, OBS_ID1)); 330 assertTrue("Observer wasn't added", hasAppUsageLimitObserver(UID, OBS_ID1)); 331 332 AppTimeLimitController.UsageGroup appUsageGroup = mController.getAppUsageGroup(UID, 333 OBS_ID1); 334 AppTimeLimitController.UsageGroup sessionUsageGroup = mController.getSessionUsageGroup(UID, 335 OBS_ID1); 336 AppTimeLimitController.UsageGroup appUsageLimitGroup = getAppUsageLimitObserver( 337 UID, OBS_ID1); 338 339 // Verify data still intact 340 assertEquals(TIME_10_MIN, appUsageGroup.getTimeLimitMs()); 341 assertEquals(TIME_30_MIN, sessionUsageGroup.getTimeLimitMs()); 342 assertEquals(TIME_10_MIN, appUsageLimitGroup.getTimeLimitMs()); 343 } 344 345 /** Verify that usage across different apps within a group are added up */ 346 @Test testAppUsageObserver_Accumulation()347 public void testAppUsageObserver_Accumulation() throws Exception { 348 setTime(0L); 349 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN); 350 startUsage(PKG_SOC1); 351 // Add 10 mins 352 setTime(TIME_10_MIN); 353 stopUsage(PKG_SOC1); 354 355 AppTimeLimitController.UsageGroup group = mController.getAppUsageGroup(UID, OBS_ID1); 356 357 long timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs(); 358 assertEquals(TIME_10_MIN * 2, timeRemaining); 359 360 startUsage(PKG_SOC1); 361 setTime(TIME_10_MIN * 2); 362 stopUsage(PKG_SOC1); 363 364 timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs(); 365 assertEquals(TIME_10_MIN, timeRemaining); 366 367 setTime(TIME_30_MIN); 368 369 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 370 371 // Add a different package in the group 372 startUsage(PKG_GAME1); 373 setTime(TIME_30_MIN + TIME_10_MIN); 374 stopUsage(PKG_GAME1); 375 376 assertEquals(0, group.getTimeLimitMs() - group.getUsageTimeMs()); 377 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 378 } 379 380 /** Verify that usage across different apps within a group are added up */ 381 @Test testUsageSessionObserver_Accumulation()382 public void testUsageSessionObserver_Accumulation() throws Exception { 383 setTime(0L); 384 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_10_MIN); 385 startUsage(PKG_SOC1); 386 // Add 10 mins 387 setTime(TIME_10_MIN); 388 stopUsage(PKG_SOC1); 389 390 AppTimeLimitController.UsageGroup group = mController.getSessionUsageGroup(UID, OBS_ID1); 391 392 long timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs(); 393 assertEquals(TIME_10_MIN * 2, timeRemaining); 394 395 startUsage(PKG_SOC1); 396 setTime(TIME_10_MIN * 2); 397 stopUsage(PKG_SOC1); 398 399 timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs(); 400 assertEquals(TIME_10_MIN, timeRemaining); 401 402 setTime(TIME_30_MIN); 403 404 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 405 406 // Add a different package in the group 407 startUsage(PKG_GAME1); 408 setTime(TIME_30_MIN + TIME_10_MIN); 409 stopUsage(PKG_GAME1); 410 411 assertEquals(0, group.getTimeLimitMs() - group.getUsageTimeMs()); 412 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 413 } 414 415 /** Verify that usage across different apps within a group are added up */ 416 @Test testAppUsageLimitObserver_Accumulation()417 public void testAppUsageLimitObserver_Accumulation() throws Exception { 418 setTime(0L); 419 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 420 startUsage(PKG_SOC1); 421 // Add 10 mins 422 setTime(TIME_10_MIN); 423 stopUsage(PKG_SOC1); 424 425 AppTimeLimitController.UsageGroup group = getAppUsageLimitObserver(UID, OBS_ID1); 426 427 long timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs(); 428 assertEquals(TIME_10_MIN * 2, timeRemaining); 429 430 startUsage(PKG_SOC1); 431 setTime(TIME_10_MIN * 2); 432 stopUsage(PKG_SOC1); 433 434 timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs(); 435 assertEquals(TIME_10_MIN, timeRemaining); 436 437 setTime(TIME_30_MIN); 438 439 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 440 441 // Add a different package in the group 442 startUsage(PKG_GAME1); 443 setTime(TIME_30_MIN + TIME_10_MIN); 444 stopUsage(PKG_GAME1); 445 446 assertEquals(0, group.getTimeLimitMs() - group.getUsageTimeMs()); 447 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 448 } 449 450 /** Verify that time limit does not get triggered due to a different app */ 451 @Test testAppUsageObserver_TimeoutOtherApp()452 public void testAppUsageObserver_TimeoutOtherApp() throws Exception { 453 setTime(0L); 454 addAppUsageObserver(OBS_ID1, GROUP1, 4_000L); 455 startUsage(PKG_SOC2); 456 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); 457 setTime(6_000L); 458 stopUsage(PKG_SOC2); 459 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 460 } 461 462 /** Verify that time limit does not get triggered due to a different app */ 463 @Test testUsageSessionObserver_TimeoutOtherApp()464 public void testUsageSessionObserver_TimeoutOtherApp() throws Exception { 465 setTime(0L); 466 addUsageSessionObserver(OBS_ID1, GROUP1, 4_000L, 1_000L); 467 startUsage(PKG_SOC2); 468 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); 469 setTime(6_000L); 470 stopUsage(PKG_SOC2); 471 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 472 473 } 474 475 /** Verify that time limit does not get triggered due to a different app */ 476 @Test testAppUsageLimitObserver_TimeoutOtherApp()477 public void testAppUsageLimitObserver_TimeoutOtherApp() throws Exception { 478 setTime(0L); 479 addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 0); 480 startUsage(PKG_SOC2); 481 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); 482 setTime(6_000L); 483 stopUsage(PKG_SOC2); 484 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 485 } 486 487 /** Verify the timeout message is delivered at the right time */ 488 @Test testAppUsageObserver_Timeout()489 public void testAppUsageObserver_Timeout() throws Exception { 490 setTime(0L); 491 addAppUsageObserver(OBS_ID1, GROUP1, 4_000L); 492 startUsage(PKG_SOC1); 493 setTime(6_000L); 494 assertTrue(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); 495 stopUsage(PKG_SOC1); 496 // Verify that the observer was removed 497 assertFalse(hasAppUsageObserver(UID, OBS_ID1)); 498 } 499 500 /** Verify the timeout message is delivered at the right time */ 501 @Test testUsageSessionObserver_Timeout()502 public void testUsageSessionObserver_Timeout() throws Exception { 503 setTime(0L); 504 addUsageSessionObserver(OBS_ID1, GROUP1, 4_000L, 1_000L); 505 startUsage(PKG_SOC1); 506 setTime(6_000L); 507 assertTrue(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); 508 stopUsage(PKG_SOC1); 509 final ArgumentCaptor<AlarmManager.OnAlarmListener> onAlarmListenerArgumentCaptor = 510 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); 511 verify(mMockAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), 512 anyString(), onAlarmListenerArgumentCaptor.capture(), any()); 513 // Usage has stopped, Session should end in a second. Verify session end occurs in a second 514 // (+/- 100ms, which is hopefully not too slim a margin) 515 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS)); 516 onAlarmListenerArgumentCaptor.getValue().onAlarm(); 517 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS)); 518 // Verify that the observer was not removed 519 assertTrue(hasUsageSessionObserver(UID, OBS_ID1)); 520 } 521 522 /** Verify the timeout message is delivered at the right time */ 523 @Test testAppUsageLimitObserver_Timeout()524 public void testAppUsageLimitObserver_Timeout() throws Exception { 525 setTime(0L); 526 addAppUsageLimitObserver(OBS_ID1, GROUP1, 4_000L, 0); 527 startUsage(PKG_SOC1); 528 setTime(6_000L); 529 assertTrue(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); 530 stopUsage(PKG_SOC1); 531 // Verify that the observer was not removed 532 assertTrue(hasAppUsageLimitObserver(UID, OBS_ID1)); 533 } 534 535 /** If an app was already running, make sure it is partially counted towards the time limit */ 536 @Test testAppUsageObserver_AlreadyRunning()537 public void testAppUsageObserver_AlreadyRunning() throws Exception { 538 setTime(TIME_10_MIN); 539 startUsage(PKG_GAME1); 540 setTime(TIME_30_MIN); 541 addAppUsageObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN); 542 setTime(TIME_30_MIN + TIME_10_MIN); 543 stopUsage(PKG_GAME1); 544 assertFalse(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); 545 546 startUsage(PKG_GAME2); 547 setTime(TIME_30_MIN + TIME_30_MIN); 548 stopUsage(PKG_GAME2); 549 assertTrue(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); 550 // Verify that the observer was removed 551 assertFalse(hasAppUsageObserver(UID, OBS_ID2)); 552 } 553 554 /** If an app was already running, make sure it is partially counted towards the time limit */ 555 @Test testUsageSessionObserver_AlreadyRunning()556 public void testUsageSessionObserver_AlreadyRunning() throws Exception { 557 setTime(TIME_10_MIN); 558 startUsage(PKG_GAME1); 559 setTime(TIME_30_MIN); 560 addUsageSessionObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, TIME_1_MIN); 561 setTime(TIME_30_MIN + TIME_10_MIN); 562 stopUsage(PKG_GAME1); 563 assertFalse(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); 564 565 startUsage(PKG_GAME2); 566 setTime(TIME_30_MIN + TIME_30_MIN); 567 stopUsage(PKG_GAME2); 568 assertTrue(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); 569 // Verify that the observer was removed 570 assertTrue(hasUsageSessionObserver(UID, OBS_ID2)); 571 } 572 573 /** If an app was already running, make sure it is partially counted towards the time limit */ 574 @Test testAppUsageLimitObserver_AlreadyRunning()575 public void testAppUsageLimitObserver_AlreadyRunning() throws Exception { 576 setTime(TIME_10_MIN); 577 startUsage(PKG_GAME1); 578 setTime(TIME_30_MIN); 579 addAppUsageLimitObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN, 0); 580 setTime(TIME_30_MIN + TIME_10_MIN); 581 stopUsage(PKG_GAME1); 582 assertFalse(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); 583 584 startUsage(PKG_GAME2); 585 setTime(TIME_30_MIN + TIME_30_MIN); 586 stopUsage(PKG_GAME2); 587 assertTrue(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); 588 // Verify that the observer was not removed 589 assertTrue(hasAppUsageLimitObserver(UID, OBS_ID2)); 590 } 591 592 /** If watched app is already running, verify the timeout callback happens at the right time */ 593 @Test testAppUsageObserver_AlreadyRunningTimeout()594 public void testAppUsageObserver_AlreadyRunningTimeout() throws Exception { 595 setTime(0); 596 startUsage(PKG_SOC1); 597 setTime(TIME_10_MIN); 598 // 10 second time limit 599 addAppUsageObserver(OBS_ID1, GROUP_SOC, 10_000L); 600 setTime(TIME_10_MIN + 5_000L); 601 // Shouldn't call back in 6 seconds 602 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); 603 setTime(TIME_10_MIN + 10_000L); 604 // Should call back by 11 seconds (6 earlier + 5 now) 605 assertTrue(mLimitReachedLatch.await(5_000L, TimeUnit.MILLISECONDS)); 606 // Verify that the observer was removed 607 assertFalse(hasAppUsageObserver(UID, OBS_ID1)); 608 } 609 610 /** If watched app is already running, verify the timeout callback happens at the right time */ 611 @Test testUsageSessionObserver_AlreadyRunningTimeout()612 public void testUsageSessionObserver_AlreadyRunningTimeout() throws Exception { 613 setTime(0); 614 startUsage(PKG_SOC1); 615 setTime(TIME_10_MIN); 616 // 10 second time limit 617 addUsageSessionObserver(OBS_ID1, GROUP_SOC, 10_000L, 1_000L); 618 setTime(TIME_10_MIN + 5_000L); 619 // Shouldn't call back in 6 seconds 620 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); 621 setTime(TIME_10_MIN + 10_000L); 622 // Should call back by 11 seconds (6 earlier + 5 now) 623 assertTrue(mLimitReachedLatch.await(5_000L, TimeUnit.MILLISECONDS)); 624 stopUsage(PKG_SOC1); 625 final ArgumentCaptor<AlarmManager.OnAlarmListener> onAlarmListenerArgumentCaptor = 626 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); 627 verify(mMockAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), 628 anyString(), onAlarmListenerArgumentCaptor.capture(), any()); 629 // Usage has stopped, Session should end in a second. Verify session end occurs in a second 630 // (+/- 100ms, which is hopefully not too slim a margin) 631 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS)); 632 onAlarmListenerArgumentCaptor.getValue().onAlarm(); 633 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS)); 634 // Verify that the observer was removed 635 assertTrue(hasUsageSessionObserver(UID, OBS_ID1)); 636 } 637 638 /** If watched app is already running, verify the timeout callback happens at the right time */ 639 @Test testAppUsageLimitObserver_AlreadyRunningTimeout()640 public void testAppUsageLimitObserver_AlreadyRunningTimeout() throws Exception { 641 setTime(0); 642 startUsage(PKG_SOC1); 643 setTime(TIME_10_MIN); 644 // 10 second time limit 645 addAppUsageLimitObserver(OBS_ID1, GROUP_SOC, 10_000L, 0); 646 setTime(TIME_10_MIN + 5_000L); 647 // Shouldn't call back in 6 seconds 648 assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); 649 setTime(TIME_10_MIN + 10_000L); 650 // Should call back by 11 seconds (6 earlier + 5 now) 651 assertTrue(mLimitReachedLatch.await(5_000L, TimeUnit.MILLISECONDS)); 652 // Verify that the observer was not removed 653 assertTrue(hasAppUsageLimitObserver(UID, OBS_ID1)); 654 } 655 656 /** 657 * Verify that App Time Limit Controller will limit the number of observerIds for app usage 658 * observers 659 */ 660 @Test testAppUsageObserver_MaxObserverLimit()661 public void testAppUsageObserver_MaxObserverLimit() throws Exception { 662 boolean receivedException = false; 663 int ANOTHER_UID = UID + 1; 664 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN); 665 addAppUsageObserver(OBS_ID2, GROUP1, TIME_30_MIN); 666 addAppUsageObserver(OBS_ID3, GROUP1, TIME_30_MIN); 667 addAppUsageObserver(OBS_ID4, GROUP1, TIME_30_MIN); 668 addAppUsageObserver(OBS_ID5, GROUP1, TIME_30_MIN); 669 addAppUsageObserver(OBS_ID6, GROUP1, TIME_30_MIN); 670 addAppUsageObserver(OBS_ID7, GROUP1, TIME_30_MIN); 671 addAppUsageObserver(OBS_ID8, GROUP1, TIME_30_MIN); 672 addAppUsageObserver(OBS_ID9, GROUP1, TIME_30_MIN); 673 addAppUsageObserver(OBS_ID10, GROUP1, TIME_30_MIN); 674 // Readding an observer should not cause an IllegalStateException 675 addAppUsageObserver(OBS_ID5, GROUP1, TIME_30_MIN); 676 // Adding an observer for a different uid shouldn't cause an IllegalStateException 677 mController.addAppUsageObserver(ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, null, USER_ID); 678 try { 679 addAppUsageObserver(OBS_ID11, GROUP1, TIME_30_MIN); 680 } catch (IllegalStateException ise) { 681 receivedException = true; 682 } 683 assertTrue("Should have caused an IllegalStateException", receivedException); 684 } 685 686 /** 687 * Verify that App Time Limit Controller will limit the number of observerIds for usage session 688 * observers 689 */ 690 @Test testUsageSessionObserver_MaxObserverLimit()691 public void testUsageSessionObserver_MaxObserverLimit() throws Exception { 692 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN); 693 boolean receivedException = false; 694 int ANOTHER_UID = UID + 1; 695 addUsageSessionObserver(OBS_ID2, GROUP1, TIME_30_MIN, TIME_1_MIN); 696 addUsageSessionObserver(OBS_ID3, GROUP1, TIME_30_MIN, TIME_1_MIN); 697 addUsageSessionObserver(OBS_ID4, GROUP1, TIME_30_MIN, TIME_1_MIN); 698 addUsageSessionObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_1_MIN); 699 addUsageSessionObserver(OBS_ID6, GROUP1, TIME_30_MIN, TIME_1_MIN); 700 addUsageSessionObserver(OBS_ID7, GROUP1, TIME_30_MIN, TIME_1_MIN); 701 addUsageSessionObserver(OBS_ID8, GROUP1, TIME_30_MIN, TIME_1_MIN); 702 addUsageSessionObserver(OBS_ID9, GROUP1, TIME_30_MIN, TIME_1_MIN); 703 addUsageSessionObserver(OBS_ID10, GROUP1, TIME_30_MIN, TIME_1_MIN); 704 // Readding an observer should not cause an IllegalStateException 705 addUsageSessionObserver(OBS_ID5, GROUP1, TIME_30_MIN, TIME_1_MIN); 706 // Adding an observer for a different uid shouldn't cause an IllegalStateException 707 mController.addUsageSessionObserver(ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, TIME_1_MIN, 708 null, null, USER_ID); 709 try { 710 addUsageSessionObserver(OBS_ID11, GROUP1, TIME_30_MIN, TIME_1_MIN); 711 } catch (IllegalStateException ise) { 712 receivedException = true; 713 } 714 assertTrue("Should have caused an IllegalStateException", receivedException); 715 } 716 717 /** 718 * Verify that App Time Limit Controller will limit the number of observerIds for app usage 719 * limit observers 720 */ 721 @Test testAppUsageLimitObserver_MaxObserverLimit()722 public void testAppUsageLimitObserver_MaxObserverLimit() throws Exception { 723 boolean receivedException = false; 724 int ANOTHER_UID = UID + 1; 725 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 726 addAppUsageLimitObserver(OBS_ID2, GROUP1, TIME_30_MIN, 0); 727 addAppUsageLimitObserver(OBS_ID3, GROUP1, TIME_30_MIN, 0); 728 addAppUsageLimitObserver(OBS_ID4, GROUP1, TIME_30_MIN, 0); 729 addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, 0); 730 addAppUsageLimitObserver(OBS_ID6, GROUP1, TIME_30_MIN, 0); 731 addAppUsageLimitObserver(OBS_ID7, GROUP1, TIME_30_MIN, 0); 732 addAppUsageLimitObserver(OBS_ID8, GROUP1, TIME_30_MIN, 0); 733 addAppUsageLimitObserver(OBS_ID9, GROUP1, TIME_30_MIN, 0); 734 addAppUsageLimitObserver(OBS_ID10, GROUP1, TIME_30_MIN, 0); 735 // Readding an observer should not cause an IllegalStateException 736 addAppUsageLimitObserver(OBS_ID5, GROUP1, TIME_30_MIN, 0); 737 // Adding an observer for a different uid shouldn't cause an IllegalStateException 738 mController.addAppUsageLimitObserver( 739 ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, 0, null, USER_ID); 740 try { 741 addAppUsageLimitObserver(OBS_ID11, GROUP1, TIME_30_MIN, 0); 742 } catch (IllegalStateException ise) { 743 receivedException = true; 744 } 745 assertTrue("Should have caused an IllegalStateException", receivedException); 746 } 747 748 /** Verify that addAppUsageObserver minimum time limit is one minute */ 749 @Test testAppUsageObserver_MinimumTimeLimit()750 public void testAppUsageObserver_MinimumTimeLimit() throws Exception { 751 boolean receivedException = false; 752 // adding an observer with a one minute time limit should not cause an exception 753 addAppUsageObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT); 754 try { 755 addAppUsageObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1); 756 } catch (IllegalArgumentException iae) { 757 receivedException = true; 758 } 759 assertTrue("Should have caused an IllegalArgumentException", receivedException); 760 } 761 762 /** Verify that addUsageSessionObserver minimum time limit is one minute */ 763 @Test testUsageSessionObserver_MinimumTimeLimit()764 public void testUsageSessionObserver_MinimumTimeLimit() throws Exception { 765 boolean receivedException = false; 766 // test also for session observers 767 addUsageSessionObserver(OBS_ID10, GROUP1, MIN_TIME_LIMIT, TIME_1_MIN); 768 try { 769 addUsageSessionObserver(OBS_ID10, GROUP1, MIN_TIME_LIMIT - 1, TIME_1_MIN); 770 } catch (IllegalArgumentException iae) { 771 receivedException = true; 772 } 773 assertTrue("Should have caused an IllegalArgumentException", receivedException); 774 } 775 776 /** Verify that addAppUsageLimitObserver minimum time limit is one minute */ 777 @Test testAppUsageLimitObserver_MinimumTimeLimit()778 public void testAppUsageLimitObserver_MinimumTimeLimit() throws Exception { 779 boolean receivedException = false; 780 // adding an observer with a one minute time limit should not cause an exception 781 addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT, 0); 782 try { 783 addAppUsageLimitObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1, 0); 784 } catch (IllegalArgumentException iae) { 785 receivedException = true; 786 } 787 assertTrue("Should have caused an IllegalArgumentException", receivedException); 788 } 789 790 /** Verify that concurrent usage from multiple apps in the same group will counted correctly */ 791 @Test testAppUsageObserver_ConcurrentUsage()792 public void testAppUsageObserver_ConcurrentUsage() throws Exception { 793 setTime(0L); 794 addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN); 795 AppTimeLimitController.UsageGroup group = mController.getAppUsageGroup(UID, OBS_ID1); 796 startUsage(PKG_SOC1); 797 // Add 10 mins 798 setTime(TIME_10_MIN); 799 800 // Add a different package in the group will first package is still in use 801 startUsage(PKG_GAME1); 802 setTime(TIME_10_MIN * 2); 803 // Stop first package usage 804 stopUsage(PKG_SOC1); 805 806 setTime(TIME_30_MIN); 807 stopUsage(PKG_GAME1); 808 809 assertEquals(TIME_30_MIN, group.getUsageTimeMs()); 810 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 811 } 812 813 /** Verify that concurrent usage from multiple apps in the same group will counted correctly */ 814 @Test testUsageSessionObserver_ConcurrentUsage()815 public void testUsageSessionObserver_ConcurrentUsage() throws Exception { 816 setTime(0L); 817 addUsageSessionObserver(OBS_ID1, GROUP1, TIME_30_MIN, TIME_1_MIN); 818 AppTimeLimitController.UsageGroup group = mController.getSessionUsageGroup(UID, OBS_ID1); 819 startUsage(PKG_SOC1); 820 // Add 10 mins 821 setTime(TIME_10_MIN); 822 823 // Add a different package in the group will first package is still in use 824 startUsage(PKG_GAME1); 825 setTime(TIME_10_MIN * 2); 826 // Stop first package usage 827 stopUsage(PKG_SOC1); 828 829 setTime(TIME_30_MIN); 830 stopUsage(PKG_GAME1); 831 832 assertEquals(TIME_30_MIN, group.getUsageTimeMs()); 833 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 834 } 835 836 /** Verify that concurrent usage from multiple apps in the same group will counted correctly */ 837 @Test testAppUsageLimitObserver_ConcurrentUsage()838 public void testAppUsageLimitObserver_ConcurrentUsage() throws Exception { 839 setTime(0L); 840 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 841 AppTimeLimitController.UsageGroup group = getAppUsageLimitObserver(UID, OBS_ID1); 842 startUsage(PKG_SOC1); 843 // Add 10 mins 844 setTime(TIME_10_MIN); 845 846 // Add a different package in the group will first package is still in use 847 startUsage(PKG_GAME1); 848 setTime(TIME_10_MIN * 2); 849 // Stop first package usage 850 stopUsage(PKG_SOC1); 851 852 setTime(TIME_30_MIN); 853 stopUsage(PKG_GAME1); 854 855 assertEquals(TIME_30_MIN, group.getUsageTimeMs()); 856 assertTrue(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 857 } 858 859 /** Verify that a session will continue if usage starts again within the session threshold */ 860 @Test testUsageSessionObserver_ContinueSession()861 public void testUsageSessionObserver_ContinueSession() throws Exception { 862 setTime(0L); 863 addUsageSessionObserver(OBS_ID1, GROUP1, 10_000L, 2_000L); 864 startUsage(PKG_SOC1); 865 setTime(6_000L); 866 stopUsage(PKG_SOC1); 867 // Wait momentarily, Session should not end 868 assertFalse(mSessionEndLatch.await(1_000L, TimeUnit.MILLISECONDS)); 869 870 setTime(7_000L); 871 startUsage(PKG_SOC1); 872 setTime(10_500L); 873 stopUsage(PKG_SOC1); 874 // Total usage time has not reached the limit. Time limit callback should not fire yet 875 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 876 877 setTime(10_600L); 878 startUsage(PKG_SOC1); 879 setTime(12_000L); 880 assertTrue(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); 881 stopUsage(PKG_SOC1); 882 final ArgumentCaptor<AlarmManager.OnAlarmListener> onAlarmListenerArgumentCaptor = 883 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); 884 verify(mMockAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), 885 anyString(), onAlarmListenerArgumentCaptor.capture(), any()); 886 // Usage has stopped, Session should end in 2 seconds. Verify session end occurs 887 // (+/- 100ms, which is hopefully not too slim a margin) 888 assertFalse(mSessionEndLatch.await(1_900L, TimeUnit.MILLISECONDS)); 889 onAlarmListenerArgumentCaptor.getValue().onAlarm(); 890 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS)); 891 // Verify that the observer was not removed 892 assertTrue(hasUsageSessionObserver(UID, OBS_ID1)); 893 } 894 895 /** Verify that a new session will start if next usage starts after the session threshold */ 896 @Test testUsageSessionObserver_NewSession()897 public void testUsageSessionObserver_NewSession() throws Exception { 898 setTime(0L); 899 addUsageSessionObserver(OBS_ID1, GROUP1, 10_000L, 1_000L); 900 startUsage(PKG_SOC1); 901 setTime(6_000L); 902 stopUsage(PKG_SOC1); 903 // Wait for longer than the session threshold. Session end callback should not be triggered 904 // because the usage timelimit hasn't been triggered. 905 assertFalse(mSessionEndLatch.await(1_500L, TimeUnit.MILLISECONDS)); 906 907 setTime(7_500L); 908 // This should be the start of a new session 909 startUsage(PKG_SOC1); 910 setTime(16_000L); 911 stopUsage(PKG_SOC1); 912 // Total usage has exceed the timelimit, but current session time has not 913 assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); 914 915 setTime(16_100L); 916 startUsage(PKG_SOC1); 917 setTime(18_000L); 918 assertTrue(mLimitReachedLatch.await(2000L, TimeUnit.MILLISECONDS)); 919 stopUsage(PKG_SOC1); 920 final ArgumentCaptor<AlarmManager.OnAlarmListener> onAlarmListenerArgumentCaptor = 921 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); 922 verify(mMockAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), 923 anyString(), onAlarmListenerArgumentCaptor.capture(), any()); 924 // Usage has stopped, Session should end in 2 seconds. Verify session end occurs 925 // (+/- 100ms, which is hopefully not too slim a margin) 926 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS)); 927 onAlarmListenerArgumentCaptor.getValue().onAlarm(); 928 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS)); 929 // Verify that the observer was not removed 930 assertTrue(hasUsageSessionObserver(UID, OBS_ID1)); 931 } 932 933 /** Verify that the callbacks will be triggered for multiple sessions */ 934 @Test testUsageSessionObserver_RepeatSessions()935 public void testUsageSessionObserver_RepeatSessions() throws Exception { 936 setTime(0L); 937 addUsageSessionObserver(OBS_ID1, GROUP1, 10_000L, 1_000L); 938 startUsage(PKG_SOC1); 939 setTime(9_000L); 940 stopUsage(PKG_SOC1); 941 // Stutter usage here, to reduce real world time needed trigger limit reached callback 942 startUsage(PKG_SOC1); 943 setTime(11_000L); 944 assertTrue(mLimitReachedLatch.await(2_000L, TimeUnit.MILLISECONDS)); 945 stopUsage(PKG_SOC1); 946 final ArgumentCaptor<AlarmManager.OnAlarmListener> onAlarmListenerArgumentCaptor = 947 ArgumentCaptor.forClass(AlarmManager.OnAlarmListener.class); 948 verify(mMockAlarmManager).setExact(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), 949 anyString(), onAlarmListenerArgumentCaptor.capture(), any()); 950 // Usage has stopped, Session should end in 1 seconds. Verify session end occurs 951 // (+/- 100ms, which is hopefully not too slim a margin) 952 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS)); 953 onAlarmListenerArgumentCaptor.getValue().onAlarm(); 954 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS)); 955 956 // Rearm the countdown latches 957 mLimitReachedLatch = new CountDownLatch(1); 958 mSessionEndLatch = new CountDownLatch(1); 959 960 // New session start 961 setTime(20_000L); 962 startUsage(PKG_SOC1); 963 setTime(29_000L); 964 stopUsage(PKG_SOC1); 965 startUsage(PKG_SOC1); 966 setTime(31_000L); 967 assertTrue(mLimitReachedLatch.await(2_000L, TimeUnit.MILLISECONDS)); 968 stopUsage(PKG_SOC1); 969 verify(mMockAlarmManager, times(2)).setExact(eq(AlarmManager.ELAPSED_REALTIME), anyLong(), 970 anyString(), onAlarmListenerArgumentCaptor.capture(), any()); 971 assertFalse(mSessionEndLatch.await(900L, TimeUnit.MILLISECONDS)); 972 onAlarmListenerArgumentCaptor.getValue().onAlarm(); 973 assertTrue(mSessionEndLatch.await(200L, TimeUnit.MILLISECONDS)); 974 assertTrue(hasUsageSessionObserver(UID, OBS_ID1)); 975 } 976 977 /** Verify the timeout message is delivered at the right time after past usage was reported */ 978 @Test testAppUsageObserver_PastUsage()979 public void testAppUsageObserver_PastUsage() throws Exception { 980 setTime(10_000L); 981 addAppUsageObserver(OBS_ID1, GROUP1, 6_000L); 982 setTime(20_000L); 983 startPastUsage(PKG_SOC1, 5_000); 984 setTime(21_000L); 985 assertTrue(mLimitReachedLatch.await(2_000L, TimeUnit.MILLISECONDS)); 986 stopUsage(PKG_SOC1); 987 // Verify that the observer was removed 988 assertFalse(hasAppUsageObserver(UID, OBS_ID1)); 989 } 990 991 /** 992 * Verify the timeout message is delivered at the right time after past usage was reported 993 * that overlaps with already known usage 994 */ 995 @Test testAppUsageObserver_PastUsageOverlap()996 public void testAppUsageObserver_PastUsageOverlap() throws Exception { 997 setTime(0L); 998 addAppUsageObserver(OBS_ID1, GROUP1, 20_000L); 999 setTime(10_000L); 1000 startUsage(PKG_SOC1); 1001 setTime(20_000L); 1002 stopUsage(PKG_SOC1); 1003 setTime(25_000L); 1004 startPastUsage(PKG_SOC1, 9_000); 1005 setTime(26_000L); 1006 // the 4 seconds of overlapped usage should not be counted 1007 assertFalse(mLimitReachedLatch.await(2_000L, TimeUnit.MILLISECONDS)); 1008 setTime(30_000L); 1009 assertTrue(mLimitReachedLatch.await(4_000L, TimeUnit.MILLISECONDS)); 1010 stopUsage(PKG_SOC1); 1011 // Verify that the observer was removed 1012 assertFalse(hasAppUsageObserver(UID, OBS_ID1)); 1013 } 1014 1015 /** Verify app usage limit observer added correctly reports its total usage limit */ 1016 @Test testAppUsageLimitObserver_GetTotalUsageLimit()1017 public void testAppUsageLimitObserver_GetTotalUsageLimit() { 1018 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 1019 AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1); 1020 assertNotNull("Observer wasn't added", group); 1021 assertEquals("Observer didn't correctly report total usage limit", 1022 TIME_30_MIN, group.getTotaUsageLimit()); 1023 } 1024 1025 /** Verify app usage limit observer added correctly reports its total usage limit */ 1026 @Test testAppUsageLimitObserver_GetUsageRemaining()1027 public void testAppUsageLimitObserver_GetUsageRemaining() { 1028 setTime(0L); 1029 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 1030 startUsage(PKG_SOC1); 1031 setTime(TIME_10_MIN); 1032 stopUsage(PKG_SOC1); 1033 AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1); 1034 assertNotNull("Observer wasn't added", group); 1035 assertEquals("Observer didn't correctly report total usage limit", 1036 TIME_10_MIN * 2, group.getUsageRemaining()); 1037 } 1038 1039 /** Verify the app usage limit observer with the smallest usage limit remaining is returned 1040 * when querying the getAppUsageLimit API. 1041 */ 1042 @Test testAppUsageLimitObserver_GetAppUsageLimit()1043 public void testAppUsageLimitObserver_GetAppUsageLimit() { 1044 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 1045 addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0); 1046 UsageStatsManagerInternal.AppUsageLimitData group = getAppUsageLimit(PKG_SOC1); 1047 assertEquals("Observer with the smallest usage limit remaining wasn't returned", 1048 TIME_10_MIN, group.getTotalUsageLimit()); 1049 } 1050 1051 /** Verify the app usage limit observer with the smallest usage limit remaining is returned 1052 * when querying the getAppUsageLimit API. 1053 */ 1054 @Test testAppUsageLimitObserver_GetAppUsageLimitUsed()1055 public void testAppUsageLimitObserver_GetAppUsageLimitUsed() { 1056 setTime(0L); 1057 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 1058 addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0); 1059 startUsage(PKG_GAME1); 1060 setTime(TIME_10_MIN * 2 + TIME_1_MIN); 1061 stopUsage(PKG_GAME1); 1062 // PKG_GAME1 is only in GROUP1 but since we're querying for PCK_SOC1 which is 1063 // in both groups, GROUP1 should be returned since it has a smaller time remaining 1064 UsageStatsManagerInternal.AppUsageLimitData group = getAppUsageLimit(PKG_SOC1); 1065 assertEquals("Observer with the smallest usage limit remaining wasn't returned", 1066 TIME_1_MIN * 9, group.getUsageRemaining()); 1067 } 1068 1069 /** Verify the app usage limit observer with the smallest usage limit remaining is returned 1070 * when querying the getAppUsageLimit API. 1071 */ 1072 @Test testAppUsageLimitObserver_GetAppUsageLimitAllUsed()1073 public void testAppUsageLimitObserver_GetAppUsageLimitAllUsed() { 1074 setTime(0L); 1075 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_30_MIN, 0); 1076 addAppUsageLimitObserver(OBS_ID2, GROUP_SOC, TIME_10_MIN, 0); 1077 startUsage(PKG_SOC1); 1078 setTime(TIME_10_MIN); 1079 stopUsage(PKG_SOC1); 1080 // GROUP_SOC should be returned since it should be completely used up (0ms remaining) 1081 UsageStatsManagerInternal.AppUsageLimitData group = getAppUsageLimit(PKG_SOC1); 1082 assertEquals("Observer with the smallest usage limit remaining wasn't returned", 1083 0L, group.getUsageRemaining()); 1084 } 1085 1086 /** Verify that a limit of 0 is not allowed. */ 1087 @Test testAppUsageLimitObserver_ZeroTimeLimitIsNotAllowed()1088 public void testAppUsageLimitObserver_ZeroTimeLimitIsNotAllowed() { 1089 try { 1090 addAppUsageLimitObserver(OBS_ID1, GROUP1, 0, 0); 1091 fail("timeLimit of 0 should not be allowed."); 1092 } catch (IllegalArgumentException expected) { 1093 // Exception expected. 1094 } 1095 } 1096 1097 /** Verify that timeUsed can be the same as timeLimit (for re-registering observers). */ 1098 @Test testAppUsageLimitObserver_ZeroTimeRemainingIsAllowed()1099 public void testAppUsageLimitObserver_ZeroTimeRemainingIsAllowed() { 1100 addAppUsageLimitObserver(OBS_ID1, GROUP1, TIME_1_MIN, TIME_1_MIN); 1101 AppTimeLimitController.AppUsageLimitGroup group = getAppUsageLimitObserver(UID, OBS_ID1); 1102 assertNotNull("Observer wasn't added", group); 1103 assertEquals("Usage remaining was not 0.", 0, group.getUsageRemaining()); 1104 } 1105 startUsage(String packageName)1106 private void startUsage(String packageName) { 1107 mController.noteUsageStart(packageName, USER_ID); 1108 } 1109 startPastUsage(String packageName, int timeAgo)1110 private void startPastUsage(String packageName, int timeAgo) { 1111 mController.noteUsageStart(packageName, USER_ID, timeAgo); 1112 } 1113 stopUsage(String packageName)1114 private void stopUsage(String packageName) { 1115 mController.noteUsageStop(packageName, USER_ID); 1116 } 1117 addAppUsageObserver(int observerId, String[] packages, long timeLimit)1118 private void addAppUsageObserver(int observerId, String[] packages, long timeLimit) { 1119 mController.addAppUsageObserver(UID, observerId, packages, timeLimit, null, USER_ID); 1120 } 1121 addUsageSessionObserver(int observerId, String[] packages, long timeLimit, long sessionThreshold)1122 private void addUsageSessionObserver(int observerId, String[] packages, long timeLimit, 1123 long sessionThreshold) { 1124 mController.addUsageSessionObserver(UID, observerId, packages, timeLimit, sessionThreshold, 1125 null, null, USER_ID); 1126 } 1127 addAppUsageLimitObserver(int observerId, String[] packages, long timeLimit, long timeUsed)1128 private void addAppUsageLimitObserver(int observerId, String[] packages, long timeLimit, 1129 long timeUsed) { 1130 mController.addAppUsageLimitObserver(UID, observerId, packages, timeLimit, timeUsed, 1131 null, USER_ID); 1132 } 1133 1134 /** Is there still an app usage observer by that id */ hasAppUsageObserver(int uid, int observerId)1135 private boolean hasAppUsageObserver(int uid, int observerId) { 1136 return mController.getAppUsageGroup(uid, observerId) != null; 1137 } 1138 1139 /** Is there still an usage session observer by that id */ hasUsageSessionObserver(int uid, int observerId)1140 private boolean hasUsageSessionObserver(int uid, int observerId) { 1141 return mController.getSessionUsageGroup(uid, observerId) != null; 1142 } 1143 1144 /** Is there still an app usage limit observer by that id */ hasAppUsageLimitObserver(int uid, int observerId)1145 private boolean hasAppUsageLimitObserver(int uid, int observerId) { 1146 return mController.getAppUsageLimitGroup(uid, observerId) != null; 1147 } 1148 getAppUsageLimitObserver( int uid, int observerId)1149 private AppTimeLimitController.AppUsageLimitGroup getAppUsageLimitObserver( 1150 int uid, int observerId) { 1151 return mController.getAppUsageLimitGroup(uid, observerId); 1152 } 1153 getAppUsageLimit(String packageName)1154 private UsageStatsManagerInternal.AppUsageLimitData getAppUsageLimit(String packageName) { 1155 return mController.getAppUsageLimit(packageName, UserHandle.of(USER_ID)); 1156 } 1157 setTime(long time)1158 private void setTime(long time) { 1159 mElapsedTime = time; 1160 } 1161 } 1162