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

Commit e62a57a2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Allow-while-idle alarms throttling for app standby"

parents c4794edf d65e58a9
Loading
Loading
Loading
Loading
+31 −26
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ import java.util.TreeSet;
import java.util.function.Predicate;

import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE;
import static android.app.AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
import static android.app.AlarmManager.RTC_WAKEUP;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.ELAPSED_REALTIME_WAKEUP;
@@ -1011,7 +1012,7 @@ class AlarmManagerService extends SystemService {
            // Recurring alarms may have passed several alarm intervals while the
            // alarm was kept pending. Send the appropriate trigger count.
            if (alarm.repeatInterval > 0) {
                alarm.count += (nowELAPSED - alarm.requestedWhenElapsed) / alarm.repeatInterval;
                alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval;
                // Also schedule its next recurrence
                final long delta = alarm.count * alarm.repeatInterval;
                final long nextElapsed = alarm.whenElapsed + delta;
@@ -1507,25 +1508,20 @@ class AlarmManagerService extends SystemService {
     * Adjusts the alarm delivery time based on the current app standby bucket.
     * @param alarm The alarm to adjust
     * @return true if the alarm delivery time was updated.
     * TODO: Reduce the number of calls to getAppStandbyBucket by batching the calls per
     * {package, user} pairs
     */
    private boolean adjustDeliveryTimeBasedOnStandbyBucketLocked(Alarm alarm) {
        if (alarm.alarmClock != null || UserHandle.isCore(alarm.creatorUid)) {
            return false;
        }
        // TODO: short term fix for b/72816079, remove after a proper fix is in place
        if ((alarm.flags & AlarmManager.FLAG_ALLOW_WHILE_IDLE) != 0) {
        if (isExemptFromAppStandby(alarm)) {
            return false;
        }
        if (mAppStandbyParole) {
            if (alarm.whenElapsed > alarm.requestedWhenElapsed) {
            if (alarm.whenElapsed > alarm.expectedWhenElapsed) {
                // We did defer this alarm earlier, restore original requirements
                alarm.whenElapsed = alarm.requestedWhenElapsed;
                alarm.maxWhenElapsed = alarm.requestedMaxWhenElapsed;
            }
                alarm.whenElapsed = alarm.expectedWhenElapsed;
                alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed;
                return true;
            }
            return false;
        }
        final long oldWhenElapsed = alarm.whenElapsed;
        final long oldMaxWhenElapsed = alarm.maxWhenElapsed;

@@ -1538,13 +1534,13 @@ class AlarmManagerService extends SystemService {
        final long lastElapsed = mLastAlarmDeliveredForPackage.getOrDefault(packageUser, 0L);
        if (lastElapsed > 0) {
            final long minElapsed = lastElapsed + getMinDelayForBucketLocked(standbyBucket);
            if (alarm.requestedWhenElapsed < minElapsed) {
            if (alarm.expectedWhenElapsed < minElapsed) {
                alarm.whenElapsed = alarm.maxWhenElapsed = minElapsed;
            } else {
                // app is now eligible to run alarms at the originally requested window.
                // Restore original requirements in case they were changed earlier.
                alarm.whenElapsed = alarm.requestedWhenElapsed;
                alarm.maxWhenElapsed = alarm.requestedMaxWhenElapsed;
                alarm.whenElapsed = alarm.expectedWhenElapsed;
                alarm.maxWhenElapsed = alarm.expectedMaxWhenElapsed;
            }
        }
        return (oldWhenElapsed != alarm.whenElapsed || oldMaxWhenElapsed != alarm.maxWhenElapsed);
@@ -1728,7 +1724,7 @@ class AlarmManagerService extends SystemService {
            // This means we will allow these alarms to go off as normal even while idle, with no
            // timing restrictions.
            } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID
                    || callingUid == mSystemUiUid
                    || UserHandle.isSameApp(callingUid, mSystemUiUid)
                    || mForceAppStandbyTracker.isUidPowerSaveWhitelisted(callingUid))) {
                flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED;
                flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE;
@@ -3000,10 +2996,11 @@ class AlarmManagerService extends SystemService {
                        // Whoops, it hasn't been long enough since the last ALLOW_WHILE_IDLE
                        // alarm went off for this app.  Reschedule the alarm to be in the
                        // correct time period.
                        alarm.whenElapsed = minTime;
                        alarm.expectedWhenElapsed = alarm.whenElapsed = minTime;
                        if (alarm.maxWhenElapsed < minTime) {
                            alarm.maxWhenElapsed = minTime;
                        }
                        alarm.expectedMaxWhenElapsed = alarm.maxWhenElapsed;
                        if (RECORD_DEVICE_IDLE_ALARMS) {
                            IdleDispatchEntry ent = new IdleDispatchEntry();
                            ent.uid = alarm.uid;
@@ -3053,7 +3050,7 @@ class AlarmManagerService extends SystemService {
                if (alarm.repeatInterval > 0) {
                    // this adjustment will be zero if we're late by
                    // less than one full repeat interval
                    alarm.count += (nowELAPSED - alarm.requestedWhenElapsed) / alarm.repeatInterval;
                    alarm.count += (nowELAPSED - alarm.expectedWhenElapsed) / alarm.repeatInterval;

                    // Also schedule its next recurrence
                    final long delta = alarm.count * alarm.repeatInterval;
@@ -3128,8 +3125,9 @@ class AlarmManagerService extends SystemService {
        public long windowLength;
        public long whenElapsed;    // 'when' in the elapsed time base
        public long maxWhenElapsed; // also in the elapsed time base
        public final long requestedWhenElapsed; // original expiry time requested by the app
        public final long requestedMaxWhenElapsed;
        // Expected alarm expiry time before app standby deferring is applied.
        public long expectedWhenElapsed;
        public long expectedMaxWhenElapsed;
        public long repeatInterval;
        public PriorityClass priorityClass;

@@ -3143,10 +3141,10 @@ class AlarmManagerService extends SystemService {
                    || _type == AlarmManager.RTC_WAKEUP;
            when = _when;
            whenElapsed = _whenElapsed;
            requestedWhenElapsed = _whenElapsed;
            expectedWhenElapsed = _whenElapsed;
            windowLength = _windowLength;
            maxWhenElapsed = _maxWhen;
            requestedMaxWhenElapsed = _maxWhen;
            expectedMaxWhenElapsed = _maxWhen;
            repeatInterval = _interval;
            operation = _op;
            listener = _rec;
@@ -3205,8 +3203,10 @@ class AlarmManagerService extends SystemService {
            final boolean isRtc = (type == RTC || type == RTC_WAKEUP);
            pw.print(prefix); pw.print("tag="); pw.println(statsTag);
            pw.print(prefix); pw.print("type="); pw.print(type);
                    pw.print(" requestedWhenElapsed="); TimeUtils.formatDuration(
                            requestedWhenElapsed, nowELAPSED, pw);
                    pw.print(" expectedWhenElapsed="); TimeUtils.formatDuration(
                    expectedWhenElapsed, nowELAPSED, pw);
                    pw.print(" expectedMaxWhenElapsed="); TimeUtils.formatDuration(
                    expectedMaxWhenElapsed, nowELAPSED, pw);
                    pw.print(" whenElapsed="); TimeUtils.formatDuration(whenElapsed,
                            nowELAPSED, pw);
                    pw.print(" when=");
@@ -3344,6 +3344,11 @@ class AlarmManagerService extends SystemService {
        }
    }

    private boolean isExemptFromAppStandby(Alarm a) {
        return a.alarmClock != null || UserHandle.isCore(a.creatorUid)
                || (a.flags & FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED) != 0;
    }

    private class AlarmThread extends Thread
    {
        public AlarmThread()
@@ -3462,7 +3467,7 @@ class AlarmManagerService extends SystemService {
                                    new ArraySet<>();
                            for (int i = 0; i < triggerList.size(); i++) {
                                final Alarm a = triggerList.get(i);
                                if (!UserHandle.isCore(a.creatorUid)) {
                                if (!isExemptFromAppStandby(a)) {
                                    triggerPackages.add(Pair.create(
                                            a.sourcePackage, UserHandle.getUserId(a.creatorUid)));
                                }
@@ -4148,7 +4153,7 @@ class AlarmManagerService extends SystemService {
                    mAllowWhileIdleDispatches.add(ent);
                }
            }
            if (!UserHandle.isCore(alarm.creatorUid)) {
            if (!isExemptFromAppStandby(alarm)) {
                final Pair<String, Integer> packageUser = Pair.create(alarm.sourcePackage,
                        UserHandle.getUserId(alarm.creatorUid));
                mLastAlarmDeliveredForPackage.put(packageUser, nowELAPSED);