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

Commit d3d6760a authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

BroadcastQueue: more misc fixes before dogfooding.

When sending broadcasts destined for a mix of registered and manifest
receivers, we need to send the combined list together to avoid the
second duplicated send from applying BroadcastOptions policy to skip
the registered receivers sent moments earlier.

SystemActions needs to send its a11y broadcasts as "foreground" since
they're user-requested actions, otherwise they risk being delayed
beyond the short timeouts used in tests.

Bug: 254769026, 254763137, 254761140
Test: atest PlatformScenarioTests:QSMediaController
Test: atest CtsInputMethodTestCases:FocusHandlingTest
Test: atest CtsContentTestCases:PackageManagerShellCommandMultiUserTest
Change-Id: I6e87a5444c65fbc06829d6732dd33aca1b9e6097
parent 620c07fb
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -597,6 +597,7 @@ public class SystemActions implements CoreStartable {
                case INTENT_ACTION_DPAD_CENTER: {
                    Intent intent = new Intent(intentAction);
                    intent.setPackage(context.getPackageName());
                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                    return PendingIntent.getBroadcast(context, 0, intent,
                            PendingIntent.FLAG_IMMUTABLE);
                }
+4 −2
Original line number Diff line number Diff line
@@ -14455,10 +14455,12 @@ public class ActivityManagerService extends IActivityManager.Stub
        filterNonExportedComponents(intent, callingUid, registeredReceivers,
                mPlatformCompat, callerPackage);
        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
        if (!ordered && NR > 0) {
        if (!ordered && NR > 0 && !mEnableModernQueue) {
            // If we are not serializing this broadcast, then send the
            // registered receivers separately so they don't wait for the
            // components to be launched.
            // components to be launched. We don't do this split for the modern
            // queue because delivery to registered receivers isn't blocked
            // behind manifest receivers.
            if (isCallerSystem) {
                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
                        isProtectedBroadcast, registeredReceivers);
+18 −5
Original line number Diff line number Diff line
@@ -210,6 +210,12 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
    private final BroadcastConstants mFgConstants;
    private final BroadcastConstants mBgConstants;

    /**
     * Timestamp when last {@link #testAllProcessQueues} failure was observed;
     * used for throttling log messages.
     */
    private @UptimeMillisLong long mLastTestFailureTime;

    private static final int MSG_UPDATE_RUNNING_LIST = 1;
    private static final int MSG_DELIVERY_TIMEOUT_SOFT = 2;
    private static final int MSG_DELIVERY_TIMEOUT_HARD = 3;
@@ -521,6 +527,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {

    @Override
    public void enqueueBroadcastLocked(@NonNull BroadcastRecord r) {
        if (DEBUG_BROADCAST) logv("Enqueuing " + r + " for " + r.receivers.size() + " receivers");

        r.applySingletonPolicy(mService);

        final IntentFilter removeMatchingFilter = (r.options != null)
@@ -859,10 +867,11 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
            mLocalHandler.removeMessages(MSG_DELIVERY_TIMEOUT_HARD, queue);
        }

        // Even if we have more broadcasts, if we've made reasonable progress
        // and someone else is waiting, retire ourselves to avoid starvation
        final boolean shouldRetire = (mRunnableHead != null)
                && (queue.getActiveCountSinceIdle() >= mConstants.MAX_RUNNING_ACTIVE_BROADCASTS);
        // If we've made reasonable progress, periodically retire ourselves to
        // avoid starvation of other processes and stack overflow when a
        // broadcast is immediately finished without waiting
        final boolean shouldRetire =
                (queue.getActiveCountSinceIdle() >= mConstants.MAX_RUNNING_ACTIVE_BROADCASTS);

        if (queue.isRunnable() && queue.isProcessWarm() && !shouldRetire) {
            // We're on a roll; move onto the next broadcast for this process
@@ -1034,7 +1043,11 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
            BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
            while (leaf != null) {
                if (!test.test(leaf)) {
                    final long now = SystemClock.uptimeMillis();
                    if (now > mLastTestFailureTime + DateUtils.SECOND_IN_MILLIS) {
                        mLastTestFailureTime = now;
                        logv("Test " + label + " failed due to " + leaf.toShortString(), pw);
                    }
                    return false;
                }
                leaf = leaf.processNameNext;