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