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

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

Merge "Defer outgoing bcasts from processes in freezable state." into main

parents 4b34eb6f 381d1185
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -144,6 +144,7 @@ message BroadcastQueueProto {
    }
    repeated BroadcastSummary historical_broadcasts_summary = 6;
    repeated BroadcastRecordProto pending_broadcasts = 7;
    repeated BroadcastRecordProto frozen_broadcasts = 8;
}

message MemInfoDumpProto {
+2 −1
Original line number Diff line number Diff line
@@ -1164,7 +1164,8 @@ final class ActivityManagerShellCommand extends ShellCommand {
        synchronized (mInternal) {
            synchronized (mInternal.mProcLock) {
                app.mOptRecord.setFreezeSticky(isSticky);
                mInternal.mOomAdjuster.mCachedAppOptimizer.freezeAppAsyncInternalLSP(app, 0, true);
                mInternal.mOomAdjuster.mCachedAppOptimizer.freezeAppAsyncInternalLSP(
                        app, 0 /* delayMillis */, true /* force */, false /* immediate */);
            }
        }
        return 0;
+16 −1
Original line number Diff line number Diff line
@@ -296,11 +296,21 @@ public class BroadcastConstants {
     * For {@link BroadcastQueueModernImpl}: How frequently we should check for the pending
     * cold start validity.
     */
    public long PENDING_COLD_START_CHECK_INTERVAL_MILLIS = 30 * 1000;
    public long PENDING_COLD_START_CHECK_INTERVAL_MILLIS =
            DEFAULT_PENDING_COLD_START_CHECK_INTERVAL_MILLIS;
    private static final String KEY_PENDING_COLD_START_CHECK_INTERVAL_MILLIS =
            "pending_cold_start_check_interval_millis";
    private static final long DEFAULT_PENDING_COLD_START_CHECK_INTERVAL_MILLIS = 30_000;

    /**
     * For {@link BroadcastQueueModernImpl}: Maximum number of outgoing broadcasts from a
     * freezable process that will be allowed before killing the process.
     */
    public long MAX_FROZEN_OUTGOING_BROADCASTS = DEFAULT_MAX_FROZEN_OUTGOING_BROADCASTS;
    private static final String KEY_MAX_FROZEN_OUTGOING_BROADCASTS =
            "max_frozen_outgoing_broadcasts";
    private static final int DEFAULT_MAX_FROZEN_OUTGOING_BROADCASTS = 32;

    // Settings override tracking for this instance
    private String mSettingsKey;
    private SettingsObserver mSettingsObserver;
@@ -453,6 +463,9 @@ public class BroadcastConstants {
            PENDING_COLD_START_CHECK_INTERVAL_MILLIS = getDeviceConfigLong(
                    KEY_PENDING_COLD_START_CHECK_INTERVAL_MILLIS,
                    DEFAULT_PENDING_COLD_START_CHECK_INTERVAL_MILLIS);
            MAX_FROZEN_OUTGOING_BROADCASTS = getDeviceConfigInt(
                    KEY_MAX_FROZEN_OUTGOING_BROADCASTS,
                    DEFAULT_MAX_FROZEN_OUTGOING_BROADCASTS);
        }

        // TODO: migrate BroadcastRecord to accept a BroadcastConstants
@@ -513,6 +526,8 @@ public class BroadcastConstants {
                    CORE_DEFER_UNTIL_ACTIVE).println();
            pw.print(KEY_PENDING_COLD_START_CHECK_INTERVAL_MILLIS,
                    PENDING_COLD_START_CHECK_INTERVAL_MILLIS).println();
            pw.print(KEY_MAX_FROZEN_OUTGOING_BROADCASTS,
                    MAX_FROZEN_OUTGOING_BROADCASTS).println();
            pw.decreaseIndent();
            pw.println();
        }
+31 −11
Original line number Diff line number Diff line
@@ -49,6 +49,11 @@ public class BroadcastHistory {
        mSummaryHistoryFinishTime = new long[MAX_BROADCAST_SUMMARY_HISTORY];
    }

    /**
     * List of broadcasts in frozen processes that are yet to be enqueued.
     */
    private final ArrayList<BroadcastRecord> mFrozenBroadcasts = new ArrayList<>();

    /**
     * List of broadcasts which are being delivered or yet to be delivered.
     */
@@ -77,7 +82,12 @@ public class BroadcastHistory {
    final long[] mSummaryHistoryDispatchTime;
    final long[] mSummaryHistoryFinishTime;

    void onBroadcastFrozenLocked(@NonNull BroadcastRecord r) {
        mFrozenBroadcasts.add(r);
    }

    void onBroadcastEnqueuedLocked(@NonNull BroadcastRecord r) {
        mFrozenBroadcasts.remove(r);
        mPendingBroadcasts.add(r);
    }

@@ -101,7 +111,7 @@ public class BroadcastHistory {
        mSummaryHistoryNext = ringAdvance(mSummaryHistoryNext, 1, MAX_BROADCAST_SUMMARY_HISTORY);
    }

    private final int ringAdvance(int x, final int increment, final int ringSize) {
    private int ringAdvance(int x, final int increment, final int ringSize) {
        x += increment;
        if (x < 0) return (ringSize - 1);
        else if (x >= ringSize) return 0;
@@ -114,6 +124,10 @@ public class BroadcastHistory {
            final BroadcastRecord r = mPendingBroadcasts.get(i);
            r.dumpDebug(proto, BroadcastQueueProto.PENDING_BROADCASTS);
        }
        for (int i = 0; i < mFrozenBroadcasts.size(); ++i) {
            final BroadcastRecord r = mFrozenBroadcasts.get(i);
            r.dumpDebug(proto, BroadcastQueueProto.FROZEN_BROADCASTS);
        }

        int lastIndex = mHistoryNext;
        int ringIndex = lastIndex;
@@ -151,16 +165,8 @@ public class BroadcastHistory {
    public boolean dumpLocked(@NonNull PrintWriter pw, @Nullable String dumpPackage,
            @NonNull String queueName, @NonNull SimpleDateFormat sdf,
            boolean dumpAll, boolean needSep) {
        pw.println("  Pending broadcasts:");
        if (mPendingBroadcasts.isEmpty()) {
            pw.println("    <empty>");
        } else {
            for (int idx = mPendingBroadcasts.size() - 1; idx >= 0; --idx) {
                final BroadcastRecord r = mPendingBroadcasts.get(idx);
                pw.print("  Broadcast #"); pw.print(idx); pw.println(":");
                r.dump(pw, "    ", sdf);
            }
        }
        dumpBroadcastList(pw, sdf, mFrozenBroadcasts, "Frozen");
        dumpBroadcastList(pw, sdf, mPendingBroadcasts, "Pending");

        int i;
        boolean printed = false;
@@ -268,4 +274,18 @@ public class BroadcastHistory {
        }
        return needSep;
    }

    private void dumpBroadcastList(@NonNull PrintWriter pw, @NonNull SimpleDateFormat sdf,
            @NonNull ArrayList<BroadcastRecord> broadcasts, @NonNull String flavor) {
        pw.print("  "); pw.print(flavor); pw.println(" broadcasts:");
        if (broadcasts.isEmpty()) {
            pw.println("    <empty>");
        } else {
            for (int idx = broadcasts.size() - 1; idx >= 0; --idx) {
                final BroadcastRecord r = broadcasts.get(idx);
                pw.print(flavor); pw.print("  broadcast #"); pw.print(idx); pw.println(":");
                r.dump(pw, "    ", sdf);
            }
        }
    }
}
+54 −5
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import dalvik.annotation.optimization.NeverCompile;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Objects;

@@ -233,6 +234,11 @@ class BroadcastProcessQueue {
     */
    private long mForcedDelayedDurationMs;

    /**
     * List of outgoing broadcasts from a freezable process.
     */
    private final ArrayList<BroadcastRecord> mOutgoingBroadcasts = new ArrayList<>();

    public BroadcastProcessQueue(@NonNull BroadcastConstants constants,
            @NonNull String processName, int uid) {
        this.constants = Objects.requireNonNull(constants);
@@ -250,6 +256,21 @@ class BroadcastProcessQueue {
        }
    }

    public void enqueueOutgoingBroadcast(@NonNull BroadcastRecord record) {
        mOutgoingBroadcasts.add(record);
    }

    public int getOutgoingBroadcastCount() {
        return mOutgoingBroadcasts.size();
    }

    public void enqueueOutgoingBroadcasts(@NonNull BroadcastRecordConsumer consumer) {
        for (int i = 0; i < mOutgoingBroadcasts.size(); ++i) {
            consumer.accept(mOutgoingBroadcasts.get(i));
        }
        mOutgoingBroadcasts.clear();
    }

    /**
     * Enqueue the given broadcast to be dispatched to this process at some
     * future point in time. The target receiver is indicated by the given index
@@ -386,8 +407,8 @@ class BroadcastProcessQueue {
    }

    /**
     * Functional interface that tests a {@link BroadcastRecord} that has been
     * previously enqueued in {@link BroadcastProcessQueue}.
     * Functional interface that tests a {@link BroadcastRecord} and an index in the
     * {@link BroadcastRecord} that has been previously enqueued in {@link BroadcastProcessQueue}.
     */
    @FunctionalInterface
    public interface BroadcastPredicate {
@@ -395,14 +416,23 @@ class BroadcastProcessQueue {
    }

    /**
     * Functional interface that consumes a {@link BroadcastRecord} that has
     * been previously enqueued in {@link BroadcastProcessQueue}.
     * Functional interface that consumes a {@link BroadcastRecord} and an index in the
     * {@link BroadcastRecord} that has been previously enqueued in {@link BroadcastProcessQueue}.
     */
    @FunctionalInterface
    public interface BroadcastConsumer {
        void accept(@NonNull BroadcastRecord r, int index);
    }

    /**
     * Functional interface that consumes a {@link BroadcastRecord} that has
     * been previously enqueued in {@link BroadcastProcessQueue}.
     */
    @FunctionalInterface
    public interface BroadcastRecordConsumer {
        void accept(@NonNull BroadcastRecord r);
    }

    /**
     * Invoke given consumer for any broadcasts matching given predicate. If
     * requested, matching broadcasts will also be removed from this queue.
@@ -774,6 +804,10 @@ class BroadcastProcessQueue {
        return mActiveIndex;
    }

    public boolean isOutgoingEmpty() {
        return mOutgoingBroadcasts.isEmpty();
    }

    public boolean isEmpty() {
        return mPending.isEmpty() && mPendingUrgent.isEmpty() && mPendingOffload.isEmpty();
    }
@@ -1443,7 +1477,7 @@ class BroadcastProcessQueue {

    @NeverCompile
    public void dumpLocked(@UptimeMillisLong long now, @NonNull IndentingPrintWriter pw) {
        if ((mActive == null) && isEmpty()) return;
        if ((mActive == null) && isEmpty() && isOutgoingEmpty()) return;

        pw.print(toShortString());
        pw.print(" ");
@@ -1454,6 +1488,12 @@ class BroadcastProcessQueue {
        dumpProcessState(pw);
        dumpBroadcastCounts(pw);

        if (!mOutgoingBroadcasts.isEmpty()) {
            for (int i = 0; i < mOutgoingBroadcasts.size(); ++i) {
                dumpOutgoingRecord(now, pw, mOutgoingBroadcasts.get(i));
            }
        }

        if (mActive != null) {
            dumpRecord("ACTIVE", now, pw, mActive, mActiveIndex);
        }
@@ -1524,6 +1564,15 @@ class BroadcastProcessQueue {
        pw.println();
    }

    @NeverCompile
    private void dumpOutgoingRecord(@UptimeMillisLong long now,
            @NonNull IndentingPrintWriter pw, @NonNull BroadcastRecord record) {
        pw.print("OUTGOING ");
        TimeUtils.formatDuration(record.enqueueTime, now, pw);
        pw.print(' ');
        pw.println(record.toShortString());
    }

    @NeverCompile
    private void dumpRecord(@Nullable String flavor, @UptimeMillisLong long now,
            @NonNull IndentingPrintWriter pw, @NonNull BroadcastRecord record, int recordIndex) {
Loading