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 Original line Diff line number Diff line
@@ -13119,7 +13119,6 @@ public class ActivityManagerService extends IActivityManager.Stub
    void updateUidReadyForBootCompletedBroadcastLocked(int uid) {
    void updateUidReadyForBootCompletedBroadcastLocked(int uid) {
        for (BroadcastQueue queue : mBroadcastQueues) {
        for (BroadcastQueue queue : mBroadcastQueues) {
            queue.updateUidReadyForBootCompletedBroadcastLocked(uid);
            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,
                            receivers, null, 0, null, null, false, true, true, -1, false, null,
                            false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */,
                            false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */,
                            null /* filterExtrasForReceiver */);
                            null /* filterExtrasForReceiver */);
                    queue.enqueueParallelBroadcastLocked(r);
                    queue.enqueueBroadcastLocked(r);
                    queue.scheduleBroadcastsLocked();
                }
                }
            }
            }
@@ -14248,13 +14246,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    sticky, false, userId, allowBackgroundActivityStarts,
                    sticky, false, userId, allowBackgroundActivityStarts,
                    backgroundActivityStartsToken, timeoutExempt, filterExtrasForReceiver);
                    backgroundActivityStartsToken, timeoutExempt, filterExtrasForReceiver);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
            final boolean replaced = replacePending
            queue.enqueueBroadcastLocked(r);
                    && (queue.replaceParallelBroadcastLocked(r) != null);
            // Note: We assume resultTo is null for non-ordered broadcasts.
            if (!replaced) {
                queue.enqueueParallelBroadcastLocked(r);
                queue.scheduleBroadcastsLocked();
            }
            registeredReceivers = null;
            registeredReceivers = null;
            NR = 0;
            NR = 0;
        }
        }
@@ -14347,31 +14339,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    backgroundActivityStartsToken, timeoutExempt, filterExtrasForReceiver);
                    backgroundActivityStartsToken, timeoutExempt, filterExtrasForReceiver);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);
            queue.enqueueBroadcastLocked(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();
            }
        } else {
        } else {
            // There was nobody interested in the broadcast, but we still want to record
            // There was nobody interested in the broadcast, but we still want to record
            // that it happened.
            // that it happened.
+2 −2
Original line number Original line Diff line number Diff line
@@ -162,7 +162,7 @@ public class BroadcastDispatcher {
    }
    }


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


package com.android.server.am;
package com.android.server.am;


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


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


    public abstract BroadcastRecord getActiveBroadcastLocked();
    public abstract BroadcastRecord getActiveBroadcastLocked();


    public abstract void enqueueParallelBroadcastLocked(BroadcastRecord r);
    /**

     * Enqueue the given broadcast to be eventually dispatched.
    public abstract void enqueueOrderedBroadcastLocked(BroadcastRecord r);
     * <p>

     * Callers must populate {@link BroadcastRecord#receivers} with the relevant
    public abstract BroadcastRecord replaceParallelBroadcastLocked(BroadcastRecord r);
     * targets before invoking this method.

     * <p>
    public abstract BroadcastRecord replaceOrderedBroadcastLocked(BroadcastRecord r);
     * 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);
    public abstract void updateUidReadyForBootCompletedBroadcastLocked(int uid);


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


    public abstract void skipCurrentReceiverLocked(ProcessRecord app);
    public abstract void skipCurrentReceiverLocked(ProcessRecord app);


    public abstract void scheduleBroadcastsLocked();

    public abstract BroadcastRecord getMatchingOrderedReceiver(IBinder receiver);
    public abstract BroadcastRecord getMatchingOrderedReceiver(IBinder receiver);


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


    public abstract void backgroundServicesFinishedLocked(int userId);
    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);
    public abstract void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj);


    /**
    /**
+55 −0
Original line number Original line 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.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager;
import android.app.AppGlobals;
import android.app.AppGlobals;
import android.app.BroadcastOptions;
import android.app.BroadcastOptions;
@@ -235,6 +236,59 @@ public class BroadcastQueueImpl extends BroadcastQueue {
        return mDispatcher.getActiveBroadcastLocked();
        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) {
    public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
        r.enqueueClockTime = System.currentTimeMillis();
        r.enqueueClockTime = System.currentTimeMillis();
        r.enqueueTime = SystemClock.uptimeMillis();
        r.enqueueTime = SystemClock.uptimeMillis();
@@ -366,6 +420,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
     */
     */
    public void updateUidReadyForBootCompletedBroadcastLocked(int uid) {
    public void updateUidReadyForBootCompletedBroadcastLocked(int uid) {
        mDispatcher.updateUidReadyForBootCompletedBroadcastLocked(uid);
        mDispatcher.updateUidReadyForBootCompletedBroadcastLocked(uid);
        scheduleBroadcastsLocked();
    }
    }


    public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
    public boolean sendPendingBroadcastsLocked(ProcessRecord app) {