Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 88fe1a30 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

[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
parent 5b2df738
Loading
Loading
Loading
Loading
+9 −26
Original line number Diff line number Diff line
@@ -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,
+9 −5
Original line number Diff line number Diff line
@@ -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.
+20 −4
Original line number Diff line number Diff line
@@ -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);
+3 −4
Original line number Diff line number Diff line
@@ -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) {
+2 −0
Original line number Diff line number Diff line
@@ -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
Loading