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

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

Merge "Verify prioritized receivers are WAI with deferrable broadcasts." into udc-dev

parents 0f351cb6 9621b244
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -399,7 +399,8 @@ class BroadcastProcessQueue {
     * Update if this process is in the "cached" state, typically signaling that
     * broadcast dispatch should be paused or delayed.
     */
    public void setProcessCached(boolean cached) {
    @VisibleForTesting
    void setProcessCached(boolean cached) {
        if (mProcessCached != cached) {
            mProcessCached = cached;
            invalidateRunnableAt();
+73 −0
Original line number Diff line number Diff line
@@ -1645,6 +1645,79 @@ public class BroadcastQueueTest {
                Set.of(mScheduledBroadcasts.remove(0)));
    }

    /**
     * Verify prioritized receivers work as expected with deferrable broadcast - broadcast to
     * app in cached state should be deferred and the rest should be delivered as per the priority
     * order.
     */
    @Test
    public void testPrioritized_withDeferrableBroadcasts() 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);
        final ProcessRecord receiverOrangeApp = makeActiveProcessRecord(PACKAGE_ORANGE);

        receiverGreenApp.setCached(true);
        receiverBlueApp.setCached(true);

        final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
        final BroadcastOptions opts = BroadcastOptions.makeBasic()
                .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
        final List receivers = List.of(
                makeRegisteredReceiver(callerApp, 10),
                makeRegisteredReceiver(receiverGreenApp, 9),
                makeRegisteredReceiver(receiverBlueApp, 8),
                makeRegisteredReceiver(receiverYellowApp, 8),
                makeRegisteredReceiver(receiverOrangeApp, 7)
        );
        enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, opts, receivers));
        waitForIdle();

        // Green ignored since it's in cached state
        verifyScheduleRegisteredReceiver(never(), receiverGreenApp, timeTick);
        // Blue ignored since it's in cached state
        verifyScheduleRegisteredReceiver(never(), receiverBlueApp, timeTick);

        final IApplicationThread redThread = mAms.getProcessRecordLocked(PACKAGE_RED,
                getUidForPackage(PACKAGE_RED)).getThread();
        final IApplicationThread yellowThread = mAms.getProcessRecordLocked(PACKAGE_YELLOW,
                getUidForPackage(PACKAGE_YELLOW)).getThread();
        final IApplicationThread orangeThread = mAms.getProcessRecordLocked(PACKAGE_ORANGE,
                getUidForPackage(PACKAGE_ORANGE)).getThread();

        // Verify apps that are not in cached state will receive the broadcast in the order
        // we expect.
        final InOrder inOrder = inOrder(redThread, yellowThread, orangeThread);
        inOrder.verify(redThread).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());
        inOrder.verify(orangeThread).scheduleRegisteredReceiver(
                any(), argThat(filterEqualsIgnoringComponent(timeTick)),
                anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(),
                eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any());

        // Shift blue to be active and confirm that deferred broadcast is delivered
        receiverBlueApp.setCached(false);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), false);
        waitForIdle();
        verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, timeTick);

        // Shift green to be active and confirm that deferred broadcast is delivered
        receiverGreenApp.setCached(false);
        mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), false);
        waitForIdle();
        verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick);
    }

    /**
     * Verify that we handle replacing a pending broadcast.
     */