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

Commit 6ef64012 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android Build Cherrypicker Worker
Browse files

Apply deferred state correctly to newly replaced bcasts.

Bug: 327285718
Test: atest services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
(cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ed480b67b34feda9c9b01f03054f89e3e984b031)
Merged-In: Iffb55f30816bd5e13f6992c434dc2cba7699b6a1
Change-Id: Iffb55f30816bd5e13f6992c434dc2cba7699b6a1
parent 12f9874b
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -264,6 +264,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
@@ -1801,6 +1801,59 @@ public class BroadcastQueueTest extends BaseBroadcastQueueTest {
        verifyScheduleRegisteredReceiver(never(), receiverYellowApp, 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);