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
This commit is contained in:
Sudheer Shanka
2023-04-05 11:10:31 -07:00
parent 0126a4048d
commit 7e6ce392cf
2 changed files with 42 additions and 7 deletions

View File

@@ -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;
}
}

View File

@@ -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);