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

Commit 2d4f558d authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

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
parent d3d6760a
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -220,6 +220,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.
     *
+6 −1
Original line number Diff line number Diff line
@@ -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.
         */
+8 −0
Original line number Diff line number Diff line
@@ -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,
+11 −2
Original line number Diff line number Diff line
@@ -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);
        }
+13 −11
Original line number Diff line number Diff line
@@ -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();