Loading services/core/java/com/android/server/am/BroadcastProcessQueue.java +68 −15 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.am.BroadcastRecord.deliveryStateToString; import static com.android.server.am.BroadcastRecord.isDeliveryStateTerminal; import static com.android.server.am.BroadcastRecord.isReceiverEquals; import android.annotation.CheckResult; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -341,7 +342,12 @@ class BroadcastProcessQueue { * Predicates that choose to remove a broadcast <em>must</em> finish * delivery of the matched broadcast, to ensure that situations like ordered * broadcasts are handled consistently. * * @return if this operation may have changed internal state, indicating * that the caller is responsible for invoking * {@link BroadcastQueueModernImpl#updateRunnableList} */ @CheckResult public boolean forEachMatchingBroadcast(@NonNull BroadcastPredicate predicate, @NonNull BroadcastConsumer consumer, boolean andRemove) { boolean didSomething = false; Loading @@ -354,6 +360,7 @@ class BroadcastProcessQueue { return didSomething; } @CheckResult private boolean forEachMatchingBroadcastInQueue(@NonNull ArrayDeque<SomeArgs> queue, @NonNull BroadcastPredicate predicate, @NonNull BroadcastConsumer consumer, boolean andRemove) { Loading @@ -370,6 +377,10 @@ class BroadcastProcessQueue { args.recycle(); it.remove(); onBroadcastDequeued(record, recordIndex, recordWouldBeSkipped); } else { // Even if we're leaving broadcast in queue, it may have // been mutated in such a way to change our runnable time invalidateRunnableAt(); } didSomething = true; } Loading @@ -381,30 +392,43 @@ class BroadcastProcessQueue { /** * Update the actively running "warm" process for this process. * * @return if this operation may have changed internal state, indicating * that the caller is responsible for invoking * {@link BroadcastQueueModernImpl#updateRunnableList} */ public void setProcess(@Nullable ProcessRecord app) { @CheckResult public boolean setProcessAndUidFrozen(@Nullable ProcessRecord app, boolean uidFrozen) { this.app = app; if (app != null) { setProcessInstrumented(app.getActiveInstrumentation() != null); setProcessPersistent(app.isPersistent()); } else { setProcessInstrumented(false); setProcessPersistent(false); } // Since we may have just changed our PID, invalidate cached strings mCachedToString = null; mCachedToShortString = null; boolean didSomething = false; if (app != null) { didSomething |= setProcessInstrumented(app.getActiveInstrumentation() != null); didSomething |= setProcessPersistent(app.isPersistent()); didSomething |= setUidFrozen(uidFrozen); } else { didSomething |= setProcessInstrumented(false); didSomething |= setProcessPersistent(false); didSomething |= setUidFrozen(uidFrozen); } return didSomething; } /** * Update if this UID is in the "frozen" state, typically signaling that * broadcast dispatch should be paused or delayed. */ public void setUidFrozen(boolean frozen) { private boolean setUidFrozen(boolean frozen) { if (mUidFrozen != frozen) { mUidFrozen = frozen; invalidateRunnableAt(); return true; } else { return false; } } Loading @@ -413,10 +437,13 @@ class BroadcastProcessQueue { * signaling that broadcast dispatch should bypass all pauses or delays, to * avoid holding up test suites. */ public void setProcessInstrumented(boolean instrumented) { private boolean setProcessInstrumented(boolean instrumented) { if (mProcessInstrumented != instrumented) { mProcessInstrumented = instrumented; invalidateRunnableAt(); return true; } else { return false; } } Loading @@ -424,10 +451,13 @@ class BroadcastProcessQueue { * Update if this process is in the "persistent" state, which signals broadcast dispatch should * bypass all pauses or delays to prevent the system from becoming out of sync with itself. */ public void setProcessPersistent(boolean persistent) { private boolean setProcessPersistent(boolean persistent) { if (mProcessPersistent != persistent) { mProcessPersistent = persistent; invalidateRunnableAt(); return true; } else { return false; } } Loading Loading @@ -647,8 +677,20 @@ class BroadcastProcessQueue { return mActive != null; } void forceDelayBroadcastDelivery(long delayedDurationMs) { /** * @return if this operation may have changed internal state, indicating * that the caller is responsible for invoking * {@link BroadcastQueueModernImpl#updateRunnableList} */ @CheckResult boolean forceDelayBroadcastDelivery(long delayedDurationMs) { if (mForcedDelayedDurationMs != delayedDurationMs) { mForcedDelayedDurationMs = delayedDurationMs; invalidateRunnableAt(); return true; } else { return false; } } /** Loading Loading @@ -720,10 +762,21 @@ class BroadcastProcessQueue { * broadcasts would be prioritized for dispatching, even if there are urgent broadcasts * waiting. This is typically used in case there are callers waiting for "barrier" to be * reached. * * @return if this operation may have changed internal state, indicating * that the caller is responsible for invoking * {@link BroadcastQueueModernImpl#updateRunnableList} */ @CheckResult @VisibleForTesting void setPrioritizeEarliest(boolean prioritizeEarliest) { boolean setPrioritizeEarliest(boolean prioritizeEarliest) { if (mPrioritizeEarliest != prioritizeEarliest) { mPrioritizeEarliest = prioritizeEarliest; invalidateRunnableAt(); return true; } else { return false; } } /** Loading services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +37 −17 Original line number Diff line number Diff line Loading @@ -360,8 +360,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // If app isn't running, and there's nothing in the queue, clean up if (queue.isEmpty() && !queue.isActive() && !queue.isProcessWarm()) { removeProcessQueue(queue.processName, queue.uid); } else { updateQueueDeferred(queue); } } Loading Loading @@ -496,8 +494,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // relevant per-process queue final BroadcastProcessQueue queue = getProcessQueue(app); if (queue != null) { queue.setProcess(app); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); setQueueProcess(queue, app); } boolean didSomething = false; Loading Loading @@ -538,8 +535,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // relevant per-process queue final BroadcastProcessQueue queue = getProcessQueue(app); if (queue != null) { queue.setProcess(null); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); setQueueProcess(queue, null); } if ((mRunningColdStart != null) && (mRunningColdStart == queue)) { Loading @@ -566,6 +562,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { return (r.receivers.get(i) instanceof BroadcastFilter); }, mBroadcastConsumerSkip, true); if (didSomething || queue.isEmpty()) { updateQueueDeferred(queue); updateRunnableList(queue); enqueueUpdateRunningList(); } Loading Loading @@ -631,6 +628,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { setDeliveryState(queue, null, r, i, receiver, BroadcastRecord.DELIVERY_DEFERRED, "deferred at enqueue time"); } updateQueueDeferred(queue); updateRunnableList(queue); enqueueUpdateRunningList(); } Loading Loading @@ -1079,6 +1077,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { final int queueIndex = getRunningIndexOf(queue); mRunning[queueIndex] = null; updateQueueDeferred(queue); updateRunnableList(queue); enqueueUpdateRunningList(); Loading Loading @@ -1161,6 +1160,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { getReceiverUid(otherReceiver)); if (otherQueue != null) { otherQueue.invalidateRunnableAt(); updateQueueDeferred(otherQueue); updateRunnableList(otherQueue); } } Loading Loading @@ -1291,6 +1291,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { if (queuePredicate.test(leaf)) { if (leaf.forEachMatchingBroadcast(broadcastPredicate, broadcastConsumer, andRemove)) { updateQueueDeferred(leaf); updateRunnableList(leaf); didSomething = true; } Loading @@ -1304,29 +1305,40 @@ class BroadcastQueueModernImpl extends BroadcastQueue { return didSomething; } private void forEachMatchingQueue( private boolean forEachMatchingQueue( @NonNull Predicate<BroadcastProcessQueue> queuePredicate, @NonNull Consumer<BroadcastProcessQueue> queueConsumer) { boolean didSomething = false; for (int i = mProcessQueues.size() - 1; i >= 0; i--) { BroadcastProcessQueue leaf = mProcessQueues.valueAt(i); while (leaf != null) { if (queuePredicate.test(leaf)) { queueConsumer.accept(leaf); updateQueueDeferred(leaf); updateRunnableList(leaf); didSomething = true; } leaf = leaf.processNameNext; } } if (didSomething) { enqueueUpdateRunningList(); } return didSomething; } private void updateQueueDeferred( @NonNull BroadcastProcessQueue leaf) { @SuppressWarnings("CheckResult") private void updateQueueDeferred(@NonNull BroadcastProcessQueue leaf) { if (leaf.isDeferredUntilActive()) { // We ignore the returned value here since callers are invoking us // just before updateRunnableList() leaf.forEachMatchingBroadcast((r, i) -> { return r.deferUntilActive && (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_PENDING); }, mBroadcastConsumerDefer, false); } else if (leaf.hasDeferredBroadcasts()) { // We ignore the returned value here since callers are invoking us // just before updateRunnableList() leaf.forEachMatchingBroadcast((r, i) -> { return r.deferUntilActive && (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_DEFERRED); Loading Loading @@ -1356,10 +1368,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { while (leaf != null) { // Update internal state by refreshing values previously // read from any known running process leaf.setProcess(leaf.app); leaf.setUidFrozen(frozen); updateQueueDeferred(leaf); updateRunnableList(leaf); setQueueProcess(leaf, leaf.app); leaf = leaf.processNameNext; } enqueueUpdateRunningList(); Loading Loading @@ -1520,8 +1529,20 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) { if (!queue.isProcessWarm()) { queue.setProcess(mService.getProcessRecordLocked(queue.processName, queue.uid)); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); setQueueProcess(queue, mService.getProcessRecordLocked(queue.processName, queue.uid)); } } /** * Update the {@link ProcessRecord} associated with the given * {@link BroadcastProcessQueue}. Also updates any runnable status that * might have changed as a side-effect. */ private void setQueueProcess(@NonNull BroadcastProcessQueue queue, @Nullable ProcessRecord app) { if (queue.setProcessAndUidFrozen(app, mUidFrozen.get(queue.uid, false))) { updateQueueDeferred(queue); updateRunnableList(queue); } } Loading Loading @@ -1715,8 +1736,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { } BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid); created.setProcess(mService.getProcessRecordLocked(processName, uid)); created.setUidFrozen(mUidFrozen.get(uid, false)); setQueueProcess(created, mService.getProcessRecordLocked(processName, uid)); if (leaf == null) { mProcessQueues.put(uid, created); Loading services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +7 −7 Original line number Diff line number Diff line Loading @@ -371,9 +371,9 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false); queue.setUidFrozen(false); queue.setProcessAndUidFrozen(null, false); final long notCachedRunnableAt = queue.getRunnableAt(); queue.setUidFrozen(true); queue.setProcessAndUidFrozen(null, true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertFalse(queue.isRunnable()); Loading @@ -398,9 +398,9 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false); queue.setUidFrozen(false); queue.setProcessAndUidFrozen(null, false); final long notCachedRunnableAt = queue.getRunnableAt(); queue.setUidFrozen(true); queue.setProcessAndUidFrozen(null, true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertTrue(queue.isRunnable()); Loading Loading @@ -430,13 +430,13 @@ public final class BroadcastQueueModernImplTest { // verify that: // (a) the queue is immediately runnable by existence of a fg-priority broadcast // (b) the next one up is the fg-priority broadcast despite its later enqueue time queue.setUidFrozen(false); queue.setProcessAndUidFrozen(null, false); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord); queue.setUidFrozen(true); queue.setProcessAndUidFrozen(null, true); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); Loading Loading @@ -499,7 +499,7 @@ public final class BroadcastQueueModernImplTest { private void doRunnableAt_Frozen(BroadcastRecord testRecord, int testRunnableAtReason) { final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN)); queue.setUidFrozen(true); queue.setProcessAndUidFrozen(null, true); final BroadcastRecord lazyRecord = makeBroadcastRecord( new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED), Loading Loading
services/core/java/com/android/server/am/BroadcastProcessQueue.java +68 −15 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import static com.android.server.am.BroadcastRecord.deliveryStateToString; import static com.android.server.am.BroadcastRecord.isDeliveryStateTerminal; import static com.android.server.am.BroadcastRecord.isReceiverEquals; import android.annotation.CheckResult; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; Loading Loading @@ -341,7 +342,12 @@ class BroadcastProcessQueue { * Predicates that choose to remove a broadcast <em>must</em> finish * delivery of the matched broadcast, to ensure that situations like ordered * broadcasts are handled consistently. * * @return if this operation may have changed internal state, indicating * that the caller is responsible for invoking * {@link BroadcastQueueModernImpl#updateRunnableList} */ @CheckResult public boolean forEachMatchingBroadcast(@NonNull BroadcastPredicate predicate, @NonNull BroadcastConsumer consumer, boolean andRemove) { boolean didSomething = false; Loading @@ -354,6 +360,7 @@ class BroadcastProcessQueue { return didSomething; } @CheckResult private boolean forEachMatchingBroadcastInQueue(@NonNull ArrayDeque<SomeArgs> queue, @NonNull BroadcastPredicate predicate, @NonNull BroadcastConsumer consumer, boolean andRemove) { Loading @@ -370,6 +377,10 @@ class BroadcastProcessQueue { args.recycle(); it.remove(); onBroadcastDequeued(record, recordIndex, recordWouldBeSkipped); } else { // Even if we're leaving broadcast in queue, it may have // been mutated in such a way to change our runnable time invalidateRunnableAt(); } didSomething = true; } Loading @@ -381,30 +392,43 @@ class BroadcastProcessQueue { /** * Update the actively running "warm" process for this process. * * @return if this operation may have changed internal state, indicating * that the caller is responsible for invoking * {@link BroadcastQueueModernImpl#updateRunnableList} */ public void setProcess(@Nullable ProcessRecord app) { @CheckResult public boolean setProcessAndUidFrozen(@Nullable ProcessRecord app, boolean uidFrozen) { this.app = app; if (app != null) { setProcessInstrumented(app.getActiveInstrumentation() != null); setProcessPersistent(app.isPersistent()); } else { setProcessInstrumented(false); setProcessPersistent(false); } // Since we may have just changed our PID, invalidate cached strings mCachedToString = null; mCachedToShortString = null; boolean didSomething = false; if (app != null) { didSomething |= setProcessInstrumented(app.getActiveInstrumentation() != null); didSomething |= setProcessPersistent(app.isPersistent()); didSomething |= setUidFrozen(uidFrozen); } else { didSomething |= setProcessInstrumented(false); didSomething |= setProcessPersistent(false); didSomething |= setUidFrozen(uidFrozen); } return didSomething; } /** * Update if this UID is in the "frozen" state, typically signaling that * broadcast dispatch should be paused or delayed. */ public void setUidFrozen(boolean frozen) { private boolean setUidFrozen(boolean frozen) { if (mUidFrozen != frozen) { mUidFrozen = frozen; invalidateRunnableAt(); return true; } else { return false; } } Loading @@ -413,10 +437,13 @@ class BroadcastProcessQueue { * signaling that broadcast dispatch should bypass all pauses or delays, to * avoid holding up test suites. */ public void setProcessInstrumented(boolean instrumented) { private boolean setProcessInstrumented(boolean instrumented) { if (mProcessInstrumented != instrumented) { mProcessInstrumented = instrumented; invalidateRunnableAt(); return true; } else { return false; } } Loading @@ -424,10 +451,13 @@ class BroadcastProcessQueue { * Update if this process is in the "persistent" state, which signals broadcast dispatch should * bypass all pauses or delays to prevent the system from becoming out of sync with itself. */ public void setProcessPersistent(boolean persistent) { private boolean setProcessPersistent(boolean persistent) { if (mProcessPersistent != persistent) { mProcessPersistent = persistent; invalidateRunnableAt(); return true; } else { return false; } } Loading Loading @@ -647,8 +677,20 @@ class BroadcastProcessQueue { return mActive != null; } void forceDelayBroadcastDelivery(long delayedDurationMs) { /** * @return if this operation may have changed internal state, indicating * that the caller is responsible for invoking * {@link BroadcastQueueModernImpl#updateRunnableList} */ @CheckResult boolean forceDelayBroadcastDelivery(long delayedDurationMs) { if (mForcedDelayedDurationMs != delayedDurationMs) { mForcedDelayedDurationMs = delayedDurationMs; invalidateRunnableAt(); return true; } else { return false; } } /** Loading Loading @@ -720,10 +762,21 @@ class BroadcastProcessQueue { * broadcasts would be prioritized for dispatching, even if there are urgent broadcasts * waiting. This is typically used in case there are callers waiting for "barrier" to be * reached. * * @return if this operation may have changed internal state, indicating * that the caller is responsible for invoking * {@link BroadcastQueueModernImpl#updateRunnableList} */ @CheckResult @VisibleForTesting void setPrioritizeEarliest(boolean prioritizeEarliest) { boolean setPrioritizeEarliest(boolean prioritizeEarliest) { if (mPrioritizeEarliest != prioritizeEarliest) { mPrioritizeEarliest = prioritizeEarliest; invalidateRunnableAt(); return true; } else { return false; } } /** Loading
services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +37 −17 Original line number Diff line number Diff line Loading @@ -360,8 +360,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // If app isn't running, and there's nothing in the queue, clean up if (queue.isEmpty() && !queue.isActive() && !queue.isProcessWarm()) { removeProcessQueue(queue.processName, queue.uid); } else { updateQueueDeferred(queue); } } Loading Loading @@ -496,8 +494,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // relevant per-process queue final BroadcastProcessQueue queue = getProcessQueue(app); if (queue != null) { queue.setProcess(app); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); setQueueProcess(queue, app); } boolean didSomething = false; Loading Loading @@ -538,8 +535,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // relevant per-process queue final BroadcastProcessQueue queue = getProcessQueue(app); if (queue != null) { queue.setProcess(null); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); setQueueProcess(queue, null); } if ((mRunningColdStart != null) && (mRunningColdStart == queue)) { Loading @@ -566,6 +562,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { return (r.receivers.get(i) instanceof BroadcastFilter); }, mBroadcastConsumerSkip, true); if (didSomething || queue.isEmpty()) { updateQueueDeferred(queue); updateRunnableList(queue); enqueueUpdateRunningList(); } Loading Loading @@ -631,6 +628,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { setDeliveryState(queue, null, r, i, receiver, BroadcastRecord.DELIVERY_DEFERRED, "deferred at enqueue time"); } updateQueueDeferred(queue); updateRunnableList(queue); enqueueUpdateRunningList(); } Loading Loading @@ -1079,6 +1077,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { final int queueIndex = getRunningIndexOf(queue); mRunning[queueIndex] = null; updateQueueDeferred(queue); updateRunnableList(queue); enqueueUpdateRunningList(); Loading Loading @@ -1161,6 +1160,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { getReceiverUid(otherReceiver)); if (otherQueue != null) { otherQueue.invalidateRunnableAt(); updateQueueDeferred(otherQueue); updateRunnableList(otherQueue); } } Loading Loading @@ -1291,6 +1291,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { if (queuePredicate.test(leaf)) { if (leaf.forEachMatchingBroadcast(broadcastPredicate, broadcastConsumer, andRemove)) { updateQueueDeferred(leaf); updateRunnableList(leaf); didSomething = true; } Loading @@ -1304,29 +1305,40 @@ class BroadcastQueueModernImpl extends BroadcastQueue { return didSomething; } private void forEachMatchingQueue( private boolean forEachMatchingQueue( @NonNull Predicate<BroadcastProcessQueue> queuePredicate, @NonNull Consumer<BroadcastProcessQueue> queueConsumer) { boolean didSomething = false; for (int i = mProcessQueues.size() - 1; i >= 0; i--) { BroadcastProcessQueue leaf = mProcessQueues.valueAt(i); while (leaf != null) { if (queuePredicate.test(leaf)) { queueConsumer.accept(leaf); updateQueueDeferred(leaf); updateRunnableList(leaf); didSomething = true; } leaf = leaf.processNameNext; } } if (didSomething) { enqueueUpdateRunningList(); } return didSomething; } private void updateQueueDeferred( @NonNull BroadcastProcessQueue leaf) { @SuppressWarnings("CheckResult") private void updateQueueDeferred(@NonNull BroadcastProcessQueue leaf) { if (leaf.isDeferredUntilActive()) { // We ignore the returned value here since callers are invoking us // just before updateRunnableList() leaf.forEachMatchingBroadcast((r, i) -> { return r.deferUntilActive && (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_PENDING); }, mBroadcastConsumerDefer, false); } else if (leaf.hasDeferredBroadcasts()) { // We ignore the returned value here since callers are invoking us // just before updateRunnableList() leaf.forEachMatchingBroadcast((r, i) -> { return r.deferUntilActive && (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_DEFERRED); Loading Loading @@ -1356,10 +1368,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { while (leaf != null) { // Update internal state by refreshing values previously // read from any known running process leaf.setProcess(leaf.app); leaf.setUidFrozen(frozen); updateQueueDeferred(leaf); updateRunnableList(leaf); setQueueProcess(leaf, leaf.app); leaf = leaf.processNameNext; } enqueueUpdateRunningList(); Loading Loading @@ -1520,8 +1529,20 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) { if (!queue.isProcessWarm()) { queue.setProcess(mService.getProcessRecordLocked(queue.processName, queue.uid)); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); setQueueProcess(queue, mService.getProcessRecordLocked(queue.processName, queue.uid)); } } /** * Update the {@link ProcessRecord} associated with the given * {@link BroadcastProcessQueue}. Also updates any runnable status that * might have changed as a side-effect. */ private void setQueueProcess(@NonNull BroadcastProcessQueue queue, @Nullable ProcessRecord app) { if (queue.setProcessAndUidFrozen(app, mUidFrozen.get(queue.uid, false))) { updateQueueDeferred(queue); updateRunnableList(queue); } } Loading Loading @@ -1715,8 +1736,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { } BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid); created.setProcess(mService.getProcessRecordLocked(processName, uid)); created.setUidFrozen(mUidFrozen.get(uid, false)); setQueueProcess(created, mService.getProcessRecordLocked(processName, uid)); if (leaf == null) { mProcessQueues.put(uid, created); Loading
services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +7 −7 Original line number Diff line number Diff line Loading @@ -371,9 +371,9 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false); queue.setUidFrozen(false); queue.setProcessAndUidFrozen(null, false); final long notCachedRunnableAt = queue.getRunnableAt(); queue.setUidFrozen(true); queue.setProcessAndUidFrozen(null, true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertFalse(queue.isRunnable()); Loading @@ -398,9 +398,9 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false); queue.setUidFrozen(false); queue.setProcessAndUidFrozen(null, false); final long notCachedRunnableAt = queue.getRunnableAt(); queue.setUidFrozen(true); queue.setProcessAndUidFrozen(null, true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertTrue(queue.isRunnable()); Loading Loading @@ -430,13 +430,13 @@ public final class BroadcastQueueModernImplTest { // verify that: // (a) the queue is immediately runnable by existence of a fg-priority broadcast // (b) the next one up is the fg-priority broadcast despite its later enqueue time queue.setUidFrozen(false); queue.setProcessAndUidFrozen(null, false); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord); queue.setUidFrozen(true); queue.setProcessAndUidFrozen(null, true); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); Loading Loading @@ -499,7 +499,7 @@ public final class BroadcastQueueModernImplTest { private void doRunnableAt_Frozen(BroadcastRecord testRecord, int testRunnableAtReason) { final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN)); queue.setUidFrozen(true); queue.setProcessAndUidFrozen(null, true); final BroadcastRecord lazyRecord = makeBroadcastRecord( new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED), Loading