Home | History | Annotate | Download | only in devicepolicy
      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