DpmMockContext.java revision 7f5c91c6bce6a8ff2414549219a321a98a98ab31
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 void settingsSecurePutIntForUser(String name, int value, int userHandle) { 205 } 206 207 public void settingsSecurePutStringForUser(String name, String value, int userHandle) { 208 } 209 210 public void settingsGlobalPutStringForUser(String name, String value, int userHandle) { 211 } 212 213 public void settingsSecurePutInt(String name, int value) { 214 } 215 216 public void settingsGlobalPutInt(String name, int value) { 217 } 218 219 public void settingsSecurePutString(String name, String value) { 220 } 221 222 public void settingsGlobalPutString(String name, String value) { 223 } 224 225 public int settingsGlobalGetInt(String name, int value) { 226 return 0; 227 } 228 229 public void securityLogSetLoggingEnabledProperty(boolean enabled) { 230 } 231 232 public boolean securityLogGetLoggingEnabledProperty() { 233 return false; 234 } 235 236 public boolean securityLogIsLoggingEnabled() { 237 return false; 238 } 239 } 240 241 public static class StorageManagerForMock { 242 public boolean isFileBasedEncryptionEnabled() { 243 return false; 244 } 245 246 public boolean isNonDefaultBlockEncrypted() { 247 return false; 248 } 249 250 public boolean isEncrypted() { 251 return false; 252 } 253 254 public boolean isEncryptable() { 255 return false; 256 } 257 } 258 259 public final Context realTestContext; 260 261 /** 262 * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}. 263 * (Spying on {@code this} instance will confuse mockito somehow and I got weired "wrong number 264 * of arguments" exceptions.) 265 */ 266 public final Context spiedContext; 267 268 public final File dataDir; 269 public final File systemUserDataDir; 270 271 public final MockBinder binder; 272 public final EnvironmentForMock environment; 273 public final Resources resources; 274 public final SystemPropertiesForMock systemProperties; 275 public final UserManager userManager; 276 public final UserManagerInternal userManagerInternal; 277 public final PackageManagerInternal packageManagerInternal; 278 public final UserManagerForMock userManagerForMock; 279 public final PowerManagerForMock powerManager; 280 public final PowerManagerInternal powerManagerInternal; 281 public final RecoverySystemForMock recoverySystem; 282 public final NotificationManager notificationManager; 283 public final IIpConnectivityMetrics iipConnectivityMetrics; 284 public final IWindowManager iwindowManager; 285 public final IActivityManager iactivityManager; 286 public final IPackageManager ipackageManager; 287 public final IBackupManager ibackupManager; 288 public final IAudioService iaudioService; 289 public final LockPatternUtils lockPatternUtils; 290 public final StorageManagerForMock storageManager; 291 public final WifiManager wifiManager; 292 public final SettingsForMock settings; 293 public final MockContentResolver contentResolver; 294 public final TelephonyManager telephonyManager; 295 public final AccountManager accountManager; 296 public final AlarmManager alarmManager; 297 public final KeyChain.KeyChainConnection keyChainConnection; 298 299 /** Note this is a partial mock, not a real mock. */ 300 public final PackageManager packageManager; 301 302 public final List<String> callerPermissions = new ArrayList<>(); 303 304 private final ArrayList<UserInfo> mUserInfos = new ArrayList<>(); 305 306 public final BuildMock buildMock = new BuildMock(); 307 308 /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */ 309 public final Map<UserHandle, Context> userContexts = new ArrayMap<>(); 310 311 public String packageName = null; 312 313 public ApplicationInfo applicationInfo = null; 314 315 public DpmMockContext(Context context, File dataDir) { 316 realTestContext = context; 317 318 this.dataDir = dataDir; 319 DpmTestUtils.clearDir(dataDir); 320 321 binder = new MockBinder(); 322 environment = mock(EnvironmentForMock.class); 323 resources = mock(Resources.class); 324 systemProperties = mock(SystemPropertiesForMock.class); 325 userManager = mock(UserManager.class); 326 userManagerInternal = mock(UserManagerInternal.class); 327 userManagerForMock = mock(UserManagerForMock.class); 328 packageManagerInternal = mock(PackageManagerInternal.class); 329 powerManager = mock(PowerManagerForMock.class); 330 powerManagerInternal = mock(PowerManagerInternal.class); 331 recoverySystem = mock(RecoverySystemForMock.class); 332 notificationManager = mock(NotificationManager.class); 333 iipConnectivityMetrics = mock(IIpConnectivityMetrics.class); 334 iwindowManager = mock(IWindowManager.class); 335 iactivityManager = mock(IActivityManager.class); 336 ipackageManager = mock(IPackageManager.class); 337 ibackupManager = mock(IBackupManager.class); 338 iaudioService = mock(IAudioService.class); 339 lockPatternUtils = mock(LockPatternUtils.class); 340 storageManager = mock(StorageManagerForMock.class); 341 wifiManager = mock(WifiManager.class); 342 settings = mock(SettingsForMock.class); 343 telephonyManager = mock(TelephonyManager.class); 344 accountManager = mock(AccountManager.class); 345 alarmManager = mock(AlarmManager.class); 346 keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS); 347 348 // Package manager is huge, so we use a partial mock instead. 349 packageManager = spy(context.getPackageManager()); 350 351 spiedContext = mock(Context.class); 352 353 contentResolver = new MockContentResolver(); 354 355 // Add the system user with a fake profile group already set up (this can happen in the real 356 // world if a managed profile is added and then removed). 357 systemUserDataDir = 358 addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM); 359 360 // System user is always running. 361 setUserRunning(UserHandle.USER_SYSTEM, true); 362 } 363 364 public File addUser(int userId, int flags) { 365 return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID); 366 } 367 368 public File addUser(int userId, int flags, int profileGroupId) { 369 // Set up (default) UserInfo for CALLER_USER_HANDLE. 370 final UserInfo uh = new UserInfo(userId, "user" + userId, flags); 371 uh.profileGroupId = profileGroupId; 372 when(userManager.getUserInfo(eq(userId))).thenReturn(uh); 373 374 mUserInfos.add(uh); 375 when(userManager.getUsers()).thenReturn(mUserInfos); 376 when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos); 377 when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true); 378 when(userManager.getUserInfo(anyInt())).thenAnswer( 379 new Answer<UserInfo>() { 380 @Override 381 public UserInfo answer(InvocationOnMock invocation) throws Throwable { 382 final int userId = (int) invocation.getArguments()[0]; 383 return getUserInfo(userId); 384 } 385 } 386 ); 387 when(userManager.getProfiles(anyInt())).thenAnswer( 388 new Answer<List<UserInfo>>() { 389 @Override 390 public List<UserInfo> answer(InvocationOnMock invocation) throws Throwable { 391 final int userId = (int) invocation.getArguments()[0]; 392 return getProfiles(userId); 393 } 394 } 395 ); 396 when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer( 397 new Answer<int[]>() { 398 @Override 399 public int[] answer(InvocationOnMock invocation) throws Throwable { 400 final int userId = (int) invocation.getArguments()[0]; 401 List<UserInfo> profiles = getProfiles(userId); 402 return profiles.stream() 403 .mapToInt(profile -> profile.id) 404 .toArray(); 405 } 406 } 407 ); 408 when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]); 409 410 // Create a data directory. 411 final File dir = new File(dataDir, "user" + userId); 412 DpmTestUtils.clearDir(dir); 413 414 when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir); 415 return dir; 416 } 417 418 public void removeUser(int userId) { 419 for (int i = 0; i < mUserInfos.size(); i++) { 420 if (mUserInfos.get(i).id == userId) { 421 mUserInfos.remove(i); 422 break; 423 } 424 } 425 when(userManager.getUserInfo(eq(userId))).thenReturn(null); 426 427 when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false); 428 } 429 430 private UserInfo getUserInfo(int userId) { 431 for (UserInfo ui : mUserInfos) { 432 if (ui.id == userId) { 433 return ui; 434 } 435 } 436 return null; 437 } 438 439 private List<UserInfo> getProfiles(int userId) { 440 final ArrayList<UserInfo> ret = new ArrayList<UserInfo>(); 441 UserInfo parent = null; 442 for (UserInfo ui : mUserInfos) { 443 if (ui.id == userId) { 444 parent = ui; 445 break; 446 } 447 } 448 if (parent == null) { 449 return ret; 450 } 451 for (UserInfo ui : mUserInfos) { 452 if (ui == parent 453 || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID 454 && ui.profileGroupId == parent.profileGroupId) { 455 ret.add(ui); 456 } 457 } 458 return ret; 459 } 460 461 /** 462 * Add multiple users at once. They'll all have flag 0. 463 */ 464 public void addUsers(int... userIds) { 465 for (int userId : userIds) { 466 addUser(userId, 0); 467 } 468 } 469 470 public void setUserRunning(int userId, boolean isRunning) { 471 when(userManager.isUserRunning(MockUtils.checkUserHandle(userId))) 472 .thenReturn(isRunning); 473 } 474 475 @Override 476 public Resources getResources() { 477 return resources; 478 } 479 480 @Override 481 public Resources.Theme getTheme() { 482 return spiedContext.getTheme(); 483 } 484 485 @Override 486 public String getPackageName() { 487 if (packageName != null) { 488 return packageName; 489 } 490 return super.getPackageName(); 491 } 492 493 @Override 494 public ApplicationInfo getApplicationInfo() { 495 if (applicationInfo != null) { 496 return applicationInfo; 497 } 498 return super.getApplicationInfo(); 499 } 500 501 @Override 502 public Object getSystemService(String name) { 503 switch (name) { 504 case Context.ALARM_SERVICE: 505 return alarmManager; 506 case Context.USER_SERVICE: 507 return userManager; 508 case Context.POWER_SERVICE: 509 return powerManager; 510 case Context.WIFI_SERVICE: 511 return wifiManager; 512 case Context.ACCOUNT_SERVICE: 513 return accountManager; 514 } 515 throw new UnsupportedOperationException(); 516 } 517 518 @Override 519 public String getSystemServiceName(Class<?> serviceClass) { 520 return realTestContext.getSystemServiceName(serviceClass); 521 } 522 523 @Override 524 public PackageManager getPackageManager() { 525 return packageManager; 526 } 527 528 @Override 529 public void enforceCallingOrSelfPermission(String permission, String message) { 530 if (binder.getCallingUid() == SYSTEM_UID) { 531 return; // Assume system has all permissions. 532 } 533 if (!callerPermissions.contains(permission)) { 534 throw new SecurityException("Caller doesn't have " + permission + " : " + message); 535 } 536 } 537 538 @Override 539 public void sendBroadcast(Intent intent) { 540 spiedContext.sendBroadcast(intent); 541 } 542 543 @Override 544 public void sendBroadcast(Intent intent, String receiverPermission) { 545 spiedContext.sendBroadcast(intent, receiverPermission); 546 } 547 548 @Override 549 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) { 550 spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions); 551 } 552 553 @Override 554 public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) { 555 spiedContext.sendBroadcast(intent, receiverPermission, options); 556 } 557 558 @Override 559 public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { 560 spiedContext.sendBroadcast(intent, receiverPermission, appOp); 561 } 562 563 @Override 564 public void sendOrderedBroadcast(Intent intent, String receiverPermission) { 565 spiedContext.sendOrderedBroadcast(intent, receiverPermission); 566 } 567 568 @Override 569 public void sendOrderedBroadcast(Intent intent, String receiverPermission, 570 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 571 String initialData, Bundle initialExtras) { 572 spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, 573 initialCode, initialData, initialExtras); 574 } 575 576 @Override 577 public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, 578 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 579 String initialData, Bundle initialExtras) { 580 spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver, 581 scheduler, 582 initialCode, initialData, initialExtras); 583 } 584 585 @Override 586 public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, 587 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 588 String initialData, Bundle initialExtras) { 589 spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver, 590 scheduler, 591 initialCode, initialData, initialExtras); 592 } 593 594 @Override 595 public void sendBroadcastAsUser(Intent intent, UserHandle user) { 596 if (binder.callingPid != SYSTEM_PID) { 597 // Unless called as the system process, can only call if the target user is the 598 // calling user. 599 // (The actual check is more complex; we may need to change it later.) 600 Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier()); 601 } 602 603 spiedContext.sendBroadcastAsUser(intent, user); 604 } 605 606 @Override 607 public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) { 608 spiedContext.sendBroadcastAsUser(intent, user, receiverPermission); 609 } 610 611 @Override 612 public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, 613 int appOp) { 614 spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp); 615 } 616 617 @Override 618 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 619 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, 620 int initialCode, String initialData, Bundle initialExtras) { 621 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver, 622 scheduler, initialCode, initialData, initialExtras); 623 resultReceiver.onReceive(spiedContext, intent); 624 } 625 626 @Override 627 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 628 String receiverPermission, int appOp, BroadcastReceiver resultReceiver, 629 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 630 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, 631 resultReceiver, 632 scheduler, initialCode, initialData, initialExtras); 633 } 634 635 @Override 636 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 637 String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, 638 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 639 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options, 640 resultReceiver, scheduler, initialCode, initialData, initialExtras); 641 } 642 643 @Override 644 public void sendStickyBroadcast(Intent intent) { 645 spiedContext.sendStickyBroadcast(intent); 646 } 647 648 @Override 649 public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, 650 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 651 spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, 652 initialData, initialExtras); 653 } 654 655 @Override 656 public void removeStickyBroadcast(Intent intent) { 657 spiedContext.removeStickyBroadcast(intent); 658 } 659 660 @Override 661 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { 662 spiedContext.sendStickyBroadcastAsUser(intent, user); 663 } 664 665 @Override 666 public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, 667 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 668 String initialData, Bundle initialExtras) { 669 spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode, 670 initialData, initialExtras); 671 } 672 673 @Override 674 public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) { 675 spiedContext.removeStickyBroadcastAsUser(intent, user); 676 } 677 678 @Override 679 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 680 return spiedContext.registerReceiver(receiver, filter); 681 } 682 683 @Override 684 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 685 String broadcastPermission, Handler scheduler) { 686 return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler); 687 } 688 689 @Override 690 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, 691 IntentFilter filter, String broadcastPermission, Handler scheduler) { 692 return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission, 693 scheduler); 694 } 695 696 @Override 697 public void unregisterReceiver(BroadcastReceiver receiver) { 698 spiedContext.unregisterReceiver(receiver); 699 } 700 701 @Override 702 public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) 703 throws PackageManager.NameNotFoundException { 704 if (!userContexts.containsKey(user)) { 705 return super.createPackageContextAsUser(packageName, flags, user); 706 } 707 if (!getPackageName().equals(packageName)) { 708 throw new UnsupportedOperationException( 709 "Creating a context as another package is not implemented"); 710 } 711 return userContexts.get(user); 712 } 713 714 @Override 715 public ContentResolver getContentResolver() { 716 return contentResolver; 717 } 718 719 @Override 720 public int getUserId() { 721 return UserHandle.getUserId(binder.getCallingUid()); 722 } 723} 724