summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/am/BroadcastConstants.java56
-rw-r--r--services/core/java/com/android/server/am/BroadcastProcessQueue.java25
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueModernImpl.java37
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java19
4 files changed, 87 insertions, 50 deletions
diff --git a/services/core/java/com/android/server/am/BroadcastConstants.java b/services/core/java/com/android/server/am/BroadcastConstants.java
index 2ebe0b48296b..3efb628a8b75 100644
--- a/services/core/java/com/android/server/am/BroadcastConstants.java
+++ b/services/core/java/com/android/server/am/BroadcastConstants.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.compat.annotation.ChangeId;
import android.compat.annotation.EnabledAfter;
import android.compat.annotation.Overridable;
@@ -24,6 +25,8 @@ import android.content.ContentResolver;
import android.database.ContentObserver;
import android.os.Build;
import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import android.util.KeyValueListParser;
import android.util.Slog;
@@ -39,6 +42,9 @@ import java.lang.annotation.RetentionPolicy;
public class BroadcastConstants {
private static final String TAG = "BroadcastConstants";
+ // TODO: migrate remaining constants to be loaded from DeviceConfig
+ // TODO: migrate fg/bg values into single constants instance
+
// Value element names within the Settings record
static final String KEY_TIMEOUT = "bcast_timeout";
static final String KEY_SLOW_TIME = "bcast_slow_time";
@@ -115,6 +121,35 @@ public class BroadcastConstants {
// started its process can start a background activity.
public long ALLOW_BG_ACTIVITY_START_TIMEOUT = DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT;
+ /**
+ * For {@link BroadcastQueueModernImpl}: Maximum number of process queues to
+ * dispatch broadcasts to simultaneously.
+ */
+ public int MAX_RUNNING_PROCESS_QUEUES = DEFAULT_MAX_RUNNING_PROCESS_QUEUES;
+ private static final int DEFAULT_MAX_RUNNING_PROCESS_QUEUES = 4;
+
+ /**
+ * For {@link BroadcastQueueModernImpl}: Maximum number of active broadcasts
+ * to dispatch to a "running" process queue before we retire them back to
+ * being "runnable" to give other processes a chance to run.
+ */
+ public int MAX_RUNNING_ACTIVE_BROADCASTS = DEFAULT_MAX_RUNNING_ACTIVE_BROADCASTS;
+ private static final int DEFAULT_MAX_RUNNING_ACTIVE_BROADCASTS = 16;
+
+ /**
+ * For {@link BroadcastQueueModernImpl}: Default delay to apply to normal
+ * broadcasts, giving a chance for debouncing of rapidly changing events.
+ */
+ public long DELAY_NORMAL_MILLIS = DEFAULT_DELAY_NORMAL_MILLIS;
+ private static final long DEFAULT_DELAY_NORMAL_MILLIS = 10_000 * Build.HW_TIMEOUT_MULTIPLIER;
+
+ /**
+ * For {@link BroadcastQueueModernImpl}: Default delay to apply to
+ * broadcasts targeting cached applications.
+ */
+ public long DELAY_CACHED_MILLIS = DEFAULT_DELAY_CACHED_MILLIS;
+ private static final long DEFAULT_DELAY_CACHED_MILLIS = 30_000 * Build.HW_TIMEOUT_MULTIPLIER;
+
// Settings override tracking for this instance
private String mSettingsKey;
private SettingsObserver mSettingsObserver;
@@ -128,7 +163,7 @@ public class BroadcastConstants {
@Override
public void onChange(boolean selfChange) {
- updateConstants();
+ updateSettingsConstants();
}
}
@@ -148,11 +183,15 @@ public class BroadcastConstants {
mSettingsObserver = new SettingsObserver(handler);
mResolver.registerContentObserver(Settings.Global.getUriFor(mSettingsKey),
false, mSettingsObserver);
+ updateSettingsConstants();
- updateConstants();
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ new HandlerExecutor(handler), this::updateDeviceConfigConstants);
+ updateDeviceConfigConstants(
+ DeviceConfig.getProperties(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER));
}
- private void updateConstants() {
+ private void updateSettingsConstants() {
synchronized (mParser) {
try {
mParser.setString(Settings.Global.getString(mResolver, mSettingsKey));
@@ -173,6 +212,17 @@ public class BroadcastConstants {
}
}
+ private void updateDeviceConfigConstants(@NonNull DeviceConfig.Properties properties) {
+ MAX_RUNNING_PROCESS_QUEUES = properties.getInt("bcast_max_running_process_queues",
+ DEFAULT_MAX_RUNNING_PROCESS_QUEUES);
+ MAX_RUNNING_ACTIVE_BROADCASTS = properties.getInt("bcast_max_running_active_broadcasts",
+ DEFAULT_MAX_RUNNING_ACTIVE_BROADCASTS);
+ DELAY_NORMAL_MILLIS = properties.getLong("bcast_delay_normal_millis",
+ DEFAULT_DELAY_NORMAL_MILLIS);
+ DELAY_CACHED_MILLIS = properties.getLong("bcast_delay_cached_millis",
+ DEFAULT_DELAY_CACHED_MILLIS);
+ }
+
/**
* Standard dumpsys support; invoked from BroadcastQueue dump
*/
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 38f71e1dd18a..70fb7a3e962b 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -32,6 +32,7 @@ import com.android.server.am.BroadcastRecord.DeliveryState;
import java.util.ArrayDeque;
import java.util.Iterator;
+import java.util.Objects;
import java.util.function.BiPredicate;
/**
@@ -47,19 +48,7 @@ import java.util.function.BiPredicate;
* dispatched.
*/
class BroadcastProcessQueue {
- /**
- * Default delay to apply to background broadcasts, giving a chance for
- * debouncing of rapidly changing events.
- */
- // TODO: shift hard-coded defaults to BroadcastConstants
- private static final long DELAY_DEFAULT_MILLIS = 10_000;
-
- /**
- * Default delay to apply to broadcasts targeting cached applications.
- */
- // TODO: shift hard-coded defaults to BroadcastConstants
- private static final long DELAY_CACHED_MILLIS = 30_000;
-
+ final @NonNull BroadcastConstants constants;
final @NonNull String processName;
final int uid;
@@ -129,8 +118,10 @@ class BroadcastProcessQueue {
private boolean mProcessCached;
- public BroadcastProcessQueue(@NonNull String processName, int uid) {
- this.processName = processName;
+ public BroadcastProcessQueue(@NonNull BroadcastConstants constants,
+ @NonNull String processName, int uid) {
+ this.constants = Objects.requireNonNull(constants);
+ this.processName = Objects.requireNonNull(processName);
this.uid = uid;
}
@@ -401,9 +392,9 @@ class BroadcastProcessQueue {
} else if (mCountAlarm > 0) {
mRunnableAt = runnableAt;
} else if (mProcessCached) {
- mRunnableAt = runnableAt + DELAY_CACHED_MILLIS;
+ mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS;
} else {
- mRunnableAt = runnableAt + DELAY_DEFAULT_MILLIS;
+ mRunnableAt = runnableAt + constants.DELAY_NORMAL_MILLIS;
}
} else {
mRunnableAt = Long.MAX_VALUE;
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index 761e12c52263..d60ad991d91e 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -111,9 +111,17 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
BroadcastConstants fgConstants, BroadcastConstants bgConstants,
BroadcastSkipPolicy skipPolicy, BroadcastHistory history) {
super(service, handler, "modern", skipPolicy, history);
+
+ // For the moment, read agnostic constants from foreground
+ mConstants = Objects.requireNonNull(fgConstants);
mFgConstants = Objects.requireNonNull(fgConstants);
mBgConstants = Objects.requireNonNull(bgConstants);
+
mLocalHandler = new Handler(handler.getLooper(), mLocalCallback);
+
+ // We configure runnable size only once at boot; it'd be too complex to
+ // try resizing dynamically at runtime
+ mRunning = new BroadcastProcessQueue[mConstants.MAX_RUNNING_PROCESS_QUEUES];
}
// TODO: add support for replacing pending broadcasts
@@ -125,21 +133,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// TODO: pause queues when processes are frozen
/**
- * Maximum number of process queues to dispatch broadcasts to
- * simultaneously.
- */
- // TODO: shift hard-coded defaults to BroadcastConstants
- private static final int MAX_RUNNING_PROCESS_QUEUES = 4;
-
- /**
- * Maximum number of active broadcasts to dispatch to a "running" process
- * queue before we retire them back to being "runnable" to give other
- * processes a chance to run.
- */
- // TODO: shift hard-coded defaults to BroadcastConstants
- private static final int MAX_RUNNING_ACTIVE_BROADCASTS = 16;
-
- /**
* Map from UID to per-process broadcast queues. If a UID hosts more than
* one process, each additional process is stored as a linked list using
* {@link BroadcastProcessQueue#next}.
@@ -168,8 +161,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* @see #getRunningIndexOf
*/
@GuardedBy("mService")
- private final BroadcastProcessQueue[] mRunning =
- new BroadcastProcessQueue[MAX_RUNNING_PROCESS_QUEUES];
+ private final BroadcastProcessQueue[] mRunning;
/**
* Single queue which is "running" but is awaiting a cold start to be
@@ -185,6 +177,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
@GuardedBy("mService")
private final ArrayList<CountDownLatch> mWaitingForIdle = new ArrayList<>();
+ private final BroadcastConstants mConstants;
private final BroadcastConstants mFgConstants;
private final BroadcastConstants mBgConstants;
@@ -299,12 +292,12 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
* Consider updating the list of "running" queues.
* <p>
* This method can promote "runnable" queues to become "running", subject to
- * a maximum of {@link #MAX_RUNNING_PROCESS_QUEUES} warm processes and only
- * one pending cold-start.
+ * a maximum of {@link BroadcastConstants#MAX_RUNNING_PROCESS_QUEUES} warm
+ * processes and only one pending cold-start.
*/
@GuardedBy("mService")
private void updateRunningList() {
- int avail = MAX_RUNNING_PROCESS_QUEUES - getRunningSize();
+ int avail = mRunning.length - getRunningSize();
if (avail == 0) return;
final int cookie = traceBegin(TAG, "updateRunningList");
@@ -714,7 +707,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
// Even if we have more broadcasts, if we've made reasonable progress
// and someone else is waiting, retire ourselves to avoid starvation
final boolean shouldRetire = (mRunnableHead != null)
- && (queue.getActiveCountSinceIdle() > MAX_RUNNING_ACTIVE_BROADCASTS);
+ && (queue.getActiveCountSinceIdle() > mConstants.MAX_RUNNING_ACTIVE_BROADCASTS);
if (queue.isRunnable() && queue.isProcessWarm() && !shouldRetire) {
// We're on a roll; move onto the next broadcast for this process
@@ -1034,7 +1027,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
leaf = leaf.processNameNext;
}
- BroadcastProcessQueue created = new BroadcastProcessQueue(processName, uid);
+ BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid);
created.app = mService.getProcessRecordLocked(processName, uid);
if (leaf == null) {
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 00e11a327d91..2b1f4a3ce56c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -65,6 +65,8 @@ public class BroadcastQueueModernImplTest {
@Mock BroadcastProcessQueue mQueue4;
HandlerThread mHandlerThread;
+
+ BroadcastConstants mConstants;
BroadcastQueueModernImpl mImpl;
BroadcastProcessQueue mHead;
@@ -75,9 +77,10 @@ public class BroadcastQueueModernImplTest {
mHandlerThread = new HandlerThread(getClass().getSimpleName());
mHandlerThread.start();
+
+ mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS);
mImpl = new BroadcastQueueModernImpl(mAms, mHandlerThread.getThreadHandler(),
- new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS),
- new BroadcastConstants(Settings.Global.BROADCAST_BG_CONSTANTS));
+ mConstants, mConstants);
doReturn(1L).when(mQueue1).getRunnableAt();
doReturn(2L).when(mQueue2).getRunnableAt();
@@ -240,8 +243,8 @@ public class BroadcastQueueModernImplTest {
*/
@Test
public void testRunnableAt_Empty() {
- BroadcastProcessQueue queue = new BroadcastProcessQueue(PACKAGE_GREEN,
- getUidForPackage(PACKAGE_GREEN));
+ BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
+ PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
assertFalse(queue.isRunnable());
assertEquals(Long.MAX_VALUE, queue.getRunnableAt());
}
@@ -252,8 +255,8 @@ public class BroadcastQueueModernImplTest {
*/
@Test
public void testRunnableAt_Normal() {
- BroadcastProcessQueue queue = new BroadcastProcessQueue(PACKAGE_GREEN,
- getUidForPackage(PACKAGE_GREEN));
+ BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
+ PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
final BroadcastRecord airplaneRecord = makeBroadcastRecord(airplane);
@@ -272,8 +275,8 @@ public class BroadcastQueueModernImplTest {
*/
@Test
public void testRunnableAt_Foreground() {
- BroadcastProcessQueue queue = new BroadcastProcessQueue(PACKAGE_GREEN,
- getUidForPackage(PACKAGE_GREEN));
+ BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
+ PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
airplane.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);