• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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