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

Commit 4d2261d5 authored by Sudheer Shanka's avatar Sudheer Shanka
Browse files

Retry when manifest broadcast delivery fails.

Bug: 281597599
Test: atest services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
Test: atest services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
Change-Id: I218790958148e51d4205dce2370a15d4a5ab6394
parent b185da2a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -4854,7 +4854,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                    }
                    checkTime(startTime, "finishAttachApplicationInner: "
                            + "after dispatching broadcasts");
                } catch (Exception e) {
                } catch (BroadcastDeliveryFailedException e) {
                    // If the app died trying to launch the receiver we declare it 'bad'
                    Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
                    badApp = true;
+32 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2023 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;

import android.util.AndroidException;

/**
 * Exception to represent that broadcast could not be delivered.
 */
public class BroadcastDeliveryFailedException extends AndroidException {
    public BroadcastDeliveryFailedException(String name) {
        super(name);
    }

    public BroadcastDeliveryFailedException(Exception cause) {
        super(cause);
    }
}
+19 −0
Original line number Diff line number Diff line
@@ -279,6 +279,25 @@ class BroadcastProcessQueue {
        return null;
    }

    /**
     * Re-enqueue the active broadcast so that it can be made active and delivered again. In order
     * to keep its previous position same to avoid issues with reordering, insert it at the head
     * of the queue.
     *
     * Callers are responsible for clearing the active broadcast by calling
     * {@link #makeActiveIdle()} after re-enqueuing it.
     */
    public void reEnqueueActiveBroadcast() {
        final BroadcastRecord record = getActive();
        final int recordIndex = getActiveIndex();

        final SomeArgs broadcastArgs = SomeArgs.obtain();
        broadcastArgs.arg1 = record;
        broadcastArgs.argi1 = recordIndex;
        getQueueForBroadcast(record).addFirst(broadcastArgs);
        onBroadcastEnqueued(record, recordIndex);
    }

    /**
     * Searches from newest to oldest in the pending broadcast queues, and at the first matching
     * pending broadcast it finds, replaces it in-place and returns -- does not attempt to handle
+2 −1
Original line number Diff line number Diff line
@@ -148,7 +148,8 @@ public abstract class BroadcastQueue {
     *         dispatching a pending broadcast
     */
    @GuardedBy("mService")
    public abstract boolean onApplicationAttachedLocked(@NonNull ProcessRecord app);
    public abstract boolean onApplicationAttachedLocked(@NonNull ProcessRecord app)
            throws BroadcastDeliveryFailedException;

    /**
     * Signal from OS internals that the given process has timed out during
+5 −3
Original line number Diff line number Diff line
@@ -438,7 +438,8 @@ public class BroadcastQueueImpl extends BroadcastQueue {
        scheduleBroadcastsLocked();
    }

    public boolean onApplicationAttachedLocked(ProcessRecord app) {
    public boolean onApplicationAttachedLocked(ProcessRecord app)
            throws BroadcastDeliveryFailedException {
        updateUidReadyForBootCompletedBroadcastLocked(app.uid);

        if (mPendingBroadcast != null && mPendingBroadcast.curApp == app) {
@@ -460,7 +461,8 @@ public class BroadcastQueueImpl extends BroadcastQueue {
        skipCurrentOrPendingReceiverLocked(app);
    }

    public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
    public boolean sendPendingBroadcastsLocked(ProcessRecord app)
            throws BroadcastDeliveryFailedException {
        boolean didSomething = false;
        final BroadcastRecord br = mPendingBroadcast;
        if (br != null && br.curApp.getPid() > 0 && br.curApp.getPid() == app.getPid()) {
@@ -483,7 +485,7 @@ public class BroadcastQueueImpl extends BroadcastQueue {
                scheduleBroadcastsLocked();
                // We need to reset the state if we failed to start the receiver.
                br.state = BroadcastRecord.IDLE;
                throw new RuntimeException(e.getMessage());
                throw new BroadcastDeliveryFailedException(e);
            }
        }
        return didSomething;
Loading