Merge "Exempt exact alarms using listener from permission"
This commit is contained in:
committed by
Android (Google) Code Review
commit
30268bd5df
@@ -800,22 +800,12 @@ public class AlarmManager {
|
||||
* if {@code null} is passed as the {@code targetHandler} parameter.
|
||||
*
|
||||
* <p class="note"><strong>Note:</strong>
|
||||
* Starting with {@link Build.VERSION_CODES#S}, apps targeting SDK level 31 or higher
|
||||
* need to request the
|
||||
* {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use this
|
||||
* API, unless the app is exempt from battery restrictions.
|
||||
* The user and the system can revoke this permission via the special app access screen in
|
||||
* Settings.
|
||||
* On previous android versions {@link Build.VERSION_CODES#S} and
|
||||
* {@link Build.VERSION_CODES#TIRAMISU}, apps targeting SDK level 31 or higher needed to hold
|
||||
* the {@link Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM} permission to use
|
||||
* this API, unless the app was exempt from battery restrictions.
|
||||
*
|
||||
* <p class="note"><strong>Note:</strong>
|
||||
* Exact alarms should only be used for user-facing features.
|
||||
* For more details, see <a
|
||||
* href="{@docRoot}about/versions/12/behavior-changes-12#exact-alarm-permission">
|
||||
* Exact alarm permission</a>.
|
||||
*
|
||||
* @see Manifest.permission#SCHEDULE_EXACT_ALARM SCHEDULE_EXACT_ALARM
|
||||
*/
|
||||
@RequiresPermission(value = Manifest.permission.SCHEDULE_EXACT_ALARM, conditional = true)
|
||||
public void setExact(@AlarmType int type, long triggerAtMillis, @Nullable String tag,
|
||||
@NonNull OnAlarmListener listener, @Nullable Handler targetHandler) {
|
||||
setImpl(type, triggerAtMillis, WINDOW_EXACT, 0, 0, null, listener, tag,
|
||||
@@ -949,7 +939,8 @@ public class AlarmManager {
|
||||
* {@link #setExact(int, long, String, OnAlarmListener, Handler)} instead.
|
||||
*
|
||||
* <p>
|
||||
* Note that using this API requires you to hold
|
||||
* Note that on previous Android versions {@link Build.VERSION_CODES#S} and
|
||||
* {@link Build.VERSION_CODES#TIRAMISU}, using this API required you to hold
|
||||
* {@link Manifest.permission#SCHEDULE_EXACT_ALARM}, unless you are on the system's power
|
||||
* allowlist. This can be set, for example, by marking the app as {@code <allow-in-power-save>}
|
||||
* within the system config.
|
||||
@@ -970,9 +961,7 @@ public class AlarmManager {
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(allOf = {
|
||||
Manifest.permission.UPDATE_DEVICE_STATS,
|
||||
Manifest.permission.SCHEDULE_EXACT_ALARM}, conditional = true)
|
||||
@RequiresPermission(Manifest.permission.UPDATE_DEVICE_STATS)
|
||||
public void setExact(@AlarmType int type, long triggerAtMillis, @Nullable String tag,
|
||||
@NonNull Executor executor, @NonNull WorkSource workSource,
|
||||
@NonNull OnAlarmListener listener) {
|
||||
@@ -1283,9 +1272,7 @@ public class AlarmManager {
|
||||
* @hide
|
||||
*/
|
||||
@SystemApi
|
||||
@RequiresPermission(allOf = {
|
||||
Manifest.permission.UPDATE_DEVICE_STATS,
|
||||
Manifest.permission.SCHEDULE_EXACT_ALARM}, conditional = true)
|
||||
@RequiresPermission(Manifest.permission.UPDATE_DEVICE_STATS)
|
||||
public void setExactAndAllowWhileIdle(@AlarmType int type, long triggerAtMillis,
|
||||
@Nullable String tag, @NonNull Executor executor, @Nullable WorkSource workSource,
|
||||
@NonNull OnAlarmListener listener) {
|
||||
|
||||
@@ -92,6 +92,14 @@ class Alarm {
|
||||
* Caller had USE_EXACT_ALARM permission.
|
||||
*/
|
||||
static final int EXACT_ALLOW_REASON_POLICY_PERMISSION = 3;
|
||||
/**
|
||||
* Caller used a listener alarm, which does not need permission to be exact.
|
||||
*/
|
||||
static final int EXACT_ALLOW_REASON_LISTENER = 4;
|
||||
/**
|
||||
* Caller used a prioritized alarm, which does not need permission to be exact.
|
||||
*/
|
||||
static final int EXACT_ALLOW_REASON_PRIORITIZED = 5;
|
||||
|
||||
public final int type;
|
||||
/**
|
||||
|
||||
@@ -47,9 +47,11 @@ import static com.android.server.alarm.Alarm.BATTERY_SAVER_POLICY_INDEX;
|
||||
import static com.android.server.alarm.Alarm.DEVICE_IDLE_POLICY_INDEX;
|
||||
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_ALLOW_LIST;
|
||||
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_COMPAT;
|
||||
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_LISTENER;
|
||||
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_NOT_APPLICABLE;
|
||||
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PERMISSION;
|
||||
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_POLICY_PERMISSION;
|
||||
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PRIORITIZED;
|
||||
import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX;
|
||||
import static com.android.server.alarm.Alarm.TARE_POLICY_INDEX;
|
||||
import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_ALARM_CANCELLED;
|
||||
@@ -2890,12 +2892,23 @@ public class AlarmManagerService extends SystemService {
|
||||
// The API doesn't allow using both together.
|
||||
flags &= ~FLAG_ALLOW_WHILE_IDLE;
|
||||
// Prioritized alarms don't need any extra permission to be exact.
|
||||
if (exact) {
|
||||
exactAllowReason = EXACT_ALLOW_REASON_PRIORITIZED;
|
||||
}
|
||||
} else if (exact || allowWhileIdle) {
|
||||
final boolean needsPermission;
|
||||
boolean lowerQuota;
|
||||
if (isExactAlarmChangeEnabled(callingPackage, callingUserId)) {
|
||||
needsPermission = exact;
|
||||
lowerQuota = !exact;
|
||||
if (directReceiver == null) {
|
||||
needsPermission = exact;
|
||||
lowerQuota = !exact;
|
||||
} else {
|
||||
needsPermission = false;
|
||||
lowerQuota = allowWhileIdle;
|
||||
if (exact) {
|
||||
exactAllowReason = EXACT_ALLOW_REASON_LISTENER;
|
||||
}
|
||||
}
|
||||
if (exact) {
|
||||
idleOptions = (alarmClock != null) ? mOptsWithFgsForAlarmClock.toBundle()
|
||||
: mOptsWithFgs.toBundle();
|
||||
@@ -2931,11 +2944,9 @@ public class AlarmManagerService extends SystemService {
|
||||
throw new SecurityException(errorMessage);
|
||||
}
|
||||
// If the app is on the full system power allow-list (not except-idle),
|
||||
// or the user-elected allow-list, or we're in a soft failure mode, we still
|
||||
// allow the alarms.
|
||||
// In both cases, ALLOW_WHILE_IDLE alarms get a lower quota equivalent to
|
||||
// what pre-S apps got. Note that user-allow-listed apps don't use the flag
|
||||
// ALLOW_WHILE_IDLE.
|
||||
// or the user-elected allow-list, we allow exact alarms.
|
||||
// ALLOW_WHILE_IDLE alarms get a lower quota equivalent to what pre-S apps
|
||||
// got. Note that user-allow-listed apps don't use FLAG_ALLOW_WHILE_IDLE.
|
||||
// We grant temporary allow-list to allow-while-idle alarms but without FGS
|
||||
// capability. AlarmClock alarms do not get the temporary allow-list.
|
||||
// This is consistent with pre-S behavior. Note that apps that are in
|
||||
|
||||
@@ -18,9 +18,11 @@ package com.android.server.alarm;
|
||||
|
||||
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__ALLOW_LIST;
|
||||
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__CHANGE_DISABLED;
|
||||
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__LISTENER;
|
||||
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__NOT_APPLICABLE;
|
||||
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__PERMISSION;
|
||||
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__POLICY_PERMISSION;
|
||||
import static com.android.internal.util.FrameworkStatsLog.ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__PRIORITIZED;
|
||||
import static com.android.server.alarm.AlarmManagerService.INDEFINITE_DELAY;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
@@ -84,14 +86,18 @@ class MetricsHelper {
|
||||
|
||||
private static int reasonToStatsReason(int reasonCode) {
|
||||
switch (reasonCode) {
|
||||
case Alarm.EXACT_ALLOW_REASON_ALLOW_LIST:
|
||||
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__ALLOW_LIST;
|
||||
case Alarm.EXACT_ALLOW_REASON_PERMISSION:
|
||||
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__PERMISSION;
|
||||
case Alarm.EXACT_ALLOW_REASON_ALLOW_LIST:
|
||||
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__ALLOW_LIST;
|
||||
case Alarm.EXACT_ALLOW_REASON_COMPAT:
|
||||
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__CHANGE_DISABLED;
|
||||
case Alarm.EXACT_ALLOW_REASON_POLICY_PERMISSION:
|
||||
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__POLICY_PERMISSION;
|
||||
case Alarm.EXACT_ALLOW_REASON_LISTENER:
|
||||
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__LISTENER;
|
||||
case Alarm.EXACT_ALLOW_REASON_PRIORITIZED:
|
||||
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__PRIORITIZED;
|
||||
default:
|
||||
return ALARM_SCHEDULED__EXACT_ALARM_ALLOWED_REASON__NOT_APPLICABLE;
|
||||
}
|
||||
|
||||
@@ -4678,7 +4678,7 @@ package android.app {
|
||||
method @RequiresPermission(android.Manifest.permission.SCHEDULE_EXACT_ALARM) public void setAlarmClock(@NonNull android.app.AlarmManager.AlarmClockInfo, @NonNull android.app.PendingIntent);
|
||||
method public void setAndAllowWhileIdle(int, long, @NonNull android.app.PendingIntent);
|
||||
method @RequiresPermission(value=android.Manifest.permission.SCHEDULE_EXACT_ALARM, conditional=true) public void setExact(int, long, @NonNull android.app.PendingIntent);
|
||||
method @RequiresPermission(value=android.Manifest.permission.SCHEDULE_EXACT_ALARM, conditional=true) public void setExact(int, long, @Nullable String, @NonNull android.app.AlarmManager.OnAlarmListener, @Nullable android.os.Handler);
|
||||
method public void setExact(int, long, @Nullable String, @NonNull android.app.AlarmManager.OnAlarmListener, @Nullable android.os.Handler);
|
||||
method @RequiresPermission(value=android.Manifest.permission.SCHEDULE_EXACT_ALARM, conditional=true) public void setExactAndAllowWhileIdle(int, long, @NonNull android.app.PendingIntent);
|
||||
method public void setInexactRepeating(int, long, long, @NonNull android.app.PendingIntent);
|
||||
method public void setRepeating(int, long, long, @NonNull android.app.PendingIntent);
|
||||
|
||||
@@ -542,8 +542,8 @@ package android.app {
|
||||
public class AlarmManager {
|
||||
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, @NonNull android.app.PendingIntent, @Nullable android.os.WorkSource);
|
||||
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void set(int, long, long, long, @NonNull android.app.AlarmManager.OnAlarmListener, @Nullable android.os.Handler, @Nullable android.os.WorkSource);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.UPDATE_DEVICE_STATS, android.Manifest.permission.SCHEDULE_EXACT_ALARM}, conditional=true) public void setExact(int, long, @Nullable String, @NonNull java.util.concurrent.Executor, @NonNull android.os.WorkSource, @NonNull android.app.AlarmManager.OnAlarmListener);
|
||||
method @RequiresPermission(allOf={android.Manifest.permission.UPDATE_DEVICE_STATS, android.Manifest.permission.SCHEDULE_EXACT_ALARM}, conditional=true) public void setExactAndAllowWhileIdle(int, long, @Nullable String, @NonNull java.util.concurrent.Executor, @Nullable android.os.WorkSource, @NonNull android.app.AlarmManager.OnAlarmListener);
|
||||
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void setExact(int, long, @Nullable String, @NonNull java.util.concurrent.Executor, @NonNull android.os.WorkSource, @NonNull android.app.AlarmManager.OnAlarmListener);
|
||||
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void setExactAndAllowWhileIdle(int, long, @Nullable String, @NonNull java.util.concurrent.Executor, @Nullable android.os.WorkSource, @NonNull android.app.AlarmManager.OnAlarmListener);
|
||||
method @RequiresPermission(android.Manifest.permission.SCHEDULE_PRIORITIZED_ALARM) public void setPrioritized(int, long, long, @Nullable String, @NonNull java.util.concurrent.Executor, @NonNull android.app.AlarmManager.OnAlarmListener);
|
||||
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public void setWindow(int, long, long, @Nullable String, @NonNull java.util.concurrent.Executor, @Nullable android.os.WorkSource, @NonNull android.app.AlarmManager.OnAlarmListener);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user