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

Commit 89329c67 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Apply deferred state correctly to newly replaced bcasts." into main

parents 79f141c2 ed480b67
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);