Loading services/core/java/com/android/server/am/ActivityManagerConstants.java +31 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_NETWORK_ACCESS_TIMEOUT_MS = "network_access_timeout_ms"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final boolean DEFAULT_PRIORITIZE_ALARM_BROADCASTS = true; private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000; private static final long DEFAULT_FGSERVICE_MIN_REPORT_TIME = 3*1000; private static final long DEFAULT_FGSERVICE_SCREEN_ON_BEFORE_TIME = 1*1000; Loading Loading @@ -325,6 +326,14 @@ final class ActivityManagerConstants extends ContentObserver { */ private static final String KEY_PROCESS_KILL_TIMEOUT = "process_kill_timeout"; /** * {@code true} to send in-flight alarm broadcasts ahead of non-alarms; {@code false} * to queue alarm broadcasts identically to non-alarms [i.e. the pre-U behavior]; or * {@code null} or empty string in order to fall back to whatever the build-time default * was for the device. */ private static final String KEY_PRIORITIZE_ALARM_BROADCASTS = "prioritize_alarm_broadcasts"; private static final String KEY_DEFER_BOOT_COMPLETED_BROADCAST = "defer_boot_completed_broadcast"; Loading Loading @@ -666,6 +675,12 @@ final class ActivityManagerConstants extends ContentObserver { volatile @BroadcastConstants.DeferBootCompletedBroadcastType int mDeferBootCompletedBroadcast = DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST; /** * Whether alarm broadcasts are delivered immediately, or queued along with the rest * of the pending ordered broadcasts. */ volatile boolean mPrioritizeAlarmBroadcasts = DEFAULT_PRIORITIZE_ALARM_BROADCASTS; /** * How long the Context.startForegroundService() grace period is to get around to * calling Service.startForeground() before we generate ANR. Loading Loading @@ -977,6 +992,9 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_PROCESS_KILL_TIMEOUT: updateProcessKillTimeout(); break; case KEY_PRIORITIZE_ALARM_BROADCASTS: updatePrioritizeAlarmBroadcasts(); break; case KEY_DEFER_BOOT_COMPLETED_BROADCAST: updateDeferBootCompletedBroadcast(); break; Loading Loading @@ -1446,6 +1464,17 @@ final class ActivityManagerConstants extends ContentObserver { } } private void updatePrioritizeAlarmBroadcasts() { // Flag value can be something that evaluates to `true` or `false`, // or empty/null. If it's empty/null, the platform default is used. final String flag = DeviceConfig.getString( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_PRIORITIZE_ALARM_BROADCASTS, ""); mPrioritizeAlarmBroadcasts = TextUtils.isEmpty(flag) ? DEFAULT_PRIORITIZE_ALARM_BROADCASTS : Boolean.parseBoolean(flag); } private void updateDeferBootCompletedBroadcast() { mDeferBootCompletedBroadcast = DeviceConfig.getInt( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, Loading Loading @@ -1786,6 +1815,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.print("="); pw.println(mComponentAliasOverrides); pw.print(" "); pw.print(KEY_DEFER_BOOT_COMPLETED_BROADCAST); pw.print("="); pw.println(mDeferBootCompletedBroadcast); pw.print(" "); pw.print(KEY_PRIORITIZE_ALARM_BROADCASTS); pw.print("="); pw.println(mPrioritizeAlarmBroadcasts); pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED); pw.print("="); pw.println(mNoKillCachedProcessesUntilBootCompleted); pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS); Loading services/core/java/com/android/server/am/BroadcastDispatcher.java +73 −25 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ public class BroadcastDispatcher { for (int i = 0; i < numEntries; i++) { if (recipientUid == mDeferredBroadcasts.get(i).uid) { Deferrals d = mDeferredBroadcasts.remove(i); mAlarmBroadcasts.add(d); mAlarmDeferrals.add(d); break; } } Loading @@ -201,10 +201,10 @@ public class BroadcastDispatcher { // No longer an alarm target, so resume ordinary deferral policy if (newCount <= 0) { final int numEntries = mAlarmBroadcasts.size(); final int numEntries = mAlarmDeferrals.size(); for (int i = 0; i < numEntries; i++) { if (recipientUid == mAlarmBroadcasts.get(i).uid) { Deferrals d = mAlarmBroadcasts.remove(i); if (recipientUid == mAlarmDeferrals.get(i).uid) { Deferrals d = mAlarmDeferrals.remove(i); insertLocked(mDeferredBroadcasts, d); break; } Loading Loading @@ -234,7 +234,13 @@ public class BroadcastDispatcher { // General deferrals not holding up alarms private final ArrayList<Deferrals> mDeferredBroadcasts = new ArrayList<>(); // Deferrals that *are* holding up alarms; ordered by alarm dispatch time private final ArrayList<Deferrals> mAlarmBroadcasts = new ArrayList<>(); private final ArrayList<Deferrals> mAlarmDeferrals = new ArrayList<>(); // Under the "deliver alarm broadcasts immediately" policy, the queue of // upcoming alarm broadcasts. These are always delivered first - if the // policy is changed on the fly from immediate-alarm-delivery to the previous // in-order-queueing behavior, pending immediate alarm deliveries will drain // and then the behavior settle into the pre-U semantics. private final ArrayList<BroadcastRecord> mAlarmQueue = new ArrayList<>(); // Next outbound broadcast, established by getNextBroadcastLocked() private BroadcastRecord mCurrentBroadcast; Loading Loading @@ -528,8 +534,9 @@ public class BroadcastDispatcher { synchronized (mLock) { return mCurrentBroadcast == null && mOrderedBroadcasts.isEmpty() && mAlarmQueue.isEmpty() && isDeferralsListEmpty(mDeferredBroadcasts) && isDeferralsListEmpty(mAlarmBroadcasts); && isDeferralsListEmpty(mAlarmDeferrals); } } Loading Loading @@ -557,7 +564,13 @@ public class BroadcastDispatcher { } sb.append(mOrderedBroadcasts.size()); sb.append(" ordered"); int n = pendingInDeferralsList(mAlarmBroadcasts); int n = mAlarmQueue.size(); if (n > 0) { sb.append(", "); sb.append(n); sb.append(" alarms"); } n = pendingInDeferralsList(mAlarmDeferrals); if (n > 0) { sb.append(", "); sb.append(n); Loading Loading @@ -592,8 +605,16 @@ public class BroadcastDispatcher { // ---------------------------------- // BroadcastQueue operation support void enqueueOrderedBroadcastLocked(BroadcastRecord r) { final ArrayList<BroadcastRecord> queue = (r.alarm && mQueue.mService.mConstants.mPrioritizeAlarmBroadcasts) ? mAlarmQueue : mOrderedBroadcasts; if (r.receivers == null || r.receivers.isEmpty()) { mOrderedBroadcasts.add(r); // Fast no-op path for broadcasts that won't actually be dispatched to // receivers - we still need to handle completion callbacks and historical // records, but we don't need to consider the fancy cases. queue.add(r); return; } Loading Loading @@ -622,7 +643,8 @@ public class BroadcastDispatcher { return; } } else { mOrderedBroadcasts.add(r); // Ordinary broadcast, so put it on the appropriate queue and carry on queue.add(r); } } Loading Loading @@ -652,10 +674,13 @@ public class BroadcastDispatcher { BroadcastRecord replaceBroadcastLocked(BroadcastRecord r, String typeForLogging) { // Simple case, in the ordinary queue. BroadcastRecord old = replaceBroadcastLocked(mOrderedBroadcasts, r, typeForLogging); // ... or possibly in the simple alarm queue if (old == null) { old = replaceBroadcastLocked(mAlarmQueue, r, typeForLogging); } // If we didn't find it, less-simple: in a deferral queue? if (old == null) { old = replaceDeferredBroadcastLocked(mAlarmBroadcasts, r, typeForLogging); old = replaceDeferredBroadcastLocked(mAlarmDeferrals, r, typeForLogging); } if (old == null) { old = replaceDeferredBroadcastLocked(mDeferredBroadcasts, r, typeForLogging); Loading Loading @@ -705,6 +730,10 @@ public class BroadcastDispatcher { // "yes we would do something" circumstance boolean didSomething = cleanupBroadcastListDisabledReceiversLocked(mOrderedBroadcasts, packageName, filterByClasses, userId, doit); if (doit || !didSomething) { didSomething = cleanupBroadcastListDisabledReceiversLocked(mAlarmQueue, packageName, filterByClasses, userId, doit); } if (doit || !didSomething) { ArrayList<BroadcastRecord> lockedBootCompletedBroadcasts = new ArrayList<>(); for (int u = 0, usize = mUser2Deferred.size(); u < usize; u++) { Loading @@ -731,7 +760,7 @@ public class BroadcastDispatcher { packageName, filterByClasses, userId, doit); } if (doit || !didSomething) { didSomething |= cleanupDeferralsListDisabledReceiversLocked(mAlarmBroadcasts, didSomething |= cleanupDeferralsListDisabledReceiversLocked(mAlarmDeferrals, packageName, filterByClasses, userId, doit); } if (doit || !didSomething) { Loading Loading @@ -781,12 +810,15 @@ public class BroadcastDispatcher { if (mCurrentBroadcast != null) { mCurrentBroadcast.dumpDebug(proto, fieldId); } for (Deferrals d : mAlarmBroadcasts) { for (Deferrals d : mAlarmDeferrals) { d.dumpDebug(proto, fieldId); } for (BroadcastRecord br : mOrderedBroadcasts) { br.dumpDebug(proto, fieldId); } for (BroadcastRecord br : mAlarmQueue) { br.dumpDebug(proto, fieldId); } for (Deferrals d : mDeferredBroadcasts) { d.dumpDebug(proto, fieldId); } Loading Loading @@ -816,23 +848,33 @@ public class BroadcastDispatcher { return mCurrentBroadcast; } final boolean someQueued = !mOrderedBroadcasts.isEmpty(); BroadcastRecord next = null; // Alarms in flight take precedence over everything else. This queue // will be non-empty only when the relevant policy is in force, but if // policy has changed on the fly we still need to drain this before we // settle into the legacy behavior. if (!mAlarmQueue.isEmpty()) { next = mAlarmQueue.remove(0); } // Next in precedence are deferred BOOT_COMPLETED broadcasts if (next == null) { next = dequeueDeferredBootCompletedBroadcast(); } if (next == null && !mAlarmBroadcasts.isEmpty()) { next = popLocked(mAlarmBroadcasts); // Alarm-related deferrals are next in precedence... if (next == null && !mAlarmDeferrals.isEmpty()) { next = popLocked(mAlarmDeferrals); if (DEBUG_BROADCAST_DEFERRAL && next != null) { Slog.i(TAG, "Next broadcast from alarm targets: " + next); } } final boolean someQueued = !mOrderedBroadcasts.isEmpty(); if (next == null && !mDeferredBroadcasts.isEmpty()) { // We're going to deliver either: // A this point we're going to deliver either: // 1. the next "overdue" deferral; or // 2. the next ordinary ordered broadcast; *or* // 3. the next not-yet-overdue deferral. Loading Loading @@ -937,7 +979,7 @@ public class BroadcastDispatcher { scheduleDeferralCheckLocked(true); } else { // alarm-related: strict order-encountered mAlarmBroadcasts.add(d); mAlarmDeferrals.add(d); } } else { // We're already deferring, but something was slow again. Reset the Loading Loading @@ -999,7 +1041,7 @@ public class BroadcastDispatcher { * immediately deliverable. Used by the wait-for-broadcast-idle mechanism. */ public void cancelDeferralsLocked() { zeroDeferralTimes(mAlarmBroadcasts); zeroDeferralTimes(mAlarmDeferrals); zeroDeferralTimes(mDeferredBroadcasts); } Loading @@ -1023,7 +1065,7 @@ public class BroadcastDispatcher { Deferrals d = findUidLocked(uid, mDeferredBroadcasts); // ...but if not there, also check alarm-prioritized deferrals if (d == null) { d = findUidLocked(uid, mAlarmBroadcasts); d = findUidLocked(uid, mAlarmDeferrals); } return d; } Loading @@ -1035,7 +1077,7 @@ public class BroadcastDispatcher { private boolean removeDeferral(Deferrals d) { boolean didRemove = mDeferredBroadcasts.remove(d); if (!didRemove) { didRemove = mAlarmBroadcasts.remove(d); didRemove = mAlarmDeferrals.remove(d); } return didRemove; } Loading Loading @@ -1103,14 +1145,20 @@ public class BroadcastDispatcher { } else { pw.println(" (null)"); } printed |= dumper.didPrint(); dumper.setHeading("Active alarm broadcasts"); dumper.setLabel("Active Alarm Broadcast"); for (BroadcastRecord br : mAlarmQueue) { dumper.dump(br); } printed |= dumper.didPrint(); dumper.setHeading("Active ordered broadcasts"); dumper.setLabel("Active Ordered Broadcast"); for (Deferrals d : mAlarmBroadcasts) { for (Deferrals d : mAlarmDeferrals) { d.dumpLocked(dumper); } printed |= dumper.didPrint(); for (BroadcastRecord br : mOrderedBroadcasts) { dumper.dump(br); } Loading Loading
services/core/java/com/android/server/am/ActivityManagerConstants.java +31 −0 Original line number Diff line number Diff line Loading @@ -146,6 +146,7 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_NETWORK_ACCESS_TIMEOUT_MS = "network_access_timeout_ms"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final boolean DEFAULT_PRIORITIZE_ALARM_BROADCASTS = true; private static final long DEFAULT_FGSERVICE_MIN_SHOWN_TIME = 2*1000; private static final long DEFAULT_FGSERVICE_MIN_REPORT_TIME = 3*1000; private static final long DEFAULT_FGSERVICE_SCREEN_ON_BEFORE_TIME = 1*1000; Loading Loading @@ -325,6 +326,14 @@ final class ActivityManagerConstants extends ContentObserver { */ private static final String KEY_PROCESS_KILL_TIMEOUT = "process_kill_timeout"; /** * {@code true} to send in-flight alarm broadcasts ahead of non-alarms; {@code false} * to queue alarm broadcasts identically to non-alarms [i.e. the pre-U behavior]; or * {@code null} or empty string in order to fall back to whatever the build-time default * was for the device. */ private static final String KEY_PRIORITIZE_ALARM_BROADCASTS = "prioritize_alarm_broadcasts"; private static final String KEY_DEFER_BOOT_COMPLETED_BROADCAST = "defer_boot_completed_broadcast"; Loading Loading @@ -666,6 +675,12 @@ final class ActivityManagerConstants extends ContentObserver { volatile @BroadcastConstants.DeferBootCompletedBroadcastType int mDeferBootCompletedBroadcast = DEFAULT_DEFER_BOOT_COMPLETED_BROADCAST; /** * Whether alarm broadcasts are delivered immediately, or queued along with the rest * of the pending ordered broadcasts. */ volatile boolean mPrioritizeAlarmBroadcasts = DEFAULT_PRIORITIZE_ALARM_BROADCASTS; /** * How long the Context.startForegroundService() grace period is to get around to * calling Service.startForeground() before we generate ANR. Loading Loading @@ -977,6 +992,9 @@ final class ActivityManagerConstants extends ContentObserver { case KEY_PROCESS_KILL_TIMEOUT: updateProcessKillTimeout(); break; case KEY_PRIORITIZE_ALARM_BROADCASTS: updatePrioritizeAlarmBroadcasts(); break; case KEY_DEFER_BOOT_COMPLETED_BROADCAST: updateDeferBootCompletedBroadcast(); break; Loading Loading @@ -1446,6 +1464,17 @@ final class ActivityManagerConstants extends ContentObserver { } } private void updatePrioritizeAlarmBroadcasts() { // Flag value can be something that evaluates to `true` or `false`, // or empty/null. If it's empty/null, the platform default is used. final String flag = DeviceConfig.getString( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_PRIORITIZE_ALARM_BROADCASTS, ""); mPrioritizeAlarmBroadcasts = TextUtils.isEmpty(flag) ? DEFAULT_PRIORITIZE_ALARM_BROADCASTS : Boolean.parseBoolean(flag); } private void updateDeferBootCompletedBroadcast() { mDeferBootCompletedBroadcast = DeviceConfig.getInt( DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, Loading Loading @@ -1786,6 +1815,8 @@ final class ActivityManagerConstants extends ContentObserver { pw.print("="); pw.println(mComponentAliasOverrides); pw.print(" "); pw.print(KEY_DEFER_BOOT_COMPLETED_BROADCAST); pw.print("="); pw.println(mDeferBootCompletedBroadcast); pw.print(" "); pw.print(KEY_PRIORITIZE_ALARM_BROADCASTS); pw.print("="); pw.println(mPrioritizeAlarmBroadcasts); pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_UNTIL_BOOT_COMPLETED); pw.print("="); pw.println(mNoKillCachedProcessesUntilBootCompleted); pw.print(" "); pw.print(KEY_NO_KILL_CACHED_PROCESSES_POST_BOOT_COMPLETED_DURATION_MILLIS); Loading
services/core/java/com/android/server/am/BroadcastDispatcher.java +73 −25 Original line number Diff line number Diff line Loading @@ -181,7 +181,7 @@ public class BroadcastDispatcher { for (int i = 0; i < numEntries; i++) { if (recipientUid == mDeferredBroadcasts.get(i).uid) { Deferrals d = mDeferredBroadcasts.remove(i); mAlarmBroadcasts.add(d); mAlarmDeferrals.add(d); break; } } Loading @@ -201,10 +201,10 @@ public class BroadcastDispatcher { // No longer an alarm target, so resume ordinary deferral policy if (newCount <= 0) { final int numEntries = mAlarmBroadcasts.size(); final int numEntries = mAlarmDeferrals.size(); for (int i = 0; i < numEntries; i++) { if (recipientUid == mAlarmBroadcasts.get(i).uid) { Deferrals d = mAlarmBroadcasts.remove(i); if (recipientUid == mAlarmDeferrals.get(i).uid) { Deferrals d = mAlarmDeferrals.remove(i); insertLocked(mDeferredBroadcasts, d); break; } Loading Loading @@ -234,7 +234,13 @@ public class BroadcastDispatcher { // General deferrals not holding up alarms private final ArrayList<Deferrals> mDeferredBroadcasts = new ArrayList<>(); // Deferrals that *are* holding up alarms; ordered by alarm dispatch time private final ArrayList<Deferrals> mAlarmBroadcasts = new ArrayList<>(); private final ArrayList<Deferrals> mAlarmDeferrals = new ArrayList<>(); // Under the "deliver alarm broadcasts immediately" policy, the queue of // upcoming alarm broadcasts. These are always delivered first - if the // policy is changed on the fly from immediate-alarm-delivery to the previous // in-order-queueing behavior, pending immediate alarm deliveries will drain // and then the behavior settle into the pre-U semantics. private final ArrayList<BroadcastRecord> mAlarmQueue = new ArrayList<>(); // Next outbound broadcast, established by getNextBroadcastLocked() private BroadcastRecord mCurrentBroadcast; Loading Loading @@ -528,8 +534,9 @@ public class BroadcastDispatcher { synchronized (mLock) { return mCurrentBroadcast == null && mOrderedBroadcasts.isEmpty() && mAlarmQueue.isEmpty() && isDeferralsListEmpty(mDeferredBroadcasts) && isDeferralsListEmpty(mAlarmBroadcasts); && isDeferralsListEmpty(mAlarmDeferrals); } } Loading Loading @@ -557,7 +564,13 @@ public class BroadcastDispatcher { } sb.append(mOrderedBroadcasts.size()); sb.append(" ordered"); int n = pendingInDeferralsList(mAlarmBroadcasts); int n = mAlarmQueue.size(); if (n > 0) { sb.append(", "); sb.append(n); sb.append(" alarms"); } n = pendingInDeferralsList(mAlarmDeferrals); if (n > 0) { sb.append(", "); sb.append(n); Loading Loading @@ -592,8 +605,16 @@ public class BroadcastDispatcher { // ---------------------------------- // BroadcastQueue operation support void enqueueOrderedBroadcastLocked(BroadcastRecord r) { final ArrayList<BroadcastRecord> queue = (r.alarm && mQueue.mService.mConstants.mPrioritizeAlarmBroadcasts) ? mAlarmQueue : mOrderedBroadcasts; if (r.receivers == null || r.receivers.isEmpty()) { mOrderedBroadcasts.add(r); // Fast no-op path for broadcasts that won't actually be dispatched to // receivers - we still need to handle completion callbacks and historical // records, but we don't need to consider the fancy cases. queue.add(r); return; } Loading Loading @@ -622,7 +643,8 @@ public class BroadcastDispatcher { return; } } else { mOrderedBroadcasts.add(r); // Ordinary broadcast, so put it on the appropriate queue and carry on queue.add(r); } } Loading Loading @@ -652,10 +674,13 @@ public class BroadcastDispatcher { BroadcastRecord replaceBroadcastLocked(BroadcastRecord r, String typeForLogging) { // Simple case, in the ordinary queue. BroadcastRecord old = replaceBroadcastLocked(mOrderedBroadcasts, r, typeForLogging); // ... or possibly in the simple alarm queue if (old == null) { old = replaceBroadcastLocked(mAlarmQueue, r, typeForLogging); } // If we didn't find it, less-simple: in a deferral queue? if (old == null) { old = replaceDeferredBroadcastLocked(mAlarmBroadcasts, r, typeForLogging); old = replaceDeferredBroadcastLocked(mAlarmDeferrals, r, typeForLogging); } if (old == null) { old = replaceDeferredBroadcastLocked(mDeferredBroadcasts, r, typeForLogging); Loading Loading @@ -705,6 +730,10 @@ public class BroadcastDispatcher { // "yes we would do something" circumstance boolean didSomething = cleanupBroadcastListDisabledReceiversLocked(mOrderedBroadcasts, packageName, filterByClasses, userId, doit); if (doit || !didSomething) { didSomething = cleanupBroadcastListDisabledReceiversLocked(mAlarmQueue, packageName, filterByClasses, userId, doit); } if (doit || !didSomething) { ArrayList<BroadcastRecord> lockedBootCompletedBroadcasts = new ArrayList<>(); for (int u = 0, usize = mUser2Deferred.size(); u < usize; u++) { Loading @@ -731,7 +760,7 @@ public class BroadcastDispatcher { packageName, filterByClasses, userId, doit); } if (doit || !didSomething) { didSomething |= cleanupDeferralsListDisabledReceiversLocked(mAlarmBroadcasts, didSomething |= cleanupDeferralsListDisabledReceiversLocked(mAlarmDeferrals, packageName, filterByClasses, userId, doit); } if (doit || !didSomething) { Loading Loading @@ -781,12 +810,15 @@ public class BroadcastDispatcher { if (mCurrentBroadcast != null) { mCurrentBroadcast.dumpDebug(proto, fieldId); } for (Deferrals d : mAlarmBroadcasts) { for (Deferrals d : mAlarmDeferrals) { d.dumpDebug(proto, fieldId); } for (BroadcastRecord br : mOrderedBroadcasts) { br.dumpDebug(proto, fieldId); } for (BroadcastRecord br : mAlarmQueue) { br.dumpDebug(proto, fieldId); } for (Deferrals d : mDeferredBroadcasts) { d.dumpDebug(proto, fieldId); } Loading Loading @@ -816,23 +848,33 @@ public class BroadcastDispatcher { return mCurrentBroadcast; } final boolean someQueued = !mOrderedBroadcasts.isEmpty(); BroadcastRecord next = null; // Alarms in flight take precedence over everything else. This queue // will be non-empty only when the relevant policy is in force, but if // policy has changed on the fly we still need to drain this before we // settle into the legacy behavior. if (!mAlarmQueue.isEmpty()) { next = mAlarmQueue.remove(0); } // Next in precedence are deferred BOOT_COMPLETED broadcasts if (next == null) { next = dequeueDeferredBootCompletedBroadcast(); } if (next == null && !mAlarmBroadcasts.isEmpty()) { next = popLocked(mAlarmBroadcasts); // Alarm-related deferrals are next in precedence... if (next == null && !mAlarmDeferrals.isEmpty()) { next = popLocked(mAlarmDeferrals); if (DEBUG_BROADCAST_DEFERRAL && next != null) { Slog.i(TAG, "Next broadcast from alarm targets: " + next); } } final boolean someQueued = !mOrderedBroadcasts.isEmpty(); if (next == null && !mDeferredBroadcasts.isEmpty()) { // We're going to deliver either: // A this point we're going to deliver either: // 1. the next "overdue" deferral; or // 2. the next ordinary ordered broadcast; *or* // 3. the next not-yet-overdue deferral. Loading Loading @@ -937,7 +979,7 @@ public class BroadcastDispatcher { scheduleDeferralCheckLocked(true); } else { // alarm-related: strict order-encountered mAlarmBroadcasts.add(d); mAlarmDeferrals.add(d); } } else { // We're already deferring, but something was slow again. Reset the Loading Loading @@ -999,7 +1041,7 @@ public class BroadcastDispatcher { * immediately deliverable. Used by the wait-for-broadcast-idle mechanism. */ public void cancelDeferralsLocked() { zeroDeferralTimes(mAlarmBroadcasts); zeroDeferralTimes(mAlarmDeferrals); zeroDeferralTimes(mDeferredBroadcasts); } Loading @@ -1023,7 +1065,7 @@ public class BroadcastDispatcher { Deferrals d = findUidLocked(uid, mDeferredBroadcasts); // ...but if not there, also check alarm-prioritized deferrals if (d == null) { d = findUidLocked(uid, mAlarmBroadcasts); d = findUidLocked(uid, mAlarmDeferrals); } return d; } Loading @@ -1035,7 +1077,7 @@ public class BroadcastDispatcher { private boolean removeDeferral(Deferrals d) { boolean didRemove = mDeferredBroadcasts.remove(d); if (!didRemove) { didRemove = mAlarmBroadcasts.remove(d); didRemove = mAlarmDeferrals.remove(d); } return didRemove; } Loading Loading @@ -1103,14 +1145,20 @@ public class BroadcastDispatcher { } else { pw.println(" (null)"); } printed |= dumper.didPrint(); dumper.setHeading("Active alarm broadcasts"); dumper.setLabel("Active Alarm Broadcast"); for (BroadcastRecord br : mAlarmQueue) { dumper.dump(br); } printed |= dumper.didPrint(); dumper.setHeading("Active ordered broadcasts"); dumper.setLabel("Active Ordered Broadcast"); for (Deferrals d : mAlarmBroadcasts) { for (Deferrals d : mAlarmDeferrals) { d.dumpLocked(dumper); } printed |= dumper.didPrint(); for (BroadcastRecord br : mOrderedBroadcasts) { dumper.dump(br); } Loading