From f965a7a8328ed7dd1a66e335b579305d6d7d3ebb Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Wed, 16 Nov 2022 11:09:46 -0700 Subject: [PATCH] BroadcastQueue: fix subtle barrier bug. We can't immediately shortcut when mActive is past the barrier, since there may still be pre-barrier broadcasts waiting in the other queues. (This shortcut was only a valid optimization when we pulled mActive from the single consistently-ordered mPending queue.) Bug: 253906105 Test: atest FrameworksMockingServicesTests:BroadcastRecordTest Test: atest FrameworksMockingServicesTests:BroadcastQueueTest Test: atest FrameworksMockingServicesTests:BroadcastQueueModernImplTest Change-Id: I6b5d37e1784a335b2992ac319d2d90c6f449c1b9 --- .../server/am/BroadcastProcessQueue.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index 47ca427be9ff4..22caef2a4682e 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -582,20 +582,21 @@ class BroadcastProcessQueue { * barrier timestamp that are still waiting to be delivered. */ public boolean isBeyondBarrierLocked(@UptimeMillisLong long barrierTime) { - if (mActive != null) { - return mActive.enqueueTime > barrierTime; - } final SomeArgs next = mPending.peekFirst(); final SomeArgs nextUrgent = mPendingUrgent.peekFirst(); final SomeArgs nextOffload = mPendingOffload.peekFirst(); - // Empty queue is past any barrier - final boolean nextLater = (next == null) + + // Empty records are always past any barrier + final boolean activeBeyond = (mActive == null) + || mActive.enqueueTime > barrierTime; + final boolean nextBeyond = (next == null) || ((BroadcastRecord) next.arg1).enqueueTime > barrierTime; - final boolean nextUrgentLater = (nextUrgent == null) + final boolean nextUrgentBeyond = (nextUrgent == null) || ((BroadcastRecord) nextUrgent.arg1).enqueueTime > barrierTime; - final boolean nextOffloadLater = (nextOffload == null) + final boolean nextOffloadBeyond = (nextOffload == null) || ((BroadcastRecord) nextOffload.arg1).enqueueTime > barrierTime; - return nextLater && nextUrgentLater && nextOffloadLater; + + return activeBeyond && nextBeyond && nextUrgentBeyond && nextOffloadBeyond; } public boolean isRunnable() {