Loading apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +46 −6 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.PermissionChecker; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.database.ContentObserver; Loading Loading @@ -1839,6 +1840,9 @@ public class AlarmManagerService extends SystemService { if (!isExactAlarmChangeEnabled(a.packageName, UserHandle.getUserId(a.uid))) { return false; } if (hasUseExactAlarmPermission(a.packageName, a.uid)) { return false; } return !isExemptFromExactAlarmPermission(a.uid); }; removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED); Loading Loading @@ -1900,6 +1904,9 @@ public class AlarmManagerService extends SystemService { || !isExactAlarmChangeEnabled(packageName, userId)) { return; } if (hasUseExactAlarmPermission(packageName, uid)) { return; } final boolean requested = mExactAlarmCandidates.contains( UserHandle.getAppId(uid)); Loading Loading @@ -2534,6 +2541,8 @@ public class AlarmManagerService extends SystemService { private static boolean getScheduleExactAlarmState(boolean requested, boolean denyListed, int appOpMode) { // This does not account for the state of the USE_EXACT_ALARM permission. // The caller should do that separately. if (!requested) { return false; } Loading @@ -2543,7 +2552,16 @@ public class AlarmManagerService extends SystemService { return appOpMode == AppOpsManager.MODE_ALLOWED; } boolean hasUseExactAlarmPermission(String packageName, int uid) { return PermissionChecker.checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM, PermissionChecker.PID_UNKNOWN, uid, packageName) == PermissionChecker.PERMISSION_GRANTED; } boolean hasScheduleExactAlarmInternal(String packageName, int uid) { if (hasUseExactAlarmPermission(packageName, uid)) { return true; } // Not using getScheduleExactAlarmState as this can avoid some calls to AppOpsService. // Not using #mLastOpScheduleExactAlarm as it may contain stale values. // No locking needed as all internal containers being queried are immutable. Loading Loading @@ -3759,6 +3777,9 @@ public class AlarmManagerService extends SystemService { if (!isExactAlarmChangeEnabled(changedPackage, userId)) { continue; } if (hasUseExactAlarmPermission(changedPackage, uid)) { continue; } final int appOpMode; synchronized (mLock) { appOpMode = mLastOpScheduleExactAlarm.get(uid, Loading @@ -3778,7 +3799,8 @@ public class AlarmManagerService extends SystemService { } if (added) { synchronized (mLock) { removeExactAlarmsOnPermissionRevokedLocked(uid, changedPackage); removeExactAlarmsOnPermissionRevokedLocked(uid, changedPackage, /*killUid = */ true); } } else { sendScheduleExactAlarmPermissionStateChangedBroadcast(changedPackage, userId); Loading @@ -3794,7 +3816,7 @@ public class AlarmManagerService extends SystemService { * This is not expected to get called frequently. */ @GuardedBy("mLock") void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName) { void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName, boolean killUid) { if (isExemptFromExactAlarmPermission(uid) || !isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) { return; Loading @@ -3805,7 +3827,7 @@ public class AlarmManagerService extends SystemService { && a.windowLength == 0); removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED); if (mConstants.KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED) { if (killUid && mConstants.KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED) { PermissionManagerService.killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid), "schedule_exact_alarm revoked"); } Loading Loading @@ -4617,6 +4639,7 @@ public class AlarmManagerService extends SystemService { public static final int EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED = 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; AlarmHandler() { super(Looper.myLooper()); Loading Loading @@ -4715,10 +4738,11 @@ public class AlarmManagerService extends SystemService { break; case REMOVE_EXACT_ALARMS: final int uid = msg.arg1; final String packageName = (String) msg.obj; int uid = msg.arg1; String packageName = (String) msg.obj; synchronized (mLock) { removeExactAlarmsOnPermissionRevokedLocked(uid, packageName); removeExactAlarmsOnPermissionRevokedLocked(uid, packageName, /*killUid = */ true); } break; case EXACT_ALARM_DENY_LIST_PACKAGES_ADDED: Loading @@ -4730,6 +4754,16 @@ public class AlarmManagerService extends SystemService { case REFRESH_EXACT_ALARM_CANDIDATES: refreshExactAlarmCandidates(); break; case CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE: packageName = (String) msg.obj; uid = msg.arg1; if (!hasScheduleExactAlarmInternal(packageName, uid)) { synchronized (mLock) { removeExactAlarmsOnPermissionRevokedLocked(uid, packageName, /*killUid = */false); } } break; default: // nope, just ignore it break; Loading Loading @@ -4914,6 +4948,12 @@ public class AlarmManagerService extends SystemService { } break; case Intent.ACTION_PACKAGE_ADDED: if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { final String packageUpdated = intent.getData().getSchemeSpecificPart(); mHandler.obtainMessage( AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1, packageUpdated).sendToTarget(); } mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES); return; } Loading core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ package android { field public static final String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS"; field public static final String UPDATE_PACKAGES_WITHOUT_USER_ACTION = "android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION"; field public static final String USE_BIOMETRIC = "android.permission.USE_BIOMETRIC"; field public static final String USE_EXACT_ALARM = "android.permission.USE_EXACT_ALARM"; field @Deprecated public static final String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT"; field public static final String USE_FULL_SCREEN_INTENT = "android.permission.USE_FULL_SCREEN_INTENT"; field public static final String USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER = "android.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER"; core/res/AndroidManifest.xml +10 −0 Original line number Diff line number Diff line Loading @@ -4403,6 +4403,16 @@ <permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:protectionLevel="normal|appop"/> <!-- Allows apps to use exact alarms just like with SCHEDULE_EXACT_ALARM but without needing to request this permission from the user. <p><b>This is only for apps that rely on exact alarms for their core functionality.</b> App stores may enforce policies to audit and review the use of this permission. Any app that requests this but is found to not require exact alarms for its primary function may be removed from the app store. --> <permission android:name="android.permission.USE_EXACT_ALARM" android:protectionLevel="normal"/> <!-- Allows an application to query tablet mode state and monitor changes in it. <p>Not for use by third-party applications. Loading services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +26 −8 Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import android.Manifest; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; Loading @@ -124,6 +125,7 @@ import android.app.usage.UsageStatsManagerInternal; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.PermissionChecker; import android.content.pm.PackageManagerInternal; import android.database.ContentObserver; import android.net.Uri; Loading Loading @@ -389,6 +391,7 @@ public class AlarmManagerServiceTest { .mockStatic(LocalServices.class) .spyStatic(Looper.class) .mockStatic(MetricsHelper.class) .mockStatic(PermissionChecker.class) .mockStatic(PermissionManagerService.class) .mockStatic(ServiceManager.class) .mockStatic(Settings.Global.class) Loading Loading @@ -445,6 +448,10 @@ public class AlarmManagerServiceTest { doReturn(true) .when(() -> DateFormat.is24HourFormat(eq(mMockContext), anyInt())); doReturn(PermissionChecker.PERMISSION_HARD_DENIED).when( () -> PermissionChecker.checkPermissionForPreflight(any(), eq(Manifest.permission.USE_EXACT_ALARM), anyInt(), anyInt(), anyString())); when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); registerAppIds(new String[]{TEST_CALLING_PACKAGE}, Loading Loading @@ -2158,6 +2165,7 @@ public class AlarmManagerServiceTest { @Test public void canScheduleExactAlarmsBinderCall() throws RemoteException { // Policy permission is denied in setUp(). mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); // No permission, no exemption. Loading @@ -2168,6 +2176,14 @@ public class AlarmManagerServiceTest { mockExactAlarmPermissionGrant(true, false, MODE_ERRORED); assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); // Policy permission only, no exemption. mockExactAlarmPermissionGrant(true, false, MODE_ERRORED); doReturn(PermissionChecker.PERMISSION_GRANTED).when( () -> PermissionChecker.checkPermissionForPreflight(eq(mMockContext), eq(Manifest.permission.USE_EXACT_ALARM), anyInt(), eq(TEST_CALLING_UID), eq(TEST_CALLING_PACKAGE))); assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); // Permission, no exemption. mockExactAlarmPermissionGrant(true, false, MODE_DEFAULT); assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); Loading Loading @@ -2699,7 +2715,8 @@ public class AlarmManagerServiceTest { mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), false); // No permission revoked. verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(anyInt(), anyString()); verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(anyInt(), anyString(), anyBoolean()); // Permission got granted only for (appId1, userId2). final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); Loading Loading @@ -2754,14 +2771,14 @@ public class AlarmManagerServiceTest { // Permission got revoked only for (appId1, userId2) verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked( eq(UserHandle.getUid(userId1, appId1)), eq(packages[0])); eq(UserHandle.getUid(userId1, appId1)), eq(packages[0]), eq(true)); verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked( eq(UserHandle.getUid(userId1, appId2)), eq(packages[1])); eq(UserHandle.getUid(userId1, appId2)), eq(packages[1]), eq(true)); verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked( eq(UserHandle.getUid(userId2, appId2)), eq(packages[1])); eq(UserHandle.getUid(userId2, appId2)), eq(packages[1]), eq(true)); verify(mService).removeExactAlarmsOnPermissionRevokedLocked( eq(UserHandle.getUid(userId2, appId1)), eq(packages[0])); eq(UserHandle.getUid(userId2, appId1)), eq(packages[0]), eq(true)); } @Test Loading @@ -2774,7 +2791,7 @@ public class AlarmManagerServiceTest { mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE); assertAndHandleMessageSync(REMOVE_EXACT_ALARMS); verify(mService).removeExactAlarmsOnPermissionRevokedLocked(TEST_CALLING_UID, TEST_CALLING_PACKAGE); TEST_CALLING_PACKAGE, true); } @Test Loading Loading @@ -2859,7 +2876,8 @@ public class AlarmManagerServiceTest { null); assertEquals(6, mService.mAlarmStore.size()); mService.removeExactAlarmsOnPermissionRevokedLocked(TEST_CALLING_UID, TEST_CALLING_PACKAGE); mService.removeExactAlarmsOnPermissionRevokedLocked(TEST_CALLING_UID, TEST_CALLING_PACKAGE, true); final ArrayList<Alarm> remaining = mService.mAlarmStore.asList(); assertEquals(3, remaining.size()); Loading Loading @@ -3080,7 +3098,7 @@ public class AlarmManagerServiceTest { SCHEDULE_EXACT_ALARM)).thenReturn(exactAlarmRequesters); final Intent packageAdded = new Intent(Intent.ACTION_PACKAGE_ADDED) .setPackage(TEST_CALLING_PACKAGE) .setData(Uri.fromParts("package", TEST_CALLING_PACKAGE, null)) .putExtra(Intent.EXTRA_REPLACING, true); mPackageChangesReceiver.onReceive(mMockContext, packageAdded); Loading Loading
apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +46 −6 Original line number Diff line number Diff line Loading @@ -72,6 +72,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.PermissionChecker; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; import android.database.ContentObserver; Loading Loading @@ -1839,6 +1840,9 @@ public class AlarmManagerService extends SystemService { if (!isExactAlarmChangeEnabled(a.packageName, UserHandle.getUserId(a.uid))) { return false; } if (hasUseExactAlarmPermission(a.packageName, a.uid)) { return false; } return !isExemptFromExactAlarmPermission(a.uid); }; removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED); Loading Loading @@ -1900,6 +1904,9 @@ public class AlarmManagerService extends SystemService { || !isExactAlarmChangeEnabled(packageName, userId)) { return; } if (hasUseExactAlarmPermission(packageName, uid)) { return; } final boolean requested = mExactAlarmCandidates.contains( UserHandle.getAppId(uid)); Loading Loading @@ -2534,6 +2541,8 @@ public class AlarmManagerService extends SystemService { private static boolean getScheduleExactAlarmState(boolean requested, boolean denyListed, int appOpMode) { // This does not account for the state of the USE_EXACT_ALARM permission. // The caller should do that separately. if (!requested) { return false; } Loading @@ -2543,7 +2552,16 @@ public class AlarmManagerService extends SystemService { return appOpMode == AppOpsManager.MODE_ALLOWED; } boolean hasUseExactAlarmPermission(String packageName, int uid) { return PermissionChecker.checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM, PermissionChecker.PID_UNKNOWN, uid, packageName) == PermissionChecker.PERMISSION_GRANTED; } boolean hasScheduleExactAlarmInternal(String packageName, int uid) { if (hasUseExactAlarmPermission(packageName, uid)) { return true; } // Not using getScheduleExactAlarmState as this can avoid some calls to AppOpsService. // Not using #mLastOpScheduleExactAlarm as it may contain stale values. // No locking needed as all internal containers being queried are immutable. Loading Loading @@ -3759,6 +3777,9 @@ public class AlarmManagerService extends SystemService { if (!isExactAlarmChangeEnabled(changedPackage, userId)) { continue; } if (hasUseExactAlarmPermission(changedPackage, uid)) { continue; } final int appOpMode; synchronized (mLock) { appOpMode = mLastOpScheduleExactAlarm.get(uid, Loading @@ -3778,7 +3799,8 @@ public class AlarmManagerService extends SystemService { } if (added) { synchronized (mLock) { removeExactAlarmsOnPermissionRevokedLocked(uid, changedPackage); removeExactAlarmsOnPermissionRevokedLocked(uid, changedPackage, /*killUid = */ true); } } else { sendScheduleExactAlarmPermissionStateChangedBroadcast(changedPackage, userId); Loading @@ -3794,7 +3816,7 @@ public class AlarmManagerService extends SystemService { * This is not expected to get called frequently. */ @GuardedBy("mLock") void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName) { void removeExactAlarmsOnPermissionRevokedLocked(int uid, String packageName, boolean killUid) { if (isExemptFromExactAlarmPermission(uid) || !isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) { return; Loading @@ -3805,7 +3827,7 @@ public class AlarmManagerService extends SystemService { && a.windowLength == 0); removeAlarmsInternalLocked(whichAlarms, REMOVE_REASON_EXACT_PERMISSION_REVOKED); if (mConstants.KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED) { if (killUid && mConstants.KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED) { PermissionManagerService.killUid(UserHandle.getAppId(uid), UserHandle.getUserId(uid), "schedule_exact_alarm revoked"); } Loading Loading @@ -4617,6 +4639,7 @@ public class AlarmManagerService extends SystemService { public static final int EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED = 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; AlarmHandler() { super(Looper.myLooper()); Loading Loading @@ -4715,10 +4738,11 @@ public class AlarmManagerService extends SystemService { break; case REMOVE_EXACT_ALARMS: final int uid = msg.arg1; final String packageName = (String) msg.obj; int uid = msg.arg1; String packageName = (String) msg.obj; synchronized (mLock) { removeExactAlarmsOnPermissionRevokedLocked(uid, packageName); removeExactAlarmsOnPermissionRevokedLocked(uid, packageName, /*killUid = */ true); } break; case EXACT_ALARM_DENY_LIST_PACKAGES_ADDED: Loading @@ -4730,6 +4754,16 @@ public class AlarmManagerService extends SystemService { case REFRESH_EXACT_ALARM_CANDIDATES: refreshExactAlarmCandidates(); break; case CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE: packageName = (String) msg.obj; uid = msg.arg1; if (!hasScheduleExactAlarmInternal(packageName, uid)) { synchronized (mLock) { removeExactAlarmsOnPermissionRevokedLocked(uid, packageName, /*killUid = */false); } } break; default: // nope, just ignore it break; Loading Loading @@ -4914,6 +4948,12 @@ public class AlarmManagerService extends SystemService { } break; case Intent.ACTION_PACKAGE_ADDED: if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { final String packageUpdated = intent.getData().getSchemeSpecificPart(); mHandler.obtainMessage( AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE, uid, -1, packageUpdated).sendToTarget(); } mHandler.sendEmptyMessage(AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES); return; } Loading
core/api/current.txt +1 −0 Original line number Diff line number Diff line Loading @@ -194,6 +194,7 @@ package android { field public static final String UPDATE_DEVICE_STATS = "android.permission.UPDATE_DEVICE_STATS"; field public static final String UPDATE_PACKAGES_WITHOUT_USER_ACTION = "android.permission.UPDATE_PACKAGES_WITHOUT_USER_ACTION"; field public static final String USE_BIOMETRIC = "android.permission.USE_BIOMETRIC"; field public static final String USE_EXACT_ALARM = "android.permission.USE_EXACT_ALARM"; field @Deprecated public static final String USE_FINGERPRINT = "android.permission.USE_FINGERPRINT"; field public static final String USE_FULL_SCREEN_INTENT = "android.permission.USE_FULL_SCREEN_INTENT"; field public static final String USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER = "android.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER";
core/res/AndroidManifest.xml +10 −0 Original line number Diff line number Diff line Loading @@ -4403,6 +4403,16 @@ <permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:protectionLevel="normal|appop"/> <!-- Allows apps to use exact alarms just like with SCHEDULE_EXACT_ALARM but without needing to request this permission from the user. <p><b>This is only for apps that rely on exact alarms for their core functionality.</b> App stores may enforce policies to audit and review the use of this permission. Any app that requests this but is found to not require exact alarms for its primary function may be removed from the app store. --> <permission android:name="android.permission.USE_EXACT_ALARM" android:protectionLevel="normal"/> <!-- Allows an application to query tablet mode state and monitor changes in it. <p>Not for use by third-party applications. Loading
services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +26 −8 Original line number Diff line number Diff line Loading @@ -108,6 +108,7 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import android.Manifest; import android.app.ActivityManager; import android.app.ActivityManagerInternal; import android.app.ActivityOptions; Loading @@ -124,6 +125,7 @@ import android.app.usage.UsageStatsManagerInternal; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.PermissionChecker; import android.content.pm.PackageManagerInternal; import android.database.ContentObserver; import android.net.Uri; Loading Loading @@ -389,6 +391,7 @@ public class AlarmManagerServiceTest { .mockStatic(LocalServices.class) .spyStatic(Looper.class) .mockStatic(MetricsHelper.class) .mockStatic(PermissionChecker.class) .mockStatic(PermissionManagerService.class) .mockStatic(ServiceManager.class) .mockStatic(Settings.Global.class) Loading Loading @@ -445,6 +448,10 @@ public class AlarmManagerServiceTest { doReturn(true) .when(() -> DateFormat.is24HourFormat(eq(mMockContext), anyInt())); doReturn(PermissionChecker.PERMISSION_HARD_DENIED).when( () -> PermissionChecker.checkPermissionForPreflight(any(), eq(Manifest.permission.USE_EXACT_ALARM), anyInt(), anyInt(), anyString())); when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); registerAppIds(new String[]{TEST_CALLING_PACKAGE}, Loading Loading @@ -2158,6 +2165,7 @@ public class AlarmManagerServiceTest { @Test public void canScheduleExactAlarmsBinderCall() throws RemoteException { // Policy permission is denied in setUp(). mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true); // No permission, no exemption. Loading @@ -2168,6 +2176,14 @@ public class AlarmManagerServiceTest { mockExactAlarmPermissionGrant(true, false, MODE_ERRORED); assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); // Policy permission only, no exemption. mockExactAlarmPermissionGrant(true, false, MODE_ERRORED); doReturn(PermissionChecker.PERMISSION_GRANTED).when( () -> PermissionChecker.checkPermissionForPreflight(eq(mMockContext), eq(Manifest.permission.USE_EXACT_ALARM), anyInt(), eq(TEST_CALLING_UID), eq(TEST_CALLING_PACKAGE))); assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); // Permission, no exemption. mockExactAlarmPermissionGrant(true, false, MODE_DEFAULT); assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE)); Loading Loading @@ -2699,7 +2715,8 @@ public class AlarmManagerServiceTest { mService.handleChangesToExactAlarmDenyList(new ArraySet<>(packages), false); // No permission revoked. verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(anyInt(), anyString()); verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked(anyInt(), anyString(), anyBoolean()); // Permission got granted only for (appId1, userId2). final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class); Loading Loading @@ -2754,14 +2771,14 @@ public class AlarmManagerServiceTest { // Permission got revoked only for (appId1, userId2) verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked( eq(UserHandle.getUid(userId1, appId1)), eq(packages[0])); eq(UserHandle.getUid(userId1, appId1)), eq(packages[0]), eq(true)); verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked( eq(UserHandle.getUid(userId1, appId2)), eq(packages[1])); eq(UserHandle.getUid(userId1, appId2)), eq(packages[1]), eq(true)); verify(mService, never()).removeExactAlarmsOnPermissionRevokedLocked( eq(UserHandle.getUid(userId2, appId2)), eq(packages[1])); eq(UserHandle.getUid(userId2, appId2)), eq(packages[1]), eq(true)); verify(mService).removeExactAlarmsOnPermissionRevokedLocked( eq(UserHandle.getUid(userId2, appId1)), eq(packages[0])); eq(UserHandle.getUid(userId2, appId1)), eq(packages[0]), eq(true)); } @Test Loading @@ -2774,7 +2791,7 @@ public class AlarmManagerServiceTest { mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE); assertAndHandleMessageSync(REMOVE_EXACT_ALARMS); verify(mService).removeExactAlarmsOnPermissionRevokedLocked(TEST_CALLING_UID, TEST_CALLING_PACKAGE); TEST_CALLING_PACKAGE, true); } @Test Loading Loading @@ -2859,7 +2876,8 @@ public class AlarmManagerServiceTest { null); assertEquals(6, mService.mAlarmStore.size()); mService.removeExactAlarmsOnPermissionRevokedLocked(TEST_CALLING_UID, TEST_CALLING_PACKAGE); mService.removeExactAlarmsOnPermissionRevokedLocked(TEST_CALLING_UID, TEST_CALLING_PACKAGE, true); final ArrayList<Alarm> remaining = mService.mAlarmStore.asList(); assertEquals(3, remaining.size()); Loading Loading @@ -3080,7 +3098,7 @@ public class AlarmManagerServiceTest { SCHEDULE_EXACT_ALARM)).thenReturn(exactAlarmRequesters); final Intent packageAdded = new Intent(Intent.ACTION_PACKAGE_ADDED) .setPackage(TEST_CALLING_PACKAGE) .setData(Uri.fromParts("package", TEST_CALLING_PACKAGE, null)) .putExtra(Intent.EXTRA_REPLACING, true); mPackageChangesReceiver.onReceive(mMockContext, packageAdded); Loading