diff options
author | 2023-11-22 21:25:23 +0000 | |
---|---|---|
committer | 2023-11-22 21:25:23 +0000 | |
commit | a090fdd7ec7b37e8df152f97682f69d81e2dddff (patch) | |
tree | cbd9db6297202e3bdafef05c23905c88ff967a9f | |
parent | 31ff244199eb563d4e944a885f887272a636e204 (diff) | |
parent | 2ea85377ba228270e243ca09b128588a853d43dd (diff) |
Merge "Skip beyond receivers in a process once it's cached." into main
5 files changed, 540 insertions, 270 deletions
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java index fc8175b76ecd..c26fd5d9b798 100644 --- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java +++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java @@ -258,13 +258,6 @@ class BroadcastProcessQueue { @Nullable public BroadcastRecord enqueueOrReplaceBroadcast(@NonNull BroadcastRecord record, int recordIndex, @NonNull BroadcastConsumer deferredStatesApplyConsumer) { - // When updateDeferredStates() has already applied a deferred state to - // all pending items, apply to this new broadcast too - if (mLastDeferredStates && record.deferUntilActive - && (record.getDeliveryState(recordIndex) == BroadcastRecord.DELIVERY_PENDING)) { - deferredStatesApplyConsumer.accept(record, recordIndex); - } - // Ignore FLAG_RECEIVER_REPLACE_PENDING if the sender specified the policy using the // BroadcastOptions delivery group APIs. if (record.isReplacePending() @@ -287,6 +280,13 @@ class BroadcastProcessQueue { // with implicit responsiveness expectations. getQueueForBroadcast(record).addLast(newBroadcastArgs); onBroadcastEnqueued(record, recordIndex); + + // When updateDeferredStates() has already applied a deferred state to + // all pending items, apply to this new broadcast too + if (mLastDeferredStates && shouldBeDeferred() + && (record.getDeliveryState(recordIndex) == BroadcastRecord.DELIVERY_PENDING)) { + deferredStatesApplyConsumer.accept(record, recordIndex); + } return null; } @@ -1221,32 +1221,45 @@ class BroadcastProcessQueue { } /** - * Update {@link BroadcastRecord.DELIVERY_DEFERRED} states of all our + * Update {@link BroadcastRecord#DELIVERY_DEFERRED} states of all our * pending broadcasts, when needed. */ void updateDeferredStates(@NonNull BroadcastConsumer applyConsumer, @NonNull BroadcastConsumer clearConsumer) { // 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; + final boolean wantDeferredStates = shouldBeDeferred(); if (mLastDeferredStates != wantDeferredStates) { mLastDeferredStates = wantDeferredStates; if (wantDeferredStates) { forEachMatchingBroadcast((r, i) -> { - return r.deferUntilActive - && (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_PENDING); + return (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_PENDING); }, applyConsumer, false); } else { forEachMatchingBroadcast((r, i) -> { - return r.deferUntilActive - && (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_DEFERRED); + return (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_DEFERRED); }, clearConsumer, false); } } } + void clearDeferredStates(@NonNull BroadcastConsumer clearConsumer) { + if (mLastDeferredStates) { + mLastDeferredStates = false; + forEachMatchingBroadcast((r, i) -> { + return (r.getDeliveryState(i) == BroadcastRecord.DELIVERY_DEFERRED); + }, clearConsumer, false); + } + } + + @VisibleForTesting + boolean shouldBeDeferred() { + if (mRunnableAtInvalidated) updateRunnableAt(); + return mRunnableAtReason == REASON_CACHED + || mRunnableAtReason == REASON_CACHED_INFINITE_DEFER; + } + /** * Check overall health, confirming things are in a reasonable state and * that we're not wedged. diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java index 5d0fefc75a28..abec890299a3 100644 --- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java +++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java @@ -464,6 +464,10 @@ class BroadcastQueueModernImpl extends BroadcastQueue { break; } + // Clear the deferred state of broadcasts in this queue as we are just about to + // deliver broadcasts to this process. + queue.clearDeferredStates(mBroadcastConsumerDeferClear); + // We might not have heard about a newly running process yet, so // consider refreshing if we think we're cold updateWarmProcess(queue); @@ -1524,12 +1528,14 @@ class BroadcastQueueModernImpl extends BroadcastQueue { r.resultExtras = null; }; - private final BroadcastConsumer mBroadcastConsumerDeferApply = (r, i) -> { + @VisibleForTesting + final BroadcastConsumer mBroadcastConsumerDeferApply = (r, i) -> { setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_DEFERRED, "mBroadcastConsumerDeferApply"); }; - private final BroadcastConsumer mBroadcastConsumerDeferClear = (r, i) -> { + @VisibleForTesting + final BroadcastConsumer mBroadcastConsumerDeferClear = (r, i) -> { setDeliveryState(null, null, r, i, r.receivers.get(i), BroadcastRecord.DELIVERY_PENDING, "mBroadcastConsumerDeferClear"); }; diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java new file mode 100644 index 000000000000..a0beb174dc94 --- /dev/null +++ b/services/tests/mockingservicestests/src/com/android/server/am/BaseBroadcastQueueTest.java @@ -0,0 +1,259 @@ +/* + * Copyright (C) 2023 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.am; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.spy; + +import android.annotation.NonNull; +import android.app.usage.UsageStatsManagerInternal; +import android.content.ComponentName; +import android.content.Context; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManagerInternal; +import android.content.pm.ResolveInfo; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.TestLooperManager; +import android.os.UserHandle; +import android.provider.Settings; +import android.util.SparseArray; + +import androidx.test.platform.app.InstrumentationRegistry; + +import com.android.server.AlarmManagerInternal; +import com.android.server.DropBoxManagerInternal; +import com.android.server.LocalServices; +import com.android.server.appop.AppOpsService; +import com.android.server.wm.ActivityTaskManagerService; + +import org.junit.Rule; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +import java.io.File; +import java.util.Objects; +import java.util.concurrent.atomic.AtomicInteger; + +public abstract class BaseBroadcastQueueTest { + + static final int USER_GUEST = 11; + + static final String PACKAGE_ANDROID = "android"; + static final String PACKAGE_PHONE = "com.android.phone"; + static final String PACKAGE_RED = "com.example.red"; + static final String PACKAGE_GREEN = "com.example.green"; + static final String PACKAGE_BLUE = "com.example.blue"; + static final String PACKAGE_YELLOW = "com.example.yellow"; + static final String PACKAGE_ORANGE = "com.example.orange"; + + static final String PROCESS_SYSTEM = "system"; + + static final String CLASS_RED = "com.example.red.Red"; + static final String CLASS_GREEN = "com.example.green.Green"; + static final String CLASS_BLUE = "com.example.blue.Blue"; + static final String CLASS_YELLOW = "com.example.yellow.Yellow"; + static final String CLASS_ORANGE = "com.example.orange.Orange"; + + static final BroadcastProcessQueue.BroadcastPredicate BROADCAST_PREDICATE_ANY = + (r, i) -> true; + + @Rule + public final ApplicationExitInfoTest.ServiceThreadRule + mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule(); + + @Mock + AppOpsService mAppOpsService; + @Mock + PackageManagerInternal mPackageManagerInt; + @Mock + UsageStatsManagerInternal mUsageStatsManagerInt; + @Mock + DropBoxManagerInternal mDropBoxManagerInt; + @Mock + AlarmManagerInternal mAlarmManagerInt; + @Mock + ProcessList mProcessList; + + Context mContext; + ActivityManagerService mAms; + BroadcastConstants mConstants; + BroadcastSkipPolicy mSkipPolicy; + HandlerThread mHandlerThread; + TestLooperManager mLooper; + AtomicInteger mNextPid; + + /** + * Map from PID to registered registered runtime receivers. + */ + SparseArray<ReceiverList> mRegisteredReceivers = new SparseArray<>(); + + public void setUp() throws Exception { + MockitoAnnotations.initMocks(this); + + mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + mHandlerThread = new HandlerThread(getTag()); + mHandlerThread.start(); + // Pause all event processing until a test chooses to resume + mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation() + .acquireLooperManager(mHandlerThread.getLooper())); + mNextPid = new AtomicInteger(100); + + LocalServices.removeServiceForTest(DropBoxManagerInternal.class); + LocalServices.addService(DropBoxManagerInternal.class, mDropBoxManagerInt); + LocalServices.removeServiceForTest(PackageManagerInternal.class); + LocalServices.addService(PackageManagerInternal.class, mPackageManagerInt); + LocalServices.removeServiceForTest(AlarmManagerInternal.class); + LocalServices.addService(AlarmManagerInternal.class, mAlarmManagerInt); + doReturn(new ComponentName("", "")).when(mPackageManagerInt).getSystemUiServiceComponent(); + doNothing().when(mPackageManagerInt).setPackageStoppedState(any(), anyBoolean(), anyInt()); + doAnswer((invocation) -> { + return getUidForPackage(invocation.getArgument(0)); + }).when(mPackageManagerInt).getPackageUid(any(), anyLong(), eq(UserHandle.USER_SYSTEM)); + + final ActivityManagerService realAms = new ActivityManagerService( + new TestInjector(mContext), mServiceThreadRule.getThread()); + realAms.mActivityTaskManager = new ActivityTaskManagerService(mContext); + realAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper()); + realAms.mAtmInternal = spy(realAms.mActivityTaskManager.getAtmInternal()); + realAms.mOomAdjuster = spy(realAms.mOomAdjuster); + realAms.mPackageManagerInt = mPackageManagerInt; + realAms.mUsageStatsService = mUsageStatsManagerInt; + realAms.mProcessesReady = true; + mAms = spy(realAms); + + mSkipPolicy = spy(new BroadcastSkipPolicy(mAms)); + doReturn(null).when(mSkipPolicy).shouldSkipMessage(any(), any()); + doReturn(false).when(mSkipPolicy).disallowBackgroundStart(any()); + + mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS); + } + + public void tearDown() throws Exception { + mHandlerThread.quit(); + } + + static int getUidForPackage(@NonNull String packageName) { + switch (packageName) { + case PACKAGE_ANDROID: return android.os.Process.SYSTEM_UID; + case PACKAGE_PHONE: return android.os.Process.PHONE_UID; + case PACKAGE_RED: return android.os.Process.FIRST_APPLICATION_UID + 1; + case PACKAGE_GREEN: return android.os.Process.FIRST_APPLICATION_UID + 2; + case PACKAGE_BLUE: return android.os.Process.FIRST_APPLICATION_UID + 3; + case PACKAGE_YELLOW: return android.os.Process.FIRST_APPLICATION_UID + 4; + case PACKAGE_ORANGE: return android.os.Process.FIRST_APPLICATION_UID + 5; + default: throw new IllegalArgumentException(); + } + } + + static int getUidForPackage(@NonNull String packageName, int userId) { + return UserHandle.getUid(userId, getUidForPackage(packageName)); + } + + private class TestInjector extends ActivityManagerService.Injector { + TestInjector(Context context) { + super(context); + } + + @Override + public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile, + Handler handler) { + return mAppOpsService; + } + + @Override + public Handler getUiHandler(ActivityManagerService service) { + return mHandlerThread.getThreadHandler(); + } + + @Override + public ProcessList getProcessList(ActivityManagerService service) { + return mProcessList; + } + } + + abstract String getTag(); + + static ApplicationInfo makeApplicationInfo(String packageName) { + return makeApplicationInfo(packageName, packageName, UserHandle.USER_SYSTEM); + } + + static ApplicationInfo makeApplicationInfo(String packageName, String processName, int userId) { + final ApplicationInfo ai = new ApplicationInfo(); + ai.packageName = packageName; + ai.processName = processName; + ai.uid = getUidForPackage(packageName, userId); + return ai; + } + + static ResolveInfo withPriority(ResolveInfo info, int priority) { + info.priority = priority; + return info; + } + + static BroadcastFilter withPriority(BroadcastFilter filter, int priority) { + filter.setPriority(priority); + return filter; + } + + static ResolveInfo makeManifestReceiver(String packageName, String name) { + return makeManifestReceiver(packageName, name, UserHandle.USER_SYSTEM); + } + + static ResolveInfo makeManifestReceiver(String packageName, String name, int userId) { + return makeManifestReceiver(packageName, packageName, name, userId); + } + + static ResolveInfo makeManifestReceiver(String packageName, String processName, + String name, int userId) { + final ResolveInfo ri = new ResolveInfo(); + ri.activityInfo = new ActivityInfo(); + ri.activityInfo.packageName = packageName; + ri.activityInfo.processName = processName; + ri.activityInfo.name = name; + ri.activityInfo.applicationInfo = makeApplicationInfo(packageName, processName, userId); + return ri; + } + + BroadcastFilter makeRegisteredReceiver(ProcessRecord app) { + return makeRegisteredReceiver(app, 0); + } + + BroadcastFilter makeRegisteredReceiver(ProcessRecord app, int priority) { + final ReceiverList receiverList = mRegisteredReceivers.get(app.getPid()); + return makeRegisteredReceiver(receiverList, priority); + } + + static BroadcastFilter makeRegisteredReceiver(ReceiverList receiverList, int priority) { + final IntentFilter filter = new IntentFilter(); + filter.setPriority(priority); + final BroadcastFilter res = new BroadcastFilter(filter, receiverList, + receiverList.app.info.packageName, null, null, null, receiverList.uid, + receiverList.userId, false, false, true); + receiverList.add(res); + return res; + } +} 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 08f5d03e0148..2378416f8bd0 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java @@ -31,17 +31,6 @@ import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_ORDERE import static com.android.server.am.BroadcastProcessQueue.REASON_CONTAINS_PRIORITIZED; 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; -import static com.android.server.am.BroadcastQueueTest.PACKAGE_YELLOW; -import static com.android.server.am.BroadcastQueueTest.getUidForPackage; -import static com.android.server.am.BroadcastQueueTest.makeManifestReceiver; -import static com.android.server.am.BroadcastQueueTest.withPriority; import static com.android.server.am.BroadcastRecord.isReceiverEquals; import static com.google.common.truth.Truth.assertThat; @@ -74,17 +63,15 @@ import android.appwidget.AppWidgetManager; import android.content.IIntentReceiver; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.ApplicationInfo; import android.content.pm.ResolveInfo; import android.media.AudioManager; import android.os.Bundle; import android.os.BundleMerger; import android.os.DropBoxManager; -import android.os.HandlerThread; import android.os.Process; import android.os.SystemClock; -import android.os.TestLooperManager; import android.os.UserHandle; -import android.provider.Settings; import android.util.IndentingPrintWriter; import android.util.Pair; @@ -108,11 +95,12 @@ import java.util.List; import java.util.Objects; @SmallTest -public final class BroadcastQueueModernImplTest { +public final class BroadcastQueueModernImplTest extends BaseBroadcastQueueTest { + private static final String TAG = "BroadcastQueueModernImplTest"; + private static final int TEST_UID = android.os.Process.FIRST_APPLICATION_UID; private static final int TEST_UID2 = android.os.Process.FIRST_APPLICATION_UID + 1; - @Mock ActivityManagerService mAms; @Mock ProcessRecord mProcess; @Mock BroadcastProcessQueue mQueue1; @@ -120,11 +108,6 @@ public final class BroadcastQueueModernImplTest { @Mock BroadcastProcessQueue mQueue3; @Mock BroadcastProcessQueue mQueue4; - HandlerThread mHandlerThread; - TestLooperManager mLooper; - - BroadcastConstants mConstants; - private BroadcastSkipPolicy mSkipPolicy; BroadcastQueueModernImpl mImpl; BroadcastProcessQueue mHead; @@ -136,22 +119,12 @@ public final class BroadcastQueueModernImplTest { @Before public void setUp() throws Exception { - mHandlerThread = new HandlerThread(getClass().getSimpleName()); - mHandlerThread.start(); - - // Pause all event processing until a test chooses to resume - mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation() - .acquireLooperManager(mHandlerThread.getLooper())); + super.setUp(); - mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS); mConstants.DELAY_URGENT_MILLIS = -120_000; mConstants.DELAY_NORMAL_MILLIS = 10_000; mConstants.DELAY_CACHED_MILLIS = 120_000; - mSkipPolicy = spy(new BroadcastSkipPolicy(mAms)); - doReturn(null).when(mSkipPolicy).shouldSkipMessage(any(), any()); - doReturn(false).when(mSkipPolicy).disallowBackgroundStart(any()); - final BroadcastHistory emptyHistory = new BroadcastHistory(mConstants) { public void addBroadcastToHistoryLocked(BroadcastRecord original) { // Ignored @@ -169,7 +142,12 @@ public final class BroadcastQueueModernImplTest { @After public void tearDown() throws Exception { - mHandlerThread.quit(); + super.tearDown(); + } + + @Override + public String getTag() { + return TAG; } /** @@ -225,11 +203,6 @@ public final class BroadcastQueueModernImplTest { List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)), false); } - private BroadcastRecord makeOrderedBroadcastRecord(Intent intent) { - return makeBroadcastRecord(intent, BroadcastOptions.makeBasic(), - List.of(makeManifestReceiver(PACKAGE_GREEN, CLASS_GREEN)), true); - } - private BroadcastRecord makeBroadcastRecord(Intent intent, List receivers) { return makeBroadcastRecord(intent, BroadcastOptions.makeBasic(), receivers, false); } @@ -246,8 +219,8 @@ public final class BroadcastQueueModernImplTest { private BroadcastRecord makeBroadcastRecord(Intent intent, BroadcastOptions options, List receivers, IIntentReceiver resultTo, boolean ordered) { - return new BroadcastRecord(mImpl, intent, mProcess, PACKAGE_RED, null, 21, 42, false, null, - null, null, null, AppOpsManager.OP_NONE, options, receivers, null, resultTo, + return new BroadcastRecord(mImpl, intent, mProcess, PACKAGE_RED, null, 21, TEST_UID, false, + null, null, null, null, AppOpsManager.OP_NONE, options, receivers, null, resultTo, Activity.RESULT_OK, null, null, ordered, false, false, UserHandle.USER_SYSTEM, BackgroundStartPrivileges.NONE, false, null, PROCESS_STATE_UNKNOWN); } @@ -259,12 +232,12 @@ public final class BroadcastQueueModernImplTest { private void enqueueOrReplaceBroadcast(BroadcastProcessQueue queue, BroadcastRecord record, int recordIndex, long enqueueTime) { - queue.enqueueOrReplaceBroadcast(record, recordIndex, (r, i) -> { - throw new UnsupportedOperationException(); - }); record.enqueueTime = enqueueTime; record.enqueueRealTime = enqueueTime; record.enqueueClockTime = enqueueTime; + queue.enqueueOrReplaceBroadcast(record, recordIndex, (r, i) -> { + throw new UnsupportedOperationException(); + }); } @Test @@ -419,6 +392,7 @@ public final class BroadcastQueueModernImplTest { assertFalse(queue.isRunnable()); assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER, queue.getRunnableAtReason()); + assertTrue(queue.shouldBeDeferred()); assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); } @@ -445,6 +419,7 @@ public final class BroadcastQueueModernImplTest { assertThat(cachedRunnableAt).isGreaterThan(notCachedRunnableAt); assertTrue(queue.isRunnable()); assertEquals(BroadcastProcessQueue.REASON_CACHED, queue.getRunnableAtReason()); + assertTrue(queue.shouldBeDeferred()); assertEquals(ProcessList.SCHED_GROUP_UNDEFINED, queue.getPreferredSchedulingGroupLocked()); } @@ -526,11 +501,13 @@ public final class BroadcastQueueModernImplTest { queue.invalidateRunnableAt(); assertThat(queue.getRunnableAt()).isGreaterThan(airplaneRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); mConstants.MAX_PENDING_BROADCASTS = 1; queue.invalidateRunnableAt(); assertThat(queue.getRunnableAt()).isAtMost(airplaneRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_MAX_PENDING, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); } @Test @@ -549,10 +526,12 @@ public final class BroadcastQueueModernImplTest { queue.setProcessAndUidState(mProcess, true, false); assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_FOREGROUND, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); queue.setProcessAndUidState(mProcess, false, false); assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); } @Test @@ -570,6 +549,7 @@ public final class BroadcastQueueModernImplTest { assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_TOP_PROCESS, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); doReturn(ActivityManager.PROCESS_STATE_SERVICE).when(mProcess).getSetProcState(); queue.setProcessAndUidState(mProcess, false, false); @@ -580,6 +560,7 @@ public final class BroadcastQueueModernImplTest { List.of(makeMockRegisteredReceiver())), 0); assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); } @Test @@ -594,16 +575,19 @@ public final class BroadcastQueueModernImplTest { assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); doReturn(true).when(mProcess).isPersistent(); queue.setProcessAndUidState(mProcess, false, false); assertThat(queue.getRunnableAt()).isLessThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_PERSISTENT, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); doReturn(false).when(mProcess).isPersistent(); queue.setProcessAndUidState(mProcess, false, false); assertThat(queue.getRunnableAt()).isGreaterThan(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_NORMAL, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); } @Test @@ -618,6 +602,7 @@ public final class BroadcastQueueModernImplTest { assertThat(queue.getRunnableAt()).isEqualTo(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_CORE_UID, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); } @Test @@ -636,10 +621,12 @@ public final class BroadcastQueueModernImplTest { assertEquals(Long.MAX_VALUE, queue.getRunnableAt()); assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER, queue.getRunnableAtReason()); + assertTrue(queue.shouldBeDeferred()); queue.setProcessAndUidState(mProcess, false, false); assertThat(queue.getRunnableAt()).isEqualTo(timeTickRecord.enqueueTime); assertEquals(BroadcastProcessQueue.REASON_CORE_UID, queue.getRunnableAtReason()); + assertFalse(queue.shouldBeDeferred()); } /** @@ -1575,6 +1562,216 @@ public final class BroadcastQueueModernImplTest { verifyPendingRecords(redQueue, List.of(userPresent, timeTick)); } + @Test + public void testDeliveryDeferredForCached() throws Exception { + final ProcessRecord greenProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_GREEN)); + final ProcessRecord redProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_RED)); + + final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); + final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, + List.of(makeRegisteredReceiver(greenProcess, 0))); + + final Intent batteryChanged = new Intent(Intent.ACTION_BATTERY_CHANGED); + final BroadcastOptions optionsBatteryChanged = + BroadcastOptions.makeWithDeferUntilActive(true); + final BroadcastRecord batteryChangedRecord = makeBroadcastRecord(batteryChanged, + optionsBatteryChanged, + List.of(makeRegisteredReceiver(greenProcess, 10), + makeRegisteredReceiver(redProcess, 0)), + false /* ordered */); + + mImpl.enqueueBroadcastLocked(timeTickRecord); + mImpl.enqueueBroadcastLocked(batteryChangedRecord); + + final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN, + getUidForPackage(PACKAGE_GREEN)); + final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED, + getUidForPackage(PACKAGE_RED)); + assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason()); + assertFalse(greenQueue.shouldBeDeferred()); + assertEquals(BroadcastProcessQueue.REASON_BLOCKED, redQueue.getRunnableAtReason()); + assertFalse(redQueue.shouldBeDeferred()); + + // Simulate process state change + greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */, + true /* processFreezable */); + greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply, + mImpl.mBroadcastConsumerDeferClear); + + assertEquals(BroadcastProcessQueue.REASON_CACHED, greenQueue.getRunnableAtReason()); + assertTrue(greenQueue.shouldBeDeferred()); + // Once the broadcasts to green process are deferred, broadcasts to red process + // shouldn't be blocked anymore. + assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason()); + assertFalse(redQueue.shouldBeDeferred()); + + // All broadcasts to green process should be deferred. + greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i)); + }, false /* andRemove */); + redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i)); + }, false /* andRemove */); + + final Intent packageChanged = new Intent(Intent.ACTION_PACKAGE_CHANGED); + final BroadcastRecord packageChangedRecord = makeBroadcastRecord(packageChanged, + List.of(makeRegisteredReceiver(greenProcess, 0))); + mImpl.enqueueBroadcastLocked(packageChangedRecord); + + assertEquals(BroadcastProcessQueue.REASON_CACHED, greenQueue.getRunnableAtReason()); + assertTrue(greenQueue.shouldBeDeferred()); + assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason()); + assertFalse(redQueue.shouldBeDeferred()); + + // All broadcasts to the green process, including the newly enqueued one, should be + // deferred. + greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i)); + }, false /* andRemove */); + redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i)); + }, false /* andRemove */); + + // Simulate process state change + greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */, + false /* processFreezable */); + greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply, + mImpl.mBroadcastConsumerDeferClear); + + assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason()); + assertFalse(greenQueue.shouldBeDeferred()); + assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason()); + assertFalse(redQueue.shouldBeDeferred()); + + greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i)); + }, false /* andRemove */); + redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i)); + }, false /* andRemove */); + } + + @Test + public void testDeliveryDeferredForCached_withInfiniteDeferred() throws Exception { + final ProcessRecord greenProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_GREEN)); + final ProcessRecord redProcess = makeProcessRecord(makeApplicationInfo(PACKAGE_RED)); + + final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK); + final BroadcastOptions optionsTimeTick = BroadcastOptions.makeWithDeferUntilActive(true); + final BroadcastRecord timeTickRecord = makeBroadcastRecord(timeTick, optionsTimeTick, + List.of(makeRegisteredReceiver(greenProcess, 0)), false /* ordered */); + + final Intent batteryChanged = new Intent(Intent.ACTION_BATTERY_CHANGED); + final BroadcastOptions optionsBatteryChanged = + BroadcastOptions.makeWithDeferUntilActive(true); + final BroadcastRecord batteryChangedRecord = makeBroadcastRecord(batteryChanged, + optionsBatteryChanged, + List.of(makeRegisteredReceiver(greenProcess, 10), + makeRegisteredReceiver(redProcess, 0)), + false /* ordered */); + + mImpl.enqueueBroadcastLocked(timeTickRecord); + mImpl.enqueueBroadcastLocked(batteryChangedRecord); + + final BroadcastProcessQueue greenQueue = mImpl.getProcessQueue(PACKAGE_GREEN, + getUidForPackage(PACKAGE_GREEN)); + final BroadcastProcessQueue redQueue = mImpl.getProcessQueue(PACKAGE_RED, + getUidForPackage(PACKAGE_RED)); + assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason()); + assertFalse(greenQueue.shouldBeDeferred()); + assertEquals(BroadcastProcessQueue.REASON_BLOCKED, redQueue.getRunnableAtReason()); + assertFalse(redQueue.shouldBeDeferred()); + + // Simulate process state change + greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */, + true /* processFreezable */); + greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply, + mImpl.mBroadcastConsumerDeferClear); + + assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER, + greenQueue.getRunnableAtReason()); + assertTrue(greenQueue.shouldBeDeferred()); + // Once the broadcasts to green process are deferred, broadcasts to red process + // shouldn't be blocked anymore. + assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason()); + assertFalse(redQueue.shouldBeDeferred()); + + // All broadcasts to green process should be deferred. + greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i)); + }, false /* andRemove */); + redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i)); + }, false /* andRemove */); + + final Intent packageChanged = new Intent(Intent.ACTION_PACKAGE_CHANGED); + final BroadcastOptions optionsPackageChanged = + BroadcastOptions.makeWithDeferUntilActive(true); + final BroadcastRecord packageChangedRecord = makeBroadcastRecord(packageChanged, + optionsPackageChanged, + List.of(makeRegisteredReceiver(greenProcess, 0)), false /* ordered */); + mImpl.enqueueBroadcastLocked(packageChangedRecord); + + assertEquals(BroadcastProcessQueue.REASON_CACHED_INFINITE_DEFER, + greenQueue.getRunnableAtReason()); + assertTrue(greenQueue.shouldBeDeferred()); + assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason()); + assertFalse(redQueue.shouldBeDeferred()); + + // All broadcasts to the green process, including the newly enqueued one, should be + // deferred. + greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_DEFERRED, r.getDeliveryState(i)); + }, false /* andRemove */); + redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i)); + }, false /* andRemove */); + + // Simulate process state change + greenQueue.setProcessAndUidState(greenProcess, false /* uidForeground */, + false /* processFreezable */); + greenQueue.updateDeferredStates(mImpl.mBroadcastConsumerDeferApply, + mImpl.mBroadcastConsumerDeferClear); + + assertEquals(BroadcastProcessQueue.REASON_NORMAL, greenQueue.getRunnableAtReason()); + assertFalse(greenQueue.shouldBeDeferred()); + assertEquals(BroadcastProcessQueue.REASON_NORMAL, redQueue.getRunnableAtReason()); + assertFalse(redQueue.shouldBeDeferred()); + + greenQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i)); + }, false /* andRemove */); + redQueue.forEachMatchingBroadcast(BROADCAST_PREDICATE_ANY, (r, i) -> { + assertEquals("Unexpected state for " + r, + BroadcastRecord.DELIVERY_PENDING, r.getDeliveryState(i)); + }, false /* andRemove */); + } + + // TODO: Reuse BroadcastQueueTest.makeActiveProcessRecord() + private ProcessRecord makeProcessRecord(ApplicationInfo info) { + final ProcessRecord r = spy(new ProcessRecord(mAms, info, info.processName, info.uid)); + r.setPid(mNextPid.incrementAndGet()); + return r; + } + + BroadcastFilter makeRegisteredReceiver(ProcessRecord app, int priority) { + final IIntentReceiver receiver = mock(IIntentReceiver.class); + final ReceiverList receiverList = new ReceiverList(mAms, app, app.getPid(), app.info.uid, + UserHandle.getUserId(app.info.uid), receiver); + return makeRegisteredReceiver(receiverList, priority); + } + private Intent createPackageChangedIntent(int uid, List<String> componentNameList) { final Intent packageChangedIntent = new Intent(Intent.ACTION_PACKAGE_CHANGED); packageChangedIntent.putExtra(Intent.EXTRA_UID, uid); 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 410ae35aa790..e91472670c2d 100644 --- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java @@ -62,58 +62,36 @@ import android.app.BroadcastOptions; import android.app.IApplicationThread; import android.app.UidObserver; import android.app.usage.UsageEvents.Event; -import android.app.usage.UsageStatsManagerInternal; import android.content.ComponentName; -import android.content.Context; import android.content.IIntentReceiver; import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; -import android.content.pm.ResolveInfo; import android.os.Binder; import android.os.Bundle; import android.os.DeadObjectException; -import android.os.Handler; -import android.os.HandlerThread; import android.os.IBinder; import android.os.PowerExemptionManager; import android.os.SystemClock; -import android.os.TestLooperManager; import android.os.UserHandle; -import android.provider.Settings; import android.util.Log; import android.util.Pair; -import android.util.SparseArray; import android.util.proto.ProtoOutputStream; import androidx.test.filters.MediumTest; import androidx.test.platform.app.InstrumentationRegistry; -import com.android.server.AlarmManagerInternal; -import com.android.server.DropBoxManagerInternal; -import com.android.server.LocalServices; -import com.android.server.am.ActivityManagerService.Injector; -import com.android.server.appop.AppOpsService; -import com.android.server.wm.ActivityTaskManagerService; - import org.junit.After; import org.junit.Assume; import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import org.mockito.ArgumentMatcher; import org.mockito.InOrder; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; import org.mockito.verification.VerificationMode; -import java.io.File; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.Writer; @@ -126,7 +104,6 @@ import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.concurrent.CountDownLatch; -import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.function.UnaryOperator; @@ -136,13 +113,9 @@ import java.util.function.UnaryOperator; @MediumTest @RunWith(Parameterized.class) @SuppressWarnings("GuardedBy") -public class BroadcastQueueTest { +public class BroadcastQueueTest extends BaseBroadcastQueueTest { private static final String TAG = "BroadcastQueueTest"; - @Rule - public final ApplicationExitInfoTest.ServiceThreadRule - mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule(); - private final Impl mImpl; private enum Impl { @@ -150,30 +123,8 @@ public class BroadcastQueueTest { MODERN, } - private Context mContext; - private HandlerThread mHandlerThread; - private TestLooperManager mLooper; - private AtomicInteger mNextPid; - - @Mock - private AppOpsService mAppOpsService; - @Mock - private ProcessList mProcessList; - @Mock - private DropBoxManagerInternal mDropBoxManagerInt; - @Mock - private PackageManagerInternal mPackageManagerInt; - @Mock - private UsageStatsManagerInternal mUsageStatsManagerInt; - @Mock - private AlarmManagerInternal mAlarmManagerInt; - - private ActivityManagerService mAms; private BroadcastQueue mQueue; - BroadcastConstants mConstants; - private BroadcastSkipPolicy mSkipPolicy; private UidObserver mUidObserver; - private UidObserver mUidCachedStateObserver; /** * Desired behavior of the next @@ -183,11 +134,6 @@ public class BroadcastQueueTest { ProcessStartBehavior.SUCCESS); /** - * Map from PID to registered registered runtime receivers. - */ - private SparseArray<ReceiverList> mRegisteredReceivers = new SparseArray<>(); - - /** * Collection of all active processes during current test run. */ private List<ProcessRecord> mActiveProcesses = new ArrayList<>(); @@ -208,41 +154,8 @@ public class BroadcastQueueTest { @Before public void setUp() throws Exception { - MockitoAnnotations.initMocks(this); - - mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + super.setUp(); - mHandlerThread = new HandlerThread(TAG); - mHandlerThread.start(); - - // Pause all event processing until a test chooses to resume - mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation() - .acquireLooperManager(mHandlerThread.getLooper())); - - mNextPid = new AtomicInteger(100); - - LocalServices.removeServiceForTest(DropBoxManagerInternal.class); - LocalServices.addService(DropBoxManagerInternal.class, mDropBoxManagerInt); - LocalServices.removeServiceForTest(PackageManagerInternal.class); - LocalServices.addService(PackageManagerInternal.class, mPackageManagerInt); - LocalServices.removeServiceForTest(AlarmManagerInternal.class); - LocalServices.addService(AlarmManagerInternal.class, mAlarmManagerInt); - doReturn(new ComponentName("", "")).when(mPackageManagerInt).getSystemUiServiceComponent(); - doNothing().when(mPackageManagerInt).setPackageStoppedState(any(), anyBoolean(), anyInt()); - doAnswer((invocation) -> { - return getUidForPackage(invocation.getArgument(0)); - }).when(mPackageManagerInt).getPackageUid(any(), anyLong(), eq(UserHandle.USER_SYSTEM)); - - final ActivityManagerService realAms = new ActivityManagerService( - new TestInjector(mContext), mServiceThreadRule.getThread()); - realAms.mActivityTaskManager = new ActivityTaskManagerService(mContext); - realAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper()); - realAms.mAtmInternal = spy(realAms.mActivityTaskManager.getAtmInternal()); - realAms.mOomAdjuster = spy(realAms.mOomAdjuster); - realAms.mPackageManagerInt = mPackageManagerInt; - realAms.mUsageStatsService = mUsageStatsManagerInt; - realAms.mProcessesReady = true; - mAms = spy(realAms); doAnswer((invocation) -> { Log.v(TAG, "Intercepting startProcessLocked() for " + Arrays.toString(invocation.getArguments())); @@ -321,21 +234,11 @@ public class BroadcastQueueTest { return null; }).when(mAms).registerUidObserver(any(), anyInt(), eq(ActivityManager.PROCESS_STATE_TOP), any()); - doAnswer((invocation) -> { - mUidCachedStateObserver = invocation.getArgument(0); - return null; - }).when(mAms).registerUidObserver(any(), anyInt(), - eq(ActivityManager.PROCESS_STATE_LAST_ACTIVITY), any()); - mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS); mConstants.TIMEOUT = 200; mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT = 0; mConstants.PENDING_COLD_START_CHECK_INTERVAL_MILLIS = 500; - mSkipPolicy = spy(new BroadcastSkipPolicy(mAms)); - doReturn(null).when(mSkipPolicy).shouldSkipMessage(any(), any()); - doReturn(false).when(mSkipPolicy).disallowBackgroundStart(any()); - final BroadcastHistory emptyHistory = new BroadcastHistory(mConstants) { public void addBroadcastToHistoryLocked(BroadcastRecord original) { // Ignored @@ -358,7 +261,7 @@ public class BroadcastQueueTest { @After public void tearDown() throws Exception { - mHandlerThread.quit(); + super.tearDown(); // Verify that all processes have finished handling broadcasts for (ProcessRecord app : mActiveProcesses) { @@ -369,26 +272,9 @@ public class BroadcastQueueTest { } } - private class TestInjector extends Injector { - TestInjector(Context context) { - super(context); - } - - @Override - public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile, - Handler handler) { - return mAppOpsService; - } - - @Override - public Handler getUiHandler(ActivityManagerService service) { - return mHandlerThread.getThreadHandler(); - } - - @Override - public ProcessList getProcessList(ActivityManagerService service) { - return mProcessList; - } + @Override + public String getTag() { + return TAG; } private enum ProcessStartBehavior { @@ -534,62 +420,6 @@ public class BroadcastQueueTest { return Pair.create(app.getPid(), intent.getAction()); } - static ApplicationInfo makeApplicationInfo(String packageName) { - return makeApplicationInfo(packageName, packageName, UserHandle.USER_SYSTEM); - } - - static ApplicationInfo makeApplicationInfo(String packageName, String processName, int userId) { - final ApplicationInfo ai = new ApplicationInfo(); - ai.packageName = packageName; - ai.processName = processName; - ai.uid = getUidForPackage(packageName, userId); - return ai; - } - - static ResolveInfo withPriority(ResolveInfo info, int priority) { - info.priority = priority; - return info; - } - - static BroadcastFilter withPriority(BroadcastFilter filter, int priority) { - filter.setPriority(priority); - return filter; - } - - static ResolveInfo makeManifestReceiver(String packageName, String name) { - return makeManifestReceiver(packageName, name, UserHandle.USER_SYSTEM); - } - - static ResolveInfo makeManifestReceiver(String packageName, String name, int userId) { - return makeManifestReceiver(packageName, packageName, name, userId); - } - - static ResolveInfo makeManifestReceiver(String packageName, String processName, String name, - int userId) { - final ResolveInfo ri = new ResolveInfo(); - ri.activityInfo = new ActivityInfo(); - ri.activityInfo.packageName = packageName; - ri.activityInfo.processName = processName; - ri.activityInfo.name = name; - ri.activityInfo.applicationInfo = makeApplicationInfo(packageName, processName, userId); - return ri; - } - - private BroadcastFilter makeRegisteredReceiver(ProcessRecord app) { - return makeRegisteredReceiver(app, 0); - } - - private BroadcastFilter makeRegisteredReceiver(ProcessRecord app, int priority) { - final ReceiverList receiverList = mRegisteredReceivers.get(app.getPid()); - final IntentFilter filter = new IntentFilter(); - filter.setPriority(priority); - final BroadcastFilter res = new BroadcastFilter(filter, receiverList, - receiverList.app.info.packageName, null, null, null, receiverList.uid, - receiverList.userId, false, false, true); - receiverList.add(res); - return res; - } - private BroadcastRecord makeBroadcastRecord(Intent intent, ProcessRecord callerApp, List<Object> receivers) { return makeBroadcastRecord(intent, callerApp, BroadcastOptions.makeBasic(), @@ -776,41 +606,6 @@ public class BroadcastQueueTest { eq(userId), anyInt(), anyInt(), any()); } - static final int USER_GUEST = 11; - - static final String PACKAGE_ANDROID = "android"; - static final String PACKAGE_PHONE = "com.android.phone"; - static final String PACKAGE_RED = "com.example.red"; - static final String PACKAGE_GREEN = "com.example.green"; - static final String PACKAGE_BLUE = "com.example.blue"; - static final String PACKAGE_YELLOW = "com.example.yellow"; - static final String PACKAGE_ORANGE = "com.example.orange"; - - static final String PROCESS_SYSTEM = "system"; - - static final String CLASS_RED = "com.example.red.Red"; - static final String CLASS_GREEN = "com.example.green.Green"; - static final String CLASS_BLUE = "com.example.blue.Blue"; - static final String CLASS_YELLOW = "com.example.yellow.Yellow"; - static final String CLASS_ORANGE = "com.example.orange.Orange"; - - static int getUidForPackage(@NonNull String packageName) { - switch (packageName) { - case PACKAGE_ANDROID: return android.os.Process.SYSTEM_UID; - case PACKAGE_PHONE: return android.os.Process.PHONE_UID; - case PACKAGE_RED: return android.os.Process.FIRST_APPLICATION_UID + 1; - case PACKAGE_GREEN: return android.os.Process.FIRST_APPLICATION_UID + 2; - case PACKAGE_BLUE: return android.os.Process.FIRST_APPLICATION_UID + 3; - case PACKAGE_YELLOW: return android.os.Process.FIRST_APPLICATION_UID + 4; - case PACKAGE_ORANGE: return android.os.Process.FIRST_APPLICATION_UID + 5; - default: throw new IllegalArgumentException(); - } - } - - static int getUidForPackage(@NonNull String packageName, int userId) { - return UserHandle.getUid(userId, getUidForPackage(packageName)); - } - /** * Baseline verification of common debugging infrastructure, mostly to make * sure it doesn't crash. |