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