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

Commit dbd71543 authored by Michal Karpinski's avatar Michal Karpinski Committed by Android (Google) Code Review
Browse files

Merge "Rework adding bg activity starts whitelisting token for broadcasts"

parents 885c9e7a 4b8aef21
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -11946,6 +11946,7 @@ public final class Settings {
         * bcast_deferral               (long)
         * bcast_deferral_decay_factor  (float)
         * bcast_deferral_floor         (long)
         * bcast_allow_bg_activity_start_timeout    (long)
         * </pre>
         *
         * @hide
+1 −1
Original line number Diff line number Diff line
@@ -15039,7 +15039,7 @@ public class ActivityManagerService extends IActivityManager.Stub
                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
                                oldRecord.intent,
                                Activity.RESULT_CANCELED, null, null,
                                false, false, oldRecord.userId, oldRecord);
                                false, false, oldRecord.userId);
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Failure ["
                                + queue.mQueueName + "] sending broadcast result of "
+10 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@ public class BroadcastConstants {
    static final String KEY_DEFERRAL = "bcast_deferral";
    static final String KEY_DEFERRAL_DECAY_FACTOR = "bcast_deferral_decay_factor";
    static final String KEY_DEFERRAL_FLOOR = "bcast_deferral_floor";
    static final String KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT =
            "bcast_allow_bg_activity_start_timeout";

    // All time intervals are in milliseconds
    private static final long DEFAULT_TIMEOUT = 10_000;
@@ -45,6 +47,7 @@ public class BroadcastConstants {
    private static final long DEFAULT_DEFERRAL = 5_000;
    private static final float DEFAULT_DEFERRAL_DECAY_FACTOR = 0.75f;
    private static final long DEFAULT_DEFERRAL_FLOOR = 0;
    private static final long DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT = 10_000;

    // All time constants are in milliseconds

@@ -59,6 +62,8 @@ public class BroadcastConstants {
    public float DEFERRAL_DECAY_FACTOR = DEFAULT_DEFERRAL_DECAY_FACTOR;
    // Minimum that the deferral time can decay to until the backlog fully clears
    public long DEFERRAL_FLOOR = DEFAULT_DEFERRAL_FLOOR;
    // For how long after a whitelisted receiver's start its process can start a background activity
    public long ALLOW_BG_ACTIVITY_START_TIMEOUT = DEFAULT_ALLOW_BG_ACTIVITY_START_TIMEOUT;

    // Settings override tracking for this instance
    private String mSettingsKey;
@@ -113,6 +118,8 @@ public class BroadcastConstants {
            DEFERRAL_DECAY_FACTOR = mParser.getFloat(KEY_DEFERRAL_DECAY_FACTOR,
                    DEFERRAL_DECAY_FACTOR);
            DEFERRAL_FLOOR = mParser.getLong(KEY_DEFERRAL_FLOOR, DEFERRAL_FLOOR);
            ALLOW_BG_ACTIVITY_START_TIMEOUT = mParser.getLong(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT,
                    ALLOW_BG_ACTIVITY_START_TIMEOUT);
        }
    }

@@ -145,6 +152,9 @@ public class BroadcastConstants {

            pw.print("    "); pw.print(KEY_DEFERRAL_FLOOR); pw.print(" = ");
            TimeUtils.formatDuration(DEFERRAL_FLOOR, pw);

            pw.print("    "); pw.print(KEY_ALLOW_BG_ACTIVITY_START_TIMEOUT); pw.print(" = ");
            TimeUtils.formatDuration(ALLOW_BG_ACTIVITY_START_TIMEOUT, pw);
            pw.println();
        }
    }
+43 −20
Original line number Diff line number Diff line
@@ -74,9 +74,6 @@ public final class BroadcastQueue {
    static final int MAX_BROADCAST_SUMMARY_HISTORY
            = ActivityManager.isLowRamDeviceStatic() ? 25 : 300;

    // For how long after a whitelisted receiver's start its process can start a background activity
    private static final int RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS = 10_000;

    final ActivityManagerService mService;

    /**
@@ -310,9 +307,6 @@ public final class BroadcastQueue {
        r.curApp = app;
        app.curReceivers.add(r);
        app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
        if (r.allowBackgroundActivityStarts) {
            app.addAllowBackgroundActivityStartsToken(r);
        }
        mService.mProcessList.updateLruProcessLocked(app, false, null);
        if (!skipOomAdj) {
            mService.updateOomAdjLocked();
@@ -454,8 +448,25 @@ public final class BroadcastQueue {
            Slog.w(TAG, "finishReceiver [" + mQueueName + "] called but state is IDLE");
        }
        if (r.allowBackgroundActivityStarts && r.curApp != null) {
            if (elapsed > mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT) {
                // if the receiver has run for more than allowed bg activity start timeout,
                // just remove the token for this process now and we're done
                r.curApp.removeAllowBackgroundActivityStartsToken(r);
            } else {
                // the receiver had run for less than allowed bg activity start timeout,
                // so allow the process to still start activities from bg for some more time
                String msgToken = (r.curApp.toShortString() + r.toString()).intern();
                // first, if there exists a past scheduled request to remove this token, drop
                // that request - we don't want the token to be swept from under our feet...
                mHandler.removeCallbacksAndMessages(msgToken);
                // ...then schedule the removal of the token after the extended timeout
                mHandler.postAtTime(() -> {
                    if (r.curApp != null) {
                        r.curApp.removeAllowBackgroundActivityStartsToken(r);
                    }
                }, msgToken, (r.receiverTime + mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT));
            }
        }
        // If we're abandoning this broadcast before any receivers were actually spun up,
        // nextReceiver is zero; in which case time-to-process bookkeeping doesn't apply.
        if (r.nextReceiver > 0) {
@@ -554,7 +565,7 @@ public final class BroadcastQueue {

    void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
            Intent intent, int resultCode, String data, Bundle extras,
            boolean ordered, boolean sticky, int sendingUser, BroadcastRecord br)
            boolean ordered, boolean sticky, int sendingUser)
            throws RemoteException {
        // Send the intent to the receiver asynchronously using one-way binder calls.
        if (app != null) {
@@ -562,15 +573,6 @@ public final class BroadcastQueue {
                // If we have an app thread, do the call through that so it is
                // correctly ordered with other one-way calls.
                try {
                    if (br.allowBackgroundActivityStarts) {
                        app.addAllowBackgroundActivityStartsToken(br);
                        // schedule removal of the whitelisting token after the timeout
                        mHandler.postDelayed(() -> {
                            if (app != null) {
                                app.removeAllowBackgroundActivityStartsToken(br);
                            }
                        }, RECEIVER_BG_ACTIVITY_START_TIMEOUT_MS);
                    }
                    app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                            data, extras, ordered, sticky, sendingUser, app.getReportedProcState());
                // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
@@ -794,9 +796,13 @@ public final class BroadcastQueue {
                    skipReceiverLocked(r);
                }
            } else {
                if (r.receiverTime == 0) {
                    r.receiverTime = SystemClock.uptimeMillis();
                }
                maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                        new Intent(r.intent), r.resultCode, r.resultData,
                        r.resultExtras, r.ordered, r.initialSticky, r.userId, r);
                        r.resultExtras, r.ordered, r.initialSticky, r.userId);
            }
            if (ordered) {
                r.state = BroadcastRecord.CALL_DONE_RECEIVE;
@@ -1100,7 +1106,7 @@ public final class BroadcastQueue {
                            }
                            performReceiveLocked(r.callerApp, r.resultTo,
                                    new Intent(r.intent), r.resultCode,
                                    r.resultData, r.resultExtras, false, false, r.userId, r);
                                    r.resultData, r.resultExtras, false, false, r.userId);
                            // Set this to null so that the reference
                            // (local and remote) isn't kept in the mBroadcastHistory.
                            r.resultTo = null;
@@ -1255,6 +1261,9 @@ public final class BroadcastQueue {
                r.state = BroadcastRecord.IDLE;
                scheduleBroadcastsLocked();
            } else {
                if (filter.receiverList != null) {
                    maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
                }
                if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
                    scheduleTempWhitelistLocked(filter.owningUid,
                            brOptions.getTemporaryAppWhitelistDuration(), r);
@@ -1561,6 +1570,7 @@ public final class BroadcastQueue {
            try {
                app.addPackage(info.activityInfo.packageName,
                        info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
                maybeAddAllowBackgroundActivityStartsToken(app, r);
                processCurBroadcastLocked(r, app, skipOomAdj);
                return;
            } catch (RemoteException e) {
@@ -1611,10 +1621,23 @@ public final class BroadcastQueue {
            return;
        }

        maybeAddAllowBackgroundActivityStartsToken(r.curApp, r);
        mPendingBroadcast = r;
        mPendingBroadcastRecvIndex = recIdx;
    }

    private void maybeAddAllowBackgroundActivityStartsToken(ProcessRecord proc, BroadcastRecord r) {
        if (r == null || proc == null || !r.allowBackgroundActivityStarts) {
            return;
        }
        String msgToken = (proc.toShortString() + r.toString()).intern();
        // first, if there exists a past scheduled request to remove this token, drop
        // that request - we don't want the token to be swept from under our feet...
        mHandler.removeCallbacksAndMessages(msgToken);
        // ...then add the token
        proc.addAllowBackgroundActivityStartsToken(r);
    }

    final void setBroadcastTimeoutLocked(long timeoutTime) {
        if (! mPendingBroadcastTimeoutMessage) {
            Message msg = mHandler.obtainMessage(BROADCAST_TIMEOUT_MSG, this);