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