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

Commit 0c61e6f6 authored by Makoto Onuki's avatar Makoto Onuki Committed by Automerger Merge Worker
Browse files

Merge "Send a broadcast when an app is granted SCHEDULE_EXACT_ALARM" into sc-dev am: 26f28d4a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14457624

Change-Id: I34bb8ce56dd1d2299ea1e8247707aa182617a82a
parents d333c921 26f28d4a
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
@@ -138,6 +139,36 @@ public class AlarmManager {
    public static final String ACTION_NEXT_ALARM_CLOCK_CHANGED =
            "android.app.action.NEXT_ALARM_CLOCK_CHANGED";

    /**
     * Broadcast Action: An app is granted the
     * {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM} permission.
     *
     * <p>When the user revokes the {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM}
     * permission, all alarms scheduled with
     * {@link #setExact}, {@link #setExactAndAllowWhileIdle} and
     * {@link #setAlarmClock(AlarmClockInfo, PendingIntent)} will be deleted.
     *
     * <p>When the user grants the {@link android.Manifest.permission#SCHEDULE_EXACT_ALARM},
     * this broadcast will be sent. Applications can reschedule all the necessary alarms when
     * receiving it.
     *
     * <p><em>Note:</em>
     * Applications are still required to check {@link #canScheduleExactAlarms()}
     * before using the above APIs after receiving this broadcast,
     * because it's possible that the permission is already revoked again by the time
     * applications receive this broadcast.
     *
     * <p>This broadcast will be sent to both runtime receivers and manifest receivers.
     *
     * <p>This broadcast is sent as a foreground broadcast.
     * See {@link android.content.Intent#FLAG_RECEIVER_FOREGROUND}.
     *
     * <p>When an application receives this broadcast, it's allowed to start a foreground service.
     */
    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
    public static final String ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED =
            "android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED";

    /** @hide */
    @UnsupportedAppUsage
    public static final long WINDOW_EXACT = 0;
+9 −0
Original line number Diff line number Diff line
@@ -251,6 +251,12 @@ public class PowerExemptionManager {
     * @hide
     */
    public static final int REASON_LOCALE_CHANGED = 206;
    /**
     * Broadcast
     * {@link android.app.AlarmManager#ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED}
     * @hide
     */
    public static final int REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED = 207;
    /* Reason code range 300-399 are reserved for other internal reasons */
    /**
     * Device idle system allow list, including EXCEPT-IDLE
@@ -386,6 +392,7 @@ public class PowerExemptionManager {
            REASON_TIMEZONE_CHANGED,
            REASON_TIME_CHANGED,
            REASON_LOCALE_CHANGED,
            REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED,
            REASON_SYSTEM_ALLOW_LISTED,
            REASON_ALARM_MANAGER_ALARM_CLOCK,
            REASON_ALARM_MANAGER_WHILE_IDLE,
@@ -664,6 +671,8 @@ public class PowerExemptionManager {
                return "TIME_CHANGED";
            case REASON_LOCALE_CHANGED:
                return "LOCALE_CHANGED";
            case REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED:
                return "REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED";
            case REASON_SYSTEM_ALLOW_LISTED:
                return "SYSTEM_ALLOW_LISTED";
            case REASON_ALARM_MANAGER_ALARM_CLOCK:
+30 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import static android.app.AlarmManager.INTERVAL_HOUR;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.RTC_WAKEUP;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.os.PowerExemptionManager.REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.PowerWhitelistManager.REASON_ALARM_MANAGER_WHILE_IDLE;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
@@ -1704,6 +1705,11 @@ public class AlarmManagerService extends SystemService {
                                if (!hasScheduleExactAlarmInternal(packageName, uid)) {
                                    mHandler.obtainMessage(AlarmHandler.REMOVE_EXACT_ALARMS,
                                            uid, 0, packageName).sendToTarget();
                                } else {
                                    // TODO(b/187206399) Make sure this won't be sent, if the app
                                    // already had the appop previously.
                                    sendScheduleExactAlarmPermissionStateChangedBroadcast(
                                            packageName, UserHandle.getUserId(uid));
                                }
                            }
                        });
@@ -4816,6 +4822,30 @@ public class AlarmManagerService extends SystemService {
        }
    }

    /**
     * Send {@link AlarmManager#ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED} to
     * the app that is just granted the permission.
     */
    private void sendScheduleExactAlarmPermissionStateChangedBroadcast(
            String packageName, int userId) {
        final Intent i = new Intent(
                AlarmManager.ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED);
        i.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING
                | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                | Intent.FLAG_RECEIVER_FOREGROUND);
        i.setPackage(packageName);

        // We need to allow the app to start a foreground service.
        // This broadcast is very rare, so we do not cache the BroadcastOptions.
        final BroadcastOptions opts = BroadcastOptions.makeBasic();
        opts.setTemporaryAppAllowlist(
                mActivityManagerInternal.getBootTimeTempAllowListDuration(),
                TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED,
                REASON_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED, "");
        getContext().sendBroadcastAsUser(i, UserHandle.of(userId), /*permission*/ null,
                opts.toBundle());
    }

    private void decrementAlarmCount(int uid, int decrement) {
        int oldCount = 0;
        final int uidIndex = mAlarmsPerUid.indexOfKey(uid);
+1 −0
Original line number Diff line number Diff line
@@ -4404,6 +4404,7 @@ package android.app {
    method public void setWindow(int, long, long, android.app.PendingIntent);
    method public void setWindow(int, long, long, String, android.app.AlarmManager.OnAlarmListener, android.os.Handler);
    field public static final String ACTION_NEXT_ALARM_CLOCK_CHANGED = "android.app.action.NEXT_ALARM_CLOCK_CHANGED";
    field public static final String ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED = "android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED";
    field public static final int ELAPSED_REALTIME = 3; // 0x3
    field public static final int ELAPSED_REALTIME_WAKEUP = 2; // 0x2
    field public static final long INTERVAL_DAY = 86400000L; // 0x5265c00L
+2 −0
Original line number Diff line number Diff line
@@ -696,6 +696,8 @@
    <protected-broadcast android:name="android.scheduling.action.REBOOT_READY" />
    <protected-broadcast android:name="android.app.action.DEVICE_POLICY_CONSTANTS_CHANGED" />

    <protected-broadcast android:name="android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED" />

    <!-- ====================================================================== -->
    <!--                          RUNTIME PERMISSIONS                           -->
    <!-- ====================================================================== -->
Loading