Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30268bd5 authored by Suprabh Shukla's avatar Suprabh Shukla Committed by Android (Google) Code Review
Browse files

Merge "Exempt exact alarms using listener from permission"

parents 674ab8a7 51ec8010
Loading
Loading
Loading
Loading
+8 −21
Original line number Diff line number Diff line
@@ -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.
     *
     * <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>.
     * 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.
     *
     * @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) {
+8 −0
Original line number Diff line number Diff line
@@ -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;
    /**
+18 −7
Original line number Diff line number Diff line
@@ -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)) {
                    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
+8 −2
Original line number Diff line number Diff line
@@ -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;
        }
+1 −1
Original line number Diff line number Diff line
@@ -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);
Loading