diff options
| author | 2022-09-02 14:28:16 -0600 | |
|---|---|---|
| committer | 2022-09-02 14:39:31 -0600 | |
| commit | 88fe1a30af6e87d05271379aa9dd397b3e244f49 (patch) | |
| tree | 555674741ff93bbb461f6cff09f3d4d792471647 | |
| parent | 5b2df738107fe9c3114a7aa40c37ff2da999eb00 (diff) | |
[8/?] Reduce BroadcastQueue interface complexity.
Remove visibility of "pending" and "active" broadcasts, since these
are details of the current implementation. A future implementation
will likely pivot to having multiple broadcasts in flight at the same
time, so we replace them with getPreferredSchedulingGroupLocked(),
which is the real question that the OS is asking.
Bug: 243656033
Test: atest CtsContentTestCases:BroadcastReceiverTest
Test: atest FrameworksMockingServicesTests:BroadcastQueueTest
Change-Id: I1b567b124d332803cc79f2fe77ecd89d410ff393
8 files changed, 50 insertions, 48 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 29349b2ed89b..9d30328f8d0c 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -2412,13 +2412,13 @@ public class ActivityManagerService extends IActivityManager.Stub mBroadcastQueues = new BroadcastQueue[4]; mFgBroadcastQueue = new BroadcastQueueImpl(this, mHandler, - "foreground", foreConstants, false); + "foreground", foreConstants, false, ProcessList.SCHED_GROUP_DEFAULT); mBgBroadcastQueue = new BroadcastQueueImpl(this, mHandler, - "background", backConstants, true); + "background", backConstants, true, ProcessList.SCHED_GROUP_BACKGROUND); mBgOffloadBroadcastQueue = new BroadcastQueueImpl(this, mHandler, - "offload_bg", offloadConstants, true); + "offload_bg", offloadConstants, true, ProcessList.SCHED_GROUP_BACKGROUND); mFgOffloadBroadcastQueue = new BroadcastQueueImpl(this, mHandler, - "offload_fg", foreConstants, true); + "offload_fg", foreConstants, true, ProcessList.SCHED_GROUP_BACKGROUND); mBroadcastQueues[0] = mFgBroadcastQueue; mBroadcastQueues[1] = mBgBroadcastQueue; mBroadcastQueues[2] = mBgOffloadBroadcastQueue; @@ -15088,30 +15088,13 @@ public class ActivityManagerService extends IActivityManager.Stub // LIFETIME MANAGEMENT // ========================================================= - // Returns whether the app is receiving broadcast. - // If receiving, fetch all broadcast queues which the app is - // the current [or imminent] receiver on. - boolean isReceivingBroadcastLocked(ProcessRecord app, - ArraySet<BroadcastQueue> receivingQueues) { - final ProcessReceiverRecord prr = app.mReceivers; - final int numOfReceivers = prr.numberOfCurReceivers(); - if (numOfReceivers > 0) { - for (int i = 0; i < numOfReceivers; i++) { - receivingQueues.add(prr.getCurReceiverAt(i).queue); - } - return true; - } - - // It's not the current receiver, but it might be starting up to become one + boolean isReceivingBroadcastLocked(ProcessRecord app, int[] outSchedGroup) { + int res = ProcessList.SCHED_GROUP_UNDEFINED; for (BroadcastQueue queue : mBroadcastQueues) { - final BroadcastRecord r = queue.getPendingBroadcastLocked(); - if (r != null && r.curApp == app) { - // found it; report which queue it's in - receivingQueues.add(queue); - } + res = Math.max(res, queue.getPreferredSchedulingGroupLocked(app)); } - - return !receivingQueues.isEmpty(); + outSchedGroup[0] = res; + return res != ProcessList.SCHED_GROUP_UNDEFINED; } Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState, diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 7ad78273069d..6814509922b1 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -66,11 +66,15 @@ public abstract class BroadcastQueue { public abstract boolean isDelayBehindServices(); - @GuardedBy("mService") - public abstract @Nullable BroadcastRecord getPendingBroadcastLocked(); - - @GuardedBy("mService") - public abstract @Nullable BroadcastRecord getActiveBroadcastLocked(); + /** + * Return the preferred scheduling group for the given process, typically + * influenced by a broadcast being actively dispatched. + * + * @return scheduling group such as {@link ProcessList#SCHED_GROUP_DEFAULT}, + * otherwise {@link ProcessList#SCHED_GROUP_UNDEFINED} if this queue + * has no opinion. + */ + public abstract int getPreferredSchedulingGroupLocked(@NonNull ProcessRecord app); /** * Enqueue the given broadcast to be eventually dispatched. diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java index a2906156e3b9..56112cfbc3e9 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java @@ -104,6 +104,8 @@ public class BroadcastQueueImpl extends BroadcastQueue { */ final boolean mDelayBehindServices; + final int mSchedGroup; + /** * Lists of all active broadcasts that are to be executed immediately * (without waiting for another broadcast to finish). Currently this only @@ -183,17 +185,19 @@ public class BroadcastQueueImpl extends BroadcastQueue { } BroadcastQueueImpl(ActivityManagerService service, Handler handler, - String name, BroadcastConstants constants, boolean allowDelayBehindServices) { + String name, BroadcastConstants constants, boolean allowDelayBehindServices, + int schedGroup) { this(service, handler, name, constants, new BroadcastSkipPolicy(service), - new BroadcastHistory(), allowDelayBehindServices); + new BroadcastHistory(), allowDelayBehindServices, schedGroup); } BroadcastQueueImpl(ActivityManagerService service, Handler handler, String name, BroadcastConstants constants, BroadcastSkipPolicy skipPolicy, - BroadcastHistory history, boolean allowDelayBehindServices) { + BroadcastHistory history, boolean allowDelayBehindServices, int schedGroup) { super(service, handler, name, constants, skipPolicy, history); mHandler = new BroadcastHandler(handler.getLooper()); mDelayBehindServices = allowDelayBehindServices; + mSchedGroup = schedGroup; mDispatcher = new BroadcastDispatcher(this, mConstants, mHandler, mService); } @@ -214,6 +218,18 @@ public class BroadcastQueueImpl extends BroadcastQueue { return mDispatcher.getActiveBroadcastLocked(); } + public int getPreferredSchedulingGroupLocked(ProcessRecord app) { + final BroadcastRecord active = getActiveBroadcastLocked(); + if (active != null && active.curApp == app) { + return mSchedGroup; + } + final BroadcastRecord pending = getPendingBroadcastLocked(); + if (pending != null && pending.curApp == app) { + return mSchedGroup; + } + return ProcessList.SCHED_GROUP_UNDEFINED; + } + public void enqueueBroadcastLocked(BroadcastRecord r) { final boolean replacePending = (r.intent.getFlags() & Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0; @@ -643,7 +659,7 @@ public class BroadcastQueueImpl extends BroadcastQueue { // If we want to wait behind services *AND* we're finishing the head/ // active broadcast on its queue if (waitForServices && r.curComponent != null && r.queue.isDelayBehindServices() - && r.queue.getActiveBroadcastLocked() == r) { + && ((BroadcastQueueImpl) r.queue).getActiveBroadcastLocked() == r) { ActivityInfo nextReceiver; if (r.nextReceiver < r.receivers.size()) { Object obj = r.receivers.get(r.nextReceiver); diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java index 12aa66b84d85..80dd2669a9a9 100644 --- a/services/core/java/com/android/server/am/OomAdjuster.java +++ b/services/core/java/com/android/server/am/OomAdjuster.java @@ -305,7 +305,7 @@ public class OomAdjuster { */ private final Handler mProcessGroupHandler; - private final ArraySet<BroadcastQueue> mTmpBroadcastQueue = new ArraySet(); + private final int[] mTmpSchedGroup = new int[1]; private final ActivityManagerService mService; private final ProcessList mProcessList; @@ -1677,14 +1677,13 @@ public class OomAdjuster { if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app); } - } else if (state.getCachedIsReceivingBroadcast(mTmpBroadcastQueue)) { + } else if (state.getCachedIsReceivingBroadcast(mTmpSchedGroup)) { // An app that is currently receiving a broadcast also // counts as being in the foreground for OOM killer purposes. // It's placed in a sched group based on the nature of the // broadcast as reflected by which queue it's active in. adj = ProcessList.FOREGROUND_APP_ADJ; - schedGroup = (mTmpBroadcastQueue.contains(mService.mFgBroadcastQueue)) - ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; + schedGroup = mTmpSchedGroup[0]; state.setAdjType("broadcast"); procState = ActivityManager.PROCESS_STATE_RECEIVER; if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java index a6b75009b35a..b74260ecbede 100644 --- a/services/core/java/com/android/server/am/ProcessList.java +++ b/services/core/java/com/android/server/am/ProcessList.java @@ -277,6 +277,8 @@ public final class ProcessList { // Memory pages are 4K. static final int PAGE_SIZE = 4 * 1024; + // Activity manager's version of an undefined schedule group + static final int SCHED_GROUP_UNDEFINED = Integer.MIN_VALUE; // Activity manager's version of Process.THREAD_GROUP_BACKGROUND static final int SCHED_GROUP_BACKGROUND = 0; // Activity manager's version of Process.THREAD_GROUP_RESTRICTED diff --git a/services/core/java/com/android/server/am/ProcessStateRecord.java b/services/core/java/com/android/server/am/ProcessStateRecord.java index eb1fd3aa49be..ef137787905f 100644 --- a/services/core/java/com/android/server/am/ProcessStateRecord.java +++ b/services/core/java/com/android/server/am/ProcessStateRecord.java @@ -30,7 +30,6 @@ import android.annotation.ElapsedRealtimeLong; import android.app.ActivityManager; import android.content.ComponentName; import android.os.SystemClock; -import android.util.ArraySet; import android.util.Slog; import android.util.TimeUtils; @@ -1071,14 +1070,12 @@ final class ProcessStateRecord { } @GuardedBy("mService") - boolean getCachedIsReceivingBroadcast(ArraySet<BroadcastQueue> tmpQueue) { + boolean getCachedIsReceivingBroadcast(int[] outSchedGroup) { if (mCachedIsReceivingBroadcast == VALUE_INVALID) { - tmpQueue.clear(); - mCachedIsReceivingBroadcast = mService.isReceivingBroadcastLocked(mApp, tmpQueue) + mCachedIsReceivingBroadcast = mService.isReceivingBroadcastLocked(mApp, outSchedGroup) ? VALUE_TRUE : VALUE_FALSE; if (mCachedIsReceivingBroadcast == VALUE_TRUE) { - mCachedSchedGroup = tmpQueue.contains(mService.mFgBroadcastQueue) - ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND; + mCachedSchedGroup = outSchedGroup[0]; mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER); } else { mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_BROADCAST_RECEIVER); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java index 94b7d5658961..9bdc93e11b6a 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java @@ -175,7 +175,8 @@ public class BroadcastQueueTest { if (mImpl == Impl.DEFAULT) { mQueue = new BroadcastQueueImpl(mAms, mHandlerThread.getThreadHandler(), TAG, - constants, emptySkipPolicy, emptyHistory, false); + constants, emptySkipPolicy, emptyHistory, false, + ProcessList.SCHED_GROUP_DEFAULT); } else { throw new UnsupportedOperationException(); } diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java index 598c6b0d9ab5..1c345484bd41 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java @@ -317,11 +317,11 @@ public class MockingOomAdjusterTests { ProcessRecord app = spy(makeDefaultProcessRecord(MOCKAPP_PID, MOCKAPP_UID, MOCKAPP_PROCESSNAME, MOCKAPP_PACKAGENAME, true)); doReturn(true).when(sService).isReceivingBroadcastLocked(any(ProcessRecord.class), - any(ArraySet.class)); + any(int[].class)); sService.mWakefulness.set(PowerManagerInternal.WAKEFULNESS_AWAKE); sService.mOomAdjuster.updateOomAdjLocked(app, OomAdjuster.OOM_ADJ_REASON_NONE); doReturn(false).when(sService).isReceivingBroadcastLocked(any(ProcessRecord.class), - any(ArraySet.class)); + any(int[].class)); assertProcStates(app, PROCESS_STATE_RECEIVER, FOREGROUND_APP_ADJ, SCHED_GROUP_BACKGROUND); } |