From 24cbdb70aa2bb9da035fe39a64109c2116e0f989 Mon Sep 17 00:00:00 2001 From: Suprabh Shukla <suprabh@google.com> Date: Thu, 12 Oct 2023 15:48:50 -0700 Subject: [PATCH] Remove code to manage the exact alarm denylist Now that exact alarms are denied to newer app installs for apps targeting T, the deny list is obsolete and the overhead of maintaining it is not worthwhile. Test: atest CtsAlarmManagerTestCases Test: atest FrameworksMockingServicesTests:com.android.server.alarm Bug: 304846238 Change-Id: I4376e5ddbb2e470f3e3d690dd0866f4b470f455b --- .../server/alarm/AlarmManagerService.java | 138 +-------- .../server/alarm/AlarmManagerServiceTest.java | 283 +++--------------- 2 files changed, 41 insertions(+), 380 deletions(-) diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java index 3cbee5d07bb92..384a480af4e95 100644 --- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java @@ -173,8 +173,6 @@ import com.android.server.usage.AppStandbyInternal.AppIdleStateChangeListener; import dalvik.annotation.optimization.NeverCompile; -import libcore.util.EmptyArray; - import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; @@ -260,7 +258,7 @@ public class AlarmManagerService extends SystemService { /** * A map from uid to the last op-mode we have seen for * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}. Used for evaluating permission state change - * when the denylist changes. + * when the app-op changes. */ @VisibleForTesting @GuardedBy("mLock") @@ -671,9 +669,6 @@ public class AlarmManagerService extends SystemService { @VisibleForTesting final class Constants implements DeviceConfig.OnPropertiesChangedListener, EconomyManagerInternal.TareStateChangeListener { - @VisibleForTesting - static final int MAX_EXACT_ALARM_DENY_LIST_SIZE = 250; - // Key names stored in the settings value. @VisibleForTesting static final String KEY_MIN_FUTURITY = "min_futurity"; @@ -727,8 +722,6 @@ public class AlarmManagerService extends SystemService { @VisibleForTesting static final String KEY_PRIORITY_ALARM_DELAY = "priority_alarm_delay"; @VisibleForTesting - static final String KEY_EXACT_ALARM_DENY_LIST = "exact_alarm_deny_list"; - @VisibleForTesting static final String KEY_MIN_DEVICE_IDLE_FUZZ = "min_device_idle_fuzz"; @VisibleForTesting static final String KEY_MAX_DEVICE_IDLE_FUZZ = "max_device_idle_fuzz"; @@ -834,13 +827,6 @@ public class AlarmManagerService extends SystemService { */ public long PRIORITY_ALARM_DELAY = DEFAULT_PRIORITY_ALARM_DELAY; - /** - * Read-only set of apps that won't get SCHEDULE_EXACT_ALARM when the app-op mode for - * OP_SCHEDULE_EXACT_ALARM is MODE_DEFAULT. Since this is read-only and volatile, this can - * be accessed without synchronizing on {@link #mLock}. - */ - public volatile Set<String> EXACT_ALARM_DENY_LIST = Collections.emptySet(); - /** * Minimum time interval that an IDLE_UNTIL will be pulled earlier to a subsequent * WAKE_FROM_IDLE alarm. @@ -1025,21 +1011,6 @@ public class AlarmManagerService extends SystemService { PRIORITY_ALARM_DELAY = properties.getLong(KEY_PRIORITY_ALARM_DELAY, DEFAULT_PRIORITY_ALARM_DELAY); break; - case KEY_EXACT_ALARM_DENY_LIST: - final String rawValue = properties.getString(KEY_EXACT_ALARM_DENY_LIST, - ""); - final String[] values = rawValue.isEmpty() - ? EmptyArray.STRING - : rawValue.split(",", MAX_EXACT_ALARM_DENY_LIST_SIZE + 1); - if (values.length > MAX_EXACT_ALARM_DENY_LIST_SIZE) { - Slog.w(TAG, "Deny list too long, truncating to " - + MAX_EXACT_ALARM_DENY_LIST_SIZE + " elements."); - updateExactAlarmDenyList( - Arrays.copyOf(values, MAX_EXACT_ALARM_DENY_LIST_SIZE)); - } else { - updateExactAlarmDenyList(values); - } - break; case KEY_MIN_DEVICE_IDLE_FUZZ: case KEY_MAX_DEVICE_IDLE_FUZZ: if (!deviceIdleFuzzBoundariesUpdated) { @@ -1110,28 +1081,6 @@ public class AlarmManagerService extends SystemService { } } - private void updateExactAlarmDenyList(String[] newDenyList) { - final Set<String> newSet = Collections.unmodifiableSet(new ArraySet<>(newDenyList)); - final Set<String> removed = new ArraySet<>(EXACT_ALARM_DENY_LIST); - final Set<String> added = new ArraySet<>(newDenyList); - - added.removeAll(EXACT_ALARM_DENY_LIST); - removed.removeAll(newSet); - if (added.size() > 0) { - mHandler.obtainMessage(AlarmHandler.EXACT_ALARM_DENY_LIST_PACKAGES_ADDED, added) - .sendToTarget(); - } - if (removed.size() > 0) { - mHandler.obtainMessage(AlarmHandler.EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED, removed) - .sendToTarget(); - } - if (newDenyList.length == 0) { - EXACT_ALARM_DENY_LIST = Collections.emptySet(); - } else { - EXACT_ALARM_DENY_LIST = newSet; - } - } - private void updateDeviceIdleFuzzBoundaries() { final DeviceConfig.Properties properties = DeviceConfig.getProperties( DeviceConfig.NAMESPACE_ALARM_MANAGER, @@ -1277,9 +1226,6 @@ public class AlarmManagerService extends SystemService { TimeUtils.formatDuration(PRIORITY_ALARM_DELAY, pw); pw.println(); - pw.print(KEY_EXACT_ALARM_DENY_LIST, EXACT_ALARM_DENY_LIST); - pw.println(); - pw.print(KEY_MIN_DEVICE_IDLE_FUZZ); pw.print("="); TimeUtils.formatDuration(MIN_DEVICE_IDLE_FUZZ, pw); @@ -2114,14 +2060,10 @@ public class AlarmManagerService extends SystemService { ? permissionState : (newMode == AppOpsManager.MODE_ALLOWED); } else { - final boolean allowedByDefault = - !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT) - ? allowedByDefault - : (oldMode == AppOpsManager.MODE_ALLOWED); + || (oldMode == AppOpsManager.MODE_ALLOWED); hasPermission = (newMode == AppOpsManager.MODE_DEFAULT) - ? allowedByDefault - : (newMode == AppOpsManager.MODE_ALLOWED); + || (newMode == AppOpsManager.MODE_ALLOWED); } if (hadPermission && !hasPermission) { @@ -2769,11 +2711,8 @@ public class AlarmManagerService extends SystemService { // Compatibility permission check for older apps. final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid, packageName); - if (mode == AppOpsManager.MODE_DEFAULT) { - hasPermission = !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); - } else { - hasPermission = (mode == AppOpsManager.MODE_ALLOWED); - } + hasPermission = (mode == AppOpsManager.MODE_DEFAULT) + || (mode == AppOpsManager.MODE_ALLOWED); } mStatLogger.logDurationStat(Stats.HAS_SCHEDULE_EXACT_ALARM, start); return hasPermission; @@ -3992,63 +3931,6 @@ public class AlarmManagerService extends SystemService { } } - /** - * Called when the {@link Constants#EXACT_ALARM_DENY_LIST}, changes with the packages that - * either got added or deleted. - * These packages may lose or gain the SCHEDULE_EXACT_ALARM permission. - * - * Note that these packages don't need to be installed on the device, but if they are and they - * do undergo a permission change, we will handle them appropriately. - * - * This should not be called with the lock held as it calls out to other services. - * This is not expected to get called frequently. - */ - void handleChangesToExactAlarmDenyList(ArraySet<String> changedPackages, boolean added) { - Slog.w(TAG, "Packages " + changedPackages + (added ? " added to" : " removed from") - + " the exact alarm deny list."); - - final int[] startedUserIds = mActivityManagerInternal.getStartedUserIds(); - - for (int i = 0; i < changedPackages.size(); i++) { - final String changedPackage = changedPackages.valueAt(i); - for (final int userId : startedUserIds) { - final int uid = mPackageManagerInternal.getPackageUid(changedPackage, 0, userId); - if (uid <= 0) { - continue; - } - if (!isExactAlarmChangeEnabled(changedPackage, userId)) { - continue; - } - if (isScheduleExactAlarmDeniedByDefault(changedPackage, userId)) { - continue; - } - if (hasUseExactAlarmInternal(changedPackage, uid)) { - continue; - } - if (!mExactAlarmCandidates.contains(UserHandle.getAppId(uid))) { - // Permission isn't requested, deny list doesn't matter. - continue; - } - final int appOpMode; - synchronized (mLock) { - appOpMode = mLastOpScheduleExactAlarm.get(uid, - AppOpsManager.opToDefaultMode(AppOpsManager.OP_SCHEDULE_EXACT_ALARM)); - } - if (appOpMode != AppOpsManager.MODE_DEFAULT) { - // Deny list doesn't matter. - continue; - } - // added: true => package was added to the deny list - // added: false => package was removed from the deny list - if (added) { - removeExactAlarmsOnPermissionRevoked(uid, changedPackage, /*killUid = */ true); - } else { - sendScheduleExactAlarmPermissionStateChangedBroadcast(changedPackage, userId); - } - } - } - } - /** * Called when an app loses the permission to use exact alarms. This will happen when the app * no longer has either {@link Manifest.permission#SCHEDULE_EXACT_ALARM} or @@ -4931,8 +4813,8 @@ public class AlarmManagerService extends SystemService { public static final int CHARGING_STATUS_CHANGED = 6; public static final int REMOVE_FOR_CANCELED = 7; public static final int REMOVE_EXACT_ALARMS = 8; - public static final int EXACT_ALARM_DENY_LIST_PACKAGES_ADDED = 9; - public static final int EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED = 10; + // Unused id 9 + // Unused id 10 public static final int REFRESH_EXACT_ALARM_CANDIDATES = 11; public static final int TARE_AFFORDABILITY_CHANGED = 12; public static final int CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE = 13; @@ -5041,12 +4923,6 @@ public class AlarmManagerService extends SystemService { String packageName = (String) msg.obj; removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */true); break; - case EXACT_ALARM_DENY_LIST_PACKAGES_ADDED: - handleChangesToExactAlarmDenyList((ArraySet<String>) msg.obj, true); - break; - case EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED: - handleChangesToExactAlarmDenyList((ArraySet<String>) msg.obj, false); - break; case REFRESH_EXACT_ALARM_CANDIDATES: refreshExactAlarmCandidates(); break; 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 5b519633081a0..21e3b34ed61a7 100644 --- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java @@ -62,8 +62,6 @@ import static com.android.server.alarm.AlarmManagerService.ACTIVE_INDEX; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.APP_STANDBY_BUCKET_CHANGED; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.CHARGING_STATUS_CHANGED; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE; -import static com.android.server.alarm.AlarmManagerService.AlarmHandler.EXACT_ALARM_DENY_LIST_PACKAGES_ADDED; -import static com.android.server.alarm.AlarmManagerService.AlarmHandler.EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_ALARMS; import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED; @@ -75,7 +73,6 @@ import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_W import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_QUOTA; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WHITELIST_DURATION; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_ALLOW_WHILE_IDLE_WINDOW; -import static com.android.server.alarm.AlarmManagerService.Constants.KEY_EXACT_ALARM_DENY_LIST; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_LISTENER_TIMEOUT; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_DEVICE_IDLE_FUZZ; import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MAX_INTERVAL; @@ -85,7 +82,6 @@ import static com.android.server.alarm.AlarmManagerService.Constants.KEY_MIN_INT 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; import static com.android.server.alarm.AlarmManagerService.IS_WAKEUP_MASK; @@ -798,47 +794,6 @@ public final class AlarmManagerServiceTest { assertEquals(70, mService.mConstants.TEMPORARY_QUOTA_BUMP); } - @Test - public void updatingExactAlarmDenyList() { - ArraySet<String> denyListed = new ArraySet<>(new String[]{ - "com.example.package1", - "com.example.package2", - "com.example.package3", - }); - setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, - "com.example.package1,com.example.package2,com.example.package3"); - assertEquals(denyListed, mService.mConstants.EXACT_ALARM_DENY_LIST); - - - denyListed = new ArraySet<>(new String[]{ - "com.example.package1", - "com.example.package4", - }); - setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, - "com.example.package1,com.example.package4"); - assertEquals(denyListed, mService.mConstants.EXACT_ALARM_DENY_LIST); - - setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, ""); - assertEquals(0, mService.mConstants.EXACT_ALARM_DENY_LIST.size()); - } - - @Test - public void exactAlarmDenyListMaxSize() { - final ArraySet<String> expectedSet = new ArraySet<>(); - final StringBuilder sb = new StringBuilder("package1"); - expectedSet.add("package1"); - for (int i = 2; i <= 2 * MAX_EXACT_ALARM_DENY_LIST_SIZE; i++) { - sb.append(",package"); - sb.append(i); - if (i <= MAX_EXACT_ALARM_DENY_LIST_SIZE) { - expectedSet.add("package" + i); - } - } - assertEquals(MAX_EXACT_ALARM_DENY_LIST_SIZE, expectedSet.size()); - setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, sb.toString()); - assertEquals(expectedSet, mService.mConstants.EXACT_ALARM_DENY_LIST); - } - @Test public void positiveWhileIdleQuotas() { setDeviceConfigInt(KEY_ALLOW_WHILE_IDLE_QUOTA, -3); @@ -2212,50 +2167,30 @@ public final class AlarmManagerServiceTest { } @Test - public void hasScheduleExactAlarmBinderCallNotDenyListedPreT() throws RemoteException { + public void hasScheduleExactAlarmBinderCallPreT() throws RemoteException { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); - mockScheduleExactAlarmStatePreT(true, false, MODE_DEFAULT); + mockScheduleExactAlarmStatePreT(true, MODE_DEFAULT); assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(true, MODE_ALLOWED); assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - mockScheduleExactAlarmStatePreT(true, false, MODE_IGNORED); + mockScheduleExactAlarmStatePreT(true, MODE_IGNORED); assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); } - @Test - public void hasScheduleExactAlarmBinderCallDenyListedPreT() throws RemoteException { - mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); - - mockScheduleExactAlarmStatePreT(true, true, MODE_ERRORED); - assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - - mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT); - assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - - mockScheduleExactAlarmStatePreT(true, true, MODE_IGNORED); - assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - - mockScheduleExactAlarmStatePreT(true, true, MODE_ALLOWED); - assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - } - @Test public void hasScheduleExactAlarmBinderCallNotDeclaredPreT() throws RemoteException { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); - mockScheduleExactAlarmStatePreT(false, false, MODE_DEFAULT); - assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - - mockScheduleExactAlarmStatePreT(false, false, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(false, MODE_DEFAULT); assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); - mockScheduleExactAlarmStatePreT(false, true, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(false, MODE_ALLOWED); assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER)); } @@ -2281,41 +2216,33 @@ public final class AlarmManagerServiceTest { mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true); // No permission, no exemption. - mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT); - assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); - - // No permission, no exemption. - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); // Policy permission only, no exemption. - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); mockUseExactAlarmState(true); assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); mockUseExactAlarmState(false); // User permission only, no exemption. - mockScheduleExactAlarmStatePreT(true, false, MODE_DEFAULT); - assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); - - // User permission only, no exemption. - mockScheduleExactAlarmStatePreT(true, true, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(true, MODE_DEFAULT); assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); // No permission, exemption. - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(true); assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); // No permission, exemption. - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(false); doReturn(true).when(() -> UserHandle.isCore(TEST_CALLING_UID)); assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); // Both permissions and exemption. - mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(true, MODE_ALLOWED); mockUseExactAlarmState(true); assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); } @@ -2514,17 +2441,12 @@ public final class AlarmManagerServiceTest { assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type); } - private void mockScheduleExactAlarmStatePreT(boolean declared, boolean denyList, int mode) { + private void mockScheduleExactAlarmStatePreT(boolean declared, int mode) { String[] requesters = declared ? new String[]{TEST_CALLING_PACKAGE} : EmptyArray.STRING; when(mPermissionManagerInternal.getAppOpPermissionPackages(SCHEDULE_EXACT_ALARM)) .thenReturn(requesters); mService.refreshExactAlarmCandidates(); - if (denyList) { - setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, TEST_CALLING_PACKAGE); - } else { - setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, ""); - } when(mAppOpsManager.checkOpNoThrow(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE)).thenReturn(mode); } @@ -2556,7 +2478,7 @@ public final class AlarmManagerServiceTest { public void alarmClockBinderCallWithoutPermission() throws RemoteException { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true); final PendingIntent alarmPi = getNewMockPendingIntent(); @@ -2630,7 +2552,7 @@ public final class AlarmManagerServiceTest { public void exactBinderCallWithAllowlist() throws RemoteException { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); // If permission is denied, only then allowlist will be checked. - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true); final PendingIntent alarmPi = getNewMockPendingIntent(); @@ -2650,7 +2572,7 @@ public final class AlarmManagerServiceTest { public void exactAllowWhileIdleBinderCallWithSEAPermission() throws RemoteException { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); - mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(true, MODE_ALLOWED); final PendingIntent alarmPi = getNewMockPendingIntent(); mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0, FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null); @@ -2676,7 +2598,7 @@ public final class AlarmManagerServiceTest { mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true); mockUseExactAlarmState(true); - mockScheduleExactAlarmStatePreT(false, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(false, MODE_ERRORED); final PendingIntent alarmPi = getNewMockPendingIntent(); mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0, FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null); @@ -2700,7 +2622,7 @@ public final class AlarmManagerServiceTest { public void exactAllowWhileIdleBinderCallWithAllowlist() throws RemoteException { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); // If permission is denied, only then allowlist will be checked. - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true); final PendingIntent alarmPi = getNewMockPendingIntent(); @@ -2726,7 +2648,7 @@ public final class AlarmManagerServiceTest { public void exactBinderCallsWithoutPermissionWithoutAllowlist() throws RemoteException { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(false); final PendingIntent alarmPi = getNewMockPendingIntent(); @@ -2836,7 +2758,7 @@ public final class AlarmManagerServiceTest { public void binderCallWithUserAllowlist() throws RemoteException { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true); when(mAppStateTracker.isUidPowerSaveUserExempt(TEST_CALLING_UID)).thenReturn(true); @@ -3051,136 +2973,12 @@ public final class AlarmManagerServiceTest { } } - @Test - public void denyListChanged() { - mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{"p1", "p2", "p3"}); - when(mActivityManagerInternal.getStartedUserIds()).thenReturn(EmptyArray.INT); - - setDeviceConfigString(KEY_EXACT_ALARM_DENY_LIST, "p2,p4,p5"); - - final ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class); - verify(mService.mHandler, times(2)).sendMessageAtTime(messageCaptor.capture(), - anyLong()); - - final List<Message> messages = messageCaptor.getAllValues(); - for (final Message msg : messages) { - assertTrue("Unwanted message sent to handler: " + msg.what, - msg.what == EXACT_ALARM_DENY_LIST_PACKAGES_ADDED - || msg.what == EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED); - mService.mHandler.handleMessage(msg); - } - - ArraySet<String> added = new ArraySet<>(new String[]{"p4", "p5"}); - verify(mService).handleChangesToExactAlarmDenyList(eq(added), eq(true)); - - ArraySet<String> removed = new ArraySet<>(new String[]{"p1", "p3"}); - verify(mService).handleChangesToExactAlarmDenyList(eq(removed), eq(false)); - } - - @Test - public void permissionGrantedDueToDenyList() { - mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); - - final String[] packages = {"example.package.1", "example.package.2"}; - - final int appId1 = 232; - final int appId2 = 431; - - final int userId1 = 42; - final int userId2 = 53; - - registerAppIds(packages, new Integer[]{appId1, appId2}); - - when(mActivityManagerInternal.getStartedUserIds()).thenReturn(new int[]{userId1, userId2}); - - when(mPermissionManagerInternal.getAppOpPermissionPackages( - SCHEDULE_EXACT_ALARM)).thenReturn(packages); - mService.refreshExactAlarmCandidates(); - - final long allowListDuration = 53442; - when(mActivityManagerInternal.getBootTimeTempAllowListDuration()).thenReturn( - allowListDuration); - - mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId1, appId1), MODE_ALLOWED); - mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId2, appId1), MODE_DEFAULT); - mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId1, appId2), MODE_IGNORED); - mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId2, appId2), MODE_ERRORED); - - mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), false); - - // No permission revoked. - verify(mService, never()).removeExactAlarmsOnPermissionRevoked(anyInt(), anyString(), - anyBoolean()); - - // Permission got granted only for (appId1, userId2). - final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); - final ArgumentCaptor<Bundle> bundleCaptor = ArgumentCaptor.forClass(Bundle.class); - final ArgumentCaptor<UserHandle> userCaptor = ArgumentCaptor.forClass(UserHandle.class); - - verify(mMockContext).sendBroadcastAsUser(intentCaptor.capture(), userCaptor.capture(), - isNull(), bundleCaptor.capture()); - - assertEquals(userId2, userCaptor.getValue().getIdentifier()); - - // Validate the intent. - assertEquals(AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED, - intentCaptor.getValue().getAction()); - assertEquals(packages[0], intentCaptor.getValue().getPackage()); - - // Validate the options. - final BroadcastOptions bOptions = new BroadcastOptions(bundleCaptor.getValue()); - assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, - bOptions.getTemporaryAppAllowlistType()); - assertEquals(allowListDuration, bOptions.getTemporaryAppAllowlistDuration()); - assertEquals(PowerExemptionManager.REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED, - bOptions.getTemporaryAppAllowlistReasonCode()); - } - - @Test - public void permissionRevokedDueToDenyList() { - mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); - - final String[] packages = {"example.package.1", "example.package.2"}; - - final int appId1 = 232; - final int appId2 = 431; - - final int userId1 = 42; - final int userId2 = 53; - - registerAppIds(packages, new Integer[]{appId1, appId2}); - - when(mActivityManagerInternal.getStartedUserIds()).thenReturn(new int[]{userId1, userId2}); - - when(mPermissionManagerInternal.getAppOpPermissionPackages( - SCHEDULE_EXACT_ALARM)).thenReturn(packages); - mService.refreshExactAlarmCandidates(); - - mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId1, appId1), MODE_ALLOWED); - mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId2, appId1), MODE_DEFAULT); - mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId1, appId2), MODE_IGNORED); - mService.mLastOpScheduleExactAlarm.put(UserHandle.getUid(userId2, appId2), MODE_ERRORED); - - mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), true); - - // Permission got revoked only for (appId1, userId2) - verify(mService, never()).removeExactAlarmsOnPermissionRevoked( - eq(UserHandle.getUid(userId1, appId1)), eq(packages[0]), eq(true)); - verify(mService, never()).removeExactAlarmsOnPermissionRevoked( - eq(UserHandle.getUid(userId1, appId2)), eq(packages[1]), eq(true)); - verify(mService, never()).removeExactAlarmsOnPermissionRevoked( - eq(UserHandle.getUid(userId2, appId2)), eq(packages[1]), eq(true)); - - verify(mService).removeExactAlarmsOnPermissionRevoked( - eq(UserHandle.getUid(userId2, appId1)), eq(packages[0]), eq(true)); - } - @Test public void opChangedPermissionRevoked() throws Exception { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ALLOWED); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE); assertAndHandleMessageSync(REMOVE_EXACT_ALARMS); @@ -3193,20 +2991,7 @@ public final class AlarmManagerServiceTest { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false); mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ALLOWED); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); - - mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE); - - verify(mService.mHandler, never()).sendMessageAtTime( - argThat(m -> m.what == REMOVE_EXACT_ALARMS), anyLong()); - } - - @Test - public void opChangedNoPermissionChangeDueToDenyList() throws Exception { - mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false); - - mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ERRORED); - mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE); @@ -3222,7 +3007,7 @@ public final class AlarmManagerServiceTest { when(mActivityManagerInternal.getBootTimeTempAllowListDuration()).thenReturn(durationMs); mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ERRORED); - mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(true, MODE_ALLOWED); mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE); final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); @@ -3482,7 +3267,7 @@ public final class AlarmManagerServiceTest { .putExtra(Intent.EXTRA_REPLACING, true); mockUseExactAlarmState(false); - mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(true, MODE_ALLOWED); mPackageChangesReceiver.onReceive(mMockContext, packageReplacedIntent); assertAndHandleMessageSync(CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE); @@ -3490,7 +3275,7 @@ public final class AlarmManagerServiceTest { assertEquals(5, mService.mAlarmStore.size()); mockUseExactAlarmState(true); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); mPackageChangesReceiver.onReceive(mMockContext, packageReplacedIntent); assertAndHandleMessageSync(CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE); @@ -3498,7 +3283,7 @@ public final class AlarmManagerServiceTest { assertEquals(5, mService.mAlarmStore.size()); mockUseExactAlarmState(false); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); mPackageChangesReceiver.onReceive(mMockContext, packageReplacedIntent); assertAndHandleMessageSync(CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE); @@ -3653,16 +3438,16 @@ public final class AlarmManagerServiceTest { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false); - mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT); - assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID)); + mockScheduleExactAlarmStatePreT(true, MODE_DEFAULT); + assertTrue(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID)); - mockScheduleExactAlarmStatePreT(false, false, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(false, MODE_ALLOWED); assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID)); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID)); - mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(true, MODE_ALLOWED); assertTrue(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID)); } @@ -3671,11 +3456,11 @@ public final class AlarmManagerServiceTest { mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false); mockScheduleExactAlarmState(true); - mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED); + mockScheduleExactAlarmStatePreT(true, MODE_ALLOWED); assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID)); mockScheduleExactAlarmState(false); - mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED); + mockScheduleExactAlarmStatePreT(true, MODE_ERRORED); assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID)); } -- GitLab