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

Commit 7b234eef authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

[3/?] Reduce BroadcastQueue interface complexity.

Instead of requesting a specific concrete action of the broadcast
stack, pivot to communicating application lifecycle changes, which
the broadcast stack can then respond to internally.

Slight rename to skipCurrentOrPendingReceiverLocked() to reflect
that it will skip either the current or pending receiver.  This
renamed method is then called via onApplicationTimeoutLocked(),
which previously tried applying pending-vs-current nuance where
it appears to have not been needed.

Bug: 243656033
Test: atest CtsContentTestCases:BroadcastReceiverTest
Change-Id: I451df11e499465940658e15d730491f44add9b62
parent 6c3670e1
Loading
Loading
Loading
Loading
+12 −56
Original line number Diff line number Diff line
@@ -4600,6 +4600,10 @@ public class ActivityManagerService extends IActivityManager.Stub
                mCpHelper.cleanupAppInLaunchingProvidersLocked(app, true);
                // Take care of any services that are waiting for the process.
                mServices.processStartTimedOutLocked(app);
                // Take care of any broadcasts waiting for the process.
                for (BroadcastQueue queue : mBroadcastQueues) {
                    queue.onApplicationTimeoutLocked(app);
                }
                if (!isKillTimeout) {
                    mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
                    app.killLocked("start timeout",
@@ -4631,16 +4635,6 @@ public class ActivityManagerService extends IActivityManager.Stub
                    }
                });
            }
            if (!isKillTimeout) {
                if (isPendingBroadcastProcessLocked(pid)) {
                    Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
                    skipPendingBroadcastLocked(pid);
                }
            } else {
                if (isPendingBroadcastProcessLocked(app)) {
                    skipCurrentReceiverLocked(app);
                }
            }
        } else {
            Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
        }
