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

Commit 60df0ce7 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

[6/?] Reduce BroadcastQueue interface complexity.

Hide getMatchingOrderedReceiver() as an implementation detail inside
the broadcast stack.

Also fix obscure unregisterReceiver() bug.  The currently active
receiver is being set like this:

    void deliverToRegisteredReceiverLocked() {
        ...
        r.receiver = filter.receiverList.receiver.asBinder();

Which means that unregisterReceiver() should be using
IIntentReceiver.asBinder() to accurately match any active broadcasts
during unregistration.  (The code before this change passed a
BroadcastRecord instance, which would never match.)

Bug: 243656033
Test: atest CtsContentTestCases:BroadcastReceiverTest
Change-Id: I8594e5060eed5f4dc0d58a29f42cf422b07c6ba7
parent fc02e8a4
Loading
Loading
Loading
Loading
+18 −24
Original line number Diff line number Diff line
@@ -670,25 +670,33 @@ public class ActivityManagerService extends IActivityManager.Stub
    TraceErrorLogger mTraceErrorLogger;
    BroadcastQueue broadcastQueueForIntent(Intent intent) {
        if (isOnFgOffloadQueue(intent.getFlags())) {
        return broadcastQueueForFlags(intent.getFlags(), intent);
    }
    BroadcastQueue broadcastQueueForFlags(int flags) {
        return broadcastQueueForFlags(flags, null);
    }
    BroadcastQueue broadcastQueueForFlags(int flags, Object cookie) {
        if (isOnFgOffloadQueue(flags)) {
            if (DEBUG_BROADCAST_BACKGROUND) {
                Slog.i(TAG_BROADCAST,
                        "Broadcast intent " + intent + " on foreground offload queue");
                        "Broadcast intent " + cookie + " on foreground offload queue");
            }
            return mFgOffloadBroadcastQueue;
        }
        if (isOnBgOffloadQueue(intent.getFlags())) {
        if (isOnBgOffloadQueue(flags)) {
            if (DEBUG_BROADCAST_BACKGROUND) {
                Slog.i(TAG_BROADCAST,
                        "Broadcast intent " + intent + " on background offload queue");
                        "Broadcast intent " + cookie + " on background offload queue");
            }
            return mBgOffloadBroadcastQueue;
        }
        final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
        final boolean isFg = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
                "Broadcast intent " + intent + " on "
                "Broadcast intent " + cookie + " on "
                + (isFg ? "foreground" : "background") + " queue");
        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
    }
@@ -13328,20 +13336,18 @@ public class ActivityManagerService extends IActivityManager.Stub
        final long origId = Binder.clearCallingIdentity();
        try {
            boolean doTrim = false;
            synchronized(this) {
                ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
                if (rl != null) {
                    final BroadcastRecord r = rl.curBroadcast;
                    if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
                    if (r != null) {
                        final boolean doNext = r.queue.finishReceiverLocked(
                                r, r.resultCode, r.resultData, r.resultExtras,
                                receiver.asBinder(), r.resultCode, r.resultData, r.resultExtras,
                                r.resultAbort, false);
                        if (doNext) {
                            doTrim = true;
                        }
                    }
                    if (rl.app != null) {
                        rl.app.mReceivers.removeReceiver(rl);
                    }
@@ -14518,22 +14524,10 @@ public class ActivityManagerService extends IActivityManager.Stub
            boolean doNext = false;
            BroadcastRecord r;
            BroadcastQueue queue;
            synchronized(this) {
                if (isOnFgOffloadQueue(flags)) {
                    queue = mFgOffloadBroadcastQueue;
                } else if (isOnBgOffloadQueue(flags)) {
                    queue = mBgOffloadBroadcastQueue;
                } else {
                    queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
                            ? mFgBroadcastQueue : mBgBroadcastQueue;
                }
                r = queue.getMatchingOrderedReceiver(who);
                if (r != null) {
                    doNext = r.queue.finishReceiverLocked(r, resultCode,
                queue = broadcastQueueForFlags(flags);
                doNext = queue.finishReceiverLocked(who, resultCode,
                        resultData, resultExtras, resultAbort, true);
                }
                // updateOomAdjLocked() will be done here
                trimApplicationsLocked(false, OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER);
            }
+4 −3
Original line number Diff line number Diff line
@@ -75,16 +75,17 @@ public abstract class BroadcastQueue {
     */
    public abstract void enqueueBroadcastLocked(BroadcastRecord r);

    public abstract BroadcastRecord getMatchingOrderedReceiver(IBinder receiver);

    /**
     * Signal delivered back from a {@link BroadcastReceiver} to indicate that
     * it's finished processing the current broadcast being dispatched to it.
     * <p>
     * If this signal isn't delivered back in a timely fashion, we assume the
     * receiver has somehow wedged and we trigger an ANR.
     *
     * @param receiver the value to match against
     *            {@link BroadcastRecord#receiver} to identify the caller.
     */
    public abstract boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
    public abstract boolean finishReceiverLocked(IBinder receiver, int resultCode,
            String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices);

    public abstract void backgroundServicesFinishedLocked(int userId);
+11 −0
Original line number Diff line number Diff line
@@ -551,6 +551,17 @@ public class BroadcastQueueImpl extends BroadcastQueue {
        }, msgToken, (r.receiverTime + mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT));
    }

    public boolean finishReceiverLocked(IBinder receiver, int resultCode,
            String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
        final BroadcastRecord r = getMatchingOrderedReceiver(receiver);
        if (r != null) {
            return finishReceiverLocked(r, resultCode,
                    resultData, resultExtras, resultAbort, waitForServices);
        } else {
            return false;
        }
    }

    public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
            String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
        final int state = r.state;