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

Commit 7e6ce392 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Promote an app to RECEIVER only when handling a broadcast.

AMS.isReceivingBroadcastLocked() uses
getPreferredSchedulingGroupLocked() to check if a process is
handling a broadcast and which scheduling group the process
should belong to. With the current implementation, even if
an app is not handling a broadcast, it will be promoted to
the RECEIVER state as long as it has some broadcasts waiting
for it, which is not necessary and prevents some broadcast
delays that we added for cached processes from being effective.

Bug: 268082390
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: I6e1df941b6e9715add1727fc5cfe0234c5a5a7f6
parent 0126a404
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -441,17 +441,17 @@ class BroadcastProcessQueue {
    }

    public int getPreferredSchedulingGroupLocked() {
        if (mCountForeground > mCountForegroundDeferred) {
        if (!isActive()) {
            return ProcessList.SCHED_GROUP_UNDEFINED;
        } else if (mCountForeground > mCountForegroundDeferred) {
            // We have a foreground broadcast somewhere down the queue, so
            // boost priority until we drain them all
            return ProcessList.SCHED_GROUP_DEFAULT;
        } else if ((mActive != null) && mActive.isForeground()) {
            // We have a foreground broadcast right now, so boost priority
            return ProcessList.SCHED_GROUP_DEFAULT;
        } else if (!isIdle()) {
            return ProcessList.SCHED_GROUP_BACKGROUND;
        } else {
            return ProcessList.SCHED_GROUP_UNDEFINED;
            return ProcessList.SCHED_GROUP_BACKGROUND;
        }
    }

+38 −3
Original line number Diff line number Diff line
@@ -406,7 +406,7 @@ public final class BroadcastQueueModernImplTest {
        assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
        assertTrue(queue.isRunnable());
        assertEquals(BroadcastProcessQueue.REASON_CACHED, queue.getRunnableAtReason());
        assertEquals(ProcessList.SCHED_GROUP_BACKGROUND, queue.getPreferredSchedulingGroupLocked());
        assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
    }

    /**
@@ -434,13 +434,13 @@ public final class BroadcastQueueModernImplTest {
        queue.setProcessAndUidCached(null, false);
        assertTrue(queue.isRunnable());
        assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
        assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
        assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
        assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord);

        queue.setProcessAndUidCached(null, true);
        assertTrue(queue.isRunnable());
        assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
        assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
        assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());
        assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord);
    }

@@ -1154,6 +1154,41 @@ public final class BroadcastQueueModernImplTest {
                times(1));
    }

    @Test
    public void testGetPreferredSchedulingGroup() throws Exception {
        final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
                PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));

        assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());

        final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK)
                .addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
        queue.enqueueOrReplaceBroadcast(makeBroadcastRecord(timeTick,
                List.of(makeMockRegisteredReceiver())), 0, false);
        assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());

        // Make the foreground broadcast as active.
        queue.makeActiveNextPending();
        assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());

        queue.makeActiveIdle();
        assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked());

        final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
        queue.enqueueOrReplaceBroadcast(makeBroadcastRecord(airplane,
                List.of(makeMockRegisteredReceiver())), 0, false);

        // Make the background broadcast as active.
        queue.makeActiveNextPending();
        assertEquals(ProcessList.SCHED_GROUP_BACKGROUND, queue.getPreferredSchedulingGroupLocked());

        queue.enqueueOrReplaceBroadcast(makeBroadcastRecord(timeTick,
                List.of(makeMockRegisteredReceiver())), 0, false);
        // Even though the active broadcast is not a foreground one, scheduling group will be
        // DEFAULT since there is a foreground broadcast waiting to be delivered.
        assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
    }

    private Intent createPackageChangedIntent(int uid, List<String> componentNameList) {
        final Intent packageChangedIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
        packageChangedIntent.putExtra(Intent.EXTRA_UID, uid);