1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package com.android.server; 17 18 import static android.app.AlarmManager.ELAPSED_REALTIME; 19 import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP; 20 import static android.app.AlarmManager.RTC; 21 import static android.app.AlarmManager.RTC_WAKEUP; 22 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_ACTIVE; 23 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_FREQUENT; 24 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_RARE; 25 import static android.app.usage.UsageStatsManager.STANDBY_BUCKET_WORKING_SET; 26 27 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; 28 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 29 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow; 30 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; 31 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession; 32 import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; 33 import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify; 34 import static com.android.dx.mockito.inline.extended.ExtendedMockito.when; 35 import static com.android.server.AlarmManagerService.ACTIVE_INDEX; 36 import static com.android.server.AlarmManagerService.AlarmHandler.APP_STANDBY_BUCKET_CHANGED; 37 import static com.android.server.AlarmManagerService.AlarmHandler.APP_STANDBY_PAROLE_CHANGED; 38 import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_LONG_TIME; 39 import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_SHORT_TIME; 40 import static com.android.server.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION; 41 import static com.android.server.AlarmManagerService.Constants.KEY_APP_STANDBY_QUOTAS_ENABLED; 42 import static com.android.server.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT; 43 import static com.android.server.AlarmManagerService.Constants.KEY_MAX_INTERVAL; 44 import static com.android.server.AlarmManagerService.Constants.KEY_MIN_FUTURITY; 45 import static com.android.server.AlarmManagerService.Constants.KEY_MIN_INTERVAL; 46 import static com.android.server.AlarmManagerService.IS_WAKEUP_MASK; 47 import static com.android.server.AlarmManagerService.TIME_CHANGED_MASK; 48 import static com.android.server.AlarmManagerService.WORKING_INDEX; 49 50 import static org.junit.Assert.assertEquals; 51 import static org.junit.Assert.assertNotNull; 52 import static org.junit.Assert.assertNull; 53 import static org.mockito.ArgumentMatchers.any; 54 import static org.mockito.ArgumentMatchers.anyInt; 55 import static org.mockito.ArgumentMatchers.anyLong; 56 import static org.mockito.ArgumentMatchers.eq; 57 import static org.mockito.ArgumentMatchers.isNull; 58 import static org.mockito.Mockito.atLeastOnce; 59 60 import android.app.ActivityManager; 61 import android.app.AlarmManager; 62 import android.app.IActivityManager; 63 import android.app.IAlarmCompleteListener; 64 import android.app.IAlarmListener; 65 import android.app.IUidObserver; 66 import android.app.PendingIntent; 67 import android.app.usage.UsageStatsManagerInternal; 68 import android.content.ContentResolver; 69 import android.content.Context; 70 import android.content.Intent; 71 import android.os.Handler; 72 import android.os.Looper; 73 import android.os.Message; 74 import android.os.PowerManager; 75 import android.os.RemoteException; 76 import android.os.UserHandle; 77 import android.platform.test.annotations.Presubmit; 78 import android.provider.Settings; 79 import android.util.Log; 80 import android.util.SparseArray; 81 82 import androidx.test.filters.FlakyTest; 83 import androidx.test.runner.AndroidJUnit4; 84 85 import com.android.internal.annotations.GuardedBy; 86 87 import org.junit.After; 88 import org.junit.Before; 89 import org.junit.Test; 90 import org.junit.runner.RunWith; 91 import org.mockito.Answers; 92 import org.mockito.ArgumentCaptor; 93 import org.mockito.Mock; 94 import org.mockito.MockitoSession; 95 import org.mockito.quality.Strictness; 96 97 import java.util.ArrayList; 98 99 @Presubmit 100 @RunWith(AndroidJUnit4.class) 101 public class AlarmManagerServiceTest { 102 private static final String TAG = AlarmManagerServiceTest.class.getSimpleName(); 103 private static final String TEST_CALLING_PACKAGE = "com.android.framework.test-package"; 104 private static final int SYSTEM_UI_UID = 123456789; 105 private static final int TEST_CALLING_UID = 12345; 106 107 private long mAppStandbyWindow; 108 private AlarmManagerService mService; 109 private UsageStatsManagerInternal.AppIdleStateChangeListener mAppStandbyListener; 110 @Mock 111 private ContentResolver mMockResolver; 112 @Mock 113 private Context mMockContext; 114 @Mock 115 private IActivityManager mIActivityManager; 116 @Mock 117 private UsageStatsManagerInternal mUsageStatsManagerInternal; 118 @Mock 119 private AppStateTracker mAppStateTracker; 120 @Mock 121 private AlarmManagerService.ClockReceiver mClockReceiver; 122 @Mock 123 private PowerManager.WakeLock mWakeLock; 124 125 private MockitoSession mMockingSession; 126 private Injector mInjector; 127 private volatile long mNowElapsedTest; 128 private volatile long mNowRtcTest; 129 @GuardedBy("mTestTimer") 130 private TestTimer mTestTimer = new TestTimer(); 131 132 static class TestTimer { 133 private long mElapsed; 134 boolean mExpired; 135 private int mType; 136 private int mFlags; // Flags used to decide what needs to be evaluated. 137 getElapsed()138 synchronized long getElapsed() { 139 return mElapsed; 140 } 141 set(int type, long millisElapsed)142 synchronized void set(int type, long millisElapsed) { 143 mType = type; 144 mElapsed = millisElapsed; 145 } 146 getType()147 synchronized int getType() { 148 return mType; 149 } 150 getFlags()151 synchronized int getFlags() { 152 return mFlags; 153 } 154 expire()155 synchronized void expire() throws InterruptedException { 156 expire(IS_WAKEUP_MASK); // Default: evaluate eligibility of all alarms 157 } 158 expire(int flags)159 synchronized void expire(int flags) throws InterruptedException { 160 mFlags = flags; 161 mExpired = true; 162 notifyAll(); 163 // Now wait for the alarm thread to finish execution. 164 wait(); 165 } 166 } 167 168 public class Injector extends AlarmManagerService.Injector { 169 boolean mIsAutomotiveOverride; 170 Injector(Context context)171 Injector(Context context) { 172 super(context); 173 } 174 175 @Override init()176 void init() { 177 // Do nothing. 178 } 179 180 @Override waitForAlarm()181 int waitForAlarm() { 182 synchronized (mTestTimer) { 183 mTestTimer.notifyAll(); 184 if (!mTestTimer.mExpired) { 185 try { 186 mTestTimer.wait(); 187 } catch (InterruptedException ie) { 188 Log.e(TAG, "Wait interrupted!", ie); 189 return 0; 190 } 191 } 192 mTestTimer.mExpired = false; 193 } 194 return mTestTimer.getFlags(); 195 } 196 197 @Override setKernelTimezone(int minutesWest)198 void setKernelTimezone(int minutesWest) { 199 // Do nothing. 200 } 201 202 @Override setAlarm(int type, long millis)203 void setAlarm(int type, long millis) { 204 mTestTimer.set(type, millis); 205 } 206 207 @Override setKernelTime(long millis)208 void setKernelTime(long millis) { 209 } 210 211 @Override getSystemUiUid()212 int getSystemUiUid() { 213 return SYSTEM_UI_UID; 214 } 215 216 @Override isAlarmDriverPresent()217 boolean isAlarmDriverPresent() { 218 // Pretend the driver is present, so code does not fall back to handler 219 return true; 220 } 221 222 @Override getElapsedRealtime()223 long getElapsedRealtime() { 224 return mNowElapsedTest; 225 } 226 227 @Override getCurrentTimeMillis()228 long getCurrentTimeMillis() { 229 return mNowRtcTest; 230 } 231 232 @Override getClockReceiver(AlarmManagerService service)233 AlarmManagerService.ClockReceiver getClockReceiver(AlarmManagerService service) { 234 return mClockReceiver; 235 } 236 237 @Override getAlarmWakeLock()238 PowerManager.WakeLock getAlarmWakeLock() { 239 return mWakeLock; 240 } 241 } 242 243 @Before setUp()244 public final void setUp() throws Exception { 245 mMockingSession = mockitoSession() 246 .initMocks(this) 247 .spyStatic(ActivityManager.class) 248 .mockStatic(LocalServices.class) 249 .spyStatic(Looper.class) 250 .spyStatic(Settings.Global.class) 251 .strictness(Strictness.WARN) 252 .startMocking(); 253 doReturn(mIActivityManager).when(ActivityManager::getService); 254 doReturn(mAppStateTracker).when(() -> LocalServices.getService(AppStateTracker.class)); 255 doReturn(null) 256 .when(() -> LocalServices.getService(DeviceIdleController.LocalService.class)); 257 doReturn(mUsageStatsManagerInternal).when( 258 () -> LocalServices.getService(UsageStatsManagerInternal.class)); 259 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), 260 eq(UserHandle.getUserId(TEST_CALLING_UID)), anyLong())) 261 .thenReturn(STANDBY_BUCKET_ACTIVE); 262 doReturn(Looper.getMainLooper()).when(Looper::myLooper); 263 264 when(mMockContext.getContentResolver()).thenReturn(mMockResolver); 265 doReturn("min_futurity=0,min_interval=0").when(() -> 266 Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS)); 267 268 mInjector = new Injector(mMockContext); 269 mService = new AlarmManagerService(mMockContext, mInjector); 270 spyOn(mService); 271 doNothing().when(mService).publishBinderService(any(), any()); 272 273 mService.onStart(); 274 spyOn(mService.mHandler); 275 // Stubbing the handler. Test should simulate any handling of messages synchronously. 276 doReturn(true).when(mService.mHandler).sendMessageAtTime(any(Message.class), anyLong()); 277 278 assertEquals(mService.mSystemUiUid, SYSTEM_UI_UID); 279 assertEquals(mService.mClockReceiver, mClockReceiver); 280 assertEquals(mService.mWakeLock, mWakeLock); 281 verify(mIActivityManager).registerUidObserver(any(IUidObserver.class), anyInt(), anyInt(), 282 isNull()); 283 284 // Other boot phases don't matter 285 mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY); 286 assertEquals(0, mService.mConstants.MIN_FUTURITY); 287 assertEquals(0, mService.mConstants.MIN_INTERVAL); 288 mAppStandbyWindow = mService.mConstants.APP_STANDBY_WINDOW; 289 ArgumentCaptor<UsageStatsManagerInternal.AppIdleStateChangeListener> captor = 290 ArgumentCaptor.forClass(UsageStatsManagerInternal.AppIdleStateChangeListener.class); 291 verify(mUsageStatsManagerInternal).addAppIdleStateChangeListener(captor.capture()); 292 mAppStandbyListener = captor.getValue(); 293 } 294 setTestAlarm(int type, long triggerTime, PendingIntent operation)295 private void setTestAlarm(int type, long triggerTime, PendingIntent operation) { 296 setTestAlarm(type, triggerTime, operation, 0, TEST_CALLING_UID); 297 } 298 setRepeatingTestAlarm(int type, long firstTrigger, long interval, PendingIntent pi)299 private void setRepeatingTestAlarm(int type, long firstTrigger, long interval, 300 PendingIntent pi) { 301 setTestAlarm(type, firstTrigger, pi, interval, TEST_CALLING_UID); 302 } 303 setTestAlarm(int type, long triggerTime, PendingIntent operation, long interval, int callingUid)304 private void setTestAlarm(int type, long triggerTime, PendingIntent operation, long interval, 305 int callingUid) { 306 mService.setImpl(type, triggerTime, AlarmManager.WINDOW_EXACT, interval, 307 operation, null, "test", AlarmManager.FLAG_STANDALONE, null, null, 308 callingUid, TEST_CALLING_PACKAGE); 309 } 310 setTestAlarmWithListener(int type, long triggerTime, IAlarmListener listener)311 private void setTestAlarmWithListener(int type, long triggerTime, IAlarmListener listener) { 312 mService.setImpl(type, triggerTime, AlarmManager.WINDOW_EXACT, 0, 313 null, listener, "test", AlarmManager.FLAG_STANDALONE, null, null, 314 TEST_CALLING_UID, TEST_CALLING_PACKAGE); 315 } 316 317 getNewMockPendingIntent()318 private PendingIntent getNewMockPendingIntent() { 319 return getNewMockPendingIntent(TEST_CALLING_UID); 320 } 321 getNewMockPendingIntent(int mockUid)322 private PendingIntent getNewMockPendingIntent(int mockUid) { 323 final PendingIntent mockPi = mock(PendingIntent.class, Answers.RETURNS_DEEP_STUBS); 324 when(mockPi.getCreatorUid()).thenReturn(mockUid); 325 when(mockPi.getCreatorPackage()).thenReturn(TEST_CALLING_PACKAGE); 326 return mockPi; 327 } 328 329 /** 330 * Careful while calling as this will replace any existing settings for the calling test. 331 */ setQuotasEnabled(boolean enabled)332 private void setQuotasEnabled(boolean enabled) { 333 final StringBuilder constantsBuilder = new StringBuilder(); 334 constantsBuilder.append(KEY_MIN_FUTURITY); 335 constantsBuilder.append("=0,"); 336 // Capping active and working quotas to make testing feasible. 337 constantsBuilder.append(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[ACTIVE_INDEX]); 338 constantsBuilder.append("=8,"); 339 constantsBuilder.append(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[WORKING_INDEX]); 340 constantsBuilder.append("=5,"); 341 if (!enabled) { 342 constantsBuilder.append(KEY_APP_STANDBY_QUOTAS_ENABLED); 343 constantsBuilder.append("=false,"); 344 } 345 doReturn(constantsBuilder.toString()).when(() -> Settings.Global.getString(mMockResolver, 346 Settings.Global.ALARM_MANAGER_CONSTANTS)); 347 mService.mConstants.onChange(false, null); 348 assertEquals(mService.mConstants.APP_STANDBY_QUOTAS_ENABLED, enabled); 349 } 350 351 @Test singleElapsedAlarmSet()352 public void singleElapsedAlarmSet() { 353 final long triggerTime = mNowElapsedTest + 5000; 354 final PendingIntent alarmPi = getNewMockPendingIntent(); 355 setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, alarmPi); 356 assertEquals(triggerTime, mTestTimer.getElapsed()); 357 } 358 359 @Test singleRtcAlarmSet()360 public void singleRtcAlarmSet() { 361 mNowElapsedTest = 54; 362 mNowRtcTest = 1243; // arbitrary values of time 363 final long triggerRtc = mNowRtcTest + 5000; 364 final PendingIntent alarmPi = getNewMockPendingIntent(); 365 setTestAlarm(RTC_WAKEUP, triggerRtc, alarmPi); 366 final long triggerElapsed = triggerRtc - (mNowRtcTest - mNowElapsedTest); 367 assertEquals(triggerElapsed, mTestTimer.getElapsed()); 368 } 369 370 @Test timeChangeMovesRtcAlarm()371 public void timeChangeMovesRtcAlarm() throws Exception { 372 mNowElapsedTest = 42; 373 mNowRtcTest = 4123; // arbitrary values of time 374 final long triggerRtc = mNowRtcTest + 5000; 375 final PendingIntent alarmPi = getNewMockPendingIntent(); 376 setTestAlarm(RTC_WAKEUP, triggerRtc, alarmPi); 377 final long triggerElapsed1 = mTestTimer.getElapsed(); 378 final long timeDelta = -123; 379 mNowRtcTest += timeDelta; 380 mTestTimer.expire(TIME_CHANGED_MASK); 381 final long triggerElapsed2 = mTestTimer.getElapsed(); 382 assertEquals("Invalid movement of triggerElapsed following time change", triggerElapsed2, 383 triggerElapsed1 - timeDelta); 384 } 385 386 @Test testSingleAlarmExpiration()387 public void testSingleAlarmExpiration() throws Exception { 388 final long triggerTime = mNowElapsedTest + 5000; 389 final PendingIntent alarmPi = getNewMockPendingIntent(); 390 setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, alarmPi); 391 392 mNowElapsedTest = mTestTimer.getElapsed(); 393 mTestTimer.expire(); 394 395 final ArgumentCaptor<PendingIntent.OnFinished> onFinishedCaptor = 396 ArgumentCaptor.forClass(PendingIntent.OnFinished.class); 397 verify(alarmPi).send(eq(mMockContext), eq(0), any(Intent.class), 398 onFinishedCaptor.capture(), any(Handler.class), isNull(), any()); 399 verify(mWakeLock).acquire(); 400 onFinishedCaptor.getValue().onSendFinished(alarmPi, null, 0, null, null); 401 verify(mWakeLock).release(); 402 } 403 404 @Test testUpdateConstants()405 public void testUpdateConstants() { 406 final StringBuilder constantsBuilder = new StringBuilder(); 407 constantsBuilder.append(KEY_MIN_FUTURITY); 408 constantsBuilder.append("=5,"); 409 constantsBuilder.append(KEY_MIN_INTERVAL); 410 constantsBuilder.append("=10,"); 411 constantsBuilder.append(KEY_MAX_INTERVAL); 412 constantsBuilder.append("=15,"); 413 constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_SHORT_TIME); 414 constantsBuilder.append("=20,"); 415 constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_LONG_TIME); 416 constantsBuilder.append("=25,"); 417 constantsBuilder.append(KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION); 418 constantsBuilder.append("=30,"); 419 constantsBuilder.append(KEY_LISTENER_TIMEOUT); 420 constantsBuilder.append("=35,"); 421 422 doReturn(constantsBuilder.toString()).when(() -> Settings.Global.getString(mMockResolver, 423 Settings.Global.ALARM_MANAGER_CONSTANTS)); 424 mService.mConstants.onChange(false, null); 425 assertEquals(5, mService.mConstants.MIN_FUTURITY); 426 assertEquals(10, mService.mConstants.MIN_INTERVAL); 427 assertEquals(15, mService.mConstants.MAX_INTERVAL); 428 assertEquals(20, mService.mConstants.ALLOW_WHILE_IDLE_SHORT_TIME); 429 assertEquals(25, mService.mConstants.ALLOW_WHILE_IDLE_LONG_TIME); 430 assertEquals(30, mService.mConstants.ALLOW_WHILE_IDLE_WHITELIST_DURATION); 431 assertEquals(35, mService.mConstants.LISTENER_TIMEOUT); 432 } 433 434 @Test testMinFuturity()435 public void testMinFuturity() { 436 doReturn("min_futurity=10").when(() -> 437 Settings.Global.getString(mMockResolver, Settings.Global.ALARM_MANAGER_CONSTANTS)); 438 mService.mConstants.onChange(false, null); 439 assertEquals(10, mService.mConstants.MIN_FUTURITY); 440 final long triggerTime = mNowElapsedTest + 1; 441 final long expectedTriggerTime = mNowElapsedTest + mService.mConstants.MIN_FUTURITY; 442 setTestAlarm(ELAPSED_REALTIME_WAKEUP, triggerTime, getNewMockPendingIntent()); 443 assertEquals(expectedTriggerTime, mTestTimer.getElapsed()); 444 } 445 446 @FlakyTest(bugId = 130313408) 447 @Test testEarliestAlarmSet()448 public void testEarliestAlarmSet() { 449 final PendingIntent pi6 = getNewMockPendingIntent(); 450 final PendingIntent pi8 = getNewMockPendingIntent(); 451 final PendingIntent pi9 = getNewMockPendingIntent(); 452 453 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 8, pi8); 454 assertEquals(mNowElapsedTest + 8, mTestTimer.getElapsed()); 455 456 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 9, pi9); 457 assertEquals(mNowElapsedTest + 8, mTestTimer.getElapsed()); 458 459 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, pi6); 460 assertEquals(mNowElapsedTest + 6, mTestTimer.getElapsed()); 461 462 mService.removeLocked(pi6, null); 463 assertEquals(mNowElapsedTest + 8, mTestTimer.getElapsed()); 464 465 mService.removeLocked(pi8, null); 466 assertEquals(mNowElapsedTest + 9, mTestTimer.getElapsed()); 467 } 468 469 @Test testStandbyBucketDelay_workingSet()470 public void testStandbyBucketDelay_workingSet() throws Exception { 471 setQuotasEnabled(false); 472 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 5, getNewMockPendingIntent()); 473 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, getNewMockPendingIntent()); 474 assertEquals(mNowElapsedTest + 5, mTestTimer.getElapsed()); 475 476 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 477 anyLong())).thenReturn(STANDBY_BUCKET_WORKING_SET); 478 479 mNowElapsedTest = mTestTimer.getElapsed(); 480 mTestTimer.expire(); 481 482 verify(mUsageStatsManagerInternal, atLeastOnce()) 483 .getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), 484 eq(UserHandle.getUserId(TEST_CALLING_UID)), anyLong()); 485 final long expectedNextTrigger = mNowElapsedTest 486 + mService.getMinDelayForBucketLocked(STANDBY_BUCKET_WORKING_SET); 487 assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); 488 } 489 490 @Test testStandbyBucketDelay_frequent()491 public void testStandbyBucketDelay_frequent() throws Exception { 492 setQuotasEnabled(false); 493 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 5, getNewMockPendingIntent()); 494 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, getNewMockPendingIntent()); 495 assertEquals(mNowElapsedTest + 5, mTestTimer.getElapsed()); 496 497 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 498 anyLong())).thenReturn(STANDBY_BUCKET_FREQUENT); 499 mNowElapsedTest = mTestTimer.getElapsed(); 500 mTestTimer.expire(); 501 502 verify(mUsageStatsManagerInternal, atLeastOnce()) 503 .getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), 504 eq(UserHandle.getUserId(TEST_CALLING_UID)), anyLong()); 505 final long expectedNextTrigger = mNowElapsedTest 506 + mService.getMinDelayForBucketLocked(STANDBY_BUCKET_FREQUENT); 507 assertEquals("Incorrect next alarm trigger.", expectedNextTrigger, mTestTimer.getElapsed()); 508 } 509 510 @Test testStandbyBucketDelay_rare()511 public void testStandbyBucketDelay_rare() throws Exception { 512 setQuotasEnabled(false); 513 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 5, getNewMockPendingIntent()); 514 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 6, getNewMockPendingIntent()); 515 assertEquals(mNowElapsedTest + 5, mTestTimer.getElapsed()); 516 517 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 518 anyLong())).thenReturn(STANDBY_BUCKET_RARE); 519 mNowElapsedTest = mTestTimer.getElapsed(); 520 mTestTimer.expire(); 521 522 verify(mUsageStatsManagerInternal, atLeastOnce()) 523 .getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), 524 eq(UserHandle.getUserId(TEST_CALLING_UID)), anyLong()); 525 final long expectedNextTrigger = mNowElapsedTest 526 + mService.getMinDelayForBucketLocked(STANDBY_BUCKET_RARE); 527 assertEquals("Incorrect next alarm trigger.", expectedNextTrigger, mTestTimer.getElapsed()); 528 } 529 testQuotasDeferralOnSet(int standbyBucket)530 private void testQuotasDeferralOnSet(int standbyBucket) throws Exception { 531 final int quota = mService.getQuotaForBucketLocked(standbyBucket); 532 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 533 anyLong())).thenReturn(standbyBucket); 534 final long firstTrigger = mNowElapsedTest + 10; 535 for (int i = 0; i < quota; i++) { 536 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 10 + i, 537 getNewMockPendingIntent()); 538 mNowElapsedTest = mTestTimer.getElapsed(); 539 mTestTimer.expire(); 540 } 541 // This one should get deferred on set 542 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + quota + 10, 543 getNewMockPendingIntent()); 544 final long expectedNextTrigger = firstTrigger + 1 + mAppStandbyWindow; 545 assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); 546 } 547 testQuotasDeferralOnExpiration(int standbyBucket)548 private void testQuotasDeferralOnExpiration(int standbyBucket) throws Exception { 549 final int quota = mService.getQuotaForBucketLocked(standbyBucket); 550 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 551 anyLong())).thenReturn(standbyBucket); 552 final long firstTrigger = mNowElapsedTest + 10; 553 for (int i = 0; i < quota; i++) { 554 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 10 + i, 555 getNewMockPendingIntent()); 556 } 557 // This one should get deferred after the latest alarm expires 558 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + quota + 10, 559 getNewMockPendingIntent()); 560 for (int i = 0; i < quota; i++) { 561 mNowElapsedTest = mTestTimer.getElapsed(); 562 mTestTimer.expire(); 563 } 564 final long expectedNextTrigger = firstTrigger + 1 + mAppStandbyWindow; 565 assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); 566 } 567 testQuotasNoDeferral(int standbyBucket)568 private void testQuotasNoDeferral(int standbyBucket) throws Exception { 569 final int quota = mService.getQuotaForBucketLocked(standbyBucket); 570 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 571 anyLong())).thenReturn(standbyBucket); 572 final long firstTrigger = mNowElapsedTest + 10; 573 for (int i = 0; i < quota; i++) { 574 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 10 + i, 575 getNewMockPendingIntent()); 576 } 577 // This delivery time maintains the quota invariant. Should not be deferred. 578 final long expectedNextTrigger = firstTrigger + mAppStandbyWindow + 5; 579 setTestAlarm(ELAPSED_REALTIME_WAKEUP, expectedNextTrigger, getNewMockPendingIntent()); 580 for (int i = 0; i < quota; i++) { 581 mNowElapsedTest = mTestTimer.getElapsed(); 582 mTestTimer.expire(); 583 } 584 assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); 585 } 586 587 @Test testActiveQuota_deferredOnSet()588 public void testActiveQuota_deferredOnSet() throws Exception { 589 setQuotasEnabled(true); 590 testQuotasDeferralOnSet(STANDBY_BUCKET_ACTIVE); 591 } 592 593 @Test testActiveQuota_deferredOnExpiration()594 public void testActiveQuota_deferredOnExpiration() throws Exception { 595 setQuotasEnabled(true); 596 testQuotasDeferralOnExpiration(STANDBY_BUCKET_ACTIVE); 597 } 598 599 @Test testActiveQuota_notDeferred()600 public void testActiveQuota_notDeferred() throws Exception { 601 setQuotasEnabled(true); 602 testQuotasNoDeferral(STANDBY_BUCKET_ACTIVE); 603 } 604 605 @Test testWorkingQuota_deferredOnSet()606 public void testWorkingQuota_deferredOnSet() throws Exception { 607 setQuotasEnabled(true); 608 testQuotasDeferralOnSet(STANDBY_BUCKET_WORKING_SET); 609 } 610 611 @Test testWorkingQuota_deferredOnExpiration()612 public void testWorkingQuota_deferredOnExpiration() throws Exception { 613 setQuotasEnabled(true); 614 testQuotasDeferralOnExpiration(STANDBY_BUCKET_WORKING_SET); 615 } 616 617 @Test testWorkingQuota_notDeferred()618 public void testWorkingQuota_notDeferred() throws Exception { 619 setQuotasEnabled(true); 620 testQuotasNoDeferral(STANDBY_BUCKET_WORKING_SET); 621 } 622 623 @Test testFrequentQuota_deferredOnSet()624 public void testFrequentQuota_deferredOnSet() throws Exception { 625 setQuotasEnabled(true); 626 testQuotasDeferralOnSet(STANDBY_BUCKET_FREQUENT); 627 } 628 629 @Test testFrequentQuota_deferredOnExpiration()630 public void testFrequentQuota_deferredOnExpiration() throws Exception { 631 setQuotasEnabled(true); 632 testQuotasDeferralOnExpiration(STANDBY_BUCKET_FREQUENT); 633 } 634 635 @Test testFrequentQuota_notDeferred()636 public void testFrequentQuota_notDeferred() throws Exception { 637 setQuotasEnabled(true); 638 testQuotasNoDeferral(STANDBY_BUCKET_FREQUENT); 639 } 640 641 @Test testRareQuota_deferredOnSet()642 public void testRareQuota_deferredOnSet() throws Exception { 643 setQuotasEnabled(true); 644 testQuotasDeferralOnSet(STANDBY_BUCKET_RARE); 645 } 646 647 @Test testRareQuota_deferredOnExpiration()648 public void testRareQuota_deferredOnExpiration() throws Exception { 649 setQuotasEnabled(true); 650 testQuotasDeferralOnExpiration(STANDBY_BUCKET_RARE); 651 } 652 653 @Test testRareQuota_notDeferred()654 public void testRareQuota_notDeferred() throws Exception { 655 setQuotasEnabled(true); 656 testQuotasNoDeferral(STANDBY_BUCKET_RARE); 657 } 658 assertAndHandleBucketChanged(int bucket)659 private void assertAndHandleBucketChanged(int bucket) { 660 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 661 anyLong())).thenReturn(bucket); 662 mAppStandbyListener.onAppIdleStateChanged(TEST_CALLING_PACKAGE, 663 UserHandle.getUserId(TEST_CALLING_UID), false, bucket, 0); 664 final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 665 verify(mService.mHandler, atLeastOnce()).sendMessage(messageCaptor.capture()); 666 final Message lastMessage = messageCaptor.getValue(); 667 assertEquals("Unexpected message send to handler", lastMessage.what, 668 APP_STANDBY_BUCKET_CHANGED); 669 mService.mHandler.handleMessage(lastMessage); 670 } 671 672 @Test testQuotaDowngrade()673 public void testQuotaDowngrade() throws Exception { 674 setQuotasEnabled(true); 675 final int workingQuota = mService.getQuotaForBucketLocked(STANDBY_BUCKET_WORKING_SET); 676 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 677 anyLong())).thenReturn(STANDBY_BUCKET_WORKING_SET); 678 679 final long firstTrigger = mNowElapsedTest + 10; 680 for (int i = 0; i < workingQuota; i++) { 681 setTestAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, getNewMockPendingIntent()); 682 } 683 // No deferrals now. 684 for (int i = 0; i < workingQuota - 1; i++) { 685 mNowElapsedTest = mTestTimer.getElapsed(); 686 assertEquals(firstTrigger + i, mNowElapsedTest); 687 mTestTimer.expire(); 688 } 689 // The next upcoming alarm in queue should also be set as expected. 690 assertEquals(firstTrigger + workingQuota - 1, mTestTimer.getElapsed()); 691 // Downgrading the bucket now 692 assertAndHandleBucketChanged(STANDBY_BUCKET_RARE); 693 final int rareQuota = mService.getQuotaForBucketLocked(STANDBY_BUCKET_RARE); 694 // The last alarm should now be deferred. 695 final long expectedNextTrigger = (firstTrigger + workingQuota - 1 - rareQuota) 696 + mAppStandbyWindow + 1; 697 assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); 698 } 699 700 @Test testQuotaUpgrade()701 public void testQuotaUpgrade() throws Exception { 702 setQuotasEnabled(true); 703 final int frequentQuota = mService.getQuotaForBucketLocked(STANDBY_BUCKET_FREQUENT); 704 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 705 anyLong())).thenReturn(STANDBY_BUCKET_FREQUENT); 706 707 final long firstTrigger = mNowElapsedTest + 10; 708 for (int i = 0; i < frequentQuota + 1; i++) { 709 setTestAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, getNewMockPendingIntent()); 710 if (i < frequentQuota) { 711 mNowElapsedTest = mTestTimer.getElapsed(); 712 mTestTimer.expire(); 713 } 714 } 715 // The last alarm should be deferred due to exceeding the quota 716 final long deferredTrigger = firstTrigger + 1 + mAppStandbyWindow; 717 assertEquals(deferredTrigger, mTestTimer.getElapsed()); 718 719 // Upgrading the bucket now 720 assertAndHandleBucketChanged(STANDBY_BUCKET_ACTIVE); 721 // The last alarm should now be rescheduled to go as per original expectations 722 final long originalTrigger = firstTrigger + frequentQuota; 723 assertEquals("Incorrect next alarm trigger", originalTrigger, mTestTimer.getElapsed()); 724 } 725 assertAndHandleParoleChanged(boolean parole)726 private void assertAndHandleParoleChanged(boolean parole) { 727 mAppStandbyListener.onParoleStateChanged(parole); 728 final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); 729 verify(mService.mHandler, atLeastOnce()).sendMessage(messageCaptor.capture()); 730 final Message lastMessage = messageCaptor.getValue(); 731 assertEquals("Unexpected message send to handler", lastMessage.what, 732 APP_STANDBY_PAROLE_CHANGED); 733 mService.mHandler.handleMessage(lastMessage); 734 } 735 736 @Test testParole()737 public void testParole() throws Exception { 738 setQuotasEnabled(true); 739 final int workingQuota = mService.getQuotaForBucketLocked(STANDBY_BUCKET_WORKING_SET); 740 when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(), 741 anyLong())).thenReturn(STANDBY_BUCKET_WORKING_SET); 742 743 final long firstTrigger = mNowElapsedTest + 10; 744 final int totalAlarms = workingQuota + 10; 745 for (int i = 0; i < totalAlarms; i++) { 746 setTestAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, getNewMockPendingIntent()); 747 } 748 // Use up the quota, no deferrals expected. 749 for (int i = 0; i < workingQuota; i++) { 750 mNowElapsedTest = mTestTimer.getElapsed(); 751 assertEquals(firstTrigger + i, mNowElapsedTest); 752 mTestTimer.expire(); 753 } 754 // Any subsequent alarms in queue should all be deferred 755 assertEquals(firstTrigger + mAppStandbyWindow + 1, mTestTimer.getElapsed()); 756 // Paroling now 757 assertAndHandleParoleChanged(true); 758 759 // Subsequent alarms should now go off as per original expectations. 760 for (int i = 0; i < 5; i++) { 761 mNowElapsedTest = mTestTimer.getElapsed(); 762 assertEquals(firstTrigger + workingQuota + i, mNowElapsedTest); 763 mTestTimer.expire(); 764 } 765 // Come out of parole 766 assertAndHandleParoleChanged(false); 767 768 // Subsequent alarms should again get deferred 769 final long expectedNextTrigger = (firstTrigger + 5) + 1 + mAppStandbyWindow; 770 assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed()); 771 } 772 773 @Test testAlarmRestrictedInBatterSaver()774 public void testAlarmRestrictedInBatterSaver() throws Exception { 775 final ArgumentCaptor<AppStateTracker.Listener> listenerArgumentCaptor = 776 ArgumentCaptor.forClass(AppStateTracker.Listener.class); 777 verify(mAppStateTracker).addListener(listenerArgumentCaptor.capture()); 778 779 final PendingIntent alarmPi = getNewMockPendingIntent(); 780 when(mAppStateTracker.areAlarmsRestricted(TEST_CALLING_UID, TEST_CALLING_PACKAGE, 781 false)).thenReturn(true); 782 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 2, alarmPi); 783 assertEquals(mNowElapsedTest + 2, mTestTimer.getElapsed()); 784 785 final SparseArray<ArrayList<AlarmManagerService.Alarm>> restrictedAlarms = 786 mService.mPendingBackgroundAlarms; 787 assertNull(restrictedAlarms.get(TEST_CALLING_UID)); 788 789 mNowElapsedTest = mTestTimer.getElapsed(); 790 mTestTimer.expire(); 791 assertNotNull(restrictedAlarms.get(TEST_CALLING_UID)); 792 793 listenerArgumentCaptor.getValue().unblockAlarmsForUid(TEST_CALLING_UID); 794 verify(alarmPi).send(eq(mMockContext), eq(0), any(Intent.class), any(), 795 any(Handler.class), isNull(), any()); 796 assertNull(restrictedAlarms.get(TEST_CALLING_UID)); 797 } 798 799 @Test sendsTimeTickOnInteractive()800 public void sendsTimeTickOnInteractive() { 801 final ArgumentCaptor<Runnable> runnableCaptor = ArgumentCaptor.forClass(Runnable.class); 802 // Stubbing so the handler doesn't actually run the runnable. 803 doReturn(true).when(mService.mHandler).post(runnableCaptor.capture()); 804 // change interactive state: false -> true 805 mService.interactiveStateChangedLocked(false); 806 mService.interactiveStateChangedLocked(true); 807 runnableCaptor.getValue().run(); 808 verify(mMockContext).sendBroadcastAsUser(mService.mTimeTickIntent, UserHandle.ALL); 809 } 810 811 @Test alarmCountKeyedOnCallingUid()812 public void alarmCountKeyedOnCallingUid() { 813 final int mockCreatorUid = 431412; 814 setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 5, 815 getNewMockPendingIntent(mockCreatorUid)); 816 assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 817 assertEquals(-1, mService.mAlarmsPerUid.get(mockCreatorUid, -1)); 818 } 819 820 @Test alarmCountOnSetPi()821 public void alarmCountOnSetPi() { 822 final int numAlarms = 103; 823 final int[] types = {RTC_WAKEUP, RTC, ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME}; 824 for (int i = 1; i <= numAlarms; i++) { 825 setTestAlarm(types[i % 4], mNowElapsedTest + i, getNewMockPendingIntent()); 826 assertEquals(i, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 827 } 828 } 829 830 @Test alarmCountOnSetListener()831 public void alarmCountOnSetListener() { 832 final int numAlarms = 103; 833 final int[] types = {RTC_WAKEUP, RTC, ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME}; 834 for (int i = 1; i <= numAlarms; i++) { 835 setTestAlarmWithListener(types[i % 4], mNowElapsedTest + i, new IAlarmListener.Stub() { 836 @Override 837 public void doAlarm(IAlarmCompleteListener callback) throws RemoteException { 838 } 839 }); 840 assertEquals(i, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 841 } 842 } 843 844 @Test alarmCountOnExpirationPi()845 public void alarmCountOnExpirationPi() throws InterruptedException { 846 final int numAlarms = 8; // This test is slow 847 for (int i = 0; i < numAlarms; i++) { 848 setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, getNewMockPendingIntent()); 849 } 850 int expired = 0; 851 while (expired < numAlarms) { 852 mNowElapsedTest = mTestTimer.getElapsed(); 853 mTestTimer.expire(); 854 expired++; 855 assertEquals(numAlarms - expired, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); 856 } 857 } 858 859 @Test alarmCountOnExpirationListener()860 public void alarmCountOnExpirationListener() throws InterruptedException { 861 final int numAlarms = 8; // This test is slow 862 for (int i = 0; i < numAlarms; i++) { 863 setTestAlarmWithListener(ELAPSED_REALTIME, mNowElapsedTest + i + 10, 864 new IAlarmListener.Stub() { 865 @Override 866 public void doAlarm(IAlarmCompleteListener callback) 867 throws RemoteException { 868 } 869 }); 870 } 871 int expired = 0; 872 while (expired < numAlarms) { 873 mNowElapsedTest = mTestTimer.getElapsed(); 874 mTestTimer.expire(); 875 expired++; 876 assertEquals(numAlarms - expired, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); 877 } 878 } 879 880 @Test alarmCountOnExceptionWhileSendingPi()881 public void alarmCountOnExceptionWhileSendingPi() throws Exception { 882 final int numAlarms = 5; // This test is slow 883 for (int i = 0; i < numAlarms; i++) { 884 final PendingIntent pi = getNewMockPendingIntent(); 885 doThrow(PendingIntent.CanceledException.class).when(pi).send(eq(mMockContext), eq(0), 886 any(), any(), any(), any(), any()); 887 setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, pi); 888 } 889 int expired = 0; 890 while (expired < numAlarms) { 891 mNowElapsedTest = mTestTimer.getElapsed(); 892 mTestTimer.expire(); 893 expired++; 894 assertEquals(numAlarms - expired, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); 895 } 896 } 897 898 @Test alarmCountOnExceptionWhileCallingListener()899 public void alarmCountOnExceptionWhileCallingListener() throws Exception { 900 final int numAlarms = 5; // This test is slow 901 for (int i = 0; i < numAlarms; i++) { 902 final IAlarmListener listener = new IAlarmListener.Stub() { 903 @Override 904 public void doAlarm(IAlarmCompleteListener callback) throws RemoteException { 905 throw new RemoteException("For testing behavior on exception"); 906 } 907 }; 908 setTestAlarmWithListener(ELAPSED_REALTIME, mNowElapsedTest + i + 10, listener); 909 } 910 int expired = 0; 911 while (expired < numAlarms) { 912 mNowElapsedTest = mTestTimer.getElapsed(); 913 mTestTimer.expire(); 914 expired++; 915 assertEquals(numAlarms - expired, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); 916 } 917 } 918 919 @Test alarmCountForRepeatingAlarms()920 public void alarmCountForRepeatingAlarms() throws Exception { 921 final long interval = 1231; 922 final long firstTrigger = mNowElapsedTest + 321; 923 final PendingIntent pi = getNewMockPendingIntent(); 924 setRepeatingTestAlarm(ELAPSED_REALTIME, firstTrigger, interval, pi); 925 assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 926 927 for (int i = 0; i < 5; i++) { 928 mNowElapsedTest = mTestTimer.getElapsed(); 929 mTestTimer.expire(); 930 assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 931 } 932 doThrow(PendingIntent.CanceledException.class).when(pi).send(eq(mMockContext), eq(0), 933 any(), any(), any(), any(), any()); 934 mNowElapsedTest = mTestTimer.getElapsed(); 935 mTestTimer.expire(); 936 assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1)); 937 } 938 939 @Test alarmCountOnUidRemoved()940 public void alarmCountOnUidRemoved() { 941 final int numAlarms = 10; 942 for (int i = 0; i < numAlarms; i++) { 943 setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, getNewMockPendingIntent()); 944 } 945 assertEquals(numAlarms, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 946 mService.removeLocked(TEST_CALLING_UID); 947 assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); 948 } 949 950 @Test alarmCountOnPackageRemoved()951 public void alarmCountOnPackageRemoved() { 952 final int numAlarms = 10; 953 for (int i = 0; i < numAlarms; i++) { 954 setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, getNewMockPendingIntent()); 955 } 956 assertEquals(numAlarms, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 957 mService.removeLocked(TEST_CALLING_PACKAGE); 958 assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); 959 } 960 961 @Test alarmCountOnUserRemoved()962 public void alarmCountOnUserRemoved() { 963 final int mockUserId = 15; 964 final int numAlarms = 10; 965 for (int i = 0; i < numAlarms; i++) { 966 int mockUid = UserHandle.getUid(mockUserId, 1234 + i); 967 setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 10, 968 getNewMockPendingIntent(mockUid), 0, mockUid); 969 } 970 assertEquals(numAlarms, mService.mAlarmsPerUid.size()); 971 mService.removeUserLocked(mockUserId); 972 assertEquals(0, mService.mAlarmsPerUid.size()); 973 } 974 975 @Test alarmCountOnRemoveFromPendingWhileIdle()976 public void alarmCountOnRemoveFromPendingWhileIdle() { 977 mService.mPendingIdleUntil = mock(AlarmManagerService.Alarm.class); 978 final int numAlarms = 15; 979 final PendingIntent[] pis = new PendingIntent[numAlarms]; 980 for (int i = 0; i < numAlarms; i++) { 981 pis[i] = getNewMockPendingIntent(); 982 setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 5, pis[i]); 983 } 984 assertEquals(numAlarms, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 985 assertEquals(numAlarms, mService.mPendingWhileIdleAlarms.size()); 986 final int toRemove = 8; 987 for (int i = 0; i < toRemove; i++) { 988 mService.removeLocked(pis[i], null); 989 assertEquals(numAlarms - i - 1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); 990 } 991 mService.removeLocked(TEST_CALLING_UID); 992 assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); 993 } 994 995 @Test alarmCountOnAlarmRemoved()996 public void alarmCountOnAlarmRemoved() { 997 final int numAlarms = 10; 998 final PendingIntent[] pis = new PendingIntent[numAlarms]; 999 for (int i = 0; i < numAlarms; i++) { 1000 pis[i] = getNewMockPendingIntent(); 1001 setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + i + 5, pis[i]); 1002 } 1003 assertEquals(numAlarms, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 1004 for (int i = 0; i < numAlarms; i++) { 1005 mService.removeLocked(pis[i], null); 1006 assertEquals(numAlarms - i - 1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, 0)); 1007 } 1008 } 1009 1010 @Test alarmTypes()1011 public void alarmTypes() throws Exception { 1012 final int[] typesToSet = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME, RTC_WAKEUP, RTC}; 1013 final int[] typesExpected = {ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME, 1014 ELAPSED_REALTIME_WAKEUP, ELAPSED_REALTIME}; 1015 assertAlarmTypeConversion(typesToSet, typesExpected); 1016 } 1017 assertAlarmTypeConversion(int[] typesToSet, int[] typesExpected)1018 private void assertAlarmTypeConversion(int[] typesToSet, int[] typesExpected) throws Exception { 1019 for (int i = 0; i < typesToSet.length; i++) { 1020 setTestAlarm(typesToSet[i], 1234, getNewMockPendingIntent()); 1021 final int typeSet = mTestTimer.getType(); 1022 assertEquals("Alarm of type " + typesToSet[i] + " was set to type " + typeSet, 1023 typesExpected[i], typeSet); 1024 mNowElapsedTest = mTestTimer.getElapsed(); 1025 mTestTimer.expire(); 1026 } 1027 } 1028 1029 @Test alarmCountOnInvalidSet()1030 public void alarmCountOnInvalidSet() { 1031 setTestAlarm(ELAPSED_REALTIME, mNowElapsedTest + 12345, null); 1032 assertEquals(-1, mService.mAlarmsPerUid.get(TEST_CALLING_UID, -1)); 1033 } 1034 1035 @Test alarmCountOnPendingIntentCancel()1036 public void alarmCountOnPendingIntentCancel() { 1037 final PendingIntent pi = getNewMockPendingIntent(); 1038 setTestAlarm(ELAPSED_REALTIME_WAKEUP, mNowElapsedTest + 123, pi); 1039 verify(pi).registerCancelListener(mService.mOperationCancelListener); 1040 assertEquals(1, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 1041 mService.mOperationCancelListener.onCancelled(pi); 1042 assertEquals(0, mService.mAlarmsPerUid.get(TEST_CALLING_UID)); 1043 } 1044 1045 @After tearDown()1046 public void tearDown() { 1047 if (mMockingSession != null) { 1048 mMockingSession.finishMocking(); 1049 } 1050 } 1051 } 1052