From cb5c57145e383536a0793478a8b5b44a4667b542 Mon Sep 17 00:00:00 2001 From: Sudheer Shanka Date: Thu, 18 May 2023 01:09:08 +0000 Subject: [PATCH] Revert "Track per-process freezable state in BroadcastQueue." This reverts commit 91fb9aee8767c908a2969177f0ae4999e4226874. Reason for revert: b/283167416 Change-Id: I755567fc1e87c342a833ce0ea2dda91a91a65efe --- .../server/am/ActivityManagerService.java | 6 -- .../server/am/BroadcastProcessQueue.java | 24 +++--- .../com/android/server/am/BroadcastQueue.java | 7 -- .../android/server/am/BroadcastQueueImpl.java | 4 - .../server/am/BroadcastQueueModernImpl.java | 72 +++++++++--------- .../android/server/am/CachedAppOptimizer.java | 38 ++-------- .../com/android/server/am/ProcessRecord.java | 3 - .../am/BroadcastQueueModernImplTest.java | 8 +- .../android/server/am/BroadcastQueueTest.java | 73 ++----------------- 9 files changed, 68 insertions(+), 167 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index ca4a253e779c4..bfa397fa2b036 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -17236,12 +17236,6 @@ public class ActivityManagerService extends IActivityManager.Stub } } - void onProcessFreezableChangedLocked(ProcessRecord app) { - if (mEnableModernQueue) { - mBroadcastQueues[0].onProcessFreezableChangedLocked(app); - } - } - @VisibleForTesting public final class LocalService extends ActivityManagerInternal implements ActivityManagerLocal { diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index 142a5dc6db0fb..3ac2b2bd9fd1b 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -201,7 +201,7 @@ class BroadcastProcessQueue { private boolean mLastDeferredStates; private boolean mUidForeground; - private boolean mProcessFreezable; + private boolean mUidCached; private boolean mProcessInstrumented; private boolean mProcessPersistent; @@ -411,7 +411,7 @@ class BroadcastProcessQueue { */ @CheckResult public boolean setProcessAndUidState(@Nullable ProcessRecord app, boolean uidForeground, - boolean processFreezable) { + boolean uidCached) { this.app = app; // Since we may have just changed our PID, invalidate cached strings @@ -420,13 +420,13 @@ class BroadcastProcessQueue { boolean didSomething = false; if (app != null) { + didSomething |= setUidCached(uidCached); didSomething |= setUidForeground(uidForeground); - didSomething |= setProcessFreezable(processFreezable); didSomething |= setProcessInstrumented(app.getActiveInstrumentation() != null); didSomething |= setProcessPersistent(app.isPersistent()); } else { + didSomething |= setUidCached(uidCached); didSomething |= setUidForeground(false); - didSomething |= setProcessFreezable(false); didSomething |= setProcessInstrumented(false); didSomething |= setProcessPersistent(false); } @@ -450,13 +450,13 @@ class BroadcastProcessQueue { } /** - * Update if this process is in the "freezable" state, typically signaling that + * Update if this process is in the "cached" state, typically signaling that * broadcast dispatch should be paused or delayed. */ @CheckResult - private boolean setProcessFreezable(boolean freezable) { - if (mProcessFreezable != freezable) { - mProcessFreezable = freezable; + private boolean setUidCached(boolean uidCached) { + if (mUidCached != uidCached) { + mUidCached = uidCached; invalidateRunnableAt(); return true; } else { @@ -1115,7 +1115,7 @@ class BroadcastProcessQueue { } else if (mCountManifest > 0) { mRunnableAt = runnableAt; mRunnableAtReason = REASON_CONTAINS_MANIFEST; - } else if (mProcessFreezable) { + } else if (mUidCached) { if (r.deferUntilActive) { // All enqueued broadcasts are deferrable, defer if (mCountDeferred == mCountEnqueued) { @@ -1185,7 +1185,7 @@ class BroadcastProcessQueue { // When all we have pending is deferred broadcasts, and we're cached, // then we want everything to be marked deferred final boolean wantDeferredStates = (mCountDeferred > 0) - && (mCountDeferred == mCountEnqueued) && mProcessFreezable; + && (mCountDeferred == mCountEnqueued) && mUidCached; if (mLastDeferredStates != wantDeferredStates) { mLastDeferredStates = wantDeferredStates; @@ -1372,9 +1372,9 @@ class BroadcastProcessQueue { if (mUidForeground) { sb.append("FG"); } - if (mProcessFreezable) { + if (mUidCached) { if (sb.length() > 0) sb.append("|"); - sb.append("FRZN"); + sb.append("CACHED"); } if (mProcessInstrumented) { if (sb.length() > 0) sb.append("|"); diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 93bde6f1132ba..8e76e5b5cf484 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -172,13 +172,6 @@ public abstract class BroadcastQueue { @GuardedBy("mService") public abstract void onApplicationCleanupLocked(@NonNull ProcessRecord app); - /** - * Signal from OS internals that the given process is in a freezable state and will be - * freezed soon after. - */ - @GuardedBy("mService") - public abstract void onProcessFreezableChangedLocked(@NonNull 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 diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java index ce635f1076c11..7f3ceb578891f 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java @@ -449,10 +449,6 @@ public class BroadcastQueueImpl extends BroadcastQueue { skipCurrentOrPendingReceiverLocked(app); } - public void onProcessFreezableChangedLocked(ProcessRecord app) { - // Not supported; ignore - } - public boolean sendPendingBroadcastsLocked(ProcessRecord app) { boolean didSomething = false; final BroadcastRecord br = mPendingBroadcast; diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index 3e0f71a57bbe4..d9b315794ea3f 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -222,6 +222,16 @@ class BroadcastQueueModernImpl extends BroadcastQueue { @GuardedBy("mService") private final SparseBooleanArray mUidForeground = new SparseBooleanArray(); + /** + * Map from UID to its last known "cached" state. + *

+ * We manually maintain this data structure since the lifecycle of + * {@link ProcessRecord} and {@link BroadcastProcessQueue} can be + * mismatched. + */ + @GuardedBy("mService") + private final SparseBooleanArray mUidCached = new SparseBooleanArray(); + private final BroadcastConstants mConstants; private final BroadcastConstants mFgConstants; private final BroadcastConstants mBgConstants; @@ -563,13 +573,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { } } - @Override - public void onProcessFreezableChangedLocked(@NonNull ProcessRecord app) { - synchronized (mService) { - refreshProcessQueueLocked(app); - } - } - @Override public int getPreferredSchedulingGroupLocked(@NonNull ProcessRecord app) { final BroadcastProcessQueue queue = getProcessQueue(app); @@ -1293,6 +1296,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue { }; broadcastPredicate = BROADCAST_PREDICATE_ANY; + cleanupUserStateLocked(mUidCached, userId); cleanupUserStateLocked(mUidForeground, userId); } return forEachMatchingBroadcast(queuePredicate, broadcastPredicate, @@ -1435,7 +1439,20 @@ class BroadcastQueueModernImpl extends BroadcastQueue { refreshProcessQueuesLocked(uid); } } - }, ActivityManager.UID_OBSERVER_PROCSTATE, ActivityManager.PROCESS_STATE_TOP, "android"); + + @Override + public void onUidCachedChanged(int uid, boolean cached) { + synchronized (mService) { + if (cached) { + mUidCached.put(uid, true); + } else { + mUidCached.delete(uid); + } + refreshProcessQueuesLocked(uid); + } + } + }, ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_CACHED, + ActivityManager.PROCESS_STATE_TOP, "android"); // Kick off periodic health checks mLocalHandler.sendEmptyMessage(MSG_CHECK_HEALTH); @@ -1624,9 +1641,10 @@ class BroadcastQueueModernImpl extends BroadcastQueue { // warm via this operation, we're going to immediately promote it to // be running, and any side effect of this operation will then apply // after it's finished and is returned to the runnable list. - final ProcessRecord app = mService.getProcessRecordLocked(queue.processName, queue.uid); - queue.setProcessAndUidState(app, mUidForeground.get(queue.uid, false), - isProcessFreezable(app)); + queue.setProcessAndUidState( + mService.getProcessRecordLocked(queue.processName, queue.uid), + mUidForeground.get(queue.uid, false), + mUidCached.get(queue.uid, false)); } } @@ -1638,21 +1656,11 @@ class BroadcastQueueModernImpl extends BroadcastQueue { private void setQueueProcess(@NonNull BroadcastProcessQueue queue, @Nullable ProcessRecord app) { if (queue.setProcessAndUidState(app, mUidForeground.get(queue.uid, false), - isProcessFreezable(app))) { + mUidCached.get(queue.uid, false))) { updateRunnableList(queue); } } - @GuardedBy("mService") - private boolean isProcessFreezable(@Nullable ProcessRecord app) { - if (app == null) { - return false; - } - synchronized (mService.mProcLock) { - return app.mOptRecord.isPendingFreeze() || app.mOptRecord.isFrozen(); - } - } - /** * Refresh the process queues with the latest process state so that runnableAt * can be updated. @@ -1669,20 +1677,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue { enqueueUpdateRunningList(); } - /** - * Refresh the process queue corresponding to {@code app} with the latest process state - * so that runnableAt can be updated. - */ - @GuardedBy("mService") - private void refreshProcessQueueLocked(@NonNull ProcessRecord app) { - final BroadcastProcessQueue queue = getProcessQueue(app.processName, app.uid); - if (queue == null || queue.app == null || queue.app.getPid() != app.getPid()) { - return; - } - setQueueProcess(queue, queue.app); - enqueueUpdateRunningList(); - } - /** * Inform other parts of OS that the given broadcast queue has started * running, typically for internal bookkeeping. @@ -2002,6 +1996,12 @@ class BroadcastQueueModernImpl extends BroadcastQueue { ipw.decreaseIndent(); ipw.println(); + ipw.println("Cached UIDs:"); + ipw.increaseIndent(); + ipw.println(mUidCached); + ipw.decreaseIndent(); + ipw.println(); + ipw.println("Foreground UIDs:"); ipw.increaseIndent(); ipw.println(mUidForeground); diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java index 28ed2cba9f197..3e82d557c01ae 100644 --- a/services/core/java/com/android/server/am/CachedAppOptimizer.java +++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java @@ -299,7 +299,6 @@ public final class CachedAppOptimizer { static final int COMPACT_NATIVE_MSG = 5; static final int UID_FROZEN_STATE_CHANGED_MSG = 6; static final int DEADLOCK_WATCHDOG_MSG = 7; - static final int REPORT_PROCESS_FREEZABLE_CHANGED = 8; // When free swap falls below this percentage threshold any full (file + anon) // compactions will be downgraded to file only compactions to reduce pressure @@ -1325,7 +1324,6 @@ public final class CachedAppOptimizer { } } } - postProcessFreezableChangedMessage(app); mFreezeHandler.sendMessageDelayed( mFreezeHandler.obtainMessage(SET_FROZEN_PROCESS_MSG, DO_FREEZE, 0, app), delayMillis); @@ -1363,7 +1361,6 @@ public final class CachedAppOptimizer { uidRec.setFrozen(false); postUidFrozenMessage(uidRec.getUid(), false); } - postProcessFreezableChangedMessage(app); opt.setFreezerOverride(false); if (pid == 0 || !opt.isFrozen()) { @@ -2041,21 +2038,6 @@ public final class CachedAppOptimizer { 0, uidObj)); } - private void reportProcessFreezableChanged(ProcessRecord app) { - synchronized (mAm) { - mAm.onProcessFreezableChangedLocked(app); - } - } - - @GuardedBy("mAm") - private void postProcessFreezableChangedMessage(ProcessRecord app) { - if (app.getPid() == 0) { - return; - } - mFreezeHandler.obtainMessage(REPORT_PROCESS_FREEZABLE_CHANGED, 0, 0, app) - .sendToTarget(); - } - private final class FreezeHandler extends Handler implements ProcLocksReader.ProcLocksReaderCallback { private FreezeHandler() { @@ -2065,7 +2047,7 @@ public final class CachedAppOptimizer { @Override public void handleMessage(Message msg) { switch (msg.what) { - case SET_FROZEN_PROCESS_MSG: { + case SET_FROZEN_PROCESS_MSG: ProcessRecord proc = (ProcessRecord) msg.obj; synchronized (mAm) { freezeProcess(proc); @@ -2075,8 +2057,8 @@ public final class CachedAppOptimizer { removeMessages(DEADLOCK_WATCHDOG_MSG); sendEmptyMessageDelayed(DEADLOCK_WATCHDOG_MSG, FREEZE_DEADLOCK_TIMEOUT_MS); } - } break; - case REPORT_UNFREEZE_MSG: { + break; + case REPORT_UNFREEZE_MSG: int pid = msg.arg1; int frozenDuration = msg.arg2; Pair obj = (Pair) msg.obj; @@ -2084,13 +2066,13 @@ public final class CachedAppOptimizer { int reason = obj.second; reportUnfreeze(pid, frozenDuration, processName, reason); - } break; - case UID_FROZEN_STATE_CHANGED_MSG: { + break; + case UID_FROZEN_STATE_CHANGED_MSG: final boolean frozen = (msg.arg1 == 1); final int uid = (int) msg.obj; reportOneUidFrozenStateChanged(uid, frozen); - } break; - case DEADLOCK_WATCHDOG_MSG: { + break; + case DEADLOCK_WATCHDOG_MSG: try { // post-check to prevent deadlock if (DEBUG_FREEZER) { @@ -2100,11 +2082,7 @@ public final class CachedAppOptimizer { } catch (IOException e) { Slog.w(TAG_AM, "Unable to check file locks"); } - } break; - case REPORT_PROCESS_FREEZABLE_CHANGED: { - final ProcessRecord app = (ProcessRecord) msg.obj; - reportProcessFreezableChanged(app); - } break; + break; default: return; } diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java index 9b1149aed977b..335d6768c37be 100644 --- a/services/core/java/com/android/server/am/ProcessRecord.java +++ b/services/core/java/com/android/server/am/ProcessRecord.java @@ -1192,9 +1192,6 @@ class ProcessRecord implements WindowProcessListener { "Killing " + toShortString() + " (adj " + mState.getSetAdj() + "): " + reason, info.uid); } - // Since the process is getting killed, reset the freezable related state. - mOptRecord.setPendingFreeze(false); - mOptRecord.setFrozen(false); if (mPid > 0) { mService.mProcessList.noteAppKill(this, reasonCode, subReason, description); EventLog.writeEvent(EventLogTags.AM_KILL, diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java index 2b4461537e9c9..f47954baf6494 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java @@ -393,9 +393,9 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); enqueueOrReplaceBroadcast(queue, airplaneRecord, 0); - queue.setProcessAndUidState(mProcess, false, false); + queue.setProcessAndUidState(null, false, false); final long notCachedRunnableAt = queue.getRunnableAt(); - queue.setProcessAndUidState(mProcess, false, true); + queue.setProcessAndUidState(null, false, true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertFalse(queue.isRunnable()); @@ -420,9 +420,9 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver()), false); enqueueOrReplaceBroadcast(queue, airplaneRecord, 0); - queue.setProcessAndUidState(mProcess, false, false); + queue.setProcessAndUidState(null, false, false); final long notCachedRunnableAt = queue.getRunnableAt(); - queue.setProcessAndUidState(mProcess, false, true); + queue.setProcessAndUidState(null, false, true); final long cachedRunnableAt = queue.getRunnableAt(); assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertTrue(queue.isRunnable()); diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java index 615b4c1e89639..ad5f0d7233cac 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java @@ -399,12 +399,6 @@ public class BroadcastQueueTest { UserHandle.USER_SYSTEM); } - private ProcessRecord makeActiveProcessRecord(String packageName, String processName) - throws Exception { - return makeActiveProcessRecord(packageName, processName, ProcessBehavior.NORMAL, - UserHandle.USER_SYSTEM); - } - private ProcessRecord makeActiveProcessRecord(String packageName, ProcessBehavior behavior) throws Exception { return makeActiveProcessRecord(packageName, packageName, behavior, UserHandle.USER_SYSTEM); @@ -602,11 +596,6 @@ public class BroadcastQueueTest { BackgroundStartPrivileges.NONE, false, null); } - private void setProcessFreezable(ProcessRecord app, boolean pendingFreeze, boolean frozen) { - app.mOptRecord.setPendingFreeze(pendingFreeze); - app.mOptRecord.setFrozen(frozen); - } - private void assertHealth() { if (mImpl == Impl.MODERN) { // If this fails, it'll throw a clear reason message @@ -1670,10 +1659,8 @@ public class BroadcastQueueTest { final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); final ProcessRecord receiverOrangeApp = makeActiveProcessRecord(PACKAGE_ORANGE); - setProcessFreezable(receiverGreenApp, true, false); - mQueue.onProcessFreezableChangedLocked(receiverGreenApp); - setProcessFreezable(receiverBlueApp, false, true); - mQueue.onProcessFreezableChangedLocked(receiverBlueApp); + mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), true); + mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), true); final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); final BroadcastOptions opts = BroadcastOptions.makeBasic() @@ -1717,14 +1704,12 @@ public class BroadcastQueueTest { eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any()); // Shift blue to be active and confirm that deferred broadcast is delivered - setProcessFreezable(receiverBlueApp, false, false); - mQueue.onProcessFreezableChangedLocked(receiverBlueApp); + mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), false); waitForIdle(); verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, timeTick); // Shift green to be active and confirm that deferred broadcast is delivered - setProcessFreezable(receiverGreenApp, false, false); - mQueue.onProcessFreezableChangedLocked(receiverGreenApp); + mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), false); waitForIdle(); verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick); } @@ -2121,12 +2106,9 @@ public class BroadcastQueueTest { final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE); final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW); - setProcessFreezable(receiverGreenApp, true, true); - mQueue.onProcessFreezableChangedLocked(receiverGreenApp); - setProcessFreezable(receiverBlueApp, true, false); - mQueue.onProcessFreezableChangedLocked(receiverBlueApp); - setProcessFreezable(receiverYellowApp, false, false); - mQueue.onProcessFreezableChangedLocked(receiverYellowApp); + mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), true); + mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), true); + mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_YELLOW), false); final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); final BroadcastOptions opts = BroadcastOptions.makeBasic() @@ -2149,50 +2131,11 @@ public class BroadcastQueueTest { verifyScheduleRegisteredReceiver(times(1), receiverYellowApp, airplane); // Shift green to be active and confirm that deferred broadcast is delivered - setProcessFreezable(receiverGreenApp, false, false); - mQueue.onProcessFreezableChangedLocked(receiverGreenApp); + mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), false); waitForIdle(); verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, airplane); } - /** - * Verify broadcasts to a runtime receiver in cached process is deferred even when a different - * process in the same package is not cached. - */ - @Test - public void testDeferralPolicy_UntilActive_WithMultiProcessUid() throws Exception { - // Legacy stack doesn't support deferral - Assume.assumeTrue(mImpl == Impl.MODERN); - - final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED); - final ProcessRecord receiverGreenApp1 = makeActiveProcessRecord(PACKAGE_GREEN); - final ProcessRecord receiverGreenApp2 = makeActiveProcessRecord(PACKAGE_GREEN, - PACKAGE_GREEN + "_proc2"); - - setProcessFreezable(receiverGreenApp1, true, true); - mQueue.onProcessFreezableChangedLocked(receiverGreenApp1); - - final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); - final BroadcastOptions opts = BroadcastOptions.makeBasic() - .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE); - enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, opts, - List.of(makeRegisteredReceiver(receiverGreenApp1), - makeRegisteredReceiver(receiverGreenApp2)))); - waitForIdle(); - - // 1st process in Green package is ignored since it is in a cached state - // but the 2nd process should still receive the broadcast. - verifyScheduleRegisteredReceiver(never(), receiverGreenApp1, airplane); - verifyScheduleRegisteredReceiver(times(1), receiverGreenApp2, airplane); - - // Shift the 1st process in Green package to be active and confirm that deferred broadcast - // is delivered - setProcessFreezable(receiverGreenApp1, false, false); - mQueue.onProcessFreezableChangedLocked(receiverGreenApp1); - waitForIdle(); - verifyScheduleRegisteredReceiver(times(1), receiverGreenApp1, airplane); - } - @Test public void testBroadcastDelivery_uidForeground() throws Exception { // Legacy stack doesn't support prioritization to foreground app.