175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov/* 275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * Copyright (C) 2017 The Android Open Source Project 375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * 475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * Licensed under the Apache License, Version 2.0 (the "License"); 575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * you may not use this file except in compliance with the License. 675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * You may obtain a copy of the License at 775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * 875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * http://www.apache.org/licenses/LICENSE-2.0 975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * 1075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * Unless required by applicable law or agreed to in writing, software 1175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * distributed under the License is distributed on an "AS IS" BASIS, 1275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * See the License for the specific language governing permissions and 1475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * limitations under the License. 1575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov */ 1675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovpackage com.android.server.devicepolicy; 1775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 1875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport static org.mockito.ArgumentMatchers.anyBoolean; 1975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport static org.mockito.ArgumentMatchers.anyInt; 2075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport static org.mockito.ArgumentMatchers.eq; 2175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport static org.mockito.Mockito.RETURNS_DEEP_STUBS; 2275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport static org.mockito.Mockito.mock; 2375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport static org.mockito.Mockito.spy; 2475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport static org.mockito.Mockito.when; 2575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 2675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.accounts.Account; 2775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.accounts.AccountManager; 2875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.app.AlarmManager; 2975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.app.IActivityManager; 3075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.app.NotificationManager; 3175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.app.backup.IBackupManager; 3275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.content.BroadcastReceiver; 3375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.content.Context; 3475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.content.Intent; 3575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.content.IntentFilter; 3675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.content.pm.IPackageManager; 3775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.content.pm.PackageManager; 3875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.content.pm.PackageManagerInternal; 3975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.content.pm.UserInfo; 4075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.media.IAudioService; 4175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.net.IIpConnectivityMetrics; 4275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.net.wifi.WifiManager; 4375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.os.Handler; 4475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.os.PowerManager; 4575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.os.PowerManagerInternal; 4675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.os.UserHandle; 4775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.os.UserManager; 4875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.os.UserManagerInternal; 499a18f5fa409d99e09bed57626d5a600142fd7009Christine Franksimport android.provider.Settings; 5075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.security.KeyChain; 5175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.telephony.TelephonyManager; 5275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.test.mock.MockContentResolver; 5375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.util.ArrayMap; 5475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.util.Pair; 5575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport android.view.IWindowManager; 5675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 579a18f5fa409d99e09bed57626d5a600142fd7009Christine Franksimport com.android.internal.util.test.FakeSettingsProvider; 5875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport com.android.internal.widget.LockPatternUtils; 5975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 6075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport java.io.File; 6175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport java.io.IOException; 6275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport java.util.ArrayList; 6375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport java.util.List; 6475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport java.util.Map; 6575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovimport java.util.concurrent.atomic.AtomicReference; 6675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 6775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov/** 6875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * System services mocks and some other data that are shared by all contexts during the test. 6975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov */ 7075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafovpublic class MockSystemServices { 7175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final File systemUserDataDir; 7275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final EnvironmentForMock environment; 7375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final SystemPropertiesForMock systemProperties; 7475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final UserManager userManager; 7575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final UserManagerInternal userManagerInternal; 7675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final PackageManagerInternal packageManagerInternal; 7775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final UserManagerForMock userManagerForMock; 7875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final PowerManagerForMock powerManager; 7975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final PowerManagerInternal powerManagerInternal; 8075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final RecoverySystemForMock recoverySystem; 8175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final NotificationManager notificationManager; 8275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final IIpConnectivityMetrics iipConnectivityMetrics; 8375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final IWindowManager iwindowManager; 8475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final IActivityManager iactivityManager; 8575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final IPackageManager ipackageManager; 8675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final IBackupManager ibackupManager; 8775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final IAudioService iaudioService; 8875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final LockPatternUtils lockPatternUtils; 8975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final StorageManagerForMock storageManager; 9075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final WifiManager wifiManager; 9175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final SettingsForMock settings; 9275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final MockContentResolver contentResolver; 9375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final TelephonyManager telephonyManager; 9475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final AccountManager accountManager; 9575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final AlarmManager alarmManager; 9675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final KeyChain.KeyChainConnection keyChainConnection; 9775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov /** Note this is a partial mock, not a real mock. */ 9875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final PackageManager packageManager; 9975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final BuildMock buildMock = new BuildMock(); 10075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final File dataDir; 10175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 10275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public MockSystemServices(Context realContext, String name) { 10375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov dataDir = new File(realContext.getCacheDir(), name); 10475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov DpmTestUtils.clearDir(dataDir); 10575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 10675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov environment = mock(EnvironmentForMock.class); 10775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov systemProperties = mock(SystemPropertiesForMock.class); 10875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov userManager = mock(UserManager.class); 10975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov userManagerInternal = mock(UserManagerInternal.class); 11075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov userManagerForMock = mock(UserManagerForMock.class); 11175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov packageManagerInternal = mock(PackageManagerInternal.class); 11275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov powerManager = mock(PowerManagerForMock.class); 11375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov powerManagerInternal = mock(PowerManagerInternal.class); 11475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov recoverySystem = mock(RecoverySystemForMock.class); 11575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov notificationManager = mock(NotificationManager.class); 11675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov iipConnectivityMetrics = mock(IIpConnectivityMetrics.class); 11775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov iwindowManager = mock(IWindowManager.class); 11875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov iactivityManager = mock(IActivityManager.class); 11975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov ipackageManager = mock(IPackageManager.class); 12075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov ibackupManager = mock(IBackupManager.class); 12175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov iaudioService = mock(IAudioService.class); 12275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov lockPatternUtils = mock(LockPatternUtils.class); 12375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov storageManager = mock(StorageManagerForMock.class); 12475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov wifiManager = mock(WifiManager.class); 12575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov settings = mock(SettingsForMock.class); 12675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov telephonyManager = mock(TelephonyManager.class); 12775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov accountManager = mock(AccountManager.class); 12875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov alarmManager = mock(AlarmManager.class); 12975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS); 13075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 13175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // Package manager is huge, so we use a partial mock instead. 13275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov packageManager = spy(realContext.getPackageManager()); 13375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 13475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov contentResolver = new MockContentResolver(); 1359a18f5fa409d99e09bed57626d5a600142fd7009Christine Franks contentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider()); 13675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 13775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // Add the system user with a fake profile group already set up (this can happen in the real 13875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // world if a managed profile is added and then removed). 13975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov systemUserDataDir = 14075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM); 14175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 14275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // System user is always running. 14375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov setUserRunning(UserHandle.USER_SYSTEM, true); 14475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 14575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 14675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */ 14775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov private final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>(); 14875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 14975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov private final ArrayList<UserInfo> mUserInfos = new ArrayList<>(); 15075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 15175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov private final List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>(); 15275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 15375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void registerReceiver( 15475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov BroadcastReceiver receiver, IntentFilter filter, Handler scheduler) { 15575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler)); 15675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 15775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 15875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void unregisterReceiver(BroadcastReceiver receiver) { 15975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov mBroadcastReceivers.removeIf(r -> r.receiver == receiver); 16075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 16175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 16275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public File addUser(int userId, int flags) { 16375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID); 16475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 16575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 16675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public File addUser(int userId, int flags, int profileGroupId) { 16775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // Set up (default) UserInfo for CALLER_USER_HANDLE. 16875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final UserInfo uh = new UserInfo(userId, "user" + userId, flags); 16975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov uh.profileGroupId = profileGroupId; 17075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.getUserInfo(eq(userId))).thenReturn(uh); 17175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 17275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov mUserInfos.add(uh); 17375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.getUsers()).thenReturn(mUserInfos); 17475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos); 17575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true); 17675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.getUserInfo(anyInt())).thenAnswer( 17775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov invocation -> { 17875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final int userId1 = (int) invocation.getArguments()[0]; 17975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return getUserInfo(userId1); 18075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 18175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov ); 18275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.getProfiles(anyInt())).thenAnswer( 18375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov invocation -> { 18475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final int userId12 = (int) invocation.getArguments()[0]; 18575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return getProfiles(userId12); 18675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 18775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov ); 18875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer( 18975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov invocation -> { 19075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final int userId13 = (int) invocation.getArguments()[0]; 19175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov List<UserInfo> profiles = getProfiles(userId13); 19275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return profiles.stream() 19375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov .mapToInt(profile -> profile.id) 19475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov .toArray(); 19575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 19675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov ); 19775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]); 19875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 19975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // Create a data directory. 20075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final File dir = new File(dataDir, "users/" + userId); 20175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov DpmTestUtils.clearDir(dir); 20275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 20375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir); 20475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return dir; 20575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 20675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 20775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void removeUser(int userId) { 20875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov for (int i = 0; i < mUserInfos.size(); i++) { 20975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (mUserInfos.get(i).id == userId) { 21075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov mUserInfos.remove(i); 21175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov break; 21275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 21375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 21475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.getUserInfo(eq(userId))).thenReturn(null); 21575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 21675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false); 21775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 21875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 21975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov private UserInfo getUserInfo(int userId) { 22075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov for (final UserInfo ui : mUserInfos) { 22175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (ui.id == userId) { 22275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return ui; 22375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 22475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 22575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return null; 22675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 22775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 22875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov private List<UserInfo> getProfiles(int userId) { 22975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final ArrayList<UserInfo> ret = new ArrayList<>(); 23075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov UserInfo parent = null; 23175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov for (final UserInfo ui : mUserInfos) { 23275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (ui.id == userId) { 23375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov parent = ui; 23475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov break; 23575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 23675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 23775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (parent == null) { 23875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return ret; 23975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 24075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov for (final UserInfo ui : mUserInfos) { 24175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (ui == parent 24275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 24375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov && ui.profileGroupId == parent.profileGroupId) { 24475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov ret.add(ui); 24575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 24675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 24775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return ret; 24875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 24975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 25075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov /** 25175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov * Add multiple users at once. They'll all have flag 0. 25275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov */ 25375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void addUsers(int... userIds) { 25475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov for (final int userId : userIds) { 25575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov addUser(userId, 0); 25675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 25775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 25875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 25975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void setUserRunning(int userId, boolean isRunning) { 26075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov when(userManager.isUserRunning(MockUtils.checkUserHandle(userId))) 26175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov .thenReturn(isRunning); 26275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 26375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 26475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void injectBroadcast(Context context, final Intent intent, int userId) { 26575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov //final int userId = UserHandle.getUserId(binder.getCallingUid()); 26675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) { 26775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov receiver.sendBroadcastIfApplicable(context, userId, intent); 26875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 26975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 27075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 27175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void rethrowBackgroundBroadcastExceptions() throws Exception { 27275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) { 27375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final Exception e = receiver.backgroundException.getAndSet(null); 27475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (e != null) { 27575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov throw e; 27675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 27775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 27875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 27975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 28075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void addPackageContext(UserHandle user, Context context) { 28175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (context.getPackageName() == null) { 28275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov throw new NullPointerException("getPackageName() == null"); 28375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 28475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov userPackageContexts.put(new Pair<>(user, context.getPackageName()), context); 28575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 28675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 28775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) 28875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov throws PackageManager.NameNotFoundException { 28975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final Pair<UserHandle, String> key = new Pair<>(user, packageName); 29075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (userPackageContexts.containsKey(key)) { 29175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return userPackageContexts.get(key); 29275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 29375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov throw new UnsupportedOperationException("No package " + packageName + " for user " + user); 29475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 29575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 29675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 29775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public static class EnvironmentForMock { 29875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public File getUserSystemDirectory(int userId) { 29975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return null; 30075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 30175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 30275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 30375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public static class BuildMock { 30475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public boolean isDebuggable = true; 30575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 30675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 30775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public static class PowerManagerForMock { 30875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public PowerManager.WakeLock newWakeLock(int levelAndFlags, String tag) { 30975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return null; 31075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 31175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 31275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void goToSleep(long time, int reason, int flags) { 31375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 31475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 31575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void reboot(String reason) { 31675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 31775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 31875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 31975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public static class RecoverySystemForMock { 320f4f9cec234bf147f0067cef2791a26eaa2cde0a0yinxu public void rebootWipeUserData(boolean shutdown, String reason, boolean force, 321f4f9cec234bf147f0067cef2791a26eaa2cde0a0yinxu boolean wipeEuicc) throws IOException { 32275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 32375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 32475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 32575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public static class SystemPropertiesForMock { 32675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public boolean getBoolean(String key, boolean def) { 32775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return false; 32875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 32975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 33075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public long getLong(String key, long def) { 33175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return 0; 33275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 33375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 33475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public String get(String key, String def) { 33575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return null; 33675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 33775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 33875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public String get(String key) { 33975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return null; 34075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 34175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 34275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void set(String key, String value) { 34375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 34475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 34575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 34675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public static class UserManagerForMock { 34775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public boolean isSplitSystemUser() { 34875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return false; 34975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 35075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 35175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 35275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public static class SettingsForMock { 35375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public int settingsSecureGetIntForUser(String name, int def, int userHandle) { 35475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return 0; 35575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 35675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 35775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public String settingsSecureGetStringForUser(String name, int userHandle) { 35875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return null; 35975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 36075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 36175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void settingsSecurePutIntForUser(String name, int value, int userHandle) { 36275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 36375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 36475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void settingsSecurePutStringForUser(String name, String value, int userHandle) { 36575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 36675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 36775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void settingsGlobalPutStringForUser(String name, String value, int userHandle) { 36875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 36975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 37075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void settingsSecurePutInt(String name, int value) { 37175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 37275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 37375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void settingsGlobalPutInt(String name, int value) { 37475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 37575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 37675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void settingsSecurePutString(String name, String value) { 37775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 37875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 37975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void settingsGlobalPutString(String name, String value) { 38075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 38175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 38275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public int settingsGlobalGetInt(String name, int value) { 38375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return 0; 38475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 38575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 38675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public String settingsGlobalGetString(String name) { 38775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return ""; 38875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 38975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 39075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void securityLogSetLoggingEnabledProperty(boolean enabled) { 39175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 39275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 39375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public boolean securityLogGetLoggingEnabledProperty() { 39475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return false; 39575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 39675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 39775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public boolean securityLogIsLoggingEnabled() { 39875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return false; 39975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 40075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 40175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 40275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public static class StorageManagerForMock { 40375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public boolean isFileBasedEncryptionEnabled() { 40475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return false; 40575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 40675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 40775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public boolean isNonDefaultBlockEncrypted() { 40875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return false; 40975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 41075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 41175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public boolean isEncrypted() { 41275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return false; 41375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 41475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 41575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public boolean isEncryptable() { 41675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov return false; 41775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 41875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 41975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 42075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // We have to keep track of broadcast receivers registered for a given intent ourselves as the 42175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does 42275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // not work. 42375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov private static class BroadcastReceiverRegistration { 42475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final BroadcastReceiver receiver; 42575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final IntentFilter filter; 42675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final Handler scheduler; 42775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 42875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov // Exceptions thrown in a background thread kill the whole test. Save them instead. 42975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public final AtomicReference<Exception> backgroundException = new AtomicReference<>(); 43075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 43175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter, 43275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov Handler scheduler) { 43375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov this.receiver = receiver; 43475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov this.filter = filter; 43575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov this.scheduler = scheduler; 43675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 43775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 43875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov public void sendBroadcastIfApplicable(Context context, int userId, Intent intent) { 43975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult( 44075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 0 /* resultCode */, null /* resultData */, null /* resultExtras */, 44175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId, 44275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov 0 /* flags */); 44375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (filter.match(null, intent, false, "DpmMockContext") > 0) { 44475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov final Runnable send = () -> { 44575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov receiver.setPendingResult(result); 44675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov receiver.onReceive(context, intent); 44775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov }; 44875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov if (scheduler != null) { 44975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov scheduler.post(() -> { 45075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov try { 45175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov send.run(); 45275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } catch (Exception e) { 45375c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov backgroundException.compareAndSet(null, e); 45475c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 45575c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov }); 45675c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } else { 45775c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov send.run(); 45875c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 45975c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 46075c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 46175c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov } 46275c0a891ae2f1170d64b06baeca49908b6183b70Pavel Grafov} 463