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 static org.mockito.Mockito.mock; 20 import static org.mockito.Mockito.when; 21 22 import android.annotation.Nullable; 23 import android.app.AppOpsManager; 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.ApplicationInfo; 30 import android.content.pm.PackageManager; 31 import android.content.res.Resources; 32 import android.os.Bundle; 33 import android.os.Handler; 34 import android.os.UserHandle; 35 import android.test.mock.MockContext; 36 import android.util.ArrayMap; 37 import android.util.DisplayMetrics; 38 import android.util.ExceptionUtils; 39 40 import androidx.annotation.NonNull; 41 42 import com.android.internal.util.FunctionalUtils; 43 import com.android.server.pm.UserManagerInternal; 44 45 import org.junit.Assert; 46 47 import java.util.ArrayList; 48 import java.util.List; 49 import java.util.Map; 50 51 /** 52 * Context used throughout DPMS tests. 53 */ 54 public class DpmMockContext extends MockContext { 55 /** 56 * User-id of a non-system user we use throughout unit tests. 57 */ 58 public static final int CALLER_USER_HANDLE = 20; 59 60 /** 61 * UID corresponding to {@link #CALLER_USER_HANDLE}. 62 */ 63 public static final int CALLER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 20123); 64 65 /** 66 * UID corresponding to {@link #CALLER_USER_HANDLE}. 67 */ 68 public static final int CALLER_MANAGED_PROVISIONING_UID = UserHandle.getUid(CALLER_USER_HANDLE, 69 20125); 70 71 /** 72 * UID used when a caller is on the system user. 73 */ 74 public static final int CALLER_SYSTEM_USER_UID = 20321; 75 76 /** 77 * PID of the caller. 78 */ 79 public static final int CALLER_PID = 22222; 80 81 /** 82 * UID of the system server. 83 */ 84 public static final int SYSTEM_UID = android.os.Process.SYSTEM_UID; 85 86 /** 87 * PID of the system server. 88 */ 89 public static final int SYSTEM_PID = 11111; 90 91 public static final String ANOTHER_PACKAGE_NAME = "com.another.package.name"; 92 public static final int ANOTHER_UID = UserHandle.getUid(UserHandle.USER_SYSTEM, 18434); 93 94 public static final String DELEGATE_PACKAGE_NAME = "com.delegate.package.name"; 95 public static final int DELEGATE_CERT_INSTALLER_UID = UserHandle.getUid(UserHandle.USER_SYSTEM, 96 18437); 97 98 private final MockSystemServices mMockSystemServices; 99 100 public static class MockBinder { 101 public int callingUid = CALLER_UID; 102 public int callingPid = CALLER_PID; 103 public final Map<Integer, List<String>> callingPermissions = new ArrayMap<>(); 104 clearCallingIdentity()105 public long clearCallingIdentity() { 106 final long token = (((long) callingUid) << 32) | (callingPid); 107 callingUid = SYSTEM_UID; 108 callingPid = SYSTEM_PID; 109 return token; 110 } 111 restoreCallingIdentity(long token)112 public void restoreCallingIdentity(long token) { 113 callingUid = (int) (token >> 32); 114 callingPid = (int) token; 115 } 116 withCleanCallingIdentity(@onNull FunctionalUtils.ThrowingRunnable action)117 public void withCleanCallingIdentity(@NonNull FunctionalUtils.ThrowingRunnable action) { 118 final long callingIdentity = clearCallingIdentity(); 119 Throwable throwableToPropagate = null; 120 try { 121 action.runOrThrow(); 122 } catch (Throwable throwable) { 123 throwableToPropagate = throwable; 124 } finally { 125 restoreCallingIdentity(callingIdentity); 126 if (throwableToPropagate != null) { 127 throw ExceptionUtils.propagate(throwableToPropagate); 128 } 129 } 130 } 131 getCallingUid()132 public int getCallingUid() { 133 return callingUid; 134 } 135 getCallingPid()136 public int getCallingPid() { 137 return callingPid; 138 } 139 getCallingUserHandle()140 public UserHandle getCallingUserHandle() { 141 return new UserHandle(UserHandle.getUserId(getCallingUid())); 142 } 143 isCallerUidMyUid()144 public boolean isCallerUidMyUid() { 145 return callingUid == SYSTEM_UID; 146 } 147 } 148 149 private final Context realTestContext; 150 151 /** 152 * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}. 153 * (Spying on {@code this} instance will confuse mockito somehow and I got weired "wrong number 154 * of arguments" exceptions.) 155 */ 156 public final Context spiedContext; 157 158 public final MockBinder binder; 159 public final Resources resources; 160 161 /** TODO: Migrate everything to use {@link #permissions} to avoid confusion. */ 162 @Deprecated 163 public final List<String> callerPermissions = new ArrayList<>(); 164 165 /** Less confusing alias for {@link #callerPermissions}. */ 166 public final List<String> permissions = callerPermissions; 167 168 public String packageName = null; 169 170 public ApplicationInfo applicationInfo = null; 171 DpmMockContext(MockSystemServices mockSystemServices, Context context)172 public DpmMockContext(MockSystemServices mockSystemServices, Context context) { 173 mMockSystemServices = mockSystemServices; 174 realTestContext = context; 175 176 binder = new MockBinder(); 177 resources = mock(Resources.class); 178 spiedContext = mock(Context.class); 179 180 // Set up density for notification building 181 DisplayMetrics displayMetrics = mock(DisplayMetrics.class); 182 displayMetrics.density = 2.25f; 183 when(resources.getDisplayMetrics()).thenReturn(displayMetrics); 184 } 185 186 @Override getResources()187 public Resources getResources() { 188 return resources; 189 } 190 191 @Override getTheme()192 public Resources.Theme getTheme() { 193 return spiedContext.getTheme(); 194 } 195 196 @Override getPackageName()197 public String getPackageName() { 198 if (packageName != null) { 199 return packageName; 200 } 201 return super.getPackageName(); 202 } 203 204 @Override getApplicationInfo()205 public ApplicationInfo getApplicationInfo() { 206 if (applicationInfo != null) { 207 return applicationInfo; 208 } 209 return super.getApplicationInfo(); 210 } 211 212 @Override getSystemService(String name)213 public Object getSystemService(String name) { 214 switch (name) { 215 case Context.ALARM_SERVICE: 216 return mMockSystemServices.alarmManager; 217 case Context.USER_SERVICE: 218 return mMockSystemServices.userManager; 219 case Context.POWER_SERVICE: 220 return mMockSystemServices.powerManager; 221 case Context.WIFI_SERVICE: 222 return mMockSystemServices.wifiManager; 223 case Context.ACCOUNT_SERVICE: 224 return mMockSystemServices.accountManager; 225 case Context.TELEPHONY_SERVICE: 226 return mMockSystemServices.telephonyManager; 227 case Context.CONNECTIVITY_SERVICE: 228 return mMockSystemServices.connectivityManager; 229 case Context.APP_OPS_SERVICE: 230 return mMockSystemServices.appOpsManager; 231 case Context.CROSS_PROFILE_APPS_SERVICE: 232 return mMockSystemServices.crossProfileApps; 233 case Context.VPN_MANAGEMENT_SERVICE: 234 return mMockSystemServices.vpnManager; 235 } 236 throw new UnsupportedOperationException(); 237 } 238 239 @Override getSystemServiceName(Class<?> serviceClass)240 public String getSystemServiceName(Class<?> serviceClass) { 241 return realTestContext.getSystemServiceName(serviceClass); 242 } 243 244 @Override getPackageManager()245 public PackageManager getPackageManager() { 246 return mMockSystemServices.packageManager; 247 } 248 getUserManagerInternal()249 public UserManagerInternal getUserManagerInternal() { 250 return mMockSystemServices.userManagerInternal; 251 } 252 253 @Override enforceCallingOrSelfPermission(String permission, String message)254 public void enforceCallingOrSelfPermission(String permission, String message) { 255 if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) { 256 return; // Assume system has all permissions. 257 } 258 List<String> permissions = binder.callingPermissions.get(binder.getCallingUid()); 259 if (permissions == null) { 260 // TODO: delete the following line. to do this without breaking any tests, first it's 261 // necessary to remove all tests that set it directly. 262 permissions = callerPermissions; 263 // throw new UnsupportedOperationException( 264 // "Caller UID " + binder.getCallingUid() + " doesn't exist"); 265 } 266 if (!permissions.contains(permission)) { 267 throw new SecurityException("Caller doesn't have " + permission + " : " + message); 268 } 269 } 270 271 @Override checkPermission(String permission, int pid, int uid)272 public int checkPermission(String permission, int pid, int uid) { 273 return checkPermission(permission); 274 } 275 276 @Override sendBroadcast(Intent intent)277 public void sendBroadcast(Intent intent) { 278 spiedContext.sendBroadcast(intent); 279 } 280 281 @Override sendBroadcast(Intent intent, String receiverPermission)282 public void sendBroadcast(Intent intent, String receiverPermission) { 283 spiedContext.sendBroadcast(intent, receiverPermission); 284 } 285 286 @Override sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions)287 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) { 288 spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions); 289 } 290 291 @Override sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, Bundle options)292 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, 293 Bundle options) { 294 spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions, options); 295 } 296 297 @Override sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, String[] receiverPermissions)298 public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, 299 String[] receiverPermissions) { 300 spiedContext.sendBroadcastAsUserMultiplePermissions(intent, user, receiverPermissions); 301 } 302 303 @Override sendBroadcast(Intent intent, String receiverPermission, Bundle options)304 public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) { 305 spiedContext.sendBroadcast(intent, receiverPermission, options); 306 } 307 308 @Override sendBroadcast(Intent intent, String receiverPermission, int appOp)309 public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { 310 spiedContext.sendBroadcast(intent, receiverPermission, appOp); 311 } 312 313 @Override sendOrderedBroadcast(Intent intent, String receiverPermission)314 public void sendOrderedBroadcast(Intent intent, String receiverPermission) { 315 spiedContext.sendOrderedBroadcast(intent, receiverPermission); 316 } 317 318 @Override sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)319 public void sendOrderedBroadcast(Intent intent, String receiverPermission, 320 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 321 String initialData, Bundle initialExtras) { 322 spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, 323 initialCode, initialData, initialExtras); 324 } 325 326 @Override sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)327 public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, 328 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 329 String initialData, Bundle initialExtras) { 330 spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver, 331 scheduler, 332 initialCode, initialData, initialExtras); 333 } 334 335 @Override sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)336 public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, 337 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 338 String initialData, Bundle initialExtras) { 339 spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver, 340 scheduler, 341 initialCode, initialData, initialExtras); 342 } 343 344 @Override sendBroadcastAsUser(Intent intent, UserHandle user)345 public void sendBroadcastAsUser(Intent intent, UserHandle user) { 346 if (binder.callingPid != SYSTEM_PID) { 347 // Unless called as the system process, can only call if the target user is the 348 // calling user. 349 // (The actual check is more complex; we may need to change it later.) 350 Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier()); 351 } 352 353 spiedContext.sendBroadcastAsUser(intent, user); 354 } 355 356 @Override sendBroadcastAsUser(Intent intent, UserHandle user, @Nullable String receiverPermission, @Nullable Bundle options)357 public void sendBroadcastAsUser(Intent intent, 358 UserHandle user, @Nullable String receiverPermission, @Nullable Bundle options) { 359 spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, options); 360 } 361 362 @Override sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission)363 public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) { 364 spiedContext.sendBroadcastAsUser(intent, user, receiverPermission); 365 } 366 367 @Override sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp)368 public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, 369 int appOp) { 370 spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp); 371 } 372 373 @Override sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)374 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 375 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, 376 int initialCode, String initialData, Bundle initialExtras) { 377 sendOrderedBroadcastAsUser( 378 intent, user, receiverPermission, AppOpsManager.OP_NONE, resultReceiver, 379 scheduler, initialCode, initialData, initialExtras); 380 } 381 382 @Override sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)383 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 384 String receiverPermission, int appOp, BroadcastReceiver resultReceiver, 385 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 386 sendOrderedBroadcastAsUser( 387 intent, user, receiverPermission, appOp, null, resultReceiver, 388 scheduler, initialCode, initialData, initialExtras); 389 } 390 391 @Override sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)392 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 393 String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, 394 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 395 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options, 396 resultReceiver, scheduler, initialCode, initialData, initialExtras); 397 resultReceiver.onReceive(spiedContext, intent); 398 } 399 400 @Override sendStickyBroadcast(Intent intent)401 public void sendStickyBroadcast(Intent intent) { 402 spiedContext.sendStickyBroadcast(intent); 403 } 404 405 @Override sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)406 public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, 407 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 408 spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, 409 initialData, initialExtras); 410 } 411 412 @Override removeStickyBroadcast(Intent intent)413 public void removeStickyBroadcast(Intent intent) { 414 spiedContext.removeStickyBroadcast(intent); 415 } 416 417 @Override sendStickyBroadcastAsUser(Intent intent, UserHandle user)418 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { 419 spiedContext.sendStickyBroadcastAsUser(intent, user); 420 } 421 422 @Override sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)423 public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, 424 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 425 String initialData, Bundle initialExtras) { 426 spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode, 427 initialData, initialExtras); 428 } 429 430 @Override removeStickyBroadcastAsUser(Intent intent, UserHandle user)431 public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) { 432 spiedContext.removeStickyBroadcastAsUser(intent, user); 433 } 434 435 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter)436 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 437 mMockSystemServices.registerReceiver(receiver, filter, null); 438 return spiedContext.registerReceiver(receiver, filter); 439 } 440 441 @Override registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)442 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 443 String broadcastPermission, Handler scheduler) { 444 mMockSystemServices.registerReceiver(receiver, filter, scheduler); 445 return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler); 446 } 447 448 @Override registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)449 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, 450 IntentFilter filter, String broadcastPermission, Handler scheduler) { 451 mMockSystemServices.registerReceiver(receiver, filter, scheduler); 452 return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission, 453 scheduler); 454 } 455 456 @Override unregisterReceiver(BroadcastReceiver receiver)457 public void unregisterReceiver(BroadcastReceiver receiver) { 458 mMockSystemServices.unregisterReceiver(receiver); 459 spiedContext.unregisterReceiver(receiver); 460 } 461 462 @Override createPackageContextAsUser(String packageName, int flags, UserHandle user)463 public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) 464 throws PackageManager.NameNotFoundException { 465 return mMockSystemServices.createPackageContextAsUser(packageName, flags, user); 466 } 467 468 @Override createContextAsUser(UserHandle user, int flags)469 public Context createContextAsUser(UserHandle user, int flags) { 470 try { 471 return mMockSystemServices.createPackageContextAsUser(packageName, flags, user); 472 } catch (PackageManager.NameNotFoundException e) { 473 throw new IllegalStateException(e); 474 } 475 } 476 477 @Override getContentResolver()478 public ContentResolver getContentResolver() { 479 return mMockSystemServices.contentResolver; 480 } 481 482 @Override getUserId()483 public int getUserId() { 484 return UserHandle.getUserId(binder.getCallingUid()); 485 } 486 487 @Override checkCallingPermission(String permission)488 public int checkCallingPermission(String permission) { 489 return checkPermission(permission); 490 } 491 492 @Override checkCallingOrSelfPermission(String permission)493 public int checkCallingOrSelfPermission(String permission) { 494 return checkPermission(permission); 495 } 496 497 @Override startActivityAsUser(Intent intent, UserHandle userHandle)498 public void startActivityAsUser(Intent intent, UserHandle userHandle) { 499 spiedContext.startActivityAsUser(intent, userHandle); 500 } 501 checkPermission(String permission)502 private int checkPermission(String permission) { 503 if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) { 504 return PackageManager.PERMISSION_GRANTED; // Assume system has all permissions. 505 } 506 List<String> permissions = binder.callingPermissions.get(binder.getCallingUid()); 507 if (permissions == null) { 508 permissions = callerPermissions; 509 } 510 if (permissions.contains(permission)) { 511 return PackageManager.PERMISSION_GRANTED; 512 } else { 513 return PackageManager.PERMISSION_DENIED; 514 } 515 } 516 517 } 518