@@ -4965,10 +4959,12 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        // Check if a next-broadcast receiver is in this process...
        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
        if (!badApp) {
            try {
                didSomething |= sendPendingBroadcastsLocked(app);
                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
                for (BroadcastQueue queue : mBroadcastQueues) {
                    didSomething |= queue.onApplicationAttachedLocked(app);
                }
                checkTime(startTime, "attachApplicationLocked: after dispatching broadcasts");
            } catch (Exception e) {
                // If the app died trying to launch the receiver we declare it 'bad'
                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
@@ -8355,12 +8351,6 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    void skipCurrentReceiverLocked(ProcessRecord app) {
        for (BroadcastQueue queue : mBroadcastQueues) {
            queue.skipCurrentReceiverLocked(app);
        }
    }
    /**
     * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
     * The application process will exit immediately after this call returns.
@@ -12373,7 +12363,9 @@ public class ActivityManagerService extends IActivityManager.Stub
            mOomAdjuster.mCachedAppOptimizer.onCleanupApplicationRecordLocked(app);
        }
        mAppProfiler.onCleanupApplicationRecordLocked(app);
        skipCurrentReceiverLocked(app);
        for (BroadcastQueue queue : mBroadcastQueues) {
            queue.onApplicationCleanupLocked(app);
        }
        updateProcessForegroundLocked(app, false, 0, false);
        mServices.killServicesLocked(app, allowRestart);
        mPhantomProcessList.onAppDied(pid);
@@ -13080,42 +13072,6 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
    }
    boolean isPendingBroadcastProcessLocked(int pid) {
        for (BroadcastQueue queue : mBroadcastQueues) {
            BroadcastRecord r = queue.getPendingBroadcastLocked();
            if (r != null && r.curApp.getPid() == pid) {
                return true;
            }
        }
        return false;
    }
    boolean isPendingBroadcastProcessLocked(ProcessRecord app) {
        for (BroadcastQueue queue : mBroadcastQueues) {
            BroadcastRecord r = queue.getPendingBroadcastLocked();
            if (r != null && r.curApp == app) {
                return true;
            }
        }
        return false;
    }
    void skipPendingBroadcastLocked(int pid) {
            Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
            for (BroadcastQueue queue : mBroadcastQueues) {
                queue.skipPendingBroadcastLocked(pid);
            }
    }
    // The app just attached; send any pending broadcasts that it should receive
    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
        boolean didSomething = false;
        for (BroadcastQueue queue : mBroadcastQueues) {
            didSomething |= queue.sendPendingBroadcastsLocked(app);
        }
        return didSomething;
    }
    void updateUidReadyForBootCompletedBroadcastLocked(int uid) {
        for (BroadcastQueue queue : mBroadcastQueues) {
            queue.updateUidReadyForBootCompletedBroadcastLocked(uid);
+25 −6
Original line number Diff line number Diff line
@@ -77,12 +77,6 @@ public abstract class BroadcastQueue {

    public abstract void updateUidReadyForBootCompletedBroadcastLocked(int uid);

    public abstract boolean sendPendingBroadcastsLocked(ProcessRecord app);

    public abstract void skipPendingBroadcastLocked(int pid);

    public abstract void skipCurrentReceiverLocked(ProcessRecord app);

    public abstract BroadcastRecord getMatchingOrderedReceiver(IBinder receiver);

    /**
@@ -99,6 +93,31 @@ public abstract class BroadcastQueue {

    public abstract void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj);

    /**
     * Signal from OS internals that the given process has just been actively
     * attached, and is ready to begin receiving broadcasts.
     */
    public abstract boolean onApplicationAttachedLocked(ProcessRecord app);

    /**
     * Signal from OS internals that the given process has timed out during
     * an attempted start and attachment.
     */
    public abstract boolean onApplicationTimeoutLocked(ProcessRecord app);

    /**
     * Signal from OS internals that the given process, which had already been
     * previously attached, has now encountered a problem such as crashing or
     * not responding.
     */
    public abstract boolean onApplicationProblemLocked(ProcessRecord app);

    /**
     * Signal from OS internals that the given process has been killed, and is
     * no longer actively running.
     */
    public abstract boolean onApplicationCleanupLocked(ProcessRecord app);

    /**
     * Signal from OS internals that the given package (or some subset of that
     * package) has been disabled or uninstalled, and that any pending
+24 −11
Original line number Diff line number Diff line
@@ -423,6 +423,26 @@ public class BroadcastQueueImpl extends BroadcastQueue {
        scheduleBroadcastsLocked();
    }

    public boolean onApplicationAttachedLocked(ProcessRecord app) {
        if (mPendingBroadcast != null && mPendingBroadcast.curApp == app) {
            return sendPendingBroadcastsLocked(app);
        } else {
            return false;
        }
    }

    public boolean onApplicationTimeoutLocked(ProcessRecord app) {
        return skipCurrentOrPendingReceiverLocked(app);
    }

    public boolean onApplicationProblemLocked(ProcessRecord app) {
        return skipCurrentOrPendingReceiverLocked(app);
    }

    public boolean onApplicationCleanupLocked(ProcessRecord app) {
        return skipCurrentOrPendingReceiverLocked(app);
    }

    public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
        boolean didSomething = false;
        final BroadcastRecord br = mPendingBroadcast;
@@ -452,18 +472,8 @@ public class BroadcastQueueImpl extends BroadcastQueue {
        return didSomething;
    }

    public void skipPendingBroadcastLocked(int pid) {
        final BroadcastRecord br = mPendingBroadcast;
        if (br != null && br.curApp.getPid() == pid) {
            br.state = BroadcastRecord.IDLE;
            br.nextReceiver = mPendingBroadcastRecvIndex;
            mPendingBroadcast = null;
            scheduleBroadcastsLocked();
        }
    }

    // Skip the current receiver, if any, that is in flight to the given process
    public void skipCurrentReceiverLocked(ProcessRecord app) {
    public boolean skipCurrentOrPendingReceiverLocked(ProcessRecord app) {
        BroadcastRecord r = null;
        final BroadcastRecord curActive = mDispatcher.getActiveBroadcastLocked();
        if (curActive != null && curActive.curApp == app) {
@@ -481,6 +491,9 @@ public class BroadcastQueueImpl extends BroadcastQueue {

        if (r != null) {
            skipReceiverLocked(r);
            return true;
        } else {
            return false;
        }
    }

+3 −1
Original line number Diff line number Diff line
@@ -605,7 +605,9 @@ class ProcessErrorStateRecord {
                        mService.mContext, mApp.info.packageName, mApp.info.flags);
            }
        }
        mService.skipCurrentReceiverLocked(mApp);
        for (BroadcastQueue queue : mService.mBroadcastQueues) {
            queue.onApplicationProblemLocked(mApp);
        }
    }

    @GuardedBy("mService")