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

Commit f769c48c authored by Suprabh Shukla's avatar Suprabh Shukla
Browse files

Disabling exact alarm permission enforcement

Disabling the CompatChange id for changing the default behavior of
SCHEDULE_EXACT_ALARM.
Removing the corresponding device_config flag as it doesn't matter with
the change id disabled.
Rest of the underlying code is kept in a working state to be testable.

Test: atest CtsAlarmManagerTestCases
atest FrameworksMockingServicesTests:AlarmManagerServiceTest

Bug: 226439802
Bug: 231661074
Change-Id: Ifff8f8ad4721868d33b7b8e201bc1411e3a7cab2
parent abeb3828
Loading
Loading
Loading
Loading
+5 −6
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.Disabled;
import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
@@ -282,15 +282,14 @@ public class AlarmManager {
    public static final long ENABLE_USE_EXACT_ALARM = 218533173L;

    /**
     * For apps targeting {@link Build.VERSION_CODES#TIRAMISU} or above, the permission
     * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} will be denied, unless the user explicitly
     * allows it from Settings.
     * The permission {@link Manifest.permission#SCHEDULE_EXACT_ALARM} will be denied, unless the
     * user explicitly allows it from Settings.
     *
     * TODO (b/226439802): change to EnabledSince(T) after SDK finalization.
     * TODO (b/226439802): Either enable it in the next SDK or replace it with a better alternative.
     * @hide
     */
    @ChangeId
    @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.S_V2)
    @Disabled
    public static final long SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = 226439802L;

    @UnsupportedAppUsage
+2 −65
Original line number Diff line number Diff line
@@ -565,9 +565,6 @@ public class AlarmManagerService extends SystemService {
        @VisibleForTesting
        static final String KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED =
                "kill_on_schedule_exact_alarm_revoked";
        @VisibleForTesting
        static final String KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT =
                "schedule_exact_alarm_denied_by_default";

        private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
        private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
@@ -612,8 +609,6 @@ public class AlarmManagerService extends SystemService {

        private static final boolean DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED = true;

        private static final boolean DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = true;

        // Minimum futurity of a new alarm
        public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;

@@ -701,14 +696,6 @@ public class AlarmManagerService extends SystemService {
        public boolean KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED =
                DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED;

        /**
         * When this is {@code true}, apps with the change
         * {@link AlarmManager#SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT} enabled will not get
         * {@link Manifest.permission#SCHEDULE_EXACT_ALARM} unless the user grants it to them.
         */
        public volatile boolean SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT =
                DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT;

        public boolean USE_TARE_POLICY = Settings.Global.DEFAULT_ENABLE_TARE == 1;

        private long mLastAllowWhileIdleWhitelistDuration = -1;
@@ -892,15 +879,6 @@ public class AlarmManagerService extends SystemService {
                                    KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED,
                                    DEFAULT_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED);
                            break;
                        case KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT:
                            final boolean oldValue = SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT;

                            SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = properties.getBoolean(
                                    KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT,
                                    DEFAULT_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT);
                            handleScheduleExactAlarmDeniedByDefaultChange(oldValue,
                                    SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT);
                            break;
                        default:
                            if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
                                // The quotas need to be updated in order, so we can't just rely
@@ -971,15 +949,6 @@ public class AlarmManagerService extends SystemService {
            }
        }

        private void handleScheduleExactAlarmDeniedByDefaultChange(boolean oldValue,
                boolean newValue) {
            if (oldValue == newValue) {
                return;
            }
            mHandler.obtainMessage(AlarmHandler.CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE,
                    newValue).sendToTarget();
        }

        private void migrateAlarmsToNewStoreLocked() {
            final AlarmStore newStore = LAZY_BATCHING ? new LazyAlarmStore()
                    : new BatchingAlarmStore();
@@ -1156,9 +1125,6 @@ public class AlarmManagerService extends SystemService {
            pw.print(KEY_KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED,
                    KILL_ON_SCHEDULE_EXACT_ALARM_REVOKED);
            pw.println();
            pw.print(KEY_SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT,
                    SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT);
            pw.println();

            pw.print(Settings.Global.ENABLE_TARE, USE_TARE_POLICY);
            pw.println();
@@ -2928,10 +2894,8 @@ public class AlarmManagerService extends SystemService {
    }

    private boolean isScheduleExactAlarmDeniedByDefault(String packageName, int userId) {
        return mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT
                && CompatChanges.isChangeEnabled(
                AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, packageName,
                UserHandle.of(userId));
        return CompatChanges.isChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT,
                packageName, UserHandle.of(userId));
    }

    @NeverCompile // Avoid size overhead of debugging code.
@@ -4707,7 +4671,6 @@ public class AlarmManagerService extends SystemService {
        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;
        public static final int CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE = 14;

        AlarmHandler() {
            super(Looper.myLooper());
@@ -4827,32 +4790,6 @@ public class AlarmManagerService extends SystemService {
                        removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */false);
                    }
                    break;
                case CHECK_EXACT_ALARM_PERMISSION_ON_FEATURE_TOGGLE:
                    final boolean defaultDenied = (Boolean) msg.obj;

                    final int[] startedUserIds = mActivityManagerInternal.getStartedUserIds();
                    for (int appId : mExactAlarmCandidates) {
                        for (int userId : startedUserIds) {
                            uid = UserHandle.getUid(userId, appId);

                            final AndroidPackage packageForUid =
                                    mPackageManagerInternal.getPackage(uid);
                            if (packageForUid == null) {
                                continue;
                            }
                            final String pkg = packageForUid.getPackageName();
                            if (defaultDenied) {
                                if (!hasScheduleExactAlarmInternal(pkg, uid)
                                        && !hasUseExactAlarmInternal(pkg, uid)) {
                                    removeExactAlarmsOnPermissionRevoked(uid, pkg, true);
                                }
                            } else if (hasScheduleExactAlarmInternal(pkg, uid)) {
                                sendScheduleExactAlarmPermissionStateChangedBroadcast(pkg,
                                        UserHandle.getUserId(uid));
                            }
                        }
                    }
                    break;
                default:
                    // nope, just ignore it
                    break;
+1 −16
Original line number Diff line number Diff line
@@ -3220,34 +3220,19 @@ public class AlarmManagerServiceTest {
        when(mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING)).thenReturn(
                Arrays.asList(package4));

        mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
        mService.mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = false;
        mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] {
                package1,
                package3,
        });

        // Deny listed packages will be false.
        assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1));
        assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2));
        assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3));
        assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4));

        mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false);
        mService.mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = true;
        mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] {
                package1,
                package3,
        });

        // Same as above, deny listed packages will be false.
        // Deny listed packages will be false.
        assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1));
        assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2));
        assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3));
        assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4));

        mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
        mService.mConstants.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT = true;
        mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[] {
                package1,
                package3,