diff --git a/services/core/java/com/android/server/am/BroadcastConstants.java b/services/core/java/com/android/server/am/BroadcastConstants.java index 87214decfe2eb..030d596a16769 100644 --- a/services/core/java/com/android/server/am/BroadcastConstants.java +++ b/services/core/java/com/android/server/am/BroadcastConstants.java @@ -246,6 +246,26 @@ public class BroadcastConstants { private static final String KEY_DELAY_URGENT_MILLIS = "bcast_delay_urgent_millis"; private static final long DEFAULT_DELAY_URGENT_MILLIS = -120_000; + /** + * For {@link BroadcastQueueModernImpl}: Delay to apply to broadcasts to + * foreground processes, typically a negative value to indicate they should be + * executed before most other pending broadcasts. + */ + public long DELAY_FOREGROUND_PROC_MILLIS = DEFAULT_DELAY_FOREGROUND_PROC_MILLIS; + private static final String KEY_DELAY_FOREGROUND_PROC_MILLIS = + "bcast_delay_foreground_proc_millis"; + private static final long DEFAULT_DELAY_FOREGROUND_PROC_MILLIS = -120_000; + + /** + * For {@link BroadcastQueueModernImpl}: Delay to apply to broadcasts to + * persistent processes, typically a negative value to indicate they should be + * executed before most other pending broadcasts. + */ + public long DELAY_PERSISTENT_PROC_MILLIS = DEFAULT_DELAY_FOREGROUND_PROC_MILLIS; + private static final String KEY_DELAY_PERSISTENT_PROC_MILLIS = + "bcast_delay_persistent_proc_millis"; + private static final long DEFAULT_DELAY_PERSISTENT_PROC_MILLIS = -120_000; + /** * For {@link BroadcastQueueModernImpl}: Maximum number of complete * historical broadcasts to retain for debugging purposes. @@ -411,6 +431,10 @@ public class BroadcastConstants { DEFAULT_DELAY_CACHED_MILLIS); DELAY_URGENT_MILLIS = getDeviceConfigLong(KEY_DELAY_URGENT_MILLIS, DEFAULT_DELAY_URGENT_MILLIS); + DELAY_FOREGROUND_PROC_MILLIS = getDeviceConfigLong(KEY_DELAY_FOREGROUND_PROC_MILLIS, + DEFAULT_DELAY_FOREGROUND_PROC_MILLIS); + DELAY_PERSISTENT_PROC_MILLIS = getDeviceConfigLong(KEY_DELAY_PERSISTENT_PROC_MILLIS, + DEFAULT_DELAY_PERSISTENT_PROC_MILLIS); MAX_HISTORY_COMPLETE_SIZE = getDeviceConfigInt(KEY_MAX_HISTORY_COMPLETE_SIZE, DEFAULT_MAX_HISTORY_COMPLETE_SIZE); MAX_HISTORY_SUMMARY_SIZE = getDeviceConfigInt(KEY_MAX_HISTORY_SUMMARY_SIZE, @@ -463,6 +487,10 @@ public class BroadcastConstants { TimeUtils.formatDuration(DELAY_CACHED_MILLIS)).println(); pw.print(KEY_DELAY_URGENT_MILLIS, TimeUtils.formatDuration(DELAY_URGENT_MILLIS)).println(); + pw.print(KEY_DELAY_FOREGROUND_PROC_MILLIS, + TimeUtils.formatDuration(DELAY_FOREGROUND_PROC_MILLIS)).println(); + pw.print(KEY_DELAY_PERSISTENT_PROC_MILLIS, + TimeUtils.formatDuration(DELAY_PERSISTENT_PROC_MILLIS)).println(); pw.print(KEY_MAX_HISTORY_COMPLETE_SIZE, MAX_HISTORY_COMPLETE_SIZE).println(); pw.print(KEY_MAX_HISTORY_SUMMARY_SIZE, MAX_HISTORY_SUMMARY_SIZE).println(); pw.print(KEY_MAX_CONSECUTIVE_URGENT_DISPATCHES, diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index 2803b4b66615f..3ac2b2bd9fd1b 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -1098,8 +1098,11 @@ class BroadcastProcessQueue { mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS; mRunnableAtReason = REASON_INSTRUMENTED; } else if (mUidForeground) { - mRunnableAt = runnableAt + constants.DELAY_URGENT_MILLIS; + mRunnableAt = runnableAt + constants.DELAY_FOREGROUND_PROC_MILLIS; mRunnableAtReason = REASON_FOREGROUND; + } else if (mProcessPersistent) { + mRunnableAt = runnableAt + constants.DELAY_PERSISTENT_PROC_MILLIS; + mRunnableAtReason = REASON_PERSISTENT; } else if (mCountOrdered > 0) { mRunnableAt = runnableAt; mRunnableAtReason = REASON_CONTAINS_ORDERED; @@ -1112,9 +1115,6 @@ class BroadcastProcessQueue { } else if (mCountManifest > 0) { mRunnableAt = runnableAt; mRunnableAtReason = REASON_CONTAINS_MANIFEST; - } else if (mProcessPersistent) { - mRunnableAt = runnableAt; - mRunnableAtReason = REASON_PERSISTENT; } else if (mUidCached) { if (r.deferUntilActive) { // All enqueued broadcasts are deferrable, defer diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java index 581fe4acf2193..f47954baf6494 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java @@ -537,6 +537,30 @@ public final class BroadcastQueueModernImplTest { assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); } + @Test + public void testRunnableAt_persistentProc() { + final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, + getUidForPackage(PACKAGE_GREEN)); + + final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); + final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, + List.of(makeMockRegisteredReceiver())); + enqueueOrReplaceBroadcast(queue, timeTickRecord, 0); + + assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime); + assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); + + doReturn(true).when(mProcess).isPersistent(); + queue.setProcessAndUidState(mProcess, false, false); + assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime); + assertEquals(BroadcastProcessQueue.REASON_PERSISTENT, queue.getRunnableAtReason()); + + doReturn(false).when(mProcess).isPersistent(); + queue.setProcessAndUidState(mProcess, false, false); + assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime); + assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); + } + /** * Verify that a cached process that would normally be delayed becomes * immediately runnable when the given broadcast is enqueued.