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         }
255         throw new UnsupportedOperationException();
256     }
257 
258     @Override
getSystemServiceName(Class<?> serviceClass)259     public String getSystemServiceName(Class<?> serviceClass) {
260         return realTestContext.getSystemServiceName(serviceClass);
261     }
262 
263     @Override
getPackageManager()264     public PackageManager getPackageManager() {
265         return mMockSystemServices.packageManager;
266     }
267 
getUserManagerInternal()268     public UserManagerInternal getUserManagerInternal() {
269         return mMockSystemServices.userManagerInternal;
270     }
271 
272     @Override
enforceCallingOrSelfPermission(String permission, String message)273     public void enforceCallingOrSelfPermission(String permission, String message) {
274         if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {
275             return; // Assume system has all permissions.
276         }
277         List<String> permissions = binder.callingPermissions.get(binder.getCallingUid());
278         if (permissions == null) {
279             // TODO: delete the following line. to do this without breaking any tests, first it's
280             //       necessary to remove all tests that set it directly.
281             permissions = callerPermissions;
282             //            throw new UnsupportedOperationException(
283             //                    "Caller UID " + binder.getCallingUid() + " doesn't exist");
284         }
285         if (!permissions.contains(permission)) {
286             throw new SecurityException("Caller doesn't have " + permission + " : " + message);
287         }
288     }
289 
290     @Override
checkPermission(String permission, int pid, int uid)291     public int checkPermission(String permission, int pid, int uid) {
292         return checkPermission(permission);
293     }
294 
295     @Override
sendBroadcast(Intent intent)296     public void sendBroadcast(Intent intent) {
297         spiedContext.sendBroadcast(intent);
298     }
299 
300     @Override
sendBroadcast(Intent intent, String receiverPermission)301     public void sendBroadcast(Intent intent, String receiverPermission) {
302         spiedContext.sendBroadcast(intent, receiverPermission);
303     }
304 
305     @Override
sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions)306     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
307         spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions);
308     }
309 
310     @Override
sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions, Bundle options)311     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions,
312             Bundle options) {
313         spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions, options);
314     }
315 
316     @Override
sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user, String[] receiverPermissions)317     public void sendBroadcastAsUserMultiplePermissions(Intent intent, UserHandle user,
318             String[] receiverPermissions) {
319         spiedContext.sendBroadcastAsUserMultiplePermissions(intent, user, receiverPermissions);
320     }
321 
322     @Override
sendBroadcast(Intent intent, String receiverPermission, Bundle options)323     public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
324         spiedContext.sendBroadcast(intent, receiverPermission, options);
325     }
326 
327     @Override
sendBroadcast(Intent intent, String receiverPermission, int appOp)328     public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
329         spiedContext.sendBroadcast(intent, receiverPermission, appOp);
330     }
331 
332     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission)333     public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
334         spiedContext.sendOrderedBroadcast(intent, receiverPermission);
335     }
336 
337     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)338     public void sendOrderedBroadcast(Intent intent, String receiverPermission,
339             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
340             String initialData, Bundle initialExtras) {
341         spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
342                 initialCode, initialData, initialExtras);
343     }
344 
345     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)346     public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
347             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
348             String initialData, Bundle initialExtras) {
349         spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver,
350                 scheduler,
351                 initialCode, initialData, initialExtras);
352     }
353 
354     @Override
sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)355     public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
356             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
357             String initialData, Bundle initialExtras) {
358         spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver,
359                 scheduler,
360                 initialCode, initialData, initialExtras);
361     }
362 
363     @Override
sendBroadcastAsUser(Intent intent, UserHandle user)364     public void sendBroadcastAsUser(Intent intent, UserHandle user) {
365         if (binder.callingPid != SYSTEM_PID) {
366             // Unless called as the system process, can only call if the target user is the
367             // calling user.
368             // (The actual check is more complex; we may need to change it later.)
369             Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier());
370         }
371 
372         spiedContext.sendBroadcastAsUser(intent, user);
373     }
374 
375     @Override
sendBroadcastAsUser(Intent intent, UserHandle user, @Nullable String receiverPermission, @Nullable Bundle options)376     public void sendBroadcastAsUser(Intent intent,
377             UserHandle user, @Nullable String receiverPermission, @Nullable Bundle options) {
378         spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, options);
379     }
380 
381     @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission)382     public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) {
383         spiedContext.sendBroadcastAsUser(intent, user, receiverPermission);
384     }
385 
386     @Override
sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp)387     public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
388             int appOp) {
389         spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp);
390     }
391 
392     @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)393     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
394             String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
395             int initialCode, String initialData, Bundle initialExtras) {
396         sendOrderedBroadcastAsUser(
397                 intent, user, receiverPermission, AppOpsManager.OP_NONE, resultReceiver,
398                 scheduler, initialCode, initialData, initialExtras);
399     }
400 
401     @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)402     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
403             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
404             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
405         sendOrderedBroadcastAsUser(
406                 intent, user, receiverPermission, appOp, null, resultReceiver,
407                 scheduler, initialCode, initialData, initialExtras);
408     }
409 
410     @Override
sendOrderedBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)411     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
412             String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
413             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
414         spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options,
415                 resultReceiver, scheduler, initialCode, initialData, initialExtras);
416         resultReceiver.onReceive(spiedContext, intent);
417     }
418 
419     @Override
sendStickyBroadcast(Intent intent)420     public void sendStickyBroadcast(Intent intent) {
421         spiedContext.sendStickyBroadcast(intent);
422     }
423 
424     @Override
sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)425     public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver,
426             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
427         spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode,
428                 initialData, initialExtras);
429     }
430 
431     @Override
removeStickyBroadcast(Intent intent)432     public void removeStickyBroadcast(Intent intent) {
433         spiedContext.removeStickyBroadcast(intent);
434     }
435 
436     @Override
sendStickyBroadcastAsUser(Intent intent, UserHandle user)437     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
438         spiedContext.sendStickyBroadcastAsUser(intent, user);
439     }
440 
441     @Override
sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user, BroadcastReceiver resultReceiver, Handler scheduler, int initialCode, String initialData, Bundle initialExtras)442     public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user,
443             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
444             String initialData, Bundle initialExtras) {
445         spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode,
446                 initialData, initialExtras);
447     }
448 
449     @Override
removeStickyBroadcastAsUser(Intent intent, UserHandle user)450     public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
451         spiedContext.removeStickyBroadcastAsUser(intent, user);
452     }
453 
454     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)455     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
456         mMockSystemServices.registerReceiver(receiver, filter, null);
457         return spiedContext.registerReceiver(receiver, filter,
458                 Context.RECEIVER_EXPORTED_UNAUDITED);
459     }
460 
461     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags)462     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, int flags) {
463         mMockSystemServices.registerReceiver(receiver, filter, null);
464         return spiedContext.registerReceiver(receiver, filter, flags);
465     }
466 
467     @Override
registerReceiver(BroadcastReceiver receiver, IntentFilter filter, String broadcastPermission, Handler scheduler)468     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
469             String broadcastPermission, Handler scheduler) {
470         mMockSystemServices.registerReceiver(receiver, filter, scheduler);
471         return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
472     }
473 
474     @Override
registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user, IntentFilter filter, String broadcastPermission, Handler scheduler)475     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
476             IntentFilter filter, String broadcastPermission, Handler scheduler) {
477         mMockSystemServices.registerReceiver(receiver, filter, scheduler);
478         return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
479                 scheduler);
480     }
481 
482     @Override
unregisterReceiver(BroadcastReceiver receiver)483     public void unregisterReceiver(BroadcastReceiver receiver) {
484         mMockSystemServices.unregisterReceiver(receiver);
485         spiedContext.unregisterReceiver(receiver);
486     }
487 
488     @Override
createPackageContextAsUser(String packageName, int flags, UserHandle user)489     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
490             throws PackageManager.NameNotFoundException {
491         return mMockSystemServices.createPackageContextAsUser(packageName, flags, user);
492     }
493 
494     @Override
createContextAsUser(UserHandle user, int flags)495     public Context createContextAsUser(UserHandle user, int flags) {
496         try {
497             return mMockSystemServices.createPackageContextAsUser(packageName, flags, user);
498         } catch (PackageManager.NameNotFoundException e) {
499             throw new IllegalStateException(e);
500         }
501     }
502 
503     @Override
getContentResolver()504     public ContentResolver getContentResolver() {
505         return mMockSystemServices.contentResolver;
506     }
507 
508     @Override
getUserId()509     public int getUserId() {
510         return UserHandle.getUserId(binder.getCallingUid());
511     }
512 
513     @Override
getMainExecutor()514     public Executor getMainExecutor() {
515         return mMockSystemServices.executor;
516     }
517 
518     @Override
checkCallingPermission(String permission)519     public int checkCallingPermission(String permission) {
520         return checkPermission(permission);
521     }
522 
523     @Override
checkCallingOrSelfPermission(String permission)524     public int checkCallingOrSelfPermission(String permission) {
525         return checkPermission(permission);
526     }
527 
528     @Override
startActivityAsUser(Intent intent, UserHandle userHandle)529     public void startActivityAsUser(Intent intent, UserHandle userHandle) {
530         spiedContext.startActivityAsUser(intent, userHandle);
531     }
532 
checkPermission(String permission)533     private int checkPermission(String permission) {
534         if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) {
535             return PackageManager.PERMISSION_GRANTED; // Assume system has all permissions.
536         }
537         List<String> permissions = binder.callingPermissions.get(binder.getCallingUid());
538         if (permissions == null) {
539             permissions = callerPermissions;
540         }
541         if (permissions.contains(permission)) {
542             return PackageManager.PERMISSION_GRANTED;
543         } else {
544             return PackageManager.PERMISSION_DENIED;
545         }
546     }
547 
548 }
549