diff options
| author | 2022-10-19 12:16:40 -0600 | |
|---|---|---|
| committer | 2022-10-24 14:53:19 -0600 | |
| commit | 2d4f558d57cf343e059c8174ba6482558bcab493 (patch) | |
| tree | d9102d0847b96baee240dc8e7236b8044edb56b4 | |
| parent | d3d6760a967545c1f71c6202da4701f1e8b20c75 (diff) | |
Deliver handful of system broadcasts as unordered.
Several existing broadcasts are being sent as ordered simply to
receive a "resultTo" signal when dispatch is finished. This was
reasonable in the legacy stack, since only one receiver was
dispatched at a time, but the modern stack can dispatch to multiple
receivers in parallel.
This change updates BOOT, SCREEN, and PACKAGE broadcasts to pivot
to this new approach when the modern queue is enabled; we retain
the previous ordered behavior when the legacy queue is being used.
Bug: 253226131
Test: atest FrameworksMockingServicesTests:BroadcastRecordTest
Test: atest FrameworksMockingServicesTests:BroadcastQueueTest
Test: atest FrameworksMockingServicesTests:BroadcastQueueModernImplTest
Change-Id: I81299b9ec6f509f5b73dfe9484aca12794eb3868
5 files changed, 44 insertions, 14 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index b8030702c244..4b1b0a260e27 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -221,6 +221,12 @@ public abstract class ActivityManagerInternal { public abstract boolean isSystemReady(); /** + * @return {@code true} if system is using the "modern" broadcast queue, + * {@code false} otherwise. + */ + public abstract boolean isModernQueueEnabled(); + + /** * Returns package name given pid. * * @param pid The pid we are searching package name for. diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c29ad73026e5..c06da5f7ee17 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -13893,7 +13893,7 @@ public class ActivityManagerService extends IActivityManager.Stub if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent + " ordered=" + ordered + " userid=" + userId); - if ((resultTo != null) && !ordered) { + if ((resultTo != null) && !ordered && !mEnableModernQueue) { Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!"); } @@ -16893,6 +16893,11 @@ public class ActivityManagerService extends IActivityManager.Stub return mSystemReady; } + @Override + public boolean isModernQueueEnabled() { + return mEnableModernQueue; + } + /** * Returns package name by pid. */ diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 3fa41c0f0420..3c26116e8ad2 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -3327,6 +3327,14 @@ class UserController implements Handler.Callback { } EventLog.writeEvent(EventLogTags.UC_SEND_USER_BROADCAST, logUserId, intent.getAction()); + // When the modern broadcast stack is enabled, deliver all our + // broadcasts as unordered, since the modern stack has better + // support for sequencing cold-starts, and it supports delivering + // resultTo for non-ordered broadcasts + if (mService.mEnableModernQueue) { + ordered = false; + } + // TODO b/64165549 Verify that mLock is not held before calling AMS methods synchronized (mService) { return mService.broadcastIntentLocked(null, null, null, intent, resolvedType, diff --git a/services/core/java/com/android/server/pm/BroadcastHelper.java b/services/core/java/com/android/server/pm/BroadcastHelper.java index 4e9c472c479a..d6233c7afe22 100644 --- a/services/core/java/com/android/server/pm/BroadcastHelper.java +++ b/services/core/java/com/android/server/pm/BroadcastHelper.java @@ -148,9 +148,18 @@ public final class BroadcastHelper { + intent.toShortString(false, true, false, false) + " " + intent.getExtras(), here); } + final boolean ordered; + if (mAmInternal.isModernQueueEnabled()) { + // When the modern broadcast stack is enabled, deliver all our + // broadcasts as unordered, since the modern stack has better + // support for sequencing cold-starts, and it supports + // delivering resultTo for non-ordered broadcasts + ordered = false; + } else { + ordered = (finishedReceiver != null); + } mAmInternal.broadcastIntent( - intent, finishedReceiver, requiredPermissions, - finishedReceiver != null, userId, + intent, finishedReceiver, requiredPermissions, ordered, userId, broadcastAllowList == null ? null : broadcastAllowList.get(userId), filterExtrasForReceiver, bOptions); } diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java index 69fb22c28728..1fe82f472937 100644 --- a/services/core/java/com/android/server/power/Notifier.java +++ b/services/core/java/com/android/server/power/Notifier.java @@ -22,8 +22,8 @@ import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.BroadcastOptions; import android.app.trust.TrustManager; -import android.content.BroadcastReceiver; import android.content.Context; +import android.content.IIntentReceiver; import android.content.Intent; import android.content.IntentFilter; import android.hardware.display.DisplayManagerInternal; @@ -796,18 +796,19 @@ public class Notifier { } if (mActivityManagerInternal.isSystemReady()) { - mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null, - AppOpsManager.OP_NONE, mScreenOnOptions, mWakeUpBroadcastDone, mHandler, - 0, null, null); + final boolean ordered = !mActivityManagerInternal.isModernQueueEnabled(); + mActivityManagerInternal.broadcastIntent(mScreenOnIntent, mWakeUpBroadcastDone, + null, ordered, UserHandle.USER_ALL, null, null, mScreenOnOptions); } else { EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1); sendNextBroadcast(); } } - private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() { + private final IIntentReceiver mWakeUpBroadcastDone = new IIntentReceiver.Stub() { @Override - public void onReceive(Context context, Intent intent) { + public void performReceive(Intent intent, int resultCode, String data, Bundle extras, + boolean ordered, boolean sticky, int sendingUser) { EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1, SystemClock.uptimeMillis() - mBroadcastStartTime, 1); sendNextBroadcast(); @@ -820,18 +821,19 @@ public class Notifier { } if (mActivityManagerInternal.isSystemReady()) { - mContext.sendOrderedBroadcastAsUser(mScreenOffIntent, UserHandle.ALL, null, - AppOpsManager.OP_NONE, mScreenOffOptions, mGoToSleepBroadcastDone, mHandler, - 0, null, null); + final boolean ordered = !mActivityManagerInternal.isModernQueueEnabled(); + mActivityManagerInternal.broadcastIntent(mScreenOffIntent, mGoToSleepBroadcastDone, + null, ordered, UserHandle.USER_ALL, null, null, mScreenOffOptions); } else { EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 3, 1); sendNextBroadcast(); } } - private final BroadcastReceiver mGoToSleepBroadcastDone = new BroadcastReceiver() { + private final IIntentReceiver mGoToSleepBroadcastDone = new IIntentReceiver.Stub() { @Override - public void onReceive(Context context, Intent intent) { + public void performReceive(Intent intent, int resultCode, String data, Bundle extras, + boolean ordered, boolean sticky, int sendingUser) { EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 0, SystemClock.uptimeMillis() - mBroadcastStartTime, 1); sendNextBroadcast(); |