Loading services/core/java/com/android/server/AlarmManagerService.java +31 −26 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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="); Loading Loading @@ -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() Loading Loading @@ -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))); } Loading Loading @@ -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); Loading Loading
services/core/java/com/android/server/AlarmManagerService.java +31 −26 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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); Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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="); Loading Loading @@ -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() Loading Loading @@ -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))); } Loading Loading @@ -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); Loading