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 21 import android.content.BroadcastReceiver; 22 import android.content.ContentResolver; 23 import android.content.Context; 24 import android.content.Intent; 25 import android.content.IntentFilter; 26 import android.content.pm.ApplicationInfo; 27 import android.content.pm.PackageManager; 28 import android.content.res.Resources; 29 import android.os.Bundle; 30 import android.os.Handler; 31 import android.os.UserHandle; 32 import android.os.UserManagerInternal; 33 import android.test.mock.MockContext; 34 import android.util.ArrayMap; 35 36 import org.junit.Assert; 37 38 import java.util.ArrayList; 39 import java.util.List; 40 import java.util.Map; 41 42 /** 43 * Context used throughout DPMS tests. 44 */ 45 public class DpmMockContext extends MockContext { 46 /** 47 * User-id of a non-system user we use throughout unit tests. 48 */ 49 public static final int CALLER_USER_HANDLE = 20; 50 51 /** 52 * UID corresponding to {@link #CALLER_USER_HANDLE}. 53 */ 54 public static final int CALLER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 20123); 55 56 /** 57 * UID used when a caller is on the system user. 58 */ 59 public static final int CALLER_SYSTEM_USER_UID = 20321; 60 61 /** 62 * PID of the caller. 63 */ 64 public static final int CALLER_PID = 22222; 65 66 /** 67 * UID of the system server. 68 */ 69 public static final int SYSTEM_UID = android.os.Process.SYSTEM_UID; 70 71 /** 72 * PID of the system server. 73 */ 74 public static final int SYSTEM_PID = 11111; 75 76 public static final String ANOTHER_PACKAGE_NAME = "com.another.package.name"; 77 public static final int ANOTHER_UID = UserHandle.getUid(UserHandle.USER_SYSTEM, 18434); 78 79 private final MockSystemServices mMockSystemServices; 80 81 public static class MockBinder { 82 public int callingUid = CALLER_UID; 83 public int callingPid = CALLER_PID; 84 public final Map<Integer, List<String>> callingPermissions = new ArrayMap<>(); 85 86 public long clearCallingIdentity() { 87 final long token = (((long) callingUid) << 32) | (callingPid); 88 callingUid = SYSTEM_UID; 89 callingPid = SYSTEM_PID; 90 return token; 91 } 92 93 public void restoreCallingIdentity(long token) { 94 callingUid = (int) (token >> 32); 95 callingPid = (int) token; 96 } 97 98 public int getCallingUid() { 99 return callingUid; 100 } 101 102 public int getCallingPid() { 103 return callingPid; 104 } 105 106 public UserHandle getCallingUserHandle() { 107 return new UserHandle(UserHandle.getUserId(getCallingUid())); 108 } 109 110 public boolean isCallerUidMyUid() { 111 return callingUid == SYSTEM_UID; 112 } 113 } 114 115 private final Context realTestContext; 116 117 /** 118 * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}. 119 * (Spying on {@code this} instance will confuse mockito somehow and I got weired "wrong number 120 * of arguments" exceptions.) 121 */ 122 public final Context spiedContext; 123 124 public final MockBinder binder; 125 public final Resources resources; 126 127 /** TODO: Migrate everything to use {@link #permissions} to avoid confusion. */ 128 @Deprecated 129 public final List<String> callerPermissions = new ArrayList<>(); 130 131 /** Less confusing alias for {@link #callerPermissions}. */ 132 public final List<String> permissions = callerPermissions; 133 134 public String packageName = null; 135 136 public ApplicationInfo applicationInfo = null; 137 138 public DpmMockContext(MockSystemServices mockSystemServices, Context context) { 139 mMockSystemServices = mockSystemServices; 140 realTestContext = context; 141 142 binder = new MockBinder(); 143 resources = mock(Resources.class); 144 spiedContext = mock(Context.class); 145 } 146 147 @Override 148 public Resources getResources() { 149 return resources; 150 } 151 152 @Override 153 public Resources.Theme getTheme() { 154 return spiedContext.getTheme(); 155 } 156 157 @Override 158 public String getPackageName() { 159 if (packageName != null) { 160 return packageName; 161 } 162 return super.getPackageName(); 163 } 164 165 @Override 166 public ApplicationInfo getApplicationInfo() { 167 if (applicationInfo != null) { 168 return applicationInfo; 169 } 170 return super.getApplicationInfo(); 171 } 172 173 @Override 174 public Object getSystemService(String name) { 175 switch (name) { 176 case Context.ALARM_SERVICE: 177 return mMockSystemServices.alarmManager; 178 case Context.USER_SERVICE: 179 return mMockSystemServices.userManager; 180 case Context.POWER_SERVICE: 181 return mMockSystemServices.powerManager; 182 case Context.WIFI_SERVICE: 183 return mMockSystemServices.wifiManager; 184 case Context.ACCOUNT_SERVICE: 185 return mMockSystemServices.accountManager; 186 } 187 throw new UnsupportedOperationException(); 188 } 189 190 @Override 191 public String getSystemServiceName(Class<?> serviceClass) { 192 return realTestContext.getSystemServiceName(serviceClass); 193 } 194 195 @Override 196 public PackageManager getPackageManager() { 197 return mMockSystemServices.packageManager; 198 } 199 200 public UserManagerInternal getUserManagerInternal() { 201 return mMockSystemServices.userManagerInternal; 202 } 203 204 @Override 205 public void enforceCallingOrSelfPermission(String permission, String message) { 206 if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) { 207 return; // Assume system has all permissions. 208 } 209 List<String> permissions = binder.callingPermissions.get(binder.getCallingUid()); 210 if (permissions == null) { 211 // TODO: delete the following line. to do this without breaking any tests, first it's 212 // necessary to remove all tests that set it directly. 213 permissions = callerPermissions; 214 // throw new UnsupportedOperationException( 215 // "Caller UID " + binder.getCallingUid() + " doesn't exist"); 216 } 217 if (!permissions.contains(permission)) { 218 throw new SecurityException("Caller doesn't have " + permission + " : " + message); 219 } 220 } 221 222 @Override 223 public void sendBroadcast(Intent intent) { 224 spiedContext.sendBroadcast(intent); 225 } 226 227 @Override 228 public void sendBroadcast(Intent intent, String receiverPermission) { 229 spiedContext.sendBroadcast(intent, receiverPermission); 230 } 231 232 @Override 233 public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) { 234 spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions); 235 } 236 237 @Override 238 public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) { 239 spiedContext.sendBroadcast(intent, receiverPermission, options); 240 } 241 242 @Override 243 public void sendBroadcast(Intent intent, String receiverPermission, int appOp) { 244 spiedContext.sendBroadcast(intent, receiverPermission, appOp); 245 } 246 247 @Override 248 public void sendOrderedBroadcast(Intent intent, String receiverPermission) { 249 spiedContext.sendOrderedBroadcast(intent, receiverPermission); 250 } 251 252 @Override 253 public void sendOrderedBroadcast(Intent intent, String receiverPermission, 254 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 255 String initialData, Bundle initialExtras) { 256 spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler, 257 initialCode, initialData, initialExtras); 258 } 259 260 @Override 261 public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, 262 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 263 String initialData, Bundle initialExtras) { 264 spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver, 265 scheduler, 266 initialCode, initialData, initialExtras); 267 } 268 269 @Override 270 public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, 271 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 272 String initialData, Bundle initialExtras) { 273 spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver, 274 scheduler, 275 initialCode, initialData, initialExtras); 276 } 277 278 @Override 279 public void sendBroadcastAsUser(Intent intent, UserHandle user) { 280 if (binder.callingPid != SYSTEM_PID) { 281 // Unless called as the system process, can only call if the target user is the 282 // calling user. 283 // (The actual check is more complex; we may need to change it later.) 284 Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier()); 285 } 286 287 spiedContext.sendBroadcastAsUser(intent, user); 288 } 289 290 @Override 291 public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) { 292 spiedContext.sendBroadcastAsUser(intent, user, receiverPermission); 293 } 294 295 @Override 296 public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, 297 int appOp) { 298 spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp); 299 } 300 301 @Override 302 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 303 String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, 304 int initialCode, String initialData, Bundle initialExtras) { 305 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver, 306 scheduler, initialCode, initialData, initialExtras); 307 resultReceiver.onReceive(spiedContext, intent); 308 } 309 310 @Override 311 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 312 String receiverPermission, int appOp, BroadcastReceiver resultReceiver, 313 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 314 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, 315 resultReceiver, 316 scheduler, initialCode, initialData, initialExtras); 317 } 318 319 @Override 320 public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user, 321 String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, 322 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 323 spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options, 324 resultReceiver, scheduler, initialCode, initialData, initialExtras); 325 } 326 327 @Override 328 public void sendStickyBroadcast(Intent intent) { 329 spiedContext.sendStickyBroadcast(intent); 330 } 331 332 @Override 333 public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, 334 Handler scheduler, int initialCode, String initialData, Bundle initialExtras) { 335 spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode, 336 initialData, initialExtras); 337 } 338 339 @Override 340 public void removeStickyBroadcast(Intent intent) { 341 spiedContext.removeStickyBroadcast(intent); 342 } 343 344 @Override 345 public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) { 346 spiedContext.sendStickyBroadcastAsUser(intent, user); 347 } 348 349 @Override 350 public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, 351 BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, 352 String initialData, Bundle initialExtras) { 353 spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode, 354 initialData, initialExtras); 355 } 356 357 @Override 358 public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) { 359 spiedContext.removeStickyBroadcastAsUser(intent, user); 360 } 361 362 @Override 363 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { 364 mMockSystemServices.registerReceiver(receiver, filter, null); 365 return spiedContext.registerReceiver(receiver, filter); 366 } 367 368 @Override 369 public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, 370 String broadcastPermission, Handler scheduler) { 371 mMockSystemServices.registerReceiver(receiver, filter, scheduler); 372 return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler); 373 } 374 375 @Override 376 public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, 377 IntentFilter filter, String broadcastPermission, Handler scheduler) { 378 mMockSystemServices.registerReceiver(receiver, filter, scheduler); 379 return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission, 380 scheduler); 381 } 382 383 @Override 384 public void unregisterReceiver(BroadcastReceiver receiver) { 385 mMockSystemServices.unregisterReceiver(receiver); 386 spiedContext.unregisterReceiver(receiver); 387 } 388 389 @Override 390 public Context createPackageContextAsUser(String packageName, int flags, UserHandle user) 391 throws PackageManager.NameNotFoundException { 392 return mMockSystemServices.createPackageContextAsUser(packageName, flags, user); 393 } 394 395 @Override 396 public ContentResolver getContentResolver() { 397 return mMockSystemServices.contentResolver; 398 } 399 400 @Override 401 public int getUserId() { 402 return UserHandle.getUserId(binder.getCallingUid()); 403 } 404 } 405