Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ed480b67 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Apply deferred state correctly to newly replaced bcasts.

Bug: 327285718
Test: atest services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
Change-Id: Iffb55f30816bd5e13f6992c434dc2cba7699b6a1
parent 1684475d
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -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;
            }
        }
+53 −0
Original line number Diff line number Diff line
@@ -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);