summaryrefslogtreecommitdiff
path: root/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java')
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java231
1 files changed, 225 insertions, 6 deletions
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index cdc9d7198cb5..494246491e47 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -67,6 +67,7 @@ import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REFRESH_
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_ALARMS;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_FOR_CANCELED;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.TARE_AFFORDABILITY_CHANGED;
+import static com.android.server.alarm.AlarmManagerService.AlarmHandler.TEMPORARY_QUOTA_CHANGED;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_QUOTA;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_COMPAT_WINDOW;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_QUOTA;
@@ -83,6 +84,7 @@ import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_FUT
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_INTERVAL;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_WINDOW;
import static com.android.server.alarm.AlarmManagerService.Constants.KEY_PRIORITY_ALARM_DELAY;
+import static com.android.server.alarm.AlarmManagerService.Constants.KEY_TEMPORARY_QUOTA_BUMP;
import static com.android.server.alarm.AlarmManagerService.Constants.MAX_EXACT_ALARM_DENY_LIST_SIZE;
import static com.android.server.alarm.AlarmManagerService.FREQUENT_INDEX;
import static com.android.server.alarm.AlarmManagerService.INDEFINITE_DELAY;
@@ -110,6 +112,7 @@ import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verifyZeroInteractions;
import android.Manifest;
import android.app.ActivityManager;
@@ -654,6 +657,7 @@ public class AlarmManagerServiceTest {
setDeviceConfigLong(KEY_MIN_INTERVAL, 0);
mDeviceConfigKeys.add(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[ACTIVE_INDEX]);
mDeviceConfigKeys.add(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[WORKING_INDEX]);
+ mDeviceConfigKeys.add(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[FREQUENT_INDEX]);
doReturn(50).when(mDeviceConfigProperties)
.getInt(eq(mService.mConstants.KEYS_APP_STANDBY_QUOTAS[ACTIVE_INDEX]), anyInt());
doReturn(35).when(mDeviceConfigProperties)
@@ -732,6 +736,7 @@ public class AlarmManagerServiceTest {
setDeviceConfigLong(KEY_PRIORITY_ALARM_DELAY, 55);
setDeviceConfigLong(KEY_MIN_DEVICE_IDLE_FUZZ, 60);
setDeviceConfigLong(KEY_MAX_DEVICE_IDLE_FUZZ, 65);
+ setDeviceConfigInt(KEY_TEMPORARY_QUOTA_BUMP, 70);
assertEquals(5, mService.mConstants.MIN_FUTURITY);
assertEquals(10, mService.mConstants.MIN_INTERVAL);
assertEquals(15, mService.mConstants.MAX_INTERVAL);
@@ -745,6 +750,7 @@ public class AlarmManagerServiceTest {
assertEquals(55, mService.mConstants.PRIORITY_ALARM_DELAY);
assertEquals(60, mService.mConstants.MIN_DEVICE_IDLE_FUZZ);
assertEquals(65, mService.mConstants.MAX_DEVICE_IDLE_FUZZ);
+ assertEquals(70, mService.mConstants.TEMPORARY_QUOTA_BUMP);
}
@Test
@@ -879,6 +885,7 @@ public class AlarmManagerServiceTest {
for (int i = 0; i < quota; i++) {
alarmSetter.accept(firstTrigger + i);
mNowElapsedTest = mTestTimer.getElapsed();
+ assertEquals("Incorrect trigger time at i=" + i, firstTrigger + i, mNowElapsedTest);
mTestTimer.expire();
}
// This one should get deferred on set
@@ -897,6 +904,7 @@ public class AlarmManagerServiceTest {
alarmSetter.accept(firstTrigger + quota);
for (int i = 0; i < quota; i++) {
mNowElapsedTest = mTestTimer.getElapsed();
+ assertEquals("Incorrect trigger time at i=" + i, firstTrigger + i, mNowElapsedTest);
mTestTimer.expire();
}
final long expectedNextTrigger = firstTrigger + window;
@@ -914,6 +922,7 @@ public class AlarmManagerServiceTest {
alarmSetter.accept(expectedNextTrigger);
for (int i = 0; i < quota; i++) {
mNowElapsedTest = mTestTimer.getElapsed();
+ assertEquals("Incorrect trigger time at i=" + i, firstTrigger + i, mNowElapsedTest);
mTestTimer.expire();
}
assertEquals("Incorrect next alarm trigger", expectedNextTrigger, mTestTimer.getElapsed());
@@ -1919,16 +1928,14 @@ public class AlarmManagerServiceTest {
getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow);
// Refresh the state
- mService.removeLocked(TEST_CALLING_UID,
- REMOVE_REASON_UNDEFINED);
+ mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED);
mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
testQuotasDeferralOnExpiration(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP,
trigger, getNewMockPendingIntent(), false, false), quota, mAllowWhileIdleWindow);
// Refresh the state
- mService.removeLocked(TEST_CALLING_UID,
- REMOVE_REASON_UNDEFINED);
+ mService.removeLocked(TEST_CALLING_UID, REMOVE_REASON_UNDEFINED);
mService.mAllowWhileIdleHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
testQuotasNoDeferral(trigger -> setAllowWhileIdleAlarm(ELAPSED_REALTIME_WAKEUP, trigger,
@@ -3303,7 +3310,7 @@ public class AlarmManagerServiceTest {
Arrays.asList(package4));
mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false);
- mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] {
+ mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{
package1,
package3,
});
@@ -3315,7 +3322,7 @@ public class AlarmManagerServiceTest {
assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4));
mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
- mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] {
+ mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{
package1,
package3,
});
@@ -3407,6 +3414,218 @@ public class AlarmManagerServiceTest {
assertFalse(mService.hasUseExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
}
+ @Test
+ public void temporaryQuotaReserve_hasQuota() {
+ final int quotaToFill = 5;
+ final String package1 = "package1";
+ final int user1 = 123;
+ final long startTime = 54;
+ final long quotaDuration = 17;
+
+ final AlarmManagerService.TemporaryQuotaReserve quotaReserve =
+ new AlarmManagerService.TemporaryQuotaReserve(quotaDuration);
+ quotaReserve.replenishQuota(package1, user1, quotaToFill, startTime);
+
+ for (long time = startTime; time <= startTime + quotaDuration; time++) {
+ assertTrue(quotaReserve.hasQuota(package1, user1, time));
+ assertFalse(quotaReserve.hasQuota("some.other.package", 21, time));
+ assertFalse(quotaReserve.hasQuota(package1, 321, time));
+ }
+
+ assertFalse(quotaReserve.hasQuota(package1, user1, startTime + quotaDuration + 1));
+ assertFalse(quotaReserve.hasQuota(package1, user1, startTime + quotaDuration + 435421));
+
+ for (int i = 0; i < quotaToFill - 1; i++) {
+ assertTrue(i < quotaDuration);
+ // Use record usage multiple times with the same timestamp.
+ quotaReserve.recordUsage(package1, user1, startTime + i);
+ quotaReserve.recordUsage(package1, user1, startTime + i);
+ quotaReserve.recordUsage(package1, user1, startTime + i);
+ quotaReserve.recordUsage(package1, user1, startTime + i);
+
+ // Quota should not run out in this loop.
+ assertTrue(quotaReserve.hasQuota(package1, user1, startTime + i));
+ }
+ quotaReserve.recordUsage(package1, user1, startTime + quotaDuration);
+
+ // Should be out of quota now.
+ for (long time = startTime; time <= startTime + quotaDuration; time++) {
+ assertFalse(quotaReserve.hasQuota(package1, user1, time));
+ }
+ }
+
+ @Test
+ public void temporaryQuotaReserve_removeForPackage() {
+ final String[] packages = new String[]{"package1", "test.package2"};
+ final int userId = 472;
+ final long startTime = 59;
+ final long quotaDuration = 100;
+
+ final AlarmManagerService.TemporaryQuotaReserve quotaReserve =
+ new AlarmManagerService.TemporaryQuotaReserve(quotaDuration);
+
+ quotaReserve.replenishQuota(packages[0], userId, 10, startTime);
+ quotaReserve.replenishQuota(packages[1], userId, 10, startTime);
+
+ assertTrue(quotaReserve.hasQuota(packages[0], userId, startTime + 1));
+ assertTrue(quotaReserve.hasQuota(packages[1], userId, startTime + 1));
+
+ quotaReserve.removeForPackage(packages[0], userId);
+
+ assertFalse(quotaReserve.hasQuota(packages[0], userId, startTime + 1));
+ assertTrue(quotaReserve.hasQuota(packages[1], userId, startTime + 1));
+ }
+
+ @Test
+ public void temporaryQuotaReserve_removeForUser() {
+ final String[] packagesUser1 = new String[]{"test1.package1", "test1.package2"};
+ final String[] packagesUser2 = new String[]{"test2.p1", "test2.p2", "test2.p3"};
+ final int user1 = 3201;
+ final int user2 = 5409;
+ final long startTime = 59;
+ final long quotaDuration = 100;
+
+ final AlarmManagerService.TemporaryQuotaReserve quotaReserve =
+ new AlarmManagerService.TemporaryQuotaReserve(quotaDuration);
+
+ for (String packageUser1 : packagesUser1) {
+ quotaReserve.replenishQuota(packageUser1, user1, 10, startTime);
+ }
+ for (String packageUser2 : packagesUser2) {
+ quotaReserve.replenishQuota(packageUser2, user2, 10, startTime);
+ }
+
+ for (String packageUser1 : packagesUser1) {
+ assertTrue(quotaReserve.hasQuota(packageUser1, user1, startTime));
+ }
+ for (String packageUser2 : packagesUser2) {
+ assertTrue(quotaReserve.hasQuota(packageUser2, user2, startTime));
+ }
+
+ quotaReserve.removeForUser(user2);
+
+ for (String packageUser1 : packagesUser1) {
+ assertTrue(quotaReserve.hasQuota(packageUser1, user1, startTime));
+ }
+ for (String packageUser2 : packagesUser2) {
+ assertFalse(quotaReserve.hasQuota(packageUser2, user2, startTime));
+ }
+ }
+
+ @Test
+ public void triggerTemporaryQuotaBump_zeroQuota() {
+ setDeviceConfigInt(KEY_TEMPORARY_QUOTA_BUMP, 0);
+
+ mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+ verifyZeroInteractions(mPackageManagerInternal);
+ verifyZeroInteractions(mService.mHandler);
+ }
+
+ private void testTemporaryQuota_bumpedAfterDeferral(int standbyBucket) throws Exception {
+ final int temporaryQuota = 31;
+ setDeviceConfigInt(KEY_TEMPORARY_QUOTA_BUMP, temporaryQuota);
+
+ final int standbyQuota = mService.getQuotaForBucketLocked(standbyBucket);
+ when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(),
+ anyLong())).thenReturn(standbyBucket);
+
+ final long firstTrigger = mNowElapsedTest + 10;
+ for (int i = 0; i < standbyQuota + 1; i++) {
+ setTestAlarm(ELAPSED_REALTIME_WAKEUP, firstTrigger + i, getNewMockPendingIntent());
+ }
+
+ for (int i = 0; i < standbyQuota; i++) {
+ mNowElapsedTest = mTestTimer.getElapsed();
+ assertEquals("Incorrect trigger time at i=" + i, firstTrigger + i, mNowElapsedTest);
+ mTestTimer.expire();
+ }
+
+ // The last alarm should be deferred due to exceeding the quota
+ final long deferredTrigger = firstTrigger + mAppStandbyWindow;
+ assertEquals(deferredTrigger, mTestTimer.getElapsed());
+
+ // Triggering temporary quota now.
+ mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+ assertAndHandleMessageSync(TEMPORARY_QUOTA_CHANGED);
+ // The last alarm should now be rescheduled to go as per original expectations
+ final long originalTrigger = firstTrigger + standbyQuota;
+ assertEquals("Incorrect next alarm trigger", originalTrigger, mTestTimer.getElapsed());
+ }
+
+
+ @Test
+ public void temporaryQuota_bumpedAfterDeferral_active() throws Exception {
+ testTemporaryQuota_bumpedAfterDeferral(STANDBY_BUCKET_ACTIVE);
+ }
+
+ @Test
+ public void temporaryQuota_bumpedAfterDeferral_working() throws Exception {
+ testTemporaryQuota_bumpedAfterDeferral(STANDBY_BUCKET_WORKING_SET);
+ }
+
+ @Test
+ public void temporaryQuota_bumpedAfterDeferral_frequent() throws Exception {
+ testTemporaryQuota_bumpedAfterDeferral(STANDBY_BUCKET_FREQUENT);
+ }
+
+ @Test
+ public void temporaryQuota_bumpedAfterDeferral_rare() throws Exception {
+ testTemporaryQuota_bumpedAfterDeferral(STANDBY_BUCKET_RARE);
+ }
+
+ private void testTemporaryQuota_bumpedBeforeDeferral(int standbyBucket) throws Exception {
+ final int temporaryQuota = 7;
+ setDeviceConfigInt(KEY_TEMPORARY_QUOTA_BUMP, temporaryQuota);
+
+ final int standbyQuota = mService.getQuotaForBucketLocked(standbyBucket);
+ when(mUsageStatsManagerInternal.getAppStandbyBucket(eq(TEST_CALLING_PACKAGE), anyInt(),
+ anyLong())).thenReturn(standbyBucket);
+
+ mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+ // No need to handle message TEMPORARY_QUOTA_CHANGED, as the quota change doesn't need to
+ // trigger a re-evaluation in this test.
+ testQuotasDeferralOnExpiration(trigger -> setTestAlarm(ELAPSED_REALTIME_WAKEUP, trigger,
+ getNewMockPendingIntent()), standbyQuota + temporaryQuota, mAppStandbyWindow);
+
+ // refresh the state.
+ mService.removeLocked(TEST_CALLING_PACKAGE);
+ mService.mAppWakeupHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+ mService.mTemporaryQuotaReserve.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+
+ mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+ testQuotasDeferralOnSet(trigger -> setTestAlarm(ELAPSED_REALTIME_WAKEUP, trigger,
+ getNewMockPendingIntent()), standbyQuota + temporaryQuota, mAppStandbyWindow);
+
+ // refresh the state.
+ mService.removeLocked(TEST_CALLING_PACKAGE);
+ mService.mAppWakeupHistory.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+ mService.mTemporaryQuotaReserve.removeForPackage(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+
+ mAppStandbyListener.triggerTemporaryQuotaBump(TEST_CALLING_PACKAGE, TEST_CALLING_USER);
+ testQuotasNoDeferral(trigger -> setTestAlarm(ELAPSED_REALTIME_WAKEUP, trigger,
+ getNewMockPendingIntent()), standbyQuota + temporaryQuota, mAppStandbyWindow);
+ }
+
+ @Test
+ public void temporaryQuota_bumpedBeforeDeferral_active() throws Exception {
+ testTemporaryQuota_bumpedBeforeDeferral(STANDBY_BUCKET_ACTIVE);
+ }
+
+ @Test
+ public void temporaryQuota_bumpedBeforeDeferral_working() throws Exception {
+ testTemporaryQuota_bumpedBeforeDeferral(STANDBY_BUCKET_WORKING_SET);
+ }
+
+ @Test
+ public void temporaryQuota_bumpedBeforeDeferral_frequent() throws Exception {
+ testTemporaryQuota_bumpedBeforeDeferral(STANDBY_BUCKET_FREQUENT);
+ }
+
+ @Test
+ public void temporaryQuota_bumpedBeforeDeferral_rare() throws Exception {
+ testTemporaryQuota_bumpedBeforeDeferral(STANDBY_BUCKET_RARE);
+ }
+
@After
public void tearDown() {
if (mMockingSession != null) {