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