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

Commit 96ad59df authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Avoid priority inversion while replacing existing broadcasts.

Bug: 304224316
Test: atest services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
Test: atest services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
Change-Id: Ia1e01625dd2f805a3cc04cc0818f1413241dedf6
parent e619e972
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -350,6 +350,13 @@ class BroadcastProcessQueue {
            final BroadcastRecord testRecord = (BroadcastRecord) args.arg1;
            final int testRecordIndex = args.argi1;
            final Object testReceiver = testRecord.receivers.get(testRecordIndex);
            // If we come across the record that's being enqueued in the queue, then that means
            // we already enqueued it for a receiver in this process and trying to insert a new
            // one past this could create priority inversion in the queue, so bail out.
            if (record == testRecord && record.blockedUntilBeyondCount[recordIndex]
                    > testRecord.blockedUntilBeyondCount[testRecordIndex]) {
                break;
            }
            if ((record.callingUid == testRecord.callingUid)
                    && (record.userId == testRecord.userId)
                    && record.intent.filterEquals(testRecord.intent)
+27 −0
Original line number Diff line number Diff line
@@ -2007,6 +2007,33 @@ public class BroadcastQueueTest {
        verifyScheduleRegisteredReceiver(never(), receiverYellowApp, airplane);
    }

    @Test
    public void testReplacePending_sameProcess_diffReceivers() throws Exception {
        final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED);
        final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN);
        final BroadcastFilter receiverGreenA = makeRegisteredReceiver(receiverGreenApp);
        final BroadcastFilter receiverGreenB = makeRegisteredReceiver(receiverGreenApp);

        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED)
                .addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);

        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of(
                withPriority(receiverGreenA, 5))));
        enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, List.of(
                withPriority(receiverGreenB, 10),
                withPriority(receiverGreenA, 5))));

        waitForIdle();
        if (mImpl == Impl.DEFAULT) {
            verifyScheduleRegisteredReceiver(times(2), receiverGreenApp, airplane);
        } else {
            // In the modern queue, we don't end up replacing the old broadcast to
            // avoid creating priority inversion and so the process will receive
            // both the old and new broadcasts.
            verifyScheduleRegisteredReceiver(times(3), receiverGreenApp, airplane);
        }
    }

    @Test
    public void testIdleAndBarrier() throws Exception {
        final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED);