BroadcastProcessQueue: ensure accuracy of persistent and instrumented flags
Persistent apps are guaranteed to be running, are never frozen, and could get out of sync if broadcasts are deferred. Accordingly, never defer those broadcasts. Additionally, there was a case where both the persistent and instrumented flags could be incorrect: 1. App starts and hits attachApplicationLocked without ever being a broadcast target. 2. BroadcastQueueModernImpl.onApplicationAttachedLocked runs, but there is no queue for the app because nothing has enqueued a broadcast (which calls getOrCreateProcessQueue). Importantly, queue.setProcess(app) is not called. 3. Eventually, something enqueues a broadcast for the app. This calls getOrCreateProcessQueue as part of enqueueBroadcastLocked. 4. getOrCreateProcessQueue creates the queue and manually assigns app without calling setProcess. 5. mProcessInstrumented and mProcessPersistent are never assigned. The fix is to call setProcess(ProcessRecord) from getOrCreateProcessQueue when a ProcessRecord is available when a queue is created for an app. Test: atest FrameworksMockingServicesTests:BroadcastRecordTest Test: atest FrameworksMockingServicesTests:BroadcastQueueTest Test: atest FrameworksMockingServicesTests:BroadcastQueueModernImplTest Test: atest CtsWifiTestCases:android.net.wifi.cts.ConcurrencyTest#testRequestNetworkInfo Bug: 258718309 Change-Id: I3059cc602b8bc75d72fe3c15dd6674f91a37a0cd
This commit is contained in:
@@ -164,6 +164,7 @@ class BroadcastProcessQueue {
|
||||
|
||||
private boolean mProcessCached;
|
||||
private boolean mProcessInstrumented;
|
||||
private boolean mProcessPersistent;
|
||||
|
||||
private String mCachedToString;
|
||||
private String mCachedToShortString;
|
||||
@@ -323,8 +324,10 @@ class BroadcastProcessQueue {
|
||||
this.app = app;
|
||||
if (app != null) {
|
||||
setProcessInstrumented(app.getActiveInstrumentation() != null);
|
||||
setProcessPersistent(app.isPersistent());
|
||||
} else {
|
||||
setProcessInstrumented(false);
|
||||
setProcessPersistent(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,6 +354,17 @@ 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.
|
||||
*/
|
||||
public void setProcessPersistent(boolean persistent) {
|
||||
if (mProcessPersistent != persistent) {
|
||||
mProcessPersistent = persistent;
|
||||
invalidateRunnableAt();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if we know of an actively running "warm" process for this queue.
|
||||
*/
|
||||
@@ -636,6 +650,7 @@ class BroadcastProcessQueue {
|
||||
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_CONTAINS_FOREGROUND = 10;
|
||||
static final int REASON_CONTAINS_ORDERED = 11;
|
||||
static final int REASON_CONTAINS_ALARM = 12;
|
||||
@@ -652,6 +667,7 @@ class BroadcastProcessQueue {
|
||||
REASON_MAX_PENDING,
|
||||
REASON_BLOCKED,
|
||||
REASON_INSTRUMENTED,
|
||||
REASON_PERSISTENT,
|
||||
REASON_CONTAINS_FOREGROUND,
|
||||
REASON_CONTAINS_ORDERED,
|
||||
REASON_CONTAINS_ALARM,
|
||||
@@ -672,6 +688,7 @@ class BroadcastProcessQueue {
|
||||
case REASON_MAX_PENDING: return "MAX_PENDING";
|
||||
case REASON_BLOCKED: return "BLOCKED";
|
||||
case REASON_INSTRUMENTED: return "INSTRUMENTED";
|
||||
case REASON_PERSISTENT: return "PERSISTENT";
|
||||
case REASON_CONTAINS_FOREGROUND: return "CONTAINS_FOREGROUND";
|
||||
case REASON_CONTAINS_ORDERED: return "CONTAINS_ORDERED";
|
||||
case REASON_CONTAINS_ALARM: return "CONTAINS_ALARM";
|
||||
@@ -731,6 +748,9 @@ class BroadcastProcessQueue {
|
||||
} else if (mCountManifest > 0) {
|
||||
mRunnableAt = runnableAt;
|
||||
mRunnableAtReason = REASON_CONTAINS_MANIFEST;
|
||||
} else if (mProcessPersistent) {
|
||||
mRunnableAt = runnableAt;
|
||||
mRunnableAtReason = REASON_PERSISTENT;
|
||||
} else if (mProcessCached) {
|
||||
mRunnableAt = runnableAt + constants.DELAY_CACHED_MILLIS;
|
||||
mRunnableAtReason = REASON_CACHED;
|
||||
|
||||
@@ -1462,7 +1462,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
}
|
||||
|
||||
BroadcastProcessQueue created = new BroadcastProcessQueue(mConstants, processName, uid);
|
||||
created.app = mService.getProcessRecordLocked(processName, uid);
|
||||
created.setProcess(mService.getProcessRecordLocked(processName, uid));
|
||||
|
||||
if (leaf == null) {
|
||||
mProcessQueues.put(uid, created);
|
||||
|
||||
Reference in New Issue
Block a user