diff options
| author | 2022-08-24 15:20:14 -0600 | |
|---|---|---|
| committer | 2022-08-24 16:53:45 -0600 | |
| commit | 6c3670e1b913b00d8a49bb03f73b2bd440da94aa (patch) | |
| tree | dc46d5c89d9842796d88c40d81bafb24777971c9 | |
| parent | 12a69868a29e797320c7cb7ff84f0401066d3c47 (diff) | |
[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
4 files changed, 71 insertions, 54 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index e79a3c6cd629..a0c2ad57241b 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -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. diff --git a/services/core/java/com/android/server/am/BroadcastDispatcher.java b/services/core/java/com/android/server/am/BroadcastDispatcher.java index 49477ad75302..e9a36e05c6c1 100644 --- a/services/core/java/com/android/server/am/BroadcastDispatcher.java +++ b/services/core/java/com/android/server/am/BroadcastDispatcher.java @@ -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; diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 7f9390d50238..d0946bec730a 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -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); /** diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java index 2f5e35f6a032..4bffe351a379 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java @@ -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) { |