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

Commit 6c3670e1 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

[2/?] Reduce BroadcastQueue interface complexity.

Add unified enqueueBroadcastLocked() method which internally
handles implementation-specific details of ordered broadcasts and
FLAG_RECEIVER_REPLACE_PENDING.

Bug: 243656033
Test: atest CtsContentTestCases:BroadcastReceiverTest
Change-Id: I914b28183370836f920821a444006dacacff6b93
parent 12a69868
Loading
Loading
Loading
Loading
+3 −35
Original line number Diff line number Diff line
@@ -13119,7 +13119,6 @@ public class ActivityManagerService extends IActivityManager.Stub
    void updateUidReadyForBootCompletedBroadcastLocked(int uid) {
        for (BroadcastQueue queue : mBroadcastQueues) {
            queue.updateUidReadyForBootCompletedBroadcastLocked(uid);
            queue.scheduleBroadcastsLocked();
        }
    }
@@ -13369,8 +13368,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                            receivers, null, 0, null, null, false, true, true, -1, false, null,
                            false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */,
                            null /* filterExtrasForReceiver */);
                    queue.enqueueParallelBroadcastLocked(r);
                    queue.scheduleBroadcastsLocked();
                    queue.enqueueBroadcastLocked(r);
                }
            }
@@ -14248,13 +14246,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    sticky, false, userId, allowBackgroundActivityStarts,
                    backgroundActivityStartsToken, timeoutExempt, filterExtrasForReceiver);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
            final boolean replaced = replacePending
                    && (queue.replaceParallelBroadcastLocked(r) != null);
            // Note: We assume resultTo is null for non-ordered broadcasts.
            if (!replaced) {
                queue.enqueueParallelBroadcastLocked(r);
                queue.scheduleBroadcastsLocked();
            }
            queue.enqueueBroadcastLocked(r);
            registeredReceivers = null;
            NR = 0;
        }
@@ -14347,31 +14339,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    backgroundActivityStartsToken, timeoutExempt, filterExtrasForReceiver);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);
            final BroadcastRecord oldRecord =
                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;
            if (oldRecord != null) {
                // Replaced, fire the result-to receiver.
                if (oldRecord.resultTo != null) {
                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
                    try {
                        oldRecord.mIsReceiverAppRunning = true;
                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
                                oldRecord.intent,
                                Activity.RESULT_CANCELED, null, null,
                                false, false, oldRecord.userId, oldRecord.callingUid, callingUid,
                                SystemClock.uptimeMillis() - oldRecord.enqueueTime, 0);
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Failure ["
                                + queue.mQueueName + "] sending broadcast result of "
                                + intent, e);
                    }
                }
            } else {
                queue.enqueueOrderedBroadcastLocked(r);
                queue.scheduleBroadcastsLocked();
            }
            queue.enqueueBroadcastLocked(r);
        } else {
            // There was nobody interested in the broadcast, but we still want to record
            // that it happened.
+2 −2
Original line number Diff line number Diff line
@@ -162,7 +162,7 @@ public class BroadcastDispatcher {
    }

    private final Object mLock;
    private final BroadcastQueue mQueue;
    private final BroadcastQueueImpl mQueue;
    private final BroadcastConstants mConstants;
    private final Handler mHandler;
    private AlarmManagerInternal mAlarm;
@@ -489,7 +489,7 @@ public class BroadcastDispatcher {
    /**
     * Constructed & sharing a lock with its associated BroadcastQueue instance
     */
    public BroadcastDispatcher(BroadcastQueue queue, BroadcastConstants constants,
    public BroadcastDispatcher(BroadcastQueueImpl queue, BroadcastConstants constants,
            Handler handler, Object lock) {
        mQueue = queue;
        mConstants = constants;
+11 −17
Original line number Diff line number Diff line
@@ -16,13 +16,12 @@

package com.android.server.am;

import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.IIntentReceiver;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.proto.ProtoOutputStream;

import java.io.FileDescriptor;
@@ -65,13 +64,16 @@ public abstract class BroadcastQueue {

    public abstract BroadcastRecord getActiveBroadcastLocked();

    public abstract void enqueueParallelBroadcastLocked(BroadcastRecord r);

    public abstract void enqueueOrderedBroadcastLocked(BroadcastRecord r);

    public abstract BroadcastRecord replaceParallelBroadcastLocked(BroadcastRecord r);

    public abstract BroadcastRecord replaceOrderedBroadcastLocked(BroadcastRecord r);
    /**
     * Enqueue the given broadcast to be eventually dispatched.
     * <p>
     * Callers must populate {@link BroadcastRecord#receivers} with the relevant
     * targets before invoking this method.
     * <p>
     * When {@link Intent#FLAG_RECEIVER_REPLACE_PENDING} is set, this method
     * internally handles replacement of any matching broadcasts.
     */
    public abstract void enqueueBroadcastLocked(BroadcastRecord r);

    public abstract void updateUidReadyForBootCompletedBroadcastLocked(int uid);

@@ -81,8 +83,6 @@ public abstract class BroadcastQueue {

    public abstract void skipCurrentReceiverLocked(ProcessRecord app);

    public abstract void scheduleBroadcastsLocked();

    public abstract BroadcastRecord getMatchingOrderedReceiver(IBinder receiver);

    /**
@@ -97,12 +97,6 @@ public abstract class BroadcastQueue {

    public abstract void backgroundServicesFinishedLocked(int userId);

    public abstract void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
            Intent intent, int resultCode, String data, Bundle extras,
            boolean ordered, boolean sticky, int sendingUser,
            int receiverUid, int callingUid, long dispatchDelay,
            long receiveDelay) throws RemoteException;

    public abstract void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj);

    /**
+55 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ import static com.android.server.am.OomAdjuster.OOM_ADJ_REASON_START_RECEIVER;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.BroadcastOptions;
@@ -235,6 +236,59 @@ public class BroadcastQueueImpl extends BroadcastQueue {
        return mDispatcher.getActiveBroadcastLocked();
    }

    public void enqueueBroadcastLocked(BroadcastRecord r) {
        final boolean replacePending = (r.intent.getFlags()
                & Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;

        // Ordered broadcasts obviously need to be dispatched in serial order,
        // but this implementation expects all manifest receivers to also be
        // dispatched in a serial fashion
        boolean serialDispatch = r.ordered;
        if (!serialDispatch) {
            final int N = (r.receivers != null) ? r.receivers.size() : 0;
            for (int i = 0; i < N; i++) {
                if (r.receivers.get(i) instanceof ResolveInfo) {
                    serialDispatch = true;
                    break;
                }
            }
        }

        if (serialDispatch) {
            final BroadcastRecord oldRecord =
                    replacePending ? replaceOrderedBroadcastLocked(r) : null;
            if (oldRecord != null) {
                // Replaced, fire the result-to receiver.
                if (oldRecord.resultTo != null) {
                    try {
                        oldRecord.mIsReceiverAppRunning = true;
                        performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
                                oldRecord.intent,
                                Activity.RESULT_CANCELED, null, null,
                                false, false, oldRecord.userId, oldRecord.callingUid, r.callingUid,
                                SystemClock.uptimeMillis() - oldRecord.enqueueTime, 0);
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Failure ["
                                + mQueueName + "] sending broadcast result of "
                                + oldRecord.intent, e);

                    }
                }
            } else {
                enqueueOrderedBroadcastLocked(r);
                scheduleBroadcastsLocked();
            }
        } else {
            final boolean replaced = replacePending
                    && (replaceParallelBroadcastLocked(r) != null);
            // Note: We assume resultTo is null for non-ordered broadcasts.
            if (!replaced) {
                enqueueParallelBroadcastLocked(r);
                scheduleBroadcastsLocked();
            }
        }
    }

    public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
        r.enqueueClockTime = System.currentTimeMillis();
        r.enqueueTime = SystemClock.uptimeMillis();
@@ -366,6 +420,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
     */
    public void updateUidReadyForBootCompletedBroadcastLocked(int uid) {
        mDispatcher.updateUidReadyForBootCompletedBroadcastLocked(uid);
        scheduleBroadcastsLocked();
    }

    public boolean sendPendingBroadcastsLocked(ProcessRecord app) {