Loading services/core/java/com/android/server/am/BroadcastProcessQueue.java +5 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,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; } } Loading services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +53 −0 Original line number Diff line number Diff line Loading @@ -2000,6 +2000,59 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest { verifyScheduleReceiver(times(2), systemApp, airplane); } @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); Loading Loading
services/core/java/com/android/server/am/BroadcastProcessQueue.java +5 −0 Original line number Diff line number Diff line Loading @@ -276,6 +276,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; } } Loading
services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +53 −0 Original line number Diff line number Diff line Loading @@ -2000,6 +2000,59 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest { verifyScheduleReceiver(times(2), systemApp, airplane); } @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); Loading