Loading core/proto/android/server/activitymanagerservice.proto +1 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ message BroadcastQueueProto { } repeated BroadcastSummary historical_broadcasts_summary = 6; repeated BroadcastRecordProto pending_broadcasts = 7; repeated BroadcastRecordProto frozen_broadcasts = 8; } message MemInfoDumpProto { Loading services/core/java/com/android/server/am/ActivityManagerShellCommand.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading services/core/java/com/android/server/am/BroadcastConstants.java +16 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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(); } Loading services/core/java/com/android/server/am/BroadcastHistory.java +31 −11 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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); } Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } } } } services/core/java/com/android/server/am/BroadcastProcessQueue.java +54 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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. Loading Loading @@ -774,6 +804,10 @@ class BroadcastProcessQueue { return mActiveIndex; } public boolean isOutgoingEmpty() { return mOutgoingBroadcasts.isEmpty(); } public boolean isEmpty() { return mPending.isEmpty() && mPendingUrgent.isEmpty() && mPendingOffload.isEmpty(); } Loading Loading @@ -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(" "); Loading @@ -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); } Loading Loading @@ -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 Loading
core/proto/android/server/activitymanagerservice.proto +1 −0 Original line number Diff line number Diff line Loading @@ -144,6 +144,7 @@ message BroadcastQueueProto { } repeated BroadcastSummary historical_broadcasts_summary = 6; repeated BroadcastRecordProto pending_broadcasts = 7; repeated BroadcastRecordProto frozen_broadcasts = 8; } message MemInfoDumpProto { Loading
services/core/java/com/android/server/am/ActivityManagerShellCommand.java +2 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
services/core/java/com/android/server/am/BroadcastConstants.java +16 −1 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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(); } Loading
services/core/java/com/android/server/am/BroadcastHistory.java +31 −11 Original line number Diff line number Diff line Loading @@ -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. */ Loading Loading @@ -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); } Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); } } } }
services/core/java/com/android/server/am/BroadcastProcessQueue.java +54 −5 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading @@ -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 Loading Loading @@ -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 { Loading @@ -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. Loading Loading @@ -774,6 +804,10 @@ class BroadcastProcessQueue { return mActiveIndex; } public boolean isOutgoingEmpty() { return mOutgoingBroadcasts.isEmpty(); } public boolean isEmpty() { return mPending.isEmpty() && mPendingUrgent.isEmpty() && mPendingOffload.isEmpty(); } Loading Loading @@ -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(" "); Loading @@ -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); } Loading Loading @@ -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