Merge "Revert "More robust updating of "runnable" list."" into udc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
5b7d07f569
@@ -21,7 +21,6 @@ import static com.android.server.am.BroadcastRecord.deliveryStateToString;
|
||||
import static com.android.server.am.BroadcastRecord.isDeliveryStateTerminal;
|
||||
import static com.android.server.am.BroadcastRecord.isReceiverEquals;
|
||||
|
||||
import android.annotation.CheckResult;
|
||||
import android.annotation.IntDef;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
@@ -342,12 +341,7 @@ class BroadcastProcessQueue {
|
||||
* Predicates that choose to remove a broadcast <em>must</em> finish
|
||||
* delivery of the matched broadcast, to ensure that situations like ordered
|
||||
* broadcasts are handled consistently.
|
||||
*
|
||||
* @return if this operation may have changed internal state, indicating
|
||||
* that the caller is responsible for invoking
|
||||
* {@link BroadcastQueueModernImpl#updateRunnableList}
|
||||
*/
|
||||
@CheckResult
|
||||
public boolean forEachMatchingBroadcast(@NonNull BroadcastPredicate predicate,
|
||||
@NonNull BroadcastConsumer consumer, boolean andRemove) {
|
||||
boolean didSomething = false;
|
||||
@@ -360,7 +354,6 @@ class BroadcastProcessQueue {
|
||||
return didSomething;
|
||||
}
|
||||
|
||||
@CheckResult
|
||||
private boolean forEachMatchingBroadcastInQueue(@NonNull ArrayDeque<SomeArgs> queue,
|
||||
@NonNull BroadcastPredicate predicate, @NonNull BroadcastConsumer consumer,
|
||||
boolean andRemove) {
|
||||
@@ -377,10 +370,6 @@ class BroadcastProcessQueue {
|
||||
args.recycle();
|
||||
it.remove();
|
||||
onBroadcastDequeued(record, recordIndex, recordWouldBeSkipped);
|
||||
} else {
|
||||
// Even if we're leaving broadcast in queue, it may have
|
||||
// been mutated in such a way to change our runnable time
|
||||
invalidateRunnableAt();
|
||||
}
|
||||
didSomething = true;
|
||||
}
|
||||
@@ -392,43 +381,30 @@ class BroadcastProcessQueue {
|
||||
|
||||
/**
|
||||
* Update the actively running "warm" process for this process.
|
||||
*
|
||||
* @return if this operation may have changed internal state, indicating
|
||||
* that the caller is responsible for invoking
|
||||
* {@link BroadcastQueueModernImpl#updateRunnableList}
|
||||
*/
|
||||
@CheckResult
|
||||
public boolean setProcessAndUidFrozen(@Nullable ProcessRecord app, boolean uidFrozen) {
|
||||
public void setProcess(@Nullable ProcessRecord app) {
|
||||
this.app = app;
|
||||
if (app != null) {
|
||||
setProcessInstrumented(app.getActiveInstrumentation() != null);
|
||||
setProcessPersistent(app.isPersistent());
|
||||
} else {
|
||||
setProcessInstrumented(false);
|
||||
setProcessPersistent(false);
|
||||
}
|
||||
|
||||
// Since we may have just changed our PID, invalidate cached strings
|
||||
mCachedToString = null;
|
||||
mCachedToShortString = null;
|
||||
|
||||
boolean didSomething = false;
|
||||
if (app != null) {
|
||||
didSomething |= setProcessInstrumented(app.getActiveInstrumentation() != null);
|
||||
didSomething |= setProcessPersistent(app.isPersistent());
|
||||
didSomething |= setUidFrozen(uidFrozen);
|
||||
} else {
|
||||
didSomething |= setProcessInstrumented(false);
|
||||
didSomething |= setProcessPersistent(false);
|
||||
didSomething |= setUidFrozen(uidFrozen);
|
||||
}
|
||||
return didSomething;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update if this UID is in the "frozen" state, typically signaling that
|
||||
* broadcast dispatch should be paused or delayed.
|
||||
*/
|
||||
private boolean setUidFrozen(boolean frozen) {
|
||||
public void setUidFrozen(boolean frozen) {
|
||||
if (mUidFrozen != frozen) {
|
||||
mUidFrozen = frozen;
|
||||
invalidateRunnableAt();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -437,13 +413,10 @@ class BroadcastProcessQueue {
|
||||
* signaling that broadcast dispatch should bypass all pauses or delays, to
|
||||
* avoid holding up test suites.
|
||||
*/
|
||||
private boolean setProcessInstrumented(boolean instrumented) {
|
||||
public void setProcessInstrumented(boolean instrumented) {
|
||||
if (mProcessInstrumented != instrumented) {
|
||||
mProcessInstrumented = instrumented;
|
||||
invalidateRunnableAt();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -451,13 +424,10 @@ class BroadcastProcessQueue {
|
||||
* Update if this process is in the "persistent" state, which signals broadcast dispatch should
|
||||
* bypass all pauses or delays to prevent the system from becoming out of sync with itself.
|
||||
*/
|
||||
private boolean setProcessPersistent(boolean persistent) {
|
||||
public void setProcessPersistent(boolean persistent) {
|
||||
if (mProcessPersistent != persistent) {
|
||||
mProcessPersistent = persistent;
|
||||
invalidateRunnableAt();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,20 +647,8 @@ class BroadcastProcessQueue {
|
||||
return mActive != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return if this operation may have changed internal state, indicating
|
||||
* that the caller is responsible for invoking
|
||||
* {@link BroadcastQueueModernImpl#updateRunnableList}
|
||||
*/
|
||||
@CheckResult
|
||||
boolean forceDelayBroadcastDelivery(long delayedDurationMs) {
|
||||
if (mForcedDelayedDurationMs != delayedDurationMs) {
|
||||
mForcedDelayedDurationMs = delayedDurationMs;
|
||||
invalidateRunnableAt();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
void forceDelayBroadcastDelivery(long delayedDurationMs) {
|
||||
mForcedDelayedDurationMs = delayedDurationMs;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -762,21 +720,10 @@ class BroadcastProcessQueue {
|
||||
* broadcasts would be prioritized for dispatching, even if there are urgent broadcasts
|
||||
* waiting. This is typically used in case there are callers waiting for "barrier" to be
|
||||
* reached.
|
||||
*
|
||||
* @return if this operation may have changed internal state, indicating
|
||||
* that the caller is responsible for invoking
|
||||
* {@link BroadcastQueueModernImpl#updateRunnableList}
|
||||
*/
|
||||
@CheckResult
|
||||
@VisibleForTesting
|
||||
boolean setPrioritizeEarliest(boolean prioritizeEarliest) {
|
||||
if (mPrioritizeEarliest != prioritizeEarliest) {
|
||||
mPrioritizeEarliest = prioritizeEarliest;
|
||||
invalidateRunnableAt();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
void setPrioritizeEarliest(boolean prioritizeEarliest) {
|
||||
mPrioritizeEarliest = prioritizeEarliest;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -361,6 +361,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
// If app isn't running, and there's nothing in the queue, clean up
|
||||
if (queue.isEmpty() && !queue.isActive() && !queue.isProcessWarm()) {
|
||||
removeProcessQueue(queue.processName, queue.uid);
|
||||
} else {
|
||||
updateQueueDeferred(queue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +497,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
// relevant per-process queue
|
||||
final BroadcastProcessQueue queue = getProcessQueue(app);
|
||||
if (queue != null) {
|
||||
setQueueProcess(queue, app);
|
||||
queue.setProcess(app);
|
||||
queue.setUidFrozen(mUidFrozen.get(queue.uid, false));
|
||||
}
|
||||
|
||||
boolean didSomething = false;
|
||||
@@ -536,7 +539,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
// relevant per-process queue
|
||||
final BroadcastProcessQueue queue = getProcessQueue(app);
|
||||
if (queue != null) {
|
||||
setQueueProcess(queue, null);
|
||||
queue.setProcess(null);
|
||||
queue.setUidFrozen(mUidFrozen.get(queue.uid, false));
|
||||
}
|
||||
|
||||
if ((mRunningColdStart != null) && (mRunningColdStart == queue)) {
|
||||
@@ -563,7 +567,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
return (r.receivers.get(i) instanceof BroadcastFilter);
|
||||
}, mBroadcastConsumerSkip, true);
|
||||
if (didSomething || queue.isEmpty()) {
|
||||
updateQueueDeferred(queue);
|
||||
updateRunnableList(queue);
|
||||
enqueueUpdateRunningList();
|
||||
}
|
||||
@@ -629,7 +632,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
setDeliveryState(queue, null, r, i, receiver, BroadcastRecord.DELIVERY_DEFERRED,
|
||||
"deferred at enqueue time");
|
||||
}
|
||||
updateQueueDeferred(queue);
|
||||
updateRunnableList(queue);
|
||||
enqueueUpdateRunningList();
|
||||
}
|
||||
@@ -1078,7 +1080,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
|
||||
final int queueIndex = getRunningIndexOf(queue);
|
||||
mRunning[queueIndex] = null;
|
||||
updateQueueDeferred(queue);
|
||||
updateRunnableList(queue);
|
||||
enqueueUpdateRunningList();
|
||||
|
||||
@@ -1161,7 +1162,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
getReceiverUid(otherReceiver));
|
||||
if (otherQueue != null) {
|
||||
otherQueue.invalidateRunnableAt();
|
||||
updateQueueDeferred(otherQueue);
|
||||
updateRunnableList(otherQueue);
|
||||
}
|
||||
}
|
||||
@@ -1294,7 +1294,6 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
if (queuePredicate.test(leaf)) {
|
||||
if (leaf.forEachMatchingBroadcast(broadcastPredicate,
|
||||
broadcastConsumer, andRemove)) {
|
||||
updateQueueDeferred(leaf);
|
||||
updateRunnableList(leaf);
|
||||
didSomething = true;
|
||||
}
|
||||
@@ -1308,40 +1307,29 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
return didSomething;
|
||||
}
|
||||
|
||||
private boolean forEachMatchingQueue(
|
||||
private void forEachMatchingQueue(
|
||||
@NonNull Predicate<BroadcastProcessQueue> queuePredicate,
|
||||
@NonNull Consumer<BroadcastProcessQueue> queueConsumer) {
|
||||
boolean didSomething = false;
|
||||
for (int i = mProcessQueues.size() - 1; i >= 0; i--) {
|
||||
BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
|
||||
while (leaf != null) {
|
||||
if (queuePredicate.test(leaf)) {
|
||||
queueConsumer.accept(leaf);
|
||||
updateQueueDeferred(leaf);
|
||||
updateRunnableList(leaf);
|
||||
didSomething = true;
|
||||
}
|
||||
leaf = leaf.processNameNext;
|
||||
}
|
||||
}
|
||||
if (didSomething) {
|
||||
enqueueUpdateRunningList();
|
||||
}
|
||||
return didSomething;
|
||||
}
|
||||
|
||||
@SuppressWarnings("CheckResult")
|
||||
private void updateQueueDeferred(@NonNull BroadcastProcessQueue leaf) {
|
||||
private void updateQueueDeferred(
|
||||
@NonNull BroadcastProcessQueue leaf) {
|
||||
if (leaf.isDeferredUntilActive()) {
|
||||
// We ignore the returned value here since callers are invoking us
|
||||
// just before updateRunnableList()
|
||||
leaf.forEachMatchingBroadcast((r, i) -> {
|
||||
return r.deferUntilActive && (r.getDeliveryState(i)
|
||||
== BroadcastRecord.DELIVERY_PENDING);
|
||||
}, mBroadcastConsumerDefer, false);
|
||||
} else if (leaf.hasDeferredBroadcasts()) {
|
||||
// We ignore the returned value here since callers are invoking us
|
||||
// just before updateRunnableList()
|
||||
leaf.forEachMatchingBroadcast((r, i) -> {
|
||||
return r.deferUntilActive && (r.getDeliveryState(i)
|
||||
== BroadcastRecord.DELIVERY_DEFERRED);
|
||||
@@ -1371,7 +1359,10 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
while (leaf != null) {
|
||||
// Update internal state by refreshing values previously
|
||||
// read from any known running process
|
||||
setQueueProcess(leaf, leaf.app);
|
||||
leaf.setProcess(leaf.app);
|
||||
leaf.setUidFrozen(frozen);
|
||||
updateQueueDeferred(leaf);
|
||||
updateRunnableList(leaf);
|
||||
leaf = leaf.processNameNext;
|
||||
}
|
||||
enqueueUpdateRunningList();
|
||||
@@ -1532,20 +1523,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
|
||||
private void updateWarmProcess(@NonNull BroadcastProcessQueue queue) {
|
||||
if (!queue.isProcessWarm()) {
|
||||
setQueueProcess(queue, mService.getProcessRecordLocked(queue.processName, queue.uid));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the {@link ProcessRecord} associated with the given
|
||||
* {@link BroadcastProcessQueue}. Also updates any runnable status that
|
||||
* might have changed as a side-effect.
|
||||
*/
|
||||
private void setQueueProcess(@NonNull BroadcastProcessQueue queue,
|
||||
@Nullable ProcessRecord app) {
|
||||
if (queue.setProcessAndUidFrozen(app, mUidFrozen.get(queue.uid, false))) {
|
||||
updateQueueDeferred(queue);
|
||||
updateRunnableList(queue);
|
||||
queue.setProcess(mService.getProcessRecordLocked(queue.processName, queue.uid));
|
||||
queue.setUidFrozen(mUidFrozen.get(queue.uid, false));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1739,7 +1718,8 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
}
|
||||
|
||||
BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid);
|
||||
setQueueProcess(created, mService.getProcessRecordLocked(processName, uid));
|
||||
created.setProcess(mService.getProcessRecordLocked(processName, uid));
|
||||
created.setUidFrozen(mUidFrozen.get(uid, false));
|
||||
|
||||
if (leaf == null) {
|
||||
mProcessQueues.put(uid, created);
|
||||
|
||||
@@ -372,9 +372,9 @@ public final class BroadcastQueueModernImplTest {
|
||||
List.of(makeMockRegisteredReceiver()), false);
|
||||
queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false);
|
||||
|
||||
queue.setProcessAndUidFrozen(null, false);
|
||||
queue.setUidFrozen(false);
|
||||
final long notCachedRunnableAt = queue.getRunnableAt();
|
||||
queue.setProcessAndUidFrozen(null, true);
|
||||
queue.setUidFrozen(true);
|
||||
final long cachedRunnableAt = queue.getRunnableAt();
|
||||
assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
|
||||
assertFalse(queue.isRunnable());
|
||||
@@ -399,9 +399,9 @@ public final class BroadcastQueueModernImplTest {
|
||||
List.of(makeMockRegisteredReceiver()), false);
|
||||
queue.enqueueOrReplaceBroadcast(airplaneRecord, 0, false);
|
||||
|
||||
queue.setProcessAndUidFrozen(null, false);
|
||||
queue.setUidFrozen(false);
|
||||
final long notCachedRunnableAt = queue.getRunnableAt();
|
||||
queue.setProcessAndUidFrozen(null, true);
|
||||
queue.setUidFrozen(true);
|
||||
final long cachedRunnableAt = queue.getRunnableAt();
|
||||
assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt);
|
||||
assertTrue(queue.isRunnable());
|
||||
@@ -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.setProcessAndUidFrozen(null, false);
|
||||
queue.setUidFrozen(false);
|
||||
assertTrue(queue.isRunnable());
|
||||
assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
|
||||
assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
|
||||
assertEquals(queue.peekNextBroadcastRecord(), airplaneRecord);
|
||||
|
||||
queue.setProcessAndUidFrozen(null, true);
|
||||
queue.setUidFrozen(true);
|
||||
assertTrue(queue.isRunnable());
|
||||
assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueClockTime);
|
||||
assertEquals(ProcessList.SCHED_GROUP_DEFAULT, queue.getPreferredSchedulingGroupLocked());
|
||||
@@ -500,7 +500,7 @@ public final class BroadcastQueueModernImplTest {
|
||||
private void doRunnableAt_Frozen(BroadcastRecord testRecord, int testRunnableAtReason) {
|
||||
final BroadcastProcessQueue queue = new BroadcastProcessQueue(mConstants,
|
||||
PACKAGE_GREEN, getUidForPackage(PACKAGE_GREEN));
|
||||
queue.setProcessAndUidFrozen(null, true);
|
||||
queue.setUidFrozen(true);
|
||||
|
||||
final BroadcastRecord lazyRecord = makeBroadcastRecord(
|
||||
new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED),
|
||||
|
||||
Reference in New Issue
Block a user