diff options
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); } |