1 /* 2 * Copyright (C) 2017 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 package com.android.server.devicepolicy; 17 18 import static org.mockito.ArgumentMatchers.any; 19 import static org.mockito.ArgumentMatchers.anyInt; 20 import static org.mockito.ArgumentMatchers.eq; 21 import static org.mockito.Mockito.RETURNS_DEEP_STUBS; 22 import static org.mockito.Mockito.mock; 23 import static org.mockito.Mockito.spy; 24 import static org.mockito.Mockito.when; 25 26 import android.accounts.Account; 27 import android.accounts.AccountManager; 28 import android.annotation.NonNull; 29 import android.app.ActivityManagerInternal; 30 import android.app.AlarmManager; 31 import android.app.AppOpsManager; 32 import android.app.IActivityManager; 33 import android.app.IActivityTaskManager; 34 import android.app.NotificationManager; 35 import android.app.admin.DevicePolicyManager; 36 import android.app.backup.IBackupManager; 37 import android.app.role.RoleManager; 38 import android.app.usage.UsageStatsManagerInternal; 39 import android.content.BroadcastReceiver; 40 import android.content.ComponentName; 41 import android.content.ContentValues; 42 import android.content.Context; 43 import android.content.Intent; 44 import android.content.IntentFilter; 45 import android.content.pm.CrossProfileApps; 46 import android.content.pm.IPackageManager; 47 import android.content.pm.PackageManager; 48 import android.content.pm.PackageManagerInternal; 49 import android.content.pm.UserInfo; 50 import android.database.Cursor; 51 import android.hardware.usb.UsbManager; 52 import android.location.LocationManager; 53 import android.media.IAudioService; 54 import android.net.ConnectivityManager; 55 import android.net.IIpConnectivityMetrics; 56 import android.net.Uri; 57 import android.net.VpnManager; 58 import android.net.wifi.WifiManager; 59 import android.os.Binder; 60 import android.os.Handler; 61 import android.os.PowerManager; 62 import android.os.PowerManagerInternal; 63 import android.os.UserHandle; 64 import android.os.UserManager; 65 import android.permission.IPermissionManager; 66 import android.provider.Settings; 67 import android.security.KeyChain; 68 import android.telephony.SubscriptionManager; 69 import android.telephony.TelephonyManager; 70 import android.test.mock.MockContentProvider; 71 import android.test.mock.MockContentResolver; 72 import android.util.ArrayMap; 73 import android.util.Pair; 74 import android.view.IWindowManager; 75 76 import com.android.internal.util.test.FakeSettingsProvider; 77 import com.android.internal.widget.LockPatternUtils; 78 import com.android.internal.widget.LockSettingsInternal; 79 import com.android.server.AlarmManagerInternal; 80 import com.android.server.pdb.PersistentDataBlockManagerInternal; 81 import com.android.server.net.NetworkPolicyManagerInternal; 82 import com.android.server.pm.PackageManagerLocal; 83 import com.android.server.pm.UserManagerInternal; 84 import com.android.server.pm.pkg.PackageState; 85 import com.android.server.pm.pkg.PackageUserState; 86 import com.android.server.wm.ActivityTaskManagerInternal; 87 88 import java.io.File; 89 import java.io.IOException; 90 import java.util.ArrayList; 91 import java.util.List; 92 import java.util.Map; 93 import java.util.concurrent.Executor; 94 import java.util.concurrent.atomic.AtomicReference; 95 96 /** 97 * System services mocks and some other data that are shared by all contexts during the test. 98 */ 99 public class MockSystemServices { 100 public final File systemUserDataDir; 101 public final EnvironmentForMock environment; 102 public final SystemPropertiesForMock systemProperties; 103 public final Executor executor; 104 public final UserManager userManager; 105 public final UserManagerInternal userManagerInternal; 106 public final UsageStatsManagerInternal usageStatsManagerInternal; 107 public final NetworkPolicyManagerInternal networkPolicyManagerInternal; 108 public final PackageManagerInternal packageManagerInternal; 109 public final PackageManagerLocal packageManagerLocal; 110 public final UserManagerForMock userManagerForMock; 111 public final PowerManagerForMock powerManager; 112 public final PowerManagerInternal powerManagerInternal; 113 public final RecoverySystemForMock recoverySystem; 114 public final NotificationManager notificationManager; 115 public final IIpConnectivityMetrics iipConnectivityMetrics; 116 public final IWindowManager iwindowManager; 117 public final IActivityManager iactivityManager; 118 public final IActivityTaskManager iactivityTaskManager; 119 public ActivityManagerInternal activityManagerInternal; 120 public ActivityTaskManagerInternal activityTaskManagerInternal; 121 public final IPackageManager ipackageManager; 122 public final IPermissionManager ipermissionManager; 123 public final IBackupManager ibackupManager; 124 public final IAudioService iaudioService; 125 public final LockPatternUtils lockPatternUtils; 126 public final LockSettingsInternal lockSettingsInternal; 127 public final StorageManagerForMock storageManager; 128 public final WifiManager wifiManager; 129 public final SettingsForMock settings; 130 public final MockContentResolver contentResolver; 131 public final TelephonyManager telephonyManager; 132 public final ConnectivityManager connectivityManager; 133 public final AccountManager accountManager; 134 public final AlarmManager alarmManager; 135 public final AlarmManagerInternal alarmManagerInternal; 136 public final KeyChain.KeyChainConnection keyChainConnection; 137 public final CrossProfileApps crossProfileApps; 138 public final PersistentDataBlockManagerInternal persistentDataBlockManagerInternal; 139 public final AppOpsManager appOpsManager; 140 public final UsbManager usbManager; 141 public final VpnManager vpnManager; 142 public final DevicePolicyManager devicePolicyManager; 143 public final LocationManager locationManager; 144 public final RoleManager roleManager; 145 public final SubscriptionManager subscriptionManager; 146 /** Note this is a partial mock, not a real mock. */ 147 public final PackageManager packageManager; 148 public final BuildMock buildMock = new BuildMock(); 149 public final File dataDir; 150 public final PolicyPathProvider pathProvider; 151 152 private final Map<String, PackageState> mTestPackageStates = new ArrayMap<>(); 153 MockSystemServices(Context realContext, String name, @NonNull DpmMockContext.MockBinder mockBinder)154 public MockSystemServices(Context realContext, String name, 155 @NonNull DpmMockContext.MockBinder mockBinder) { 156 dataDir = new File(realContext.getCacheDir(), name); 157 DpmTestUtils.clearDir(dataDir); 158 159 environment = mock(EnvironmentForMock.class); 160 systemProperties = mock(SystemPropertiesForMock.class); 161 executor = mock(Executor.class); 162 userManager = mock(UserManager.class); 163 userManagerInternal = mock(UserManagerInternal.class); 164 usageStatsManagerInternal = mock(UsageStatsManagerInternal.class); 165 networkPolicyManagerInternal = mock(NetworkPolicyManagerInternal.class); 166 167 userManagerForMock = mock(UserManagerForMock.class); 168 packageManagerInternal = mock(PackageManagerInternal.class); 169 packageManagerLocal = mock(PackageManagerLocal.class); 170 powerManager = mock(PowerManagerForMock.class); 171 powerManagerInternal = mock(PowerManagerInternal.class); 172 recoverySystem = mock(RecoverySystemForMock.class); 173 notificationManager = mock(NotificationManager.class); 174 iipConnectivityMetrics = mock(IIpConnectivityMetrics.class); 175 iwindowManager = mock(IWindowManager.class); 176 iactivityManager = mock(IActivityManager.class); 177 iactivityTaskManager = mock(IActivityTaskManager.class); 178 activityManagerInternal = mock(ActivityManagerInternal.class); 179 activityTaskManagerInternal = mock(ActivityTaskManagerInternal.class); 180 ipackageManager = mock(IPackageManager.class); 181 ipermissionManager = mock(IPermissionManager.class); 182 ibackupManager = mock(IBackupManager.class); 183 iaudioService = mock(IAudioService.class); 184 lockPatternUtils = mock(LockPatternUtils.class); 185 lockSettingsInternal = mock(LockSettingsInternal.class); 186 storageManager = mock(StorageManagerForMock.class); 187 wifiManager = mock(WifiManager.class); 188 settings = mock(SettingsForMock.class); 189 telephonyManager = mock(TelephonyManager.class); 190 connectivityManager = mock(ConnectivityManager.class); 191 accountManager = mock(AccountManager.class); 192 alarmManager = mock(AlarmManager.class); 193 alarmManagerInternal = mock(AlarmManagerInternal.class); 194 keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS); 195 crossProfileApps = mock(CrossProfileApps.class); 196 persistentDataBlockManagerInternal = mock(PersistentDataBlockManagerInternal.class); 197 appOpsManager = mock(AppOpsManager.class); 198 usbManager = mock(UsbManager.class); 199 vpnManager = mock(VpnManager.class); 200 devicePolicyManager = mock(DevicePolicyManager.class); 201 locationManager = mock(LocationManager.class); 202 roleManager = realContext.getSystemService(RoleManager.class); 203 subscriptionManager = mock(SubscriptionManager.class); 204 205 // Package manager is huge, so we use a partial mock instead. 206 packageManager = spy(realContext.getPackageManager()); 207 when(packageManagerInternal.getSystemUiServiceComponent()).thenReturn( 208 new ComponentName("com.android.systemui", ".Service")); 209 210 addTestPackageUid("android", DpmMockContext.SYSTEM_UID); 211 addTestPackageUid(realContext.getPackageName(), Binder.getCallingUid()); 212 when(packageManagerLocal.withUnfilteredSnapshot()).thenAnswer(unused -> { 213 var snapshot = mock(PackageManagerLocal.UnfilteredSnapshot.class); 214 when(snapshot.getPackageStates()).thenAnswer(unused1 -> mTestPackageStates); 215 return snapshot; 216 }); 217 218 contentResolver = new MockContentResolver(); 219 contentResolver.addProvider("telephony", new MockContentProvider(realContext) { 220 @Override 221 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { 222 return 0; 223 } 224 225 @Override 226 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, 227 String sortOrder) { 228 return null; 229 } 230 231 @Override 232 public int delete(Uri uri, String selection, String[] selectionArgs) { 233 return 0; 234 } 235 }); 236 contentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); 237 238 // Add the system user with a fake profile group already set up (this can happen in the real 239 // world if a managed profile is added and then removed). 240 systemUserDataDir = addUser(UserHandle.USER_SYSTEM, 241 UserInfo.FLAG_PRIMARY | UserInfo.FLAG_MAIN, 242 UserManager.USER_TYPE_FULL_SYSTEM, UserHandle.USER_SYSTEM); 243 when(userManager.getMainUser()).thenReturn(UserHandle.SYSTEM); 244 245 // System user is always running. 246 setUserRunning(UserHandle.USER_SYSTEM, true); 247 pathProvider = new PolicyPathProvider() { 248 @Override 249 public File getDataSystemDirectory() { 250 return new File(systemUserDataDir.getAbsolutePath()); 251 } 252 253 @Override 254 public File getUserSystemDirectory(int userId) { 255 return environment.getUserSystemDirectory(userId); 256 } 257 }; 258 } 259 260 /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */ 261 private final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>(); 262 263 private final ArrayList<UserInfo> mUserInfos = new ArrayList<>(); 264 265 private final List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>(); 266 registerReceiver( BroadcastReceiver receiver, IntentFilter filter, Handler scheduler)267 public void registerReceiver( 268 BroadcastReceiver receiver, IntentFilter filter, Handler scheduler) { 269 mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler)); 270 } 271 unregisterReceiver(BroadcastReceiver receiver)272 public void unregisterReceiver(BroadcastReceiver receiver) { 273 mBroadcastReceivers.removeIf(r -> r.receiver == receiver); 274 } 275 addUser(int userId, int flags, String type)276 public File addUser(int userId, int flags, String type) { 277 return addUser(userId, flags, type, UserInfo.NO_PROFILE_GROUP_ID); 278 } 279 addUser(int userId, int flags, String type, int profileGroupId)280 public File addUser(int userId, int flags, String type, int profileGroupId) { 281 // Set up (default) UserInfo for CALLER_USER_HANDLE. 282 final UserInfo uh = new UserInfo(userId, "user" + userId, flags); 283 284 uh.userType = type; 285 uh.profileGroupId = profileGroupId; 286 when(userManager.getUserInfo(eq(userId))).thenReturn(uh); 287 // Ensure there are no duplicate UserInfo records. 288 // TODO: fix tests so that this is not needed. 289 for (int i = 0; i < mUserInfos.size(); i++) { 290 if (mUserInfos.get(i).id == userId) { 291 mUserInfos.remove(i); 292 break; 293 } 294 } 295 mUserInfos.add(uh); 296 when(userManager.getUsers()).thenReturn(mUserInfos); 297 when(userManager.getAliveUsers()).thenReturn(mUserInfos); 298 when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true); 299 when(userManager.getProfileParent(anyInt())).thenAnswer( 300 invocation -> { 301 final int userId1 = (int) invocation.getArguments()[0]; 302 final UserInfo ui = getUserInfo(userId1); 303 return ui == null ? null : getUserInfo(ui.profileGroupId); 304 } 305 ); 306 when(userManager.getProfileParent(any(UserHandle.class))).thenAnswer( 307 invocation -> { 308 final UserHandle userHandle = (UserHandle) invocation.getArguments()[0]; 309 final UserInfo ui = getUserInfo(userHandle.getIdentifier()); 310 return ui == null ? UserHandle.USER_NULL : UserHandle.of(ui.profileGroupId); 311 } 312 ); 313 when(userManager.getProfiles(anyInt())).thenAnswer( 314 invocation -> { 315 final int userId12 = (int) invocation.getArguments()[0]; 316 return getProfiles(userId12); 317 } 318 ); 319 when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer( 320 invocation -> { 321 final int userId13 = (int) invocation.getArguments()[0]; 322 List<UserInfo> profiles = getProfiles(userId13); 323 return profiles.stream() 324 .mapToInt(profile -> profile.id) 325 .toArray(); 326 } 327 ); 328 when(userManagerInternal.getUserInfos()).thenReturn( 329 mUserInfos.toArray(new UserInfo[mUserInfos.size()])); 330 331 when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]); 332 333 // Create a data directory. 334 final File dir = new File(dataDir, "users/" + userId); 335 DpmTestUtils.clearDir(dir); 336 337 when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir); 338 return dir; 339 } 340 removeUser(int userId)341 public void removeUser(int userId) { 342 for (int i = 0; i < mUserInfos.size(); i++) { 343 if (mUserInfos.get(i).id == userId) { 344 mUserInfos.remove(i); 345 break; 346 } 347 } 348 when(userManager.getUserInfo(eq(userId))).thenReturn(null); 349 350 when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false); 351 } 352 getUserInfo(int userId)353 private UserInfo getUserInfo(int userId) { 354 for (final UserInfo ui : mUserInfos) { 355 if (ui.id == userId) { 356 return ui; 357 } 358 } 359 return null; 360 } 361 getProfiles(int userId)362 private List<UserInfo> getProfiles(int userId) { 363 final ArrayList<UserInfo> ret = new ArrayList<>(); 364 UserInfo parent = null; 365 for (final UserInfo ui : mUserInfos) { 366 if (ui.id == userId) { 367 parent = ui; 368 break; 369 } 370 } 371 if (parent == null) { 372 return ret; 373 } 374 for (final UserInfo ui : mUserInfos) { 375 if (ui == parent 376 || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 377 && ui.profileGroupId == parent.profileGroupId) { 378 ret.add(ui); 379 } 380 } 381 return ret; 382 } 383 384 /** 385 * Add multiple users at once. They'll all have flag 0. 386 */ addUsers(int... userIds)387 public void addUsers(int... userIds) { 388 for (final int userId : userIds) { 389 addUser(userId, 0, ""); 390 } 391 } 392 setUserRunning(int userId, boolean isRunning)393 public void setUserRunning(int userId, boolean isRunning) { 394 when(userManager.isUserRunning(MockUtils.checkUserHandle(userId))) 395 .thenReturn(isRunning); 396 } 397 injectBroadcast(Context context, final Intent intent, int userId)398 public void injectBroadcast(Context context, final Intent intent, int userId) { 399 //final int userId = UserHandle.getUserId(binder.getCallingUid()); 400 for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) { 401 receiver.sendBroadcastIfApplicable(context, userId, intent); 402 } 403 } 404 rethrowBackgroundBroadcastExceptions()405 public void rethrowBackgroundBroadcastExceptions() throws Exception { 406 for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) { 407 final Exception e = receiver.backgroundException.getAndSet(null); 408 if (e != null) { 409 throw e; 410 } 411 } 412 } 413 addPackageContext(UserHandle user, Context context)414 public void addPackageContext(UserHandle user, Context context) { 415 if (context.getPackageName() == null) { 416 throw new NullPointerException("getPackageName() == null"); 417 } 418 userPackageContexts.put(new Pair<>(user, context.getPackageName()), context); 419 } 420 createPackageContextAsUser(String packageName, int flags, UserHandle user)421 public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) 422 throws PackageManager.NameNotFoundException { 423 final Pair<UserHandle, String> key = new Pair<>(user, packageName); 424 if (userPackageContexts.containsKey(key)) { 425 return userPackageContexts.get(key); 426 } 427 throw new UnsupportedOperationException("No package " + packageName + " for user " + user); 428 } 429 addTestPackageUid(@onNull String packageName, int uid)430 public void addTestPackageUid(@NonNull String packageName, int uid) { 431 var packageState = mock(PackageState.class); 432 when(packageState.getAppId()).thenReturn(UserHandle.getAppId(uid)); 433 when(packageState.getUserStateOrDefault(anyInt())).thenAnswer(invocation -> { 434 var userState = mock(PackageUserState.class); 435 when(userState.isInstalled()).thenReturn(true); 436 return userState; 437 }); 438 mTestPackageStates.put(packageName, packageState); 439 } 440 441 public static class EnvironmentForMock { getUserSystemDirectory(int userId)442 public File getUserSystemDirectory(int userId) { 443 return null; 444 } 445 } 446 447 public static class BuildMock { 448 public boolean isDebuggable = true; 449 } 450 451 public static class PowerManagerForMock { newWakeLock(int levelAndFlags, String tag)452 public PowerManager.WakeLock newWakeLock(int levelAndFlags, String tag) { 453 return null; 454 } 455 goToSleep(long time, int reason, int flags)456 public void goToSleep(long time, int reason, int flags) { 457 } 458 reboot(String reason)459 public void reboot(String reason) { 460 } 461 } 462 463 public static class RecoverySystemForMock { rebootWipeUserData(boolean shutdown, String reason, boolean force, boolean wipeEuicc, boolean wipeExtRequested, boolean wipeResetProtectionData)464 public boolean rebootWipeUserData(boolean shutdown, String reason, boolean force, 465 boolean wipeEuicc, boolean wipeExtRequested, boolean wipeResetProtectionData) 466 throws IOException { 467 return false; 468 } 469 } 470 471 public static class SystemPropertiesForMock { getBoolean(String key, boolean def)472 public boolean getBoolean(String key, boolean def) { 473 return false; 474 } 475 getLong(String key, long def)476 public long getLong(String key, long def) { 477 return 0; 478 } 479 get(String key, String def)480 public String get(String key, String def) { 481 return null; 482 } 483 get(String key)484 public String get(String key) { 485 return null; 486 } 487 set(String key, String value)488 public void set(String key, String value) { 489 } 490 } 491 492 public static class UserManagerForMock { isHeadlessSystemUserMode()493 public boolean isHeadlessSystemUserMode() { 494 return false; 495 } 496 } 497 498 public static class SettingsForMock { settingsSecureGetIntForUser(String name, int def, int userHandle)499 public int settingsSecureGetIntForUser(String name, int def, int userHandle) { 500 return 0; 501 } 502 settingsSecureGetStringForUser(String name, int userHandle)503 public String settingsSecureGetStringForUser(String name, int userHandle) { 504 return null; 505 } 506 settingsSecurePutIntForUser(String name, int value, int userHandle)507 public void settingsSecurePutIntForUser(String name, int value, int userHandle) { 508 } 509 settingsSecurePutStringForUser(String name, String value, int userHandle)510 public void settingsSecurePutStringForUser(String name, String value, int userHandle) { 511 } 512 settingsGlobalPutStringForUser(String name, String value, int userHandle)513 public void settingsGlobalPutStringForUser(String name, String value, int userHandle) { 514 } 515 settingsSecurePutInt(String name, int value)516 public void settingsSecurePutInt(String name, int value) { 517 } 518 settingsGlobalPutInt(String name, int value)519 public void settingsGlobalPutInt(String name, int value) { 520 } 521 settingsSecurePutString(String name, String value)522 public void settingsSecurePutString(String name, String value) { 523 } 524 settingsGlobalPutString(String name, String value)525 public void settingsGlobalPutString(String name, String value) { 526 } 527 settingsSystemPutStringForUser(String name, String value, int callingUserId)528 public void settingsSystemPutStringForUser(String name, String value, int callingUserId) { 529 } 530 settingsGlobalGetInt(String name, int value)531 public int settingsGlobalGetInt(String name, int value) { 532 return 0; 533 } 534 settingsGlobalGetString(String name)535 public String settingsGlobalGetString(String name) { 536 return ""; 537 } 538 securityLogSetLoggingEnabledProperty(boolean enabled)539 public void securityLogSetLoggingEnabledProperty(boolean enabled) { 540 } 541 securityLogGetLoggingEnabledProperty()542 public boolean securityLogGetLoggingEnabledProperty() { 543 return false; 544 } 545 securityLogIsLoggingEnabled()546 public boolean securityLogIsLoggingEnabled() { 547 return false; 548 } 549 } 550 551 public static class StorageManagerForMock { isFileBasedEncryptionEnabled()552 public boolean isFileBasedEncryptionEnabled() { 553 return false; 554 } 555 } 556 557 // We have to keep track of broadcast receivers registered for a given intent ourselves as the 558 // DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does 559 // not work. 560 private static class BroadcastReceiverRegistration { 561 public final BroadcastReceiver receiver; 562 public final IntentFilter filter; 563 public final Handler scheduler; 564 565 // Exceptions thrown in a background thread kill the whole test. Save them instead. 566 public final AtomicReference<Exception> backgroundException = new AtomicReference<>(); 567 BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter, Handler scheduler)568 public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter, 569 Handler scheduler) { 570 this.receiver = receiver; 571 this.filter = filter; 572 this.scheduler = scheduler; 573 } 574 sendBroadcastIfApplicable(Context context, int userId, Intent intent)575 public void sendBroadcastIfApplicable(Context context, int userId, Intent intent) { 576 final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult( 577 0 /* resultCode */, null /* resultData */, null /* resultExtras */, 578 0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId, 579 0 /* flags */); 580 if (filter.match(null, intent, false, "DpmMockContext") > 0) { 581 final Runnable send = () -> { 582 receiver.setPendingResult(result); 583 receiver.onReceive(context, intent); 584 }; 585 if (scheduler != null) { 586 scheduler.post(() -> { 587 try { 588 send.run(); 589 } catch (Exception e) { 590 backgroundException.compareAndSet(null, e); 591 } 592 }); 593 } else { 594 send.run(); 595 } 596 } 597 } 598 } 599 } 600