Merge "Fix user cleanup in modern broadcast queue."
This commit is contained in:
committed by
Android (Google) Code Review
commit
0bec75ce35
@@ -1341,7 +1341,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
@NonNull BroadcastPredicate broadcastPredicate,
|
||||
@NonNull BroadcastConsumer broadcastConsumer, boolean andRemove) {
|
||||
boolean didSomething = false;
|
||||
for (int i = 0; i < mProcessQueues.size(); i++) {
|
||||
for (int i = mProcessQueues.size() - 1; i >= 0; i--) {
|
||||
BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
|
||||
while (leaf != null) {
|
||||
if (queuePredicate.test(leaf)) {
|
||||
@@ -1363,7 +1363,7 @@ class BroadcastQueueModernImpl extends BroadcastQueue {
|
||||
private void forEachMatchingQueue(
|
||||
@NonNull Predicate<BroadcastProcessQueue> queuePredicate,
|
||||
@NonNull Consumer<BroadcastProcessQueue> queueConsumer) {
|
||||
for (int i = 0; i < mProcessQueues.size(); i++) {
|
||||
for (int i = mProcessQueues.size() - 1; i >= 0; i--) {
|
||||
BroadcastProcessQueue leaf = mProcessQueues.valueAt(i);
|
||||
while (leaf != null) {
|
||||
if (queuePredicate.test(leaf)) {
|
||||
|
||||
@@ -25,7 +25,10 @@ import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_PRIORI
|
||||
import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_RESULT_TO;
|
||||
import static com.android.server.am.BroadcastProcessQueue.insertIntoRunnableList;
|
||||
import static com.android.server.am.BroadcastProcessQueue.removeFromRunnableList;
|
||||
import static com.android.server.am.BroadcastQueueTest.CLASS_BLUE;
|
||||
import static com.android.server.am.BroadcastQueueTest.CLASS_GREEN;
|
||||
import static com.android.server.am.BroadcastQueueTest.CLASS_RED;
|
||||
import static com.android.server.am.BroadcastQueueTest.CLASS_YELLOW;
|
||||
import static com.android.server.am.BroadcastQueueTest.PACKAGE_BLUE;
|
||||
import static com.android.server.am.BroadcastQueueTest.PACKAGE_GREEN;
|
||||
import static com.android.server.am.BroadcastQueueTest.PACKAGE_RED;
|
||||
@@ -981,6 +984,40 @@ public class BroadcastQueueModernImplTest {
|
||||
assertTrue(queue.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCleanupDisabledPackageReceiversLocked() {
|
||||
final Intent userPresent = new Intent(Intent.ACTION_USER_PRESENT);
|
||||
final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
|
||||
|
||||
final BroadcastRecord record1 = makeBroadcastRecord(userPresent, List.of(
|
||||
makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
|
||||
makeManifestReceiver(PACKAGE_RED, CLASS_BLUE),
|
||||
makeManifestReceiver(PACKAGE_YELLOW, CLASS_RED),
|
||||
makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN)
|
||||
));
|
||||
final BroadcastRecord record2 = makeBroadcastRecord(timeTick, List.of(
|
||||
makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN),
|
||||
makeManifestReceiver(PACKAGE_RED, CLASS_RED),
|
||||
makeManifestReceiver(PACKAGE_YELLOW, CLASS_YELLOW)
|
||||
));
|
||||
|
||||
// Halt all processing so that we get a consistent view
|
||||
mHandlerThread.getLooper().getQueue().postSyncBarrier();
|
||||
mImpl.enqueueBroadcastLocked(record1);
|
||||
mImpl.enqueueBroadcastLocked(record2);
|
||||
|
||||
mImpl.cleanupDisabledPackageReceiversLocked(null, null, UserHandle.USER_SYSTEM);
|
||||
|
||||
// Verify that all receivers have been marked as "skipped".
|
||||
for (BroadcastRecord record : new BroadcastRecord[] {record1, record2}) {
|
||||
for (int i = 0; i < record.receivers.size(); ++i) {
|
||||
final String errMsg = "Unexpected delivery state for record:" + record
|
||||
+ "; receiver=" + record.receivers.get(i);
|
||||
assertEquals(errMsg, BroadcastRecord.DELIVERY_SKIPPED, record.getDeliveryState(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Intent createPackageChangedIntent(int uid, List<String> componentNameList) {
|
||||
final Intent packageChangedIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED);
|
||||
packageChangedIntent.putExtra(Intent.EXTRA_UID, uid);
|
||||
|
||||
@@ -25,6 +25,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
@@ -805,14 +806,27 @@ public class BroadcastQueueTest {
|
||||
null, null, null, null, null, null, userId, null));
|
||||
}
|
||||
|
||||
private void verifyScheduleReceiver(VerificationMode mode, ProcessRecord app,
|
||||
int userId) throws Exception {
|
||||
verify(app.getThread(), mode).scheduleReceiverList(
|
||||
manifestReceiver(null,
|
||||
null, null, null, null, null, null, userId, null));
|
||||
}
|
||||
|
||||
private void verifyScheduleRegisteredReceiver(ProcessRecord app,
|
||||
Intent intent)
|
||||
throws Exception {
|
||||
Intent intent) throws Exception {
|
||||
verify(app.getThread()).scheduleReceiverList(
|
||||
registeredReceiver(null, filterEqualsIgnoringComponent(intent),
|
||||
null, null, null, null, null, UserHandle.USER_SYSTEM, null));
|
||||
}
|
||||
|
||||
private void verifyScheduleRegisteredReceiver(VerificationMode mode, ProcessRecord app,
|
||||
int userId) throws Exception {
|
||||
verify(app.getThread(), mode).scheduleReceiverList(
|
||||
registeredReceiver(null, null,
|
||||
null, null, null, null, null, userId, null));
|
||||
}
|
||||
|
||||
static final int USER_GUEST = 11;
|
||||
|
||||
static final String PACKAGE_ANDROID = "android";
|
||||
@@ -1222,6 +1236,45 @@ public class BroadcastQueueTest {
|
||||
new ComponentName(PACKAGE_GREEN, CLASS_BLUE));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCleanup_userRemoved() throws Exception {
|
||||
final ProcessRecord callerApp = makeActiveProcessRecord(
|
||||
PACKAGE_RED, PACKAGE_RED, ProcessBehavior.NORMAL,
|
||||
USER_GUEST);
|
||||
|
||||
final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
|
||||
final Intent timeZone = new Intent(Intent.ACTION_TIMEZONE_CHANGED);
|
||||
try (SyncBarrier b = new SyncBarrier()) {
|
||||
enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, USER_GUEST, new ArrayList<>(
|
||||
List.of(makeRegisteredReceiver(callerApp),
|
||||
makeManifestReceiver(PACKAGE_GREEN, CLASS_RED, USER_GUEST),
|
||||
makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN, USER_GUEST),
|
||||
makeManifestReceiver(PACKAGE_YELLOW, CLASS_BLUE, USER_GUEST)))));
|
||||
enqueueBroadcast(makeBroadcastRecord(timeZone, callerApp, USER_GUEST, new ArrayList<>(
|
||||
List.of(makeRegisteredReceiver(callerApp),
|
||||
makeManifestReceiver(PACKAGE_GREEN, CLASS_RED, USER_GUEST),
|
||||
makeManifestReceiver(PACKAGE_BLUE, CLASS_GREEN, USER_GUEST),
|
||||
makeManifestReceiver(PACKAGE_YELLOW, CLASS_BLUE, USER_GUEST)))));
|
||||
|
||||
synchronized (mAms) {
|
||||
mQueue.cleanupDisabledPackageReceiversLocked(null, null, USER_GUEST);
|
||||
}
|
||||
}
|
||||
|
||||
waitForIdle();
|
||||
// Legacy stack does not remove registered receivers as part of
|
||||
// cleanUpDisabledPackageReceiversLocked() call, so verify this only on modern queue.
|
||||
if (mImpl == Impl.MODERN) {
|
||||
verifyScheduleReceiver(never(), callerApp, USER_GUEST);
|
||||
verifyScheduleRegisteredReceiver(never(), callerApp, USER_GUEST);
|
||||
}
|
||||
for (String pkg : new String[] {
|
||||
PACKAGE_GREEN, PACKAGE_BLUE, PACKAGE_YELLOW
|
||||
}) {
|
||||
assertNull(mAms.getProcessRecordLocked(pkg, getUidForPackage(pkg, USER_GUEST)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that killing a running process skips registered receivers.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user