1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.am; 18 19 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing; 20 import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; 21 22 import static org.mockito.ArgumentMatchers.any; 23 import static org.mockito.ArgumentMatchers.anyInt; 24 import static org.mockito.ArgumentMatchers.anyLong; 25 import static org.mockito.ArgumentMatchers.eq; 26 import static org.mockito.Mockito.doAnswer; 27 import static org.mockito.Mockito.mock; 28 import static org.mockito.Mockito.spy; 29 30 import android.annotation.NonNull; 31 import android.app.Activity; 32 import android.app.ActivityManager; 33 import android.app.AppGlobals; 34 import android.app.AppOpsManager; 35 import android.app.BackgroundStartPrivileges; 36 import android.app.BroadcastOptions; 37 import android.app.SystemServiceRegistry; 38 import android.app.usage.UsageStatsManagerInternal; 39 import android.content.ComponentName; 40 import android.content.Context; 41 import android.content.IIntentReceiver; 42 import android.content.Intent; 43 import android.content.IntentFilter; 44 import android.content.pm.ActivityInfo; 45 import android.content.pm.ApplicationInfo; 46 import android.content.pm.IPackageManager; 47 import android.content.pm.PackageManagerInternal; 48 import android.content.pm.ResolveInfo; 49 import android.os.Bundle; 50 import android.os.Handler; 51 import android.os.HandlerThread; 52 import android.os.TestLooperManager; 53 import android.os.UserHandle; 54 import android.permission.IPermissionManager; 55 import android.permission.PermissionManager; 56 import android.platform.test.flag.junit.CheckFlagsRule; 57 import android.platform.test.flag.junit.DeviceFlagsValueProvider; 58 import android.platform.test.flag.junit.SetFlagsRule; 59 import android.provider.Settings; 60 import android.util.SparseArray; 61 62 import androidx.test.platform.app.InstrumentationRegistry; 63 64 import com.android.internal.util.FrameworkStatsLog; 65 import com.android.modules.utils.testing.ExtendedMockitoRule; 66 import com.android.server.AlarmManagerInternal; 67 import com.android.server.DropBoxManagerInternal; 68 import com.android.server.LocalServices; 69 import com.android.server.appop.AppOpsService; 70 import com.android.server.compat.PlatformCompat; 71 import com.android.server.firewall.IntentFirewall; 72 import com.android.server.wm.ActivityTaskManagerService; 73 74 import org.junit.Rule; 75 import org.mockito.ArgumentMatcher; 76 import org.mockito.Mock; 77 import org.mockito.MockitoAnnotations; 78 79 import java.io.File; 80 import java.util.Collections; 81 import java.util.List; 82 import java.util.Objects; 83 import java.util.concurrent.atomic.AtomicInteger; 84 import java.util.function.BiFunction; 85 86 public abstract class BaseBroadcastQueueTest { 87 88 static final int USER_GUEST = 11; 89 90 static final String PACKAGE_ANDROID = "android"; 91 static final String PACKAGE_PHONE = "com.android.phone"; 92 static final String PACKAGE_RED = "com.example.red"; 93 static final String PACKAGE_GREEN = "com.example.green"; 94 static final String PACKAGE_BLUE = "com.example.blue"; 95 static final String PACKAGE_YELLOW = "com.example.yellow"; 96 static final String PACKAGE_ORANGE = "com.example.orange"; 97 98 static final String PROCESS_SYSTEM = "system"; 99 100 static final String CLASS_RED = "com.example.red.Red"; 101 static final String CLASS_GREEN = "com.example.green.Green"; 102 static final String CLASS_BLUE = "com.example.blue.Blue"; 103 static final String CLASS_YELLOW = "com.example.yellow.Yellow"; 104 static final String CLASS_ORANGE = "com.example.orange.Orange"; 105 106 static final BroadcastProcessQueue.BroadcastPredicate BROADCAST_PREDICATE_ANY = 107 (r, i) -> true; 108 109 @Rule 110 public final ApplicationExitInfoTest.ServiceThreadRule 111 mServiceThreadRule = new ApplicationExitInfoTest.ServiceThreadRule(); 112 113 @Rule 114 public final ExtendedMockitoRule mExtendedMockitoRule = new ExtendedMockitoRule.Builder(this) 115 .spyStatic(FrameworkStatsLog.class) 116 .spyStatic(ProcessList.class) 117 .spyStatic(SystemServiceRegistry.class) 118 .mockStatic(AppGlobals.class) 119 .build(); 120 121 122 @Rule 123 public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); 124 @Rule 125 public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); 126 127 @Mock 128 AppOpsService mAppOpsService; 129 @Mock 130 PackageManagerInternal mPackageManagerInt; 131 @Mock 132 UsageStatsManagerInternal mUsageStatsManagerInt; 133 @Mock 134 DropBoxManagerInternal mDropBoxManagerInt; 135 @Mock 136 AlarmManagerInternal mAlarmManagerInt; 137 @Mock 138 ProcessList mProcessList; 139 @Mock 140 PlatformCompat mPlatformCompat; 141 @Mock 142 IntentFirewall mIntentFirewall; 143 @Mock 144 IPackageManager mIPackageManager; 145 @Mock 146 AppOpsManager mAppOpsManager; 147 @Mock 148 IPermissionManager mIPermissionManager; 149 @Mock 150 PermissionManager mPermissionManager; 151 152 @Mock 153 AppStartInfoTracker mAppStartInfoTracker; 154 155 Context mContext; 156 ActivityManagerService mAms; 157 BroadcastConstants mConstants; 158 BroadcastSkipPolicy mSkipPolicy; 159 HandlerThread mHandlerThread; 160 TestLooperManager mLooper; 161 AtomicInteger mNextPid; 162 BroadcastHistory mEmptyHistory; 163 164 /** 165 * Map from PID to registered registered runtime receivers. 166 */ 167 SparseArray<ReceiverList> mRegisteredReceivers = new SparseArray<>(); 168 setUp()169 public void setUp() throws Exception { 170 MockitoAnnotations.initMocks(this); 171 172 mContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); 173 mHandlerThread = new HandlerThread(getTag()); 174 mHandlerThread.start(); 175 // Pause all event processing until a test chooses to resume 176 mLooper = Objects.requireNonNull(InstrumentationRegistry.getInstrumentation() 177 .acquireLooperManager(mHandlerThread.getLooper())); 178 mNextPid = new AtomicInteger(100); 179 180 mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS); 181 mEmptyHistory = new BroadcastHistory(mConstants) { 182 public void addBroadcastToHistoryLocked(BroadcastRecord original) { 183 // Ignored 184 } 185 }; 186 187 LocalServices.removeServiceForTest(DropBoxManagerInternal.class); 188 LocalServices.addService(DropBoxManagerInternal.class, mDropBoxManagerInt); 189 LocalServices.removeServiceForTest(PackageManagerInternal.class); 190 LocalServices.addService(PackageManagerInternal.class, mPackageManagerInt); 191 LocalServices.removeServiceForTest(AlarmManagerInternal.class); 192 LocalServices.addService(AlarmManagerInternal.class, mAlarmManagerInt); 193 doReturn(new ComponentName("", "")).when(mPackageManagerInt).getSystemUiServiceComponent(); 194 doNothing().when(mPackageManagerInt).notifyComponentUsed(any(), anyInt(), any(), any()); 195 doAnswer((invocation) -> { 196 return getUidForPackage(invocation.getArgument(0)); 197 }).when(mPackageManagerInt).getPackageUid(any(), anyLong(), eq(UserHandle.USER_SYSTEM)); 198 199 final Context spyContext = spy(mContext); 200 doReturn(mPermissionManager).when(spyContext).getSystemService(PermissionManager.class); 201 final ActivityManagerService realAms = new ActivityManagerService( 202 new TestInjector(spyContext), mServiceThreadRule.getThread()); 203 realAms.mActivityTaskManager = new ActivityTaskManagerService(mContext); 204 realAms.mActivityTaskManager.initialize(null, null, mContext.getMainLooper()); 205 realAms.mAtmInternal = spy(realAms.mActivityTaskManager.getAtmInternal()); 206 realAms.mOomAdjuster.mCachedAppOptimizer = mock(CachedAppOptimizer.class); 207 realAms.mOomAdjuster = spy(realAms.mOomAdjuster); 208 doNothing().when(() -> ProcessList.setOomAdj(anyInt(), anyInt(), anyInt())); 209 realAms.mPackageManagerInt = mPackageManagerInt; 210 realAms.mUsageStatsService = mUsageStatsManagerInt; 211 realAms.mProcessesReady = true; 212 mAms = spy(realAms); 213 214 mSkipPolicy = createBroadcastSkipPolicy(); 215 216 doReturn(mAppStartInfoTracker).when(mProcessList).getAppStartInfoTracker(); 217 218 doReturn(true).when(mPlatformCompat).isChangeEnabledInternalNoLogging( 219 eq(BroadcastFilter.RESTRICT_PRIORITY_VALUES), any(ApplicationInfo.class)); 220 doReturn(true).when(mPlatformCompat).isChangeEnabledInternalNoLogging( 221 eq(BroadcastRecord.LIMIT_PRIORITY_SCOPE), any(ApplicationInfo.class)); 222 } 223 tearDown()224 public void tearDown() throws Exception { 225 if (mHandlerThread != null) { 226 mHandlerThread.quit(); 227 } 228 } 229 createBroadcastSkipPolicy()230 public BroadcastSkipPolicy createBroadcastSkipPolicy() { 231 final BroadcastSkipPolicy skipPolicy = spy(new BroadcastSkipPolicy(mAms)); 232 doReturn(null).when(skipPolicy).shouldSkipAtEnqueueMessage(any(), any()); 233 doReturn(null).when(skipPolicy).shouldSkipMessage(any(), any()); 234 doReturn(false).when(skipPolicy).disallowBackgroundStart(any()); 235 return skipPolicy; 236 } 237 getUidForPackage(@onNull String packageName)238 static int getUidForPackage(@NonNull String packageName) { 239 switch (packageName) { 240 case PACKAGE_ANDROID: return android.os.Process.SYSTEM_UID; 241 case PACKAGE_PHONE: return android.os.Process.PHONE_UID; 242 case PACKAGE_RED: return android.os.Process.FIRST_APPLICATION_UID + 1; 243 case PACKAGE_GREEN: return android.os.Process.FIRST_APPLICATION_UID + 2; 244 case PACKAGE_BLUE: return android.os.Process.FIRST_APPLICATION_UID + 3; 245 case PACKAGE_YELLOW: return android.os.Process.FIRST_APPLICATION_UID + 4; 246 case PACKAGE_ORANGE: return android.os.Process.FIRST_APPLICATION_UID + 5; 247 default: throw new IllegalArgumentException(); 248 } 249 } 250 getUidForPackage(@onNull String packageName, int userId)251 static int getUidForPackage(@NonNull String packageName, int userId) { 252 return UserHandle.getUid(userId, getUidForPackage(packageName)); 253 } 254 255 private class TestInjector extends ActivityManagerService.Injector { TestInjector(Context context)256 TestInjector(Context context) { 257 super(context); 258 } 259 260 @Override getAppOpsService(File recentAccessesFile, File storageFile, Handler handler)261 public AppOpsService getAppOpsService(File recentAccessesFile, File storageFile, 262 Handler handler) { 263 return mAppOpsService; 264 } 265 266 @Override getUiHandler(ActivityManagerService service)267 public Handler getUiHandler(ActivityManagerService service) { 268 return mHandlerThread.getThreadHandler(); 269 } 270 271 @Override getProcessList(ActivityManagerService service)272 public ProcessList getProcessList(ActivityManagerService service) { 273 return mProcessList; 274 } 275 276 @Override getBroadcastQueue(ActivityManagerService service)277 public BroadcastQueue getBroadcastQueue(ActivityManagerService service) { 278 return null; 279 } 280 281 @Override getIntentFirewall()282 public IntentFirewall getIntentFirewall() { 283 return mIntentFirewall; 284 } 285 } 286 getTag()287 abstract String getTag(); 288 makeApplicationInfo(String packageName)289 static ApplicationInfo makeApplicationInfo(String packageName) { 290 return makeApplicationInfo(packageName, packageName, UserHandle.USER_SYSTEM); 291 } 292 makeApplicationInfo(String packageName, String processName, int userId)293 static ApplicationInfo makeApplicationInfo(String packageName, String processName, int userId) { 294 final ApplicationInfo ai = new ApplicationInfo(); 295 ai.packageName = packageName; 296 ai.processName = processName; 297 ai.uid = getUidForPackage(packageName, userId); 298 return ai; 299 } 300 withPriority(ResolveInfo info, int priority)301 static ResolveInfo withPriority(ResolveInfo info, int priority) { 302 info.priority = priority; 303 return info; 304 } 305 withPriority(BroadcastFilter filter, int priority)306 static BroadcastFilter withPriority(BroadcastFilter filter, int priority) { 307 filter.setPriority(priority); 308 return filter; 309 } 310 makeManifestReceiver(String packageName, String name)311 static ResolveInfo makeManifestReceiver(String packageName, String name) { 312 return makeManifestReceiver(packageName, name, UserHandle.USER_SYSTEM); 313 } 314 makeManifestReceiver(String packageName, String name, int userId)315 static ResolveInfo makeManifestReceiver(String packageName, String name, int userId) { 316 return makeManifestReceiver(packageName, packageName, name, userId); 317 } 318 makeManifestReceiver(String packageName, String processName, String name, int userId)319 static ResolveInfo makeManifestReceiver(String packageName, String processName, 320 String name, int userId) { 321 final ResolveInfo ri = new ResolveInfo(); 322 ri.activityInfo = new ActivityInfo(); 323 ri.activityInfo.packageName = packageName; 324 ri.activityInfo.processName = processName; 325 ri.activityInfo.name = name; 326 ri.activityInfo.exported = true; 327 ri.activityInfo.applicationInfo = makeApplicationInfo(packageName, processName, userId); 328 return ri; 329 } 330 331 // TODO: Reuse BroadcastQueueTest.makeActiveProcessRecord() 332 @SuppressWarnings("GuardedBy") makeProcessRecord(ApplicationInfo info)333 ProcessRecord makeProcessRecord(ApplicationInfo info) { 334 final ProcessRecord r = spy(new ProcessRecord(mAms, info, info.processName, info.uid)); 335 r.setPid(mNextPid.incrementAndGet()); 336 ProcessRecord.updateProcessRecordNodes(r); 337 return r; 338 } 339 makeRegisteredReceiver(ProcessRecord app)340 BroadcastFilter makeRegisteredReceiver(ProcessRecord app) { 341 return makeRegisteredReceiver(app, 0); 342 } 343 makeRegisteredReceiver(ProcessRecord app, int priority)344 BroadcastFilter makeRegisteredReceiver(ProcessRecord app, int priority) { 345 final ReceiverList receiverList = mRegisteredReceivers.get(app.getPid()); 346 return makeRegisteredReceiver(receiverList, priority, null); 347 } 348 makeRegisteredReceiver(ReceiverList receiverList, int priority, String requiredPermission)349 static BroadcastFilter makeRegisteredReceiver(ReceiverList receiverList, int priority, 350 String requiredPermission) { 351 final IntentFilter filter = new IntentFilter(); 352 filter.setPriority(priority); 353 final BroadcastFilter res = new BroadcastFilter(filter, receiverList, 354 receiverList.app.info.packageName, null, null, requiredPermission, receiverList.uid, 355 receiverList.userId, false, false, true, receiverList.app.info, 356 mock(PlatformCompat.class)); 357 receiverList.add(res); 358 return res; 359 } 360 setProcessFreezable(ProcessRecord app, boolean pendingFreeze, boolean frozen)361 void setProcessFreezable(ProcessRecord app, boolean pendingFreeze, boolean frozen) { 362 app.mOptRecord.setPendingFreeze(pendingFreeze); 363 app.mOptRecord.setFrozen(frozen); 364 } 365 appInfoEquals(int uid)366 ArgumentMatcher<ApplicationInfo> appInfoEquals(int uid) { 367 return test -> (test.uid == uid); 368 } 369 370 static final class BroadcastRecordBuilder { 371 private BroadcastQueue mQueue = mock(BroadcastQueue.class); 372 private Intent mIntent = mock(Intent.class); 373 private ProcessRecord mProcessRecord = mock(ProcessRecord.class); 374 private String mCallerPackage; 375 private String mCallerFeatureId; 376 private int mCallingPid; 377 private int mCallingUid; 378 private boolean mCallerInstantApp; 379 private String mResolvedType; 380 private String[] mRequiredPermissions; 381 private String[] mExcludedPermissions; 382 private String[] mExcludedPackages; 383 private int mAppOp; 384 private BroadcastOptions mOptions = BroadcastOptions.makeBasic(); 385 private List mReceivers = Collections.emptyList(); 386 private ProcessRecord mResultToApp; 387 private IIntentReceiver mResultTo; 388 private int mResultCode = Activity.RESULT_OK; 389 private String mResultData; 390 private Bundle mResultExtras; 391 private boolean mSerialized; 392 private boolean mSticky; 393 private boolean mInitialSticky; 394 private int mUserId = UserHandle.USER_SYSTEM; 395 private BackgroundStartPrivileges mBackgroundStartPrivileges = 396 BackgroundStartPrivileges.NONE; 397 private boolean mTimeoutExempt; 398 private BiFunction<Integer, Bundle, Bundle> mFilterExtrasForReceiver; 399 private int mCallerAppProcState = ActivityManager.PROCESS_STATE_UNKNOWN; 400 private PlatformCompat mPlatformCompat = mock(PlatformCompat.class); 401 setIntent(Intent intent)402 public BroadcastRecordBuilder setIntent(Intent intent) { 403 mIntent = intent; 404 return this; 405 } 406 setRequiredPermissions(String[] requiredPermissions)407 public BroadcastRecordBuilder setRequiredPermissions(String[] requiredPermissions) { 408 mRequiredPermissions = requiredPermissions; 409 return this; 410 } 411 setAppOp(int appOp)412 public BroadcastRecordBuilder setAppOp(int appOp) { 413 mAppOp = appOp; 414 return this; 415 } 416 build()417 public BroadcastRecord build() { 418 return new BroadcastRecord(mQueue, mIntent, mProcessRecord, mCallerPackage, 419 mCallerFeatureId, mCallingPid, mCallingUid, mCallerInstantApp, mResolvedType, 420 mRequiredPermissions, mExcludedPermissions, mExcludedPackages, mAppOp, 421 mOptions, mReceivers, mResultToApp, mResultTo, mResultCode, mResultData, 422 mResultExtras, mSerialized, mSticky, mInitialSticky, mUserId, 423 mBackgroundStartPrivileges, mTimeoutExempt, mFilterExtrasForReceiver, 424 mCallerAppProcState, mPlatformCompat); 425 } 426 } 427 } 428