summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Jeff Sharkey <jsharkey@android.com> 2022-08-24 15:20:14 -0600
committer Jeff Sharkey <jsharkey@android.com> 2022-08-24 16:53:45 -0600
commit6c3670e1b913b00d8a49bb03f73b2bd440da94aa (patch)
treedc46d5c89d9842796d88c40d81bafb24777971c9
parent12a69868a29e797320c7cb7ff84f0401066d3c47 (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
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java38
-rw-r--r--services/core/java/com/android/server/am/BroadcastDispatcher.java4
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java28
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueueImpl.java55
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) {