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

Commit 817cd868 authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Android (Google) Code Review
Browse files

Merge "Ignore re-enqueued bcast delivery failure to avoid repeated attempts." into main

parents 92b9d407 1158e704
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -151,6 +151,11 @@ class BroadcastProcessQueue {
     */
    private int mActiveIndex;

    /**
     * True if the broadcast actively being dispatched to this process was re-enqueued previously.
     */
    private boolean mActiveReEnqueued;

    /**
     * Count of {@link #mActive} broadcasts that have been dispatched since this
     * queue was last idle.
@@ -312,6 +317,7 @@ class BroadcastProcessQueue {
        final SomeArgs broadcastArgs = SomeArgs.obtain();
        broadcastArgs.arg1 = record;
        broadcastArgs.argi1 = recordIndex;
        broadcastArgs.argi2 = 1;
        getQueueForBroadcast(record).addFirst(broadcastArgs);
        onBroadcastEnqueued(record, recordIndex);
    }
@@ -609,6 +615,7 @@ class BroadcastProcessQueue {
        final SomeArgs next = removeNextBroadcast();
        mActive = (BroadcastRecord) next.arg1;
        mActiveIndex = next.argi1;
        mActiveReEnqueued = (next.argi2 == 1);
        mActiveCountSinceIdle++;
        mActiveAssumedDeliveryCountSinceIdle +=
                (mActive.isAssumedDelivered(mActiveIndex) ? 1 : 0);
@@ -624,12 +631,21 @@ class BroadcastProcessQueue {
    public void makeActiveIdle() {
        mActive = null;
        mActiveIndex = 0;
        mActiveReEnqueued = false;
        mActiveCountSinceIdle = 0;
        mActiveAssumedDeliveryCountSinceIdle = 0;
        mActiveViaColdStart = false;
        invalidateRunnableAt();
    }

    public boolean wasActiveBroadcastReEnqueued() {
        // If the flag is not enabled, treat as if the broadcast was never re-enqueued.
        if (!Flags.avoidRepeatedBcastReEnqueues()) {
            return false;
        }
        return mActiveReEnqueued;
    }

    /**
     * Update summary statistics when the given record has been enqueued.
     */
@@ -1476,6 +1492,9 @@ class BroadcastProcessQueue {
        if (runningOomAdjusted) {
            pw.print("runningOomAdjusted:"); pw.println(runningOomAdjusted);
        }
        if (mActiveReEnqueued) {
            pw.print("activeReEnqueued:"); pw.println(mActiveReEnqueued);
        }
    }

    @NeverCompile
+29 −17
Original line number Diff line number Diff line
@@ -542,8 +542,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                updateOomAdj |= queue.runningOomAdjusted;
                try {
                    completed = scheduleReceiverWarmLocked(queue);
                } catch (BroadcastDeliveryFailedException e) {
                    reEnqueueActiveBroadcast(queue);
                } catch (BroadcastRetryException e) {
                    finishOrReEnqueueActiveBroadcast(queue);
                    completed = true;
                }
            } else {
@@ -586,7 +586,12 @@ class BroadcastQueueModernImpl extends BroadcastQueue {

    private void clearInvalidPendingColdStart() {
        logw("Clearing invalid pending cold start: " + mRunningColdStart);
        if (mRunningColdStart.wasActiveBroadcastReEnqueued()) {
            finishReceiverActiveLocked(mRunningColdStart, BroadcastRecord.DELIVERY_FAILURE,
                    "invalid start with re-enqueued broadcast");
        } else {
            mRunningColdStart.reEnqueueActiveBroadcast();
        }
        demoteFromRunningLocked(mRunningColdStart);
        clearRunningColdStart();
        enqueueUpdateRunningList();
@@ -613,19 +618,26 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
        }
    }

    private void reEnqueueActiveBroadcast(@NonNull BroadcastProcessQueue queue) {
    private void finishOrReEnqueueActiveBroadcast(@NonNull BroadcastProcessQueue queue) {
        checkState(queue.isActive(), "isActive");

        if (queue.wasActiveBroadcastReEnqueued()) {
            // If the broadcast was already re-enqueued previously, finish it to avoid repeated
            // delivery attempts
            finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
                    "re-enqueued broadcast delivery failed");
        } else {
            final BroadcastRecord record = queue.getActive();
            final int index = queue.getActiveIndex();
            setDeliveryState(queue, queue.app, record, index, record.receivers.get(index),
                    BroadcastRecord.DELIVERY_PENDING, "reEnqueueActiveBroadcast");
            queue.reEnqueueActiveBroadcast();
        }
    }

    @Override
    public boolean onApplicationAttachedLocked(@NonNull ProcessRecord app)
            throws BroadcastDeliveryFailedException {
            throws BroadcastRetryException {
        if (DEBUG_BROADCAST) {
            logv("Process " + app + " is attached");
        }
@@ -653,8 +665,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                if (scheduleReceiverWarmLocked(queue)) {
                    demoteFromRunningLocked(queue);
                }
            } catch (BroadcastDeliveryFailedException e) {
                reEnqueueActiveBroadcast(queue);
            } catch (BroadcastRetryException e) {
                finishOrReEnqueueActiveBroadcast(queue);
                demoteFromRunningLocked(queue);
                throw e;
            }
@@ -983,7 +995,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
    @CheckResult
    @GuardedBy("mService")
    private boolean scheduleReceiverWarmLocked(@NonNull BroadcastProcessQueue queue)
            throws BroadcastDeliveryFailedException {
            throws BroadcastRetryException {
        checkState(queue.isActive(), "isActive");

        final int cookie = traceBegin("scheduleReceiverWarmLocked");
@@ -1065,7 +1077,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
     */
    @CheckResult
    private boolean dispatchReceivers(@NonNull BroadcastProcessQueue queue,
            @NonNull BroadcastRecord r, int index) throws BroadcastDeliveryFailedException {
            @NonNull BroadcastRecord r, int index) throws BroadcastRetryException {
        final ProcessRecord app = queue.app;
        final Object receiver = r.receivers.get(index);

@@ -1157,7 +1169,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                // to try redelivering the broadcast to this receiver.
                if (receiver instanceof ResolveInfo) {
                    cancelDeliveryTimeoutLocked(queue);
                    throw new BroadcastDeliveryFailedException(e);
                    throw new BroadcastRetryException(e);
                }
                finishReceiverActiveLocked(queue, BroadcastRecord.DELIVERY_FAILURE,
                        "remote app");
@@ -1316,8 +1328,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
                demoteFromRunningLocked(queue);
                return true;
            }
        } catch (BroadcastDeliveryFailedException e) {
            reEnqueueActiveBroadcast(queue);
        } catch (BroadcastRetryException e) {
            finishOrReEnqueueActiveBroadcast(queue);
            demoteFromRunningLocked(queue);
            return true;
        }
+30 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.am;

/**
 * Exception to represent that broadcast delivery failed and we should try redelivering it.
 */
public class BroadcastRetryException extends BroadcastDeliveryFailedException {
    public BroadcastRetryException(String name) {
        super(name);
    }

    public BroadcastRetryException(Exception cause) {
        super(cause);
    }
}
+11 −0
Original line number Diff line number Diff line
@@ -42,3 +42,14 @@ flag {
    description: "Optimize the service bindings by different policies like skipping oom adjuster"
    bug: "318717054"
}

flag {
    namespace: "backstage_power"
    name: "avoid_repeated_bcast_re_enqueues"
    description: "Avoid re-enqueueing a broadcast repeatedly"
    bug: "319225224"
    is_fixed_read_only: true
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}
+1 −0
Original line number Diff line number Diff line
@@ -73,6 +73,7 @@ android_test {
        "testng",
        "compatibility-device-util-axt",
        "flag-junit",
        "am_flags_lib",
    ],

    libs: [
Loading