Loading apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +34 −49 Original line number Diff line number Diff line Loading @@ -30,6 +30,9 @@ import static android.app.AlarmManager.INTERVAL_DAY; import static android.app.AlarmManager.INTERVAL_HOUR; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.RTC_WAKEUP; import static android.content.PermissionChecker.PERMISSION_GRANTED; import static android.content.PermissionChecker.PID_UNKNOWN; import static android.content.PermissionChecker.checkPermissionForPreflight; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; import static android.os.PowerExemptionManager.REASON_ALARM_MANAGER_ALARM_CLOCK; import static android.os.PowerExemptionManager.REASON_DENIED; Loading Loading @@ -87,11 +90,9 @@ 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.content.pm.UserPackage; import android.database.ContentObserver; import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryStatsInternal; Loading Loading @@ -182,7 +183,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.TimeZone; Loading Loading @@ -269,7 +269,8 @@ public class AlarmManagerService extends SystemService { /** * A map from uid to the last op-mode we have seen for * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM} * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}. Used for evaluating permission state change * when the denylist changes. */ @VisibleForTesting @GuardedBy("mLock") Loading Loading @@ -2097,20 +2098,31 @@ public class AlarmManagerService extends SystemService { if (oldMode == newMode) { return; } final boolean allowedByDefault = isScheduleExactAlarmAllowedByDefault(packageName, uid); final boolean deniedByDefault = isScheduleExactAlarmDeniedByDefault( packageName, UserHandle.getUserId(uid)); final boolean hadPermission; if (oldMode != AppOpsManager.MODE_DEFAULT) { hadPermission = (oldMode == AppOpsManager.MODE_ALLOWED); } else { hadPermission = allowedByDefault; } final boolean hasPermission; if (newMode != AppOpsManager.MODE_DEFAULT) { hasPermission = (newMode == AppOpsManager.MODE_ALLOWED); if (deniedByDefault) { final boolean permissionState = getContext().checkPermission( Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN, uid) == PackageManager.PERMISSION_GRANTED; hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT) ? permissionState : (oldMode == AppOpsManager.MODE_ALLOWED); hasPermission = (newMode == AppOpsManager.MODE_DEFAULT) ? permissionState : (newMode == AppOpsManager.MODE_ALLOWED); } else { hasPermission = allowedByDefault; final boolean allowedByDefault = !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT) ? allowedByDefault : (oldMode == AppOpsManager.MODE_ALLOWED); hasPermission = (newMode == AppOpsManager.MODE_DEFAULT) ? allowedByDefault : (newMode == AppOpsManager.MODE_ALLOWED); } if (hadPermission && !hasPermission) { Loading Loading @@ -2754,41 +2766,13 @@ public class AlarmManagerService extends SystemService { boolean hasUseExactAlarmInternal(String packageName, int uid) { return isUseExactAlarmEnabled(packageName, UserHandle.getUserId(uid)) && (PermissionChecker.checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM, PermissionChecker.PID_UNKNOWN, uid, packageName) == PermissionChecker.PERMISSION_GRANTED); } /** * Returns whether SCHEDULE_EXACT_ALARM is allowed by default. */ boolean isScheduleExactAlarmAllowedByDefault(String packageName, int uid) { if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) { // This is essentially like changing the protection level of the permission to // (privileged|signature|role|appop), but have to implement this logic to maintain // compatibility for older apps. if (mPackageManagerInternal.isPlatformSigned(packageName) || mPackageManagerInternal.isUidPrivileged(uid)) { return true; } final long token = Binder.clearCallingIdentity(); try { final List<String> wellbeingHolders = (mRoleManager != null) ? mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING) : Collections.emptyList(); return wellbeingHolders.contains(packageName); } finally { Binder.restoreCallingIdentity(token); } } return !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); && (checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM, PID_UNKNOWN, uid, packageName) == PERMISSION_GRANTED); } boolean hasScheduleExactAlarmInternal(String packageName, int uid) { final long start = mStatLogger.getTime(); // 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. final boolean hasPermission; Loading @@ -2796,11 +2780,16 @@ public class AlarmManagerService extends SystemService { hasPermission = false; } else if (!isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) { hasPermission = false; } else if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) { hasPermission = (checkPermissionForPreflight(getContext(), Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN, uid, packageName) == PERMISSION_GRANTED); } else { // Compatibility permission check for older apps. final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid, packageName); if (mode == AppOpsManager.MODE_DEFAULT) { hasPermission = isScheduleExactAlarmAllowedByDefault(packageName, uid); hasPermission = !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); } else { hasPermission = (mode == AppOpsManager.MODE_ALLOWED); } Loading Loading @@ -4685,10 +4674,6 @@ public class AlarmManagerService extends SystemService { return service.new ClockReceiver(); } void registerContentObserver(ContentObserver contentObserver, Uri uri) { mContext.getContentResolver().registerContentObserver(uri, false, contentObserver); } void registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener) { DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ALARM_MANAGER, AppSchedulingModuleThread.getExecutor(), listener); Loading core/res/AndroidManifest.xml +2 −2 Original line number Diff line number Diff line Loading @@ -5303,12 +5303,12 @@ {@link android.Manifest.permission#USE_EXACT_ALARM} once it targets API {@link android.os.Build.VERSION_CODES#TIRAMISU}. All apps using exact alarms for secondary features (which should still be user facing) should continue using this permission. <p>Protection level: appop <p>Protection level: signature|privileged|appop --> <permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:label="@string/permlab_schedule_exact_alarm" android:description="@string/permdesc_schedule_exact_alarm" android:protectionLevel="normal|appop"/> android:protectionLevel="signature|privileged|appop"/> <!-- Allows apps to use exact alarms just like with {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM} but without needing to request this Loading data/etc/com.android.emergency.xml +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ <permission name="android.permission.CALL_PRIVILEGED"/> <permission name="android.permission.MANAGE_USERS"/> <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> <permission name="android.permission.SCHEDULE_EXACT_ALARM"/> <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/> <!-- Required to update emergency gesture settings --> <permission name="android.permission.WRITE_SECURE_SETTINGS"/> Loading data/etc/privapp-permissions-platform.xml +1 −0 Original line number Diff line number Diff line Loading @@ -321,6 +321,7 @@ applications that come with the platform <permission name="android.permission.REGISTER_CONNECTION_MANAGER"/> <permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/> <permission name="android.permission.RETRIEVE_WINDOW_CONTENT"/> <permission name="android.permission.SCHEDULE_EXACT_ALARM"/> <permission name="android.permission.SET_ALWAYS_FINISH"/> <permission name="android.permission.SET_ANIMATION_SCALE"/> <permission name="android.permission.SET_DEBUG_APP"/> Loading services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +164 −116 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java +34 −49 Original line number Diff line number Diff line Loading @@ -30,6 +30,9 @@ import static android.app.AlarmManager.INTERVAL_DAY; import static android.app.AlarmManager.INTERVAL_HOUR; import static android.app.AlarmManager.RTC; import static android.app.AlarmManager.RTC_WAKEUP; import static android.content.PermissionChecker.PERMISSION_GRANTED; import static android.content.PermissionChecker.PID_UNKNOWN; import static android.content.PermissionChecker.checkPermissionForPreflight; import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; import static android.os.PowerExemptionManager.REASON_ALARM_MANAGER_ALARM_CLOCK; import static android.os.PowerExemptionManager.REASON_DENIED; Loading Loading @@ -87,11 +90,9 @@ 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.content.pm.UserPackage; import android.database.ContentObserver; import android.net.Uri; import android.os.BatteryManager; import android.os.BatteryStatsInternal; Loading Loading @@ -182,7 +183,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Set; import java.util.TimeZone; Loading Loading @@ -269,7 +269,8 @@ public class AlarmManagerService extends SystemService { /** * A map from uid to the last op-mode we have seen for * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM} * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}. Used for evaluating permission state change * when the denylist changes. */ @VisibleForTesting @GuardedBy("mLock") Loading Loading @@ -2097,20 +2098,31 @@ public class AlarmManagerService extends SystemService { if (oldMode == newMode) { return; } final boolean allowedByDefault = isScheduleExactAlarmAllowedByDefault(packageName, uid); final boolean deniedByDefault = isScheduleExactAlarmDeniedByDefault( packageName, UserHandle.getUserId(uid)); final boolean hadPermission; if (oldMode != AppOpsManager.MODE_DEFAULT) { hadPermission = (oldMode == AppOpsManager.MODE_ALLOWED); } else { hadPermission = allowedByDefault; } final boolean hasPermission; if (newMode != AppOpsManager.MODE_DEFAULT) { hasPermission = (newMode == AppOpsManager.MODE_ALLOWED); if (deniedByDefault) { final boolean permissionState = getContext().checkPermission( Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN, uid) == PackageManager.PERMISSION_GRANTED; hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT) ? permissionState : (oldMode == AppOpsManager.MODE_ALLOWED); hasPermission = (newMode == AppOpsManager.MODE_DEFAULT) ? permissionState : (newMode == AppOpsManager.MODE_ALLOWED); } else { hasPermission = allowedByDefault; final boolean allowedByDefault = !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT) ? allowedByDefault : (oldMode == AppOpsManager.MODE_ALLOWED); hasPermission = (newMode == AppOpsManager.MODE_DEFAULT) ? allowedByDefault : (newMode == AppOpsManager.MODE_ALLOWED); } if (hadPermission && !hasPermission) { Loading Loading @@ -2754,41 +2766,13 @@ public class AlarmManagerService extends SystemService { boolean hasUseExactAlarmInternal(String packageName, int uid) { return isUseExactAlarmEnabled(packageName, UserHandle.getUserId(uid)) && (PermissionChecker.checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM, PermissionChecker.PID_UNKNOWN, uid, packageName) == PermissionChecker.PERMISSION_GRANTED); } /** * Returns whether SCHEDULE_EXACT_ALARM is allowed by default. */ boolean isScheduleExactAlarmAllowedByDefault(String packageName, int uid) { if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) { // This is essentially like changing the protection level of the permission to // (privileged|signature|role|appop), but have to implement this logic to maintain // compatibility for older apps. if (mPackageManagerInternal.isPlatformSigned(packageName) || mPackageManagerInternal.isUidPrivileged(uid)) { return true; } final long token = Binder.clearCallingIdentity(); try { final List<String> wellbeingHolders = (mRoleManager != null) ? mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING) : Collections.emptyList(); return wellbeingHolders.contains(packageName); } finally { Binder.restoreCallingIdentity(token); } } return !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); && (checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM, PID_UNKNOWN, uid, packageName) == PERMISSION_GRANTED); } boolean hasScheduleExactAlarmInternal(String packageName, int uid) { final long start = mStatLogger.getTime(); // 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. final boolean hasPermission; Loading @@ -2796,11 +2780,16 @@ public class AlarmManagerService extends SystemService { hasPermission = false; } else if (!isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) { hasPermission = false; } else if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) { hasPermission = (checkPermissionForPreflight(getContext(), Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN, uid, packageName) == PERMISSION_GRANTED); } else { // Compatibility permission check for older apps. final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid, packageName); if (mode == AppOpsManager.MODE_DEFAULT) { hasPermission = isScheduleExactAlarmAllowedByDefault(packageName, uid); hasPermission = !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName); } else { hasPermission = (mode == AppOpsManager.MODE_ALLOWED); } Loading Loading @@ -4685,10 +4674,6 @@ public class AlarmManagerService extends SystemService { return service.new ClockReceiver(); } void registerContentObserver(ContentObserver contentObserver, Uri uri) { mContext.getContentResolver().registerContentObserver(uri, false, contentObserver); } void registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener) { DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ALARM_MANAGER, AppSchedulingModuleThread.getExecutor(), listener); Loading
core/res/AndroidManifest.xml +2 −2 Original line number Diff line number Diff line Loading @@ -5303,12 +5303,12 @@ {@link android.Manifest.permission#USE_EXACT_ALARM} once it targets API {@link android.os.Build.VERSION_CODES#TIRAMISU}. All apps using exact alarms for secondary features (which should still be user facing) should continue using this permission. <p>Protection level: appop <p>Protection level: signature|privileged|appop --> <permission android:name="android.permission.SCHEDULE_EXACT_ALARM" android:label="@string/permlab_schedule_exact_alarm" android:description="@string/permdesc_schedule_exact_alarm" android:protectionLevel="normal|appop"/> android:protectionLevel="signature|privileged|appop"/> <!-- Allows apps to use exact alarms just like with {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM} but without needing to request this Loading
data/etc/com.android.emergency.xml +1 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ <permission name="android.permission.CALL_PRIVILEGED"/> <permission name="android.permission.MANAGE_USERS"/> <permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/> <permission name="android.permission.SCHEDULE_EXACT_ALARM"/> <permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/> <!-- Required to update emergency gesture settings --> <permission name="android.permission.WRITE_SECURE_SETTINGS"/> Loading
data/etc/privapp-permissions-platform.xml +1 −0 Original line number Diff line number Diff line Loading @@ -321,6 +321,7 @@ applications that come with the platform <permission name="android.permission.REGISTER_CONNECTION_MANAGER"/> <permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/> <permission name="android.permission.RETRIEVE_WINDOW_CONTENT"/> <permission name="android.permission.SCHEDULE_EXACT_ALARM"/> <permission name="android.permission.SET_ALWAYS_FINISH"/> <permission name="android.permission.SET_ANIMATION_SCALE"/> <permission name="android.permission.SET_DEBUG_APP"/> Loading
services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java +164 −116 File changed.Preview size limit exceeded, changes collapsed. Show changes