Loading services/core/java/com/android/server/am/ActivityManagerService.java +0 −2 Original line number Diff line number Diff line Loading @@ -18763,7 +18763,6 @@ public class ActivityManagerService extends IActivityManager.Stub // too quickly in parallel below pingCount.incrementAndGet(); synchronized (this) { synchronized (mProcLock) { final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessList.getProcessNamesLOSP().getMap(); Loading @@ -18788,7 +18787,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } // Now that we've dispatched all "ping" events above, we can send our // "pong" sentinel value services/core/java/com/android/server/am/BroadcastConstants.java +8 −8 Original line number Diff line number Diff line Loading @@ -203,11 +203,11 @@ public class BroadcastConstants { /** * For {@link BroadcastQueueModernImpl}: Delay to apply to broadcasts * targeting frozen applications. * targeting cached applications. */ public long DELAY_FROZEN_MILLIS = DEFAULT_DELAY_FROZEN_MILLIS; private static final String KEY_DELAY_FROZEN_MILLIS = "bcast_delay_frozen_millis"; private static final long DEFAULT_DELAY_FROZEN_MILLIS = +120_000; public long DELAY_CACHED_MILLIS = DEFAULT_DELAY_CACHED_MILLIS; private static final String KEY_DELAY_CACHED_MILLIS = "bcast_delay_cached_millis"; private static final long DEFAULT_DELAY_CACHED_MILLIS = +120_000; /** * For {@link BroadcastQueueModernImpl}: Delay to apply to urgent Loading Loading @@ -373,8 +373,8 @@ public class BroadcastConstants { DEFAULT_MAX_PENDING_BROADCASTS); DELAY_NORMAL_MILLIS = getDeviceConfigLong(KEY_DELAY_NORMAL_MILLIS, DEFAULT_DELAY_NORMAL_MILLIS); DELAY_FROZEN_MILLIS = getDeviceConfigLong(KEY_DELAY_FROZEN_MILLIS, DEFAULT_DELAY_FROZEN_MILLIS); DELAY_CACHED_MILLIS = getDeviceConfigLong(KEY_DELAY_CACHED_MILLIS, DEFAULT_DELAY_CACHED_MILLIS); DELAY_URGENT_MILLIS = getDeviceConfigLong(KEY_DELAY_URGENT_MILLIS, DEFAULT_DELAY_URGENT_MILLIS); MAX_HISTORY_COMPLETE_SIZE = getDeviceConfigInt(KEY_MAX_HISTORY_COMPLETE_SIZE, Loading Loading @@ -421,8 +421,8 @@ public class BroadcastConstants { pw.print(KEY_MAX_PENDING_BROADCASTS, MAX_PENDING_BROADCASTS).println(); pw.print(KEY_DELAY_NORMAL_MILLIS, TimeUtils.formatDuration(DELAY_NORMAL_MILLIS)).println(); pw.print(KEY_DELAY_FROZEN_MILLIS, TimeUtils.formatDuration(DELAY_FROZEN_MILLIS)).println(); pw.print(KEY_DELAY_CACHED_MILLIS, TimeUtils.formatDuration(DELAY_CACHED_MILLIS)).println(); pw.print(KEY_DELAY_URGENT_MILLIS, TimeUtils.formatDuration(DELAY_URGENT_MILLIS)).println(); pw.print(KEY_MAX_HISTORY_COMPLETE_SIZE, MAX_HISTORY_COMPLETE_SIZE).println(); Loading services/core/java/com/android/server/am/BroadcastProcessQueue.java +23 −20 Original line number Diff line number Diff line Loading @@ -188,7 +188,7 @@ class BroadcastProcessQueue { private @Reason int mRunnableAtReason = REASON_EMPTY; private boolean mRunnableAtInvalidated; private boolean mUidFrozen; private boolean mProcessCached; private boolean mProcessInstrumented; private boolean mProcessPersistent; Loading Loading @@ -385,9 +385,11 @@ class BroadcastProcessQueue { public void setProcess(@Nullable ProcessRecord app) { this.app = app; if (app != null) { setProcessCached(app.isCached()); setProcessInstrumented(app.getActiveInstrumentation() != null); setProcessPersistent(app.isPersistent()); } else { setProcessCached(false); setProcessInstrumented(false); setProcessPersistent(false); } Loading @@ -398,12 +400,13 @@ class BroadcastProcessQueue { } /** * Update if this UID is in the "frozen" state, typically signaling that * Update if this process is in the "cached" state, typically signaling that * broadcast dispatch should be paused or delayed. */ public void setUidFrozen(boolean frozen) { if (mUidFrozen != frozen) { mUidFrozen = frozen; @VisibleForTesting void setProcessCached(boolean cached) { if (mProcessCached != cached) { mProcessCached = cached; invalidateRunnableAt(); } } Loading Loading @@ -810,7 +813,7 @@ class BroadcastProcessQueue { public boolean isDeferredUntilActive() { if (mRunnableAtInvalidated) updateRunnableAt(); return mRunnableAtReason == BroadcastProcessQueue.REASON_INFINITE_DEFER; return mRunnableAtReason == BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER; } public boolean hasDeferredBroadcasts() { Loading Loading @@ -845,14 +848,14 @@ class BroadcastProcessQueue { } static final int REASON_EMPTY = 0; static final int REASON_FROZEN = 1; static final int REASON_CACHED = 1; static final int REASON_NORMAL = 2; static final int REASON_MAX_PENDING = 3; static final int REASON_BLOCKED = 4; static final int REASON_INSTRUMENTED = 5; static final int REASON_PERSISTENT = 6; static final int REASON_FORCE_DELAYED = 7; static final int REASON_INFINITE_DEFER = 8; static final int REASON_CACHED_INFINITE_DEFER = 8; static final int REASON_CONTAINS_FOREGROUND = 10; static final int REASON_CONTAINS_ORDERED = 11; static final int REASON_CONTAINS_ALARM = 12; Loading @@ -865,14 +868,14 @@ class BroadcastProcessQueue { @IntDef(flag = false, prefix = { "REASON_" }, value = { REASON_EMPTY, REASON_FROZEN, REASON_CACHED, REASON_NORMAL, REASON_MAX_PENDING, REASON_BLOCKED, REASON_INSTRUMENTED, REASON_PERSISTENT, REASON_FORCE_DELAYED, REASON_INFINITE_DEFER, REASON_CACHED_INFINITE_DEFER, REASON_CONTAINS_FOREGROUND, REASON_CONTAINS_ORDERED, REASON_CONTAINS_ALARM, Loading @@ -889,14 +892,14 @@ class BroadcastProcessQueue { static @NonNull String reasonToString(@Reason int reason) { switch (reason) { case REASON_EMPTY: return "EMPTY"; case REASON_FROZEN: return "FROZEN"; case REASON_CACHED: return "CACHED"; case REASON_NORMAL: return "NORMAL"; case REASON_MAX_PENDING: return "MAX_PENDING"; case REASON_BLOCKED: return "BLOCKED"; case REASON_INSTRUMENTED: return "INSTRUMENTED"; case REASON_PERSISTENT: return "PERSISTENT"; case REASON_FORCE_DELAYED: return "FORCE_DELAYED"; case REASON_INFINITE_DEFER: return "INFINITE_DEFER"; case REASON_CACHED_INFINITE_DEFER: return "INFINITE_DEFER"; case REASON_CONTAINS_FOREGROUND: return "CONTAINS_FOREGROUND"; case REASON_CONTAINS_ORDERED: return "CONTAINS_ORDERED"; case REASON_CONTAINS_ALARM: return "CONTAINS_ALARM"; Loading Loading @@ -983,12 +986,12 @@ class BroadcastProcessQueue { } else if (mProcessPersistent) { mRunnableAt = runnableAt; mRunnableAtReason = REASON_PERSISTENT; } else if (mUidFrozen) { } else if (mProcessCached) { if (r.deferUntilActive) { // All enqueued broadcasts are deferrable, defer if (mCountDeferred == mCountEnqueued) { mRunnableAt = Long.MAX_VALUE; mRunnableAtReason = REASON_INFINITE_DEFER; mRunnableAtReason = REASON_CACHED_INFINITE_DEFER; } else { // At least one enqueued broadcast isn't deferrable, repick time and reason // for this record. If a later record is not deferrable and is one of these Loading @@ -1003,14 +1006,14 @@ class BroadcastProcessQueue { mRunnableAt = runnableAt; mRunnableAtReason = REASON_CONTAINS_RESULT_TO; } else { mRunnableAt = runnableAt + constants.DELAY_FROZEN_MILLIS; mRunnableAtReason = REASON_FROZEN; mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS; mRunnableAtReason = REASON_CACHED; } } } else { // This record isn't deferrable mRunnableAt = runnableAt + constants.DELAY_FROZEN_MILLIS; mRunnableAtReason = REASON_FROZEN; mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS; mRunnableAtReason = REASON_CACHED; } } else if (mCountResultTo > 0) { // All resultTo broadcasts are infinitely deferrable, so if the app Loading Loading @@ -1192,8 +1195,8 @@ class BroadcastProcessQueue { @NeverCompile private void dumpProcessState(@NonNull IndentingPrintWriter pw) { final StringBuilder sb = new StringBuilder(); if (mUidFrozen) { sb.append("FROZEN"); if (mProcessCached) { sb.append("CACHED"); } if (mProcessInstrumented) { if (sb.length() > 0) sb.append("|"); Loading services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +14 −47 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.am; import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN; import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY; import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE; Loading Loading @@ -49,7 +48,7 @@ import android.app.ActivityManager; import android.app.ApplicationExitInfo; import android.app.BroadcastOptions; import android.app.IApplicationThread; import android.app.IUidFrozenStateChangedCallback; import android.app.UidObserver; import android.app.usage.UsageEvents.Event; import android.content.ComponentName; import android.content.ContentResolver; Loading @@ -73,7 +72,6 @@ import android.util.MathUtils; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; Loading Loading @@ -211,16 +209,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private final AtomicReference<ArraySet<BroadcastRecord>> mReplacedBroadcastsCache = new AtomicReference<>(); /** * Map from UID to its last known "frozen" state. * <p> * We manually maintain this data structure since the lifecycle of * {@link ProcessRecord} and {@link BroadcastProcessQueue} can be * mismatched. */ @GuardedBy("mService") private final SparseBooleanArray mUidFrozen = new SparseBooleanArray(); private final BroadcastConstants mConstants; private final BroadcastConstants mFgConstants; private final BroadcastConstants mBgConstants; Loading Loading @@ -498,7 +486,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { final BroadcastProcessQueue queue = getProcessQueue(app); if (queue != null) { queue.setProcess(app); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); } boolean didSomething = false; Loading Loading @@ -540,7 +527,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { final BroadcastProcessQueue queue = getProcessQueue(app); if (queue != null) { queue.setProcess(null); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); } if ((mRunningColdStart != null) && (mRunningColdStart == queue)) { Loading Loading @@ -1342,25 +1328,15 @@ class BroadcastQueueModernImpl extends BroadcastQueue { mFgConstants.startObserving(mHandler, resolver); mBgConstants.startObserving(mHandler, resolver); mService.registerUidFrozenStateChangedCallback(new IUidFrozenStateChangedCallback.Stub() { mService.registerUidObserver(new UidObserver() { @Override public void onUidFrozenStateChanged(int[] uids, int[] frozenStates) { public void onUidCachedChanged(int uid, boolean cached) { synchronized (mService) { for (int i = 0; i < uids.length; i++) { final int uid = uids[i]; final boolean frozen = frozenStates[i] == UID_FROZEN_STATE_FROZEN; if (frozen) { mUidFrozen.put(uid, true); } else { mUidFrozen.delete(uid); } BroadcastProcessQueue leaf = mProcessQueues.get(uid); while (leaf != null) { // Update internal state by refreshing values previously // read from any known running process leaf.setProcess(leaf.app); leaf.setUidFrozen(frozen); updateQueueDeferred(leaf); updateRunnableList(leaf); leaf = leaf.processNameNext; Loading @@ -1368,8 +1344,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { enqueueUpdateRunningList(); } } } }); }, ActivityManager.UID_OBSERVER_CACHED, 0, "android"); // Kick off periodic health checks mLocalHandler.sendEmptyMessage(MSG_CHECK_HEALTH); Loading Loading @@ -1524,7 +1499,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) { if (!queue.isProcessWarm()) { queue.setProcess(mService.getProcessRecordLocked(queue.processName, queue.uid)); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); } } Loading Loading @@ -1719,7 +1693,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid); created.setProcess(mService.getProcessRecordLocked(processName, uid)); created.setUidFrozen(mUidFrozen.get(uid, false)); if (leaf == null) { mProcessQueues.put(uid, created); Loading Loading @@ -1848,12 +1821,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { ipw.decreaseIndent(); ipw.println(); ipw.println("Frozen UIDs:"); ipw.increaseIndent(); ipw.println(mUidFrozen.toString()); ipw.decreaseIndent(); ipw.println(); if (dumpConstants) { mConstants.dump(ipw); } Loading services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +23 −23 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ public final class BroadcastQueueModernImplTest { mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS); mConstants.DELAY_URGENT_MILLIS = -120_000; mConstants.DELAY_NORMAL_MILLIS = 10_000; mConstants.DELAY_FROZEN_MILLIS = 120_000; mConstants.DELAY_CACHED_MILLIS = 120_000; final BroadcastSkipPolicy emptySkipPolicy = new BroadcastSkipPolicy(mAms) { public boolean shouldSkip(BroadcastRecord r, Object o) { Loading Loading @@ -372,13 +372,13 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false); queue.setUidFrozen(false); queue.setProcessCached(false); final long notCachedRunnableAt = queue.getRunnableAt(); queue.setUidFrozen(true); queue.setProcessCached(true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertFalse(queue.isRunnable()); assertEquals(BroadcastProcessQueue.REASON_INFINITE_DEFER, assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER, queue.getRunnableAtReason()); assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); } Loading @@ -399,13 +399,13 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false); queue.setUidFrozen(false); queue.setProcessCached(false); final long notCachedRunnableAt = queue.getRunnableAt(); queue.setUidFrozen(true); queue.setProcessCached(true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertTrue(queue.isRunnable()); assertEquals(BroadcastProcessQueue.REASON_FROZEN, queue.getRunnableAtReason()); assertEquals(BroadcastProcessQueue.REASON_CACHED, queue.getRunnableAtReason()); assertEquals(ProcessList.SCHED_GROUP_BACKGROUND, queue.getPreferredSchedulingGroupLocked()); } Loading @@ -431,13 +431,13 @@ public final class BroadcastQueueModernImplTest { // verify that: // (a) the queue is immediately runnable by existence of a fg-priority broadcast // (b) the next one up is the fg-priority broadcast despite its later enqueue time queue.setUidFrozen(false); queue.setProcessCached(false); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord); queue.setUidFrozen(true); queue.setProcessCached(true); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); Loading Loading @@ -497,10 +497,10 @@ public final class BroadcastQueueModernImplTest { * Verify that a cached process that would normally be delayed becomes * immediately runnable when the given broadcast is enqueued. */ private void doRunnableAt_Frozen(BroadcastRecord testRecord, int testRunnableAtReason) { private void doRunnableAt_Cached(BroadcastRecord testRecord, int testRunnableAtReason) { final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN)); queue.setUidFrozen(true); queue.setProcessCached(true); final BroadcastRecord lazyRecord = makeBroadcastRecord( new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED), Loading @@ -516,49 +516,49 @@ public final class BroadcastQueueModernImplTest { } @Test public void testRunnableAt_Frozen_Manifest() { doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), null, public void testRunnableAt_Cached_Manifest() { doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null, List.of(makeMockManifestReceiver()), null, false), REASON_CONTAINS_MANIFEST); } @Test public void testRunnableAt_Frozen_Ordered() { doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), null, public void testRunnableAt_Cached_Ordered() { doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null, List.of(makeMockRegisteredReceiver()), null, true), REASON_CONTAINS_ORDERED); } @Test public void testRunnableAt_Frozen_Foreground() { public void testRunnableAt_Cached_Foreground() { final Intent foregroundIntent = new Intent(); foregroundIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); doRunnableAt_Frozen(makeBroadcastRecord(foregroundIntent, null, doRunnableAt_Cached(makeBroadcastRecord(foregroundIntent, null, List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_FOREGROUND); } @Test public void testRunnableAt_Frozen_Interactive() { public void testRunnableAt_Cached_Interactive() { final BroadcastOptions options = BroadcastOptions.makeBasic(); options.setInteractive(true); doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), options, doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options, List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_INTERACTIVE); } @Test public void testRunnableAt_Frozen_Alarm() { public void testRunnableAt_Cached_Alarm() { final BroadcastOptions options = BroadcastOptions.makeBasic(); options.setAlarmBroadcast(true); doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), options, doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options, List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_ALARM); } @Test public void testRunnableAt_Frozen_Prioritized_NonDeferrable() { public void testRunnableAt_Cached_Prioritized_NonDeferrable() { final List receivers = List.of( withPriority(makeManifestReceiver(PACKAGE_RED, PACKAGE_RED), 10), withPriority(makeManifestReceiver(PACKAGE_GREEN, PACKAGE_GREEN), -10)); final BroadcastOptions options = BroadcastOptions.makeBasic() .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE); doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), options, doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options, receivers, null, false), REASON_CONTAINS_PRIORITIZED); } Loading Loading
services/core/java/com/android/server/am/ActivityManagerService.java +0 −2 Original line number Diff line number Diff line Loading @@ -18763,7 +18763,6 @@ public class ActivityManagerService extends IActivityManager.Stub // too quickly in parallel below pingCount.incrementAndGet(); synchronized (this) { synchronized (mProcLock) { final ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessList.getProcessNamesLOSP().getMap(); Loading @@ -18788,7 +18787,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } } } // Now that we've dispatched all "ping" events above, we can send our // "pong" sentinel value
services/core/java/com/android/server/am/BroadcastConstants.java +8 −8 Original line number Diff line number Diff line Loading @@ -203,11 +203,11 @@ public class BroadcastConstants { /** * For {@link BroadcastQueueModernImpl}: Delay to apply to broadcasts * targeting frozen applications. * targeting cached applications. */ public long DELAY_FROZEN_MILLIS = DEFAULT_DELAY_FROZEN_MILLIS; private static final String KEY_DELAY_FROZEN_MILLIS = "bcast_delay_frozen_millis"; private static final long DEFAULT_DELAY_FROZEN_MILLIS = +120_000; public long DELAY_CACHED_MILLIS = DEFAULT_DELAY_CACHED_MILLIS; private static final String KEY_DELAY_CACHED_MILLIS = "bcast_delay_cached_millis"; private static final long DEFAULT_DELAY_CACHED_MILLIS = +120_000; /** * For {@link BroadcastQueueModernImpl}: Delay to apply to urgent Loading Loading @@ -373,8 +373,8 @@ public class BroadcastConstants { DEFAULT_MAX_PENDING_BROADCASTS); DELAY_NORMAL_MILLIS = getDeviceConfigLong(KEY_DELAY_NORMAL_MILLIS, DEFAULT_DELAY_NORMAL_MILLIS); DELAY_FROZEN_MILLIS = getDeviceConfigLong(KEY_DELAY_FROZEN_MILLIS, DEFAULT_DELAY_FROZEN_MILLIS); DELAY_CACHED_MILLIS = getDeviceConfigLong(KEY_DELAY_CACHED_MILLIS, DEFAULT_DELAY_CACHED_MILLIS); DELAY_URGENT_MILLIS = getDeviceConfigLong(KEY_DELAY_URGENT_MILLIS, DEFAULT_DELAY_URGENT_MILLIS); MAX_HISTORY_COMPLETE_SIZE = getDeviceConfigInt(KEY_MAX_HISTORY_COMPLETE_SIZE, Loading Loading @@ -421,8 +421,8 @@ public class BroadcastConstants { pw.print(KEY_MAX_PENDING_BROADCASTS, MAX_PENDING_BROADCASTS).println(); pw.print(KEY_DELAY_NORMAL_MILLIS, TimeUtils.formatDuration(DELAY_NORMAL_MILLIS)).println(); pw.print(KEY_DELAY_FROZEN_MILLIS, TimeUtils.formatDuration(DELAY_FROZEN_MILLIS)).println(); pw.print(KEY_DELAY_CACHED_MILLIS, TimeUtils.formatDuration(DELAY_CACHED_MILLIS)).println(); pw.print(KEY_DELAY_URGENT_MILLIS, TimeUtils.formatDuration(DELAY_URGENT_MILLIS)).println(); pw.print(KEY_MAX_HISTORY_COMPLETE_SIZE, MAX_HISTORY_COMPLETE_SIZE).println(); Loading
services/core/java/com/android/server/am/BroadcastProcessQueue.java +23 −20 Original line number Diff line number Diff line Loading @@ -188,7 +188,7 @@ class BroadcastProcessQueue { private @Reason int mRunnableAtReason = REASON_EMPTY; private boolean mRunnableAtInvalidated; private boolean mUidFrozen; private boolean mProcessCached; private boolean mProcessInstrumented; private boolean mProcessPersistent; Loading Loading @@ -385,9 +385,11 @@ class BroadcastProcessQueue { public void setProcess(@Nullable ProcessRecord app) { this.app = app; if (app != null) { setProcessCached(app.isCached()); setProcessInstrumented(app.getActiveInstrumentation() != null); setProcessPersistent(app.isPersistent()); } else { setProcessCached(false); setProcessInstrumented(false); setProcessPersistent(false); } Loading @@ -398,12 +400,13 @@ class BroadcastProcessQueue { } /** * Update if this UID is in the "frozen" state, typically signaling that * Update if this process is in the "cached" state, typically signaling that * broadcast dispatch should be paused or delayed. */ public void setUidFrozen(boolean frozen) { if (mUidFrozen != frozen) { mUidFrozen = frozen; @VisibleForTesting void setProcessCached(boolean cached) { if (mProcessCached != cached) { mProcessCached = cached; invalidateRunnableAt(); } } Loading Loading @@ -810,7 +813,7 @@ class BroadcastProcessQueue { public boolean isDeferredUntilActive() { if (mRunnableAtInvalidated) updateRunnableAt(); return mRunnableAtReason == BroadcastProcessQueue.REASON_INFINITE_DEFER; return mRunnableAtReason == BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER; } public boolean hasDeferredBroadcasts() { Loading Loading @@ -845,14 +848,14 @@ class BroadcastProcessQueue { } static final int REASON_EMPTY = 0; static final int REASON_FROZEN = 1; static final int REASON_CACHED = 1; static final int REASON_NORMAL = 2; static final int REASON_MAX_PENDING = 3; static final int REASON_BLOCKED = 4; static final int REASON_INSTRUMENTED = 5; static final int REASON_PERSISTENT = 6; static final int REASON_FORCE_DELAYED = 7; static final int REASON_INFINITE_DEFER = 8; static final int REASON_CACHED_INFINITE_DEFER = 8; static final int REASON_CONTAINS_FOREGROUND = 10; static final int REASON_CONTAINS_ORDERED = 11; static final int REASON_CONTAINS_ALARM = 12; Loading @@ -865,14 +868,14 @@ class BroadcastProcessQueue { @IntDef(flag = false, prefix = { "REASON_" }, value = { REASON_EMPTY, REASON_FROZEN, REASON_CACHED, REASON_NORMAL, REASON_MAX_PENDING, REASON_BLOCKED, REASON_INSTRUMENTED, REASON_PERSISTENT, REASON_FORCE_DELAYED, REASON_INFINITE_DEFER, REASON_CACHED_INFINITE_DEFER, REASON_CONTAINS_FOREGROUND, REASON_CONTAINS_ORDERED, REASON_CONTAINS_ALARM, Loading @@ -889,14 +892,14 @@ class BroadcastProcessQueue { static @NonNull String reasonToString(@Reason int reason) { switch (reason) { case REASON_EMPTY: return "EMPTY"; case REASON_FROZEN: return "FROZEN"; case REASON_CACHED: return "CACHED"; case REASON_NORMAL: return "NORMAL"; case REASON_MAX_PENDING: return "MAX_PENDING"; case REASON_BLOCKED: return "BLOCKED"; case REASON_INSTRUMENTED: return "INSTRUMENTED"; case REASON_PERSISTENT: return "PERSISTENT"; case REASON_FORCE_DELAYED: return "FORCE_DELAYED"; case REASON_INFINITE_DEFER: return "INFINITE_DEFER"; case REASON_CACHED_INFINITE_DEFER: return "INFINITE_DEFER"; case REASON_CONTAINS_FOREGROUND: return "CONTAINS_FOREGROUND"; case REASON_CONTAINS_ORDERED: return "CONTAINS_ORDERED"; case REASON_CONTAINS_ALARM: return "CONTAINS_ALARM"; Loading Loading @@ -983,12 +986,12 @@ class BroadcastProcessQueue { } else if (mProcessPersistent) { mRunnableAt = runnableAt; mRunnableAtReason = REASON_PERSISTENT; } else if (mUidFrozen) { } else if (mProcessCached) { if (r.deferUntilActive) { // All enqueued broadcasts are deferrable, defer if (mCountDeferred == mCountEnqueued) { mRunnableAt = Long.MAX_VALUE; mRunnableAtReason = REASON_INFINITE_DEFER; mRunnableAtReason = REASON_CACHED_INFINITE_DEFER; } else { // At least one enqueued broadcast isn't deferrable, repick time and reason // for this record. If a later record is not deferrable and is one of these Loading @@ -1003,14 +1006,14 @@ class BroadcastProcessQueue { mRunnableAt = runnableAt; mRunnableAtReason = REASON_CONTAINS_RESULT_TO; } else { mRunnableAt = runnableAt + constants.DELAY_FROZEN_MILLIS; mRunnableAtReason = REASON_FROZEN; mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS; mRunnableAtReason = REASON_CACHED; } } } else { // This record isn't deferrable mRunnableAt = runnableAt + constants.DELAY_FROZEN_MILLIS; mRunnableAtReason = REASON_FROZEN; mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS; mRunnableAtReason = REASON_CACHED; } } else if (mCountResultTo > 0) { // All resultTo broadcasts are infinitely deferrable, so if the app Loading Loading @@ -1192,8 +1195,8 @@ class BroadcastProcessQueue { @NeverCompile private void dumpProcessState(@NonNull IndentingPrintWriter pw) { final StringBuilder sb = new StringBuilder(); if (mUidFrozen) { sb.append("FROZEN"); if (mProcessCached) { sb.append("CACHED"); } if (mProcessInstrumented) { if (sb.length() > 0) sb.append("|"); Loading
services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +14 −47 Original line number Diff line number Diff line Loading @@ -16,7 +16,6 @@ package com.android.server.am; import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN; import static android.os.Process.ZYGOTE_POLICY_FLAG_EMPTY; import static android.os.Process.ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE; Loading Loading @@ -49,7 +48,7 @@ import android.app.ActivityManager; import android.app.ApplicationExitInfo; import android.app.BroadcastOptions; import android.app.IApplicationThread; import android.app.IUidFrozenStateChangedCallback; import android.app.UidObserver; import android.app.usage.UsageEvents.Event; import android.content.ComponentName; import android.content.ContentResolver; Loading @@ -73,7 +72,6 @@ import android.util.MathUtils; import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseBooleanArray; import android.util.TimeUtils; import android.util.proto.ProtoOutputStream; Loading Loading @@ -211,16 +209,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private final AtomicReference<ArraySet<BroadcastRecord>> mReplacedBroadcastsCache = new AtomicReference<>(); /** * Map from UID to its last known "frozen" state. * <p> * We manually maintain this data structure since the lifecycle of * {@link ProcessRecord} and {@link BroadcastProcessQueue} can be * mismatched. */ @GuardedBy("mService") private final SparseBooleanArray mUidFrozen = new SparseBooleanArray(); private final BroadcastConstants mConstants; private final BroadcastConstants mFgConstants; private final BroadcastConstants mBgConstants; Loading Loading @@ -498,7 +486,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { final BroadcastProcessQueue queue = getProcessQueue(app); if (queue != null) { queue.setProcess(app); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); } boolean didSomething = false; Loading Loading @@ -540,7 +527,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { final BroadcastProcessQueue queue = getProcessQueue(app); if (queue != null) { queue.setProcess(null); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); } if ((mRunningColdStart != null) && (mRunningColdStart == queue)) { Loading Loading @@ -1342,25 +1328,15 @@ class BroadcastQueueModernImpl extends BroadcastQueue { mFgConstants.startObserving(mHandler, resolver); mBgConstants.startObserving(mHandler, resolver); mService.registerUidFrozenStateChangedCallback(new IUidFrozenStateChangedCallback.Stub() { mService.registerUidObserver(new UidObserver() { @Override public void onUidFrozenStateChanged(int[] uids, int[] frozenStates) { public void onUidCachedChanged(int uid, boolean cached) { synchronized (mService) { for (int i = 0; i < uids.length; i++) { final int uid = uids[i]; final boolean frozen = frozenStates[i] == UID_FROZEN_STATE_FROZEN; if (frozen) { mUidFrozen.put(uid, true); } else { mUidFrozen.delete(uid); } BroadcastProcessQueue leaf = mProcessQueues.get(uid); while (leaf != null) { // Update internal state by refreshing values previously // read from any known running process leaf.setProcess(leaf.app); leaf.setUidFrozen(frozen); updateQueueDeferred(leaf); updateRunnableList(leaf); leaf = leaf.processNameNext; Loading @@ -1368,8 +1344,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { enqueueUpdateRunningList(); } } } }); }, ActivityManager.UID_OBSERVER_CACHED, 0, "android"); // Kick off periodic health checks mLocalHandler.sendEmptyMessage(MSG_CHECK_HEALTH); Loading Loading @@ -1524,7 +1499,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) { if (!queue.isProcessWarm()) { queue.setProcess(mService.getProcessRecordLocked(queue.processName, queue.uid)); queue.setUidFrozen(mUidFrozen.get(queue.uid, false)); } } Loading Loading @@ -1719,7 +1693,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid); created.setProcess(mService.getProcessRecordLocked(processName, uid)); created.setUidFrozen(mUidFrozen.get(uid, false)); if (leaf == null) { mProcessQueues.put(uid, created); Loading Loading @@ -1848,12 +1821,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { ipw.decreaseIndent(); ipw.println(); ipw.println("Frozen UIDs:"); ipw.increaseIndent(); ipw.println(mUidFrozen.toString()); ipw.decreaseIndent(); ipw.println(); if (dumpConstants) { mConstants.dump(ipw); } Loading
services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +23 −23 Original line number Diff line number Diff line Loading @@ -130,7 +130,7 @@ public final class BroadcastQueueModernImplTest { mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS); mConstants.DELAY_URGENT_MILLIS = -120_000; mConstants.DELAY_NORMAL_MILLIS = 10_000; mConstants.DELAY_FROZEN_MILLIS = 120_000; mConstants.DELAY_CACHED_MILLIS = 120_000; final BroadcastSkipPolicy emptySkipPolicy = new BroadcastSkipPolicy(mAms) { public boolean shouldSkip(BroadcastRecord r, Object o) { Loading Loading @@ -372,13 +372,13 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false); queue.setUidFrozen(false); queue.setProcessCached(false); final long notCachedRunnableAt = queue.getRunnableAt(); queue.setUidFrozen(true); queue.setProcessCached(true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertFalse(queue.isRunnable()); assertEquals(BroadcastProcessQueue.REASON_INFINITE_DEFER, assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER, queue.getRunnableAtReason()); assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); } Loading @@ -399,13 +399,13 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false); queue.setUidFrozen(false); queue.setProcessCached(false); final long notCachedRunnableAt = queue.getRunnableAt(); queue.setUidFrozen(true); queue.setProcessCached(true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertTrue(queue.isRunnable()); assertEquals(BroadcastProcessQueue.REASON_FROZEN, queue.getRunnableAtReason()); assertEquals(BroadcastProcessQueue.REASON_CACHED, queue.getRunnableAtReason()); assertEquals(ProcessList.SCHED_GROUP_BACKGROUND, queue.getPreferredSchedulingGroupLocked()); } Loading @@ -431,13 +431,13 @@ public final class BroadcastQueueModernImplTest { // verify that: // (a) the queue is immediately runnable by existence of a fg-priority broadcast // (b) the next one up is the fg-priority broadcast despite its later enqueue time queue.setUidFrozen(false); queue.setProcessCached(false); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord); queue.setUidFrozen(true); queue.setProcessCached(true); assertTrue(queue.isRunnable()); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime); assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked()); Loading Loading @@ -497,10 +497,10 @@ public final class BroadcastQueueModernImplTest { * Verify that a cached process that would normally be delayed becomes * immediately runnable when the given broadcast is enqueued. */ private void doRunnableAt_Frozen(BroadcastRecord testRecord, int testRunnableAtReason) { private void doRunnableAt_Cached(BroadcastRecord testRecord, int testRunnableAtReason) { final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants, PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN)); queue.setUidFrozen(true); queue.setProcessCached(true); final BroadcastRecord lazyRecord = makeBroadcastRecord( new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED), Loading @@ -516,49 +516,49 @@ public final class BroadcastQueueModernImplTest { } @Test public void testRunnableAt_Frozen_Manifest() { doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), null, public void testRunnableAt_Cached_Manifest() { doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null, List.of(makeMockManifestReceiver()), null, false), REASON_CONTAINS_MANIFEST); } @Test public void testRunnableAt_Frozen_Ordered() { doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), null, public void testRunnableAt_Cached_Ordered() { doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), null, List.of(makeMockRegisteredReceiver()), null, true), REASON_CONTAINS_ORDERED); } @Test public void testRunnableAt_Frozen_Foreground() { public void testRunnableAt_Cached_Foreground() { final Intent foregroundIntent = new Intent(); foregroundIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); doRunnableAt_Frozen(makeBroadcastRecord(foregroundIntent, null, doRunnableAt_Cached(makeBroadcastRecord(foregroundIntent, null, List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_FOREGROUND); } @Test public void testRunnableAt_Frozen_Interactive() { public void testRunnableAt_Cached_Interactive() { final BroadcastOptions options = BroadcastOptions.makeBasic(); options.setInteractive(true); doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), options, doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options, List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_INTERACTIVE); } @Test public void testRunnableAt_Frozen_Alarm() { public void testRunnableAt_Cached_Alarm() { final BroadcastOptions options = BroadcastOptions.makeBasic(); options.setAlarmBroadcast(true); doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), options, doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options, List.of(makeMockRegisteredReceiver()), null, false), REASON_CONTAINS_ALARM); } @Test public void testRunnableAt_Frozen_Prioritized_NonDeferrable() { public void testRunnableAt_Cached_Prioritized_NonDeferrable() { final List receivers = List.of( withPriority(makeManifestReceiver(PACKAGE_RED, PACKAGE_RED), 10), withPriority(makeManifestReceiver(PACKAGE_GREEN, PACKAGE_GREEN), -10)); final BroadcastOptions options = BroadcastOptions.makeBasic() .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_NONE); doRunnableAt_Frozen(makeBroadcastRecord(makeMockIntent(), options, doRunnableAt_Cached(makeBroadcastRecord(makeMockIntent(), options, receivers, null, false), REASON_CONTAINS_PRIORITIZED); } Loading