DpmMockContext.java revision aff5e9c21c28f21f7a3688d84e747727cf17f382
1/* 2 * Copyright (C) 2015 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 17package com.android.server.devicepolicy; 18 19import android.accounts.Account; 20import android.accounts.AccountManager; 21import android.app.AlarmManager; 22import android.app.IActivityManager; 23import android.app.NotificationManager; 24import android.app.backup.IBackupManager; 25import android.content.BroadcastReceiver; 26import android.content.ContentResolver; 27import android.content.Context; 28import android.content.Intent; 29import android.content.IntentFilter; 30import android.content.pm.ApplicationInfo; 31import android.content.pm.IPackageManager; 32import android.content.pm.PackageManager; 33import android.content.pm.PackageManagerInternal; 34import android.content.pm.UserInfo; 35import android.content.res.Resources; 36import android.media.IAudioService; 37import android.net.IIpConnectivityMetrics; 38import android.net.wifi.WifiManager; 39import android.os.Bundle; 40import android.os.Handler; 41import android.os.PowerManager.WakeLock; 42import android.os.PowerManagerInternal; 43import android.os.UserHandle; 44import android.os.UserManager; 45import android.os.UserManagerInternal; 46import android.security.KeyChain; 47import android.telephony.TelephonyManager; 48import android.test.mock.MockContentResolver; 49import android.test.mock.MockContext; 50import android.util.ArrayMap; 51import android.view.IWindowManager; 52 53import com.android.internal.widget.LockPatternUtils; 54 55import org.junit.Assert; 56import org.mockito.invocation.InvocationOnMock; 57import org.mockito.stubbing.Answer; 58 59import java.io.File; 60import java.io.IOException; 61import java.util.ArrayList; 62import java.util.List; 63import java.util.Map; 64 65import static org.mockito.Matchers.anyBoolean; 66import static org.mockito.Matchers.anyInt; 67import static org.mockito.Matchers.eq; 68import static org.mockito.Mockito.RETURNS_DEEP_STUBS; 69import static org.mockito.Mockito.mock; 70import static org.mockito.Mockito.spy; 71import static org.mockito.Mockito.when; 72 73/** 74 * Context used throughout DPMS tests. 75 */ 76public class DpmMockContext extends MockContext { 77 /** 78 * User-id of a non-system user we use throughout unit tests. 79 */ 80 public static final int CALLER_USER_HANDLE = 20; 81 82 /** 83 * UID corresponding to {@link #CALLER_USER_HANDLE}. 84 */ 85 public static final int CALLER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 20123); 86 87 /** 88 * UID used when a caller is on the system user. 89 */ 90 public static final int CALLER_SYSTEM_USER_UID = 20321; 91 92 /** 93 * PID of the caller. 94 */ 95 public static final int CALLER_PID = 22222; 96 97 /** 98 * UID of the system server. 99 */ 100 public static final int SYSTEM_UID = android.os.Process.SYSTEM_UID; 101 102 /** 103 * PID of the system server. 104 */ 105 public static final int SYSTEM_PID = 11111; 106 107 public static final String ANOTHER_PACKAGE_NAME = "com.another.package.name"; 108 109 public static final int ANOTHER_UID = UserHandle.getUid(UserHandle.USER_SYSTEM, 18434); 110 111 public static class MockBinder { 112 public int callingUid = CALLER_UID; 113 public int callingPid = CALLER_PID; 114 115 public long clearCallingIdentity() { 116 final long token = (((long) callingUid) << 32) | (callingPid); 117 callingUid = SYSTEM_UID; 118 callingPid = SYSTEM_PID; 119 return token; 120 } 121 122 public void restoreCallingIdentity(long token) { 123 callingUid = (int) (token >> 32); 124 callingPid = (int) token; 125 } 126 127 public int getCallingUid() { 128 return callingUid; 129 } 130 131 public int getCallingPid() { 132 return callingPid; 133 } 134 135 public UserHandle getCallingUserHandle() { 136 return new UserHandle(UserHandle.getUserId(getCallingUid())); 137 } 138 139 public boolean isCallerUidMyUid() { 140 return callingUid == SYSTEM_UID; 141 } 142 } 143 144 public static class EnvironmentForMock { 145 public File getUserSystemDirectory(int userId) { 146 return null; 147 } 148 } 149 150 public static class BuildMock { 151 public boolean isDebuggable = true; 152 } 153 154 public static class PowerManagerForMock { 155 public WakeLock newWakeLock(int levelAndFlags, String tag) { 156 return null; 157 } 158 159 public void goToSleep(long time, int reason, int flags) { 160 } 161 162 public void reboot(String reason) { 163 } 164 } 165 166 public static class RecoverySystemForMock { 167 public void rebootWipeUserData( 168 boolean shutdown, String reason, boolean force) throws IOException { 169 } 170 } 171 172 public static class SystemPropertiesForMock { 173 public boolean getBoolean(String key, boolean def) { 174 return false; 175 } 176 177 public long getLong(String key, long def) { 178 return 0; 179 } 180 181 public String get(String key, String def) { 182 return null; 183 } 184 185 public String get(String key) { 186 return null; 187 } 188 189 public void set(String key, String value) { 190 } 191 } 192 193 public static class UserManagerForMock { 194 public boolean isSplitSystemUser() { 195 return false; 196 } 197 } 198 199 public static class SettingsForMock { 200 public int settingsSecureGetIntForUser(String name, int def, int userHandle) { 201 return 0; 202 } 203 204 public String settingsSecureGetStringForUser(String name, int userHandle) { 205 return null; 206 } 207 208 public void settingsSecurePutIntForUser(String name, int value, int userHandle) { 209 } 210 211 public void settingsSecurePutStringForUser(String name, String value, int userHandle) { 212 } 213 214 public void settingsGlobalPutStringForUser(String name, String value, int userHandle) { 215 } 216 217 public void settingsSecurePutInt(String name, int value) { 218 } 219 220 public void settingsGlobalPutInt(String name, int value) { 221 } 222 223 public void settingsSecurePutString(String name, String value) { 224 } 225 226 public void settingsGlobalPutString(String name, String value) { 227 } 228 229 public int settingsGlobalGetInt(String name, int value) { 230 return 0; 231 } 232 233 public void securityLogSetLoggingEnabledProperty(boolean enabled) { 234 } 235 236 public boolean securityLogGetLoggingEnabledProperty() { 237 return false; 238 } 239 240 public boolean securityLogIsLoggingEnabled() { 241 return false; 242 } 243 } 244 245 public static class StorageManagerForMock { 246 public boolean isFileBasedEncryptionEnabled() { 247 return false; 248 } 249 250 public boolean isNonDefaultBlockEncrypted() { 251 return false; 252 } 253 254 public boolean isEncrypted() { 255 return false; 256 } 257 258 public boolean isEncryptable() { 259 return false; 260 } 261 } 262 263 public final Context realTestContext; 264 265 /** 266 * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}. 267 * (Spying on {@code this} instance will confuse mockito somehow and I got weired "wrong number 268 * of arguments" exceptions.) 269 */ 270 public final Context spiedContext; 271 272 public final File dataDir; 273 public final File systemUserDataDir; 274 275 public final MockBinder binder; 276 public final EnvironmentForMock environment; 277 public final Resources resources; 278 public final SystemPropertiesForMock systemProperties; 279 public final UserManager userManager; 280 public final UserManagerInternal userManagerInternal; 281 public final PackageManagerInternal packageManagerInternal; 282 public final UserManagerForMock userManagerForMock; 283 public final PowerManagerForMock powerManager; 284 public final PowerManagerInternal powerManagerInternal; 285 public final RecoverySystemForMock recoverySystem; 286 public final NotificationManager notificationManager; 287 public final IIpConnectivityMetrics iipConnectivityMetrics; 288 public final IWindowManager iwindowManager; 289 public final IActivityManager iactivityManager; 290 public final IPackageManager ipackageManager; 291 public final IBackupManager ibackupManager; 292 public final IAudioService iaudioService; 293 public final LockPatternUtils lockPatternUtils; 294 public final StorageManagerForMock storageManager; 295 public final WifiManager wifiManager; 296 public final SettingsForMock settings; 297 public final MockContentResolver contentResolver; 298 public final TelephonyManager telephonyManager; 299 public final AccountManager accountManager; 300 public final AlarmManager alarmManager; 301 public final KeyChain.KeyChainConnection keyChainConnection; 302 303 /** Note this is a partial mock, not a real mock. */ 304 public final PackageManager packageManager; 305 306 public final List<String> callerPermissions = new ArrayList<>(); 307 308 private final ArrayList<UserInfo> mUserInfos = new ArrayList<>(); 309 310 public final BuildMock buildMock = new BuildMock(); 311 312 /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */ 313 public final Map<UserHandle, Context> userContexts = new ArrayMap<>(); 314 315 public String packageName = null; 316 317 public ApplicationInfo applicationInfo = null; 318 319 public DpmMockContext(Context context, File dataDir) { 320 realTestContext = context; 321 322 this.dataDir = dataDir; 323 DpmTestUtils.clearDir(dataDir); 324 325 binder = new MockBinder(); 326 environment = mock(EnvironmentForMock.class); 327 resources = mock(Resources.class); 328 systemProperties = mock(SystemPropertiesForMock.class); 329 userManager = mock(UserManager.class); 330 userManagerInternal = mock(UserManagerInternal.class); 331 userManagerForMock = mock(UserManagerForMock.class); 332 packageManagerInternal = mock(PackageManagerInternal.class); 333 powerManager = mock(PowerManagerForMock.class); 334 powerManagerInternal = mock(PowerManagerInternal.class); 335 recoverySystem = mock(RecoverySystemForMock.class); 336 notificationManager = mock(NotificationManager.class); 337 iipConnectivityMetrics = mock(IIpConnectivityMetrics.class); 338 iwindowManager = mock(IWindowManager.class); 339 iactivityManager = mock(IActivityManager.class); 340 ipackageManager = mock(IPackageManager.class); 341 ibackupManager = mock(IBackupManager.class); 342 iaudioService = mock(IAudioService.class); 343 lockPatternUtils = mock(LockPatternUtils.class); 344 storageManager = mock(StorageManagerForMock.class); 345 wifiManager = mock(WifiManager.class); 346 settings = mock(SettingsForMock.class); 347 telephonyManager = mock(TelephonyManager.class); 348 accountManager = mock(AccountManager.class); 349 alarmManager = mock(AlarmManager.class); 350 keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS); 351 352 // Package manager is huge, so we use a partial mock instead. 353 packageManager = spy(context.getPackageManager()); 354 355 spiedContext = mock(Context.class); 356 357 contentResolver = new MockContentResolver(); 358 359 // Add the system user with a fake profile group already set up (this can happen in the real 360 // world if a managed profile is added and then removed). 361 systemUserDataDir = 362 addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM); 363 364 // System user is always running. 365 setUserRunning(UserHandle.USER_SYSTEM, true); 366 } 367 368 public File addUser(int userId, int flags) { 369 return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID); 370 } 371 372 public File addUser(int userId, int flags, int profileGroupId) { 373 // Set up (default) UserInfo for CALLER_USER_HANDLE. 374 final UserInfo uh = new UserInfo(userId, "user" + userId, flags); 375 uh.profileGroupId = profileGroupId; 376 when(userManager.getUserInfo(eq(userId))).thenReturn(uh); 377 378 mUserInfos.add(uh); 379 when(userManager.getUsers()).thenReturn(mUserInfos); 380 when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos); 381 when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true); 382 when(userManager.getUserInfo(anyInt())).thenAnswer( 383 new Answer<UserInfo>() { 384 @Override 385 public UserInfo answer(InvocationOnMock invocation) throws Throwable { 386 final int userId = (int) invocation.getArguments()[0]; 387 return getUserInfo(userId); 388 } 389 } 390 ); 391 when(userManager.getProfiles(anyInt())).thenAnswer( 392 new Answer<List<UserInfo>>() { 393 @Override 394 public List<UserInfo> answer(InvocationOnMock invocation) throws Throwable { 395 final int userId = (int) invocation.getArguments()[0]; 396 return getProfiles(userId); 397 } 398 } 399 ); 400 when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer( 401 new Answer<int[]>() { 402 @Override 403 public int[] answer(InvocationOnMock invocation) throws Throwable { 404 final int userId = (int) invocation.getArguments()[0]; 405 List<UserInfo> profiles = getProfiles(userId); 406 return profiles.stream() 407 .mapToInt(profile -> profile.id) 408 .toArray(); 409 } 410 } 411 ); 412 when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]); 413 414 // Create a data directory. 415 final File dir = new File(dataDir, "user" + userId); 416 DpmTestUtils.clearDir(dir); 417 418 when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir); 419 return dir; 420 } 421 422 public void removeUser(int userId) { 423 for (int i = 0; i < mUserInfos.size(); i++) { 424 if (mUserInfos.get(i).id == userId) { 425 mUserInfos.remove(i); 426 break; 427 } 428 } 429 when(userManager.getUserInfo(eq(userId))).thenReturn(null); 430 431 when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false); 432 } 433 434 private UserInfo getUserInfo(int userId) { 435 for (UserInfo ui : mUserInfos) { 436 if (ui.id == userId) { 437 return ui; 438 } 439 } 440 return null; 441 } 442 443 private List<UserInfo> getProfiles(int userId) { 444 final ArrayList<UserInfo> ret = new ArrayList<UserInfo>(); 445 UserInfo parent = null; 446 for (UserInfo ui : mUserInfos) { 447 if (ui.id == userId) { 448 parent = ui; 449 break; 450 } 451 } 452 if (parent == null) { 453 return ret; 454 } 455 for (UserInfo ui : mUserInfos) { 456 if (ui == parent 457 || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 458 && ui.profileGroupId == parent.profileGroupId) { 459 ret.add(ui); 460 } 461 } 462 return ret; 463 } 464 465 /** 466 * Add multiple users at once. They'll all have flag 0. 467 */ 468 public void addUsers(int... userIds) { 469 for (int userId : userIds) { 470 addUser(userId, 0); 471 } 472 } 473 474 public void setUserRunning(int userId, boolean isRunning) { 475 when(userManager.isUserRunning(MockUtils.checkUserHandle(userId))) 476 .thenReturn(isRunning); 477 } 478 479 @Override 480 public Resources getResources() { 481 return resources; 482 } 483 484 @Override 485 public Resources.Theme getTheme() { 486 return spiedContext.getTheme(); 487 } 488 489 @Override 490 public String getPackageName() { 491 if (packageName != null) { 492 return packageName; 493 } 494 return super.getPackageName(); 495 } 496 497 @Override 498 public ApplicationInfo getApplicationInfo() { 499 if (applicationInfo != null) { 500 return applicationInfo; 501 } 502 return super.getApplicationInfo(); 503 } 504 505 @Override 506 public Object getSystemService(String name) { 507 switch (name) { 508 case Context.ALARM_SERVICE: 509 return alarmManager; 510 case Context.USER_SERVICE: 511 return userManager; 512 case Context.POWER_SERVICE: 513 return powerManager; 514 case Context.WIFI_SERVICE: 515 return wifiManager; 516 case Context.ACCOUNT_SERVICE: 517 return accountManager; 518 } 519 throw new UnsupportedOperationException(); 520 } 521 522 @Override 523 public String getSystemServiceName(Class<?> serviceClass) { 524 return realTestContext.getSystemServiceName(serviceClass); 525 } 526 527 @Override 528 public PackageManager getPackageManager() { 529 return packageManager; 530 } 531 532 @Override 533 public void enforceCallingOrSelfPermission(String permission, String message) { 534 if (binder.getCallingUid() == SYSTEM_UID) { 535 return; // Assume system has all permissions. 536 } 537 if (!callerPermissions.contains(permission)) { 538 throw new SecurityException("Caller doesn't have " + permission + " : " + message); 539 } 540 } 541 542 @Override 543 public void sendBroadcast(Intent intent) { 544 spiedContext.sendBroadcast(intent); 545 } 546 547 @Override 548 public void sendBroadcast(Intent intent, String receiverPermission) { 549 spiedContext.sendBroadcast(intent, receiverPermission); 550 } 551 552 @Override 553 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) { 554 spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions); 555 } 556 557 @Override 558 public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) { 559 spiedContext.sendBroadcast(intent, receiverPermission, options); 560 } 561 562 @Override 563 public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { 564 spiedContext.sendBroadcast(intent, receiverPermission, appOp); 565 } 566 567 @Override 568 public void sendOrderedBroadcast(Intent intent, String receiverPermission) { 569 spiedContext.sendOrderedBroadcast(intent, receiverPermission); 570 } 571 572 @Override 573 public void sendOrderedBroadcast(Intent intent, String receiverPermission, 574 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 575 String initialData, Bundle initialExtras) { 576 spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, 577 initialCode, initialData, initialExtras); 578 } 579 580 @Override 581 public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, 582 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 583 String initialData, Bundle initialExtras) { 584 spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver, 585 scheduler, 586 initialCode, initialData, initialExtras); 587 } 588 589 @Override 590 public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, 591 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 592 String initialData, Bundle initialExtras) { 593 spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver, 594 scheduler, 595 initialCode, initialData, initialExtras); 596 } 597 598 @Override 599 public void sendBroadcastAsUser(Intent intent, UserHandle user) { 600 if (binder.callingPid != SYSTEM_PID) { 601 // Unless called as the system process, can only call if the target user is the 602 // calling user. 603 // (The actual check is more complex; we may need to change it later.) 604 Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier()); 605 } 606 607 spiedContext.sendBroadcastAsUser(intent, user); 608 } 609 610 @Override 611 public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) { 612 spiedContext.sendBroadcastAsUser(intent, user, receiverPermission); 613 } 614 615 @Override 616 public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, 617 int appOp) { 618 spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp); 619 } 620 621 @Override 622 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 623 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, 624 int initialCode, String initialData, Bundle initialExtras) { 625 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver, 626 scheduler, initialCode, initialData, initialExtras); 627 resultReceiver.onReceive(spiedContext, intent); 628 } 629 630 @Override 631 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 632 String receiverPermission, int appOp, BroadcastReceiver resultReceiver, 633 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 634 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, 635 resultReceiver, 636 scheduler, initialCode, initialData, initialExtras); 637 } 638 639 @Override 640 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 641 String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, 642 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 643 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options, 644 resultReceiver, scheduler, initialCode, initialData, initialExtras); 645 } 646 647 @Override 648 public void sendStickyBroadcast(Intent intent) { 649 spiedContext.sendStickyBroadcast(intent); 650 } 651 652 @Override 653 public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, 654 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 655 spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, 656 initialData, initialExtras); 657 } 658 659 @Override 660 public void removeStickyBroadcast(Intent intent) { 661 spiedContext.removeStickyBroadcast(intent); 662 } 663 664 @Override 665 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { 666 spiedContext.sendStickyBroadcastAsUser(intent, user); 667 } 668 669 @Override 670 public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, 671 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 672 String initialData, Bundle initialExtras) { 673 spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode, 674 initialData, initialExtras); 675 } 676 677 @Override 678 public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) { 679 spiedContext.removeStickyBroadcastAsUser(intent, user); 680 } 681 682 @Override 683 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 684 return spiedContext.registerReceiver(receiver, filter); 685 } 686 687 @Override 688 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 689 String broadcastPermission, Handler scheduler) { 690 return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler); 691 } 692 693 @Override 694 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, 695 IntentFilter filter, String broadcastPermission, Handler scheduler) { 696 return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission, 697 scheduler); 698 } 699 700 @Override 701 public void unregisterReceiver(BroadcastReceiver receiver) { 702 spiedContext.unregisterReceiver(receiver); 703 } 704 705 @Override 706 public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) 707 throws PackageManager.NameNotFoundException { 708 if (!userContexts.containsKey(user)) { 709 return super.createPackageContextAsUser(packageName, flags, user); 710 } 711 if (!getPackageName().equals(packageName)) { 712 throw new UnsupportedOperationException( 713 "Creating a context as another package is not implemented"); 714 } 715 return userContexts.get(user); 716 } 717 718 @Override 719 public ContentResolver getContentResolver() { 720 return contentResolver; 721 } 722 723 @Override 724 public int getUserId() { 725 return UserHandle.getUserId(binder.getCallingUid()); 726 } 727} 728