diff options
| -rw-r--r-- | services/core/java/com/android/server/am/BroadcastProcessQueue.java | 5 | ||||
| -rw-r--r-- | services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java | 53 |
2 files changed, 58 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index 0b561467a078..1586e334d332 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -271,6 +271,11 @@ class BroadcastProcessQueue { && record.getDeliveryGroupPolicy() == BroadcastOptions.DELIVERY_GROUP_POLICY_ALL) { final BroadcastRecord replacedBroadcastRecord = replaceBroadcast(record, recordIndex); if (replacedBroadcastRecord != null) { + if (mLastDeferredStates && shouldBeDeferred() + && (record.getDeliveryState(recordIndex) + == BroadcastRecord.DELIVERY_PENDING)) { + deferredStatesApplyConsumer.accept(record, recordIndex); + } return replacedBroadcastRecord; } } diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java index 0fd424b89837..c3559e0e6df3 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java @@ -1877,6 +1877,59 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest { } @Test + public void testReplacePendingToCachedProcess_withDeferrableBroadcast() throws Exception { + // Legacy stack doesn't support deferral + Assume.assumeTrue(mImpl == Impl.MODERN); + + final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); + final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN); + final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); + final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); + + setProcessFreezable(receiverGreenApp, true, false); + mQueue.onProcessFreezableChangedLocked(receiverGreenApp); + waitForIdle(); + + final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK) + .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + final BroadcastOptions opts = BroadcastOptions.makeBasic() + .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); + + final BroadcastFilter receiverGreen = makeRegisteredReceiver(receiverGreenApp, 10); + final BroadcastFilter receiverBlue = makeRegisteredReceiver(receiverBlueApp, 5); + final BroadcastFilter receiverYellow = makeRegisteredReceiver(receiverYellowApp, 0); + enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, opts, List.of( + receiverGreen, receiverBlue, receiverYellow))); + + // Enqueue the broadcast again to replace the earlier one + enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, opts, List.of( + receiverGreen, receiverBlue, receiverYellow))); + + waitForIdle(); + // Green should still be in the cached state and shouldn't receive the broadcast + verifyScheduleRegisteredReceiver(never(), receiverGreenApp, timeTick); + + final IApplicationThread blueThread = receiverBlueApp.getThread(); + final IApplicationThread yellowThread = receiverYellowApp.getThread(); + final InOrder inOrder = inOrder(blueThread, yellowThread); + inOrder.verify(blueThread).scheduleRegisteredReceiver( + any(), argThat(filterEqualsIgnoringComponent(timeTick)), + anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), + eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); + inOrder.verify(yellowThread).scheduleRegisteredReceiver( + any(), argThat(filterEqualsIgnoringComponent(timeTick)), + anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(), + eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); + + setProcessFreezable(receiverGreenApp, false, false); + mQueue.onProcessFreezableChangedLocked(receiverGreenApp); + waitForIdle(); + + // Confirm that green receives the broadcast once it comes out of the cached state + verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick); + } + + @Test public void testIdleAndBarrier() throws Exception { final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); final ProcessRecord receiverApp = makeActiveProcessRecord(PACKAGE_GREEN); |