Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 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.assertTrue; |
| 22 | |
| 23 | import android.app.PendingIntent; |
| 24 | import android.os.HandlerThread; |
| 25 | import android.os.Looper; |
Brett Chabot | a26eda9 | 2018-07-23 13:08:30 -0700 | [diff] [blame] | 26 | |
| 27 | import androidx.test.filters.MediumTest; |
| 28 | import androidx.test.runner.AndroidJUnit4; |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 29 | |
| 30 | import org.junit.After; |
| 31 | import org.junit.Before; |
| 32 | import org.junit.Test; |
| 33 | import org.junit.runner.RunWith; |
| 34 | |
| 35 | import java.util.concurrent.CountDownLatch; |
| 36 | import java.util.concurrent.TimeUnit; |
| 37 | |
| 38 | @RunWith(AndroidJUnit4.class) |
| 39 | @MediumTest |
| 40 | public 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 Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 53 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 61 | |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 62 | private static final long TIME_30_MIN = 30 * 60_000L; |
| 63 | private static final long TIME_10_MIN = 10 * 60_000L; |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 64 | private static final long TIME_1_MIN = 10 * 60_000L; |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 65 | |
| 66 | private static final long MAX_OBSERVER_PER_UID = 10; |
| 67 | private static final long MIN_TIME_LIMIT = 4_000L; |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 68 | |
| 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 Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 81 | private CountDownLatch mLimitReachedLatch = new CountDownLatch(1); |
| 82 | private CountDownLatch mSessionEndLatch = new CountDownLatch(1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 83 | |
| 84 | private AppTimeLimitController mController; |
| 85 | |
| 86 | private HandlerThread mThread; |
| 87 | |
| 88 | private long mUptimeMillis; |
| 89 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 90 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 98 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 99 | @Override |
| 100 | public void onSessionEnd(int observerId, int userId, long timeElapsed, |
| 101 | PendingIntent callbackIntent) { |
| 102 | mSessionEndLatch.countDown(); |
| 103 | } |
| 104 | }; |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 105 | |
| 106 | class MyAppTimeLimitController extends AppTimeLimitController { |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 107 | MyAppTimeLimitController(AppTimeLimitController.TimeLimitCallbackListener listener, |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 108 | Looper looper) { |
| 109 | super(listener, looper); |
| 110 | } |
| 111 | |
| 112 | @Override |
| 113 | protected long getUptimeMillis() { |
| 114 | return mUptimeMillis; |
| 115 | } |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 116 | |
| 117 | @Override |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 118 | protected long getAppUsageObserverPerUidLimit() { |
| 119 | return MAX_OBSERVER_PER_UID; |
| 120 | } |
| 121 | |
| 122 | @Override |
| 123 | protected long getUsageSessionObserverPerUidLimit() { |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 124 | return MAX_OBSERVER_PER_UID; |
| 125 | } |
| 126 | |
| 127 | @Override |
| 128 | protected long getMinTimeLimit() { |
| 129 | return MIN_TIME_LIMIT; |
| 130 | } |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 131 | } |
| 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 Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 145 | /** Verify app usage observer is added */ |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 146 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 147 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 153 | } |
| 154 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 155 | /** Verify usage session observer is added */ |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 156 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 157 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 181 | } |
| 182 | |
| 183 | /** Re-adding an observer should result in only one copy */ |
| 184 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 185 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 189 | assertTrue("Observer wasn't added", |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 190 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 223 | } |
| 224 | |
| 225 | /** Verify that usage across different apps within a group are added up */ |
| 226 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 227 | public void testAppUsageObserver_Accumulation() throws Exception { |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 228 | setTime(0L); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 229 | addAppUsageObserver(OBS_ID1, GROUP1, TIME_30_MIN); |
| 230 | startUsage(PKG_SOC1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 231 | // Add 10 mins |
| 232 | setTime(TIME_10_MIN); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 233 | stopUsage(PKG_SOC1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 234 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 235 | AppTimeLimitController.UsageGroup group = mController.getAppUsageGroup(UID, OBS_ID1); |
| 236 | |
| 237 | long timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs(); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 238 | assertEquals(TIME_10_MIN * 2, timeRemaining); |
| 239 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 240 | startUsage(PKG_SOC1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 241 | setTime(TIME_10_MIN * 2); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 242 | stopUsage(PKG_SOC1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 243 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 244 | timeRemaining = group.getTimeLimitMs() - group.getUsageTimeMs(); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 245 | assertEquals(TIME_10_MIN, timeRemaining); |
| 246 | |
| 247 | setTime(TIME_30_MIN); |
| 248 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 249 | assertFalse(mLimitReachedLatch.await(100L, TimeUnit.MILLISECONDS)); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 250 | |
| 251 | // Add a different package in the group |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 252 | startUsage(PKG_GAME1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 253 | setTime(TIME_30_MIN + TIME_10_MIN); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 254 | stopUsage(PKG_GAME1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 255 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 256 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 293 | } |
| 294 | |
| 295 | /** Verify that time limit does not get triggered due to a different app */ |
| 296 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 297 | public void testAppUsageObserver_TimeoutOtherApp() throws Exception { |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 298 | setTime(0L); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 299 | addAppUsageObserver(OBS_ID1, GROUP1, 4_000L); |
| 300 | startUsage(PKG_SOC2); |
| 301 | assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 302 | setTime(6_000L); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 303 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 318 | } |
| 319 | |
| 320 | /** Verify the timeout message is delivered at the right time */ |
| 321 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 322 | public void testAppUsageObserver_Timeout() throws Exception { |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 323 | setTime(0L); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 324 | addAppUsageObserver(OBS_ID1, GROUP1, 4_000L); |
| 325 | startUsage(PKG_SOC1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 326 | setTime(6_000L); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 327 | assertTrue(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); |
| 328 | stopUsage(PKG_SOC1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 329 | // Verify that the observer was removed |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 330 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 348 | } |
| 349 | |
| 350 | /** If an app was already running, make sure it is partially counted towards the time limit */ |
| 351 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 352 | public void testAppUsageObserver_AlreadyRunning() throws Exception { |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 353 | setTime(TIME_10_MIN); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 354 | startUsage(PKG_GAME1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 355 | setTime(TIME_30_MIN); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 356 | addAppUsageObserver(OBS_ID2, GROUP_GAME, TIME_30_MIN); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 357 | setTime(TIME_30_MIN + TIME_10_MIN); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 358 | stopUsage(PKG_GAME1); |
| 359 | assertFalse(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 360 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 361 | startUsage(PKG_GAME2); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 362 | setTime(TIME_30_MIN + TIME_30_MIN); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 363 | stopUsage(PKG_GAME2); |
| 364 | assertTrue(mLimitReachedLatch.await(1_000L, TimeUnit.MILLISECONDS)); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 365 | // Verify that the observer was removed |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 366 | 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 386 | } |
| 387 | |
| 388 | /** If watched app is already running, verify the timeout callback happens at the right time */ |
| 389 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 390 | public void testAppUsageObserver_AlreadyRunningTimeout() throws Exception { |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 391 | setTime(0); |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 392 | startUsage(PKG_SOC1); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 393 | setTime(TIME_10_MIN); |
| 394 | // 10 second time limit |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 395 | addAppUsageObserver(OBS_ID1, GROUP_SOC, 10_000L); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 396 | setTime(TIME_10_MIN + 5_000L); |
| 397 | // Shouldn't call back in 6 seconds |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 398 | assertFalse(mLimitReachedLatch.await(6_000L, TimeUnit.MILLISECONDS)); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 399 | setTime(TIME_10_MIN + 10_000L); |
| 400 | // Should call back by 11 seconds (6 earlier + 5 now) |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 401 | assertTrue(mLimitReachedLatch.await(5_000L, TimeUnit.MILLISECONDS)); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 402 | // Verify that the observer was removed |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 403 | assertFalse(hasAppUsageObserver(UID, OBS_ID1)); |
Amith Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 404 | } |
| 405 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 406 | /** If watched app is already running, verify the timeout callback happens at the right time */ |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 407 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 408 | 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 Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 435 | boolean receivedException = false; |
| 436 | int ANOTHER_UID = UID + 1; |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 437 | 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 Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 447 | // Readding an observer should not cause an IllegalStateException |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 448 | addAppUsageObserver(OBS_ID5, GROUP1, TIME_30_MIN); |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 449 | // Adding an observer for a different uid shouldn't cause an IllegalStateException |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 450 | mController.addAppUsageObserver(ANOTHER_UID, OBS_ID11, GROUP1, TIME_30_MIN, null, USER_ID); |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 451 | try { |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 452 | addAppUsageObserver(OBS_ID11, GROUP1, TIME_30_MIN); |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 453 | } catch (IllegalStateException ise) { |
| 454 | receivedException = true; |
| 455 | } |
| 456 | assertTrue("Should have caused an IllegalStateException", receivedException); |
| 457 | } |
| 458 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 459 | /** |
| 460 | * Verify that App Time Limit Controller will limit the number of observerIds for usage session |
| 461 | * observers |
| 462 | */ |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 463 | @Test |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 464 | 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 Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 493 | boolean receivedException = false; |
| 494 | // adding an observer with a one minute time limit should not cause an exception |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 495 | addAppUsageObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT); |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 496 | try { |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 497 | addAppUsageObserver(OBS_ID1, GROUP1, MIN_TIME_LIMIT - 1); |
Michael Wachenschwanz | c870309 | 2018-05-01 16:02:45 -0700 | [diff] [blame] | 498 | } catch (IllegalArgumentException iae) { |
| 499 | receivedException = true; |
| 500 | } |
| 501 | assertTrue("Should have caused an IllegalArgumentException", receivedException); |
| 502 | } |
| 503 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 504 | /** 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 516 | } |
| 517 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 518 | /** 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 539 | } |
| 540 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 541 | /** 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 562 | } |
| 563 | |
Michael Wachenschwanz | 0f47284 | 2018-10-23 23:02:48 -0700 | [diff] [blame^] | 564 | /** 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 Yamasani | 62ec27e9 | 2018-03-11 14:42:06 -0700 | [diff] [blame] | 690 | } |
| 691 | |
| 692 | private void setTime(long time) { |
| 693 | mUptimeMillis = time; |
| 694 | } |
| 695 | } |