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 com.android.internal.widget.LockPatternUtils;
     20 
     21 import android.app.IActivityManager;
     22 import android.app.NotificationManager;
     23 import android.app.backup.IBackupManager;
     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.IPackageManager;
     30 import android.content.pm.PackageManager;
     31 import android.content.pm.PackageManagerInternal;
     32 import android.content.pm.UserInfo;
     33 import android.media.IAudioService;
     34 import android.net.wifi.WifiManager;
     35 import android.os.Bundle;
     36 import android.os.Handler;
     37 import android.os.PowerManager.WakeLock;
     38 import android.os.PowerManagerInternal;
     39 import android.os.UserHandle;
     40 import android.os.UserManager;
     41 import android.os.UserManagerInternal;
     42 import android.telephony.TelephonyManager;
     43 import android.test.mock.MockContentResolver;
     44 import android.test.mock.MockContext;
     45 import android.view.IWindowManager;
     46 
     47 import org.junit.Assert;
     48 import org.mockito.invocation.InvocationOnMock;
     49 import org.mockito.stubbing.Answer;
     50 
     51 import java.io.File;
     52 import java.util.ArrayList;
     53 import java.util.List;
     54 
     55 import static org.mockito.Matchers.anyBoolean;
     56 import static org.mockito.Matchers.anyInt;
     57 import static org.mockito.Matchers.eq;
     58 import static org.mockito.Mockito.mock;
     59 import static org.mockito.Mockito.spy;
     60 import static org.mockito.Mockito.when;
     61 
     62 /**
     63  * Context used throughout DPMS tests.
     64  */
     65 public class DpmMockContext extends MockContext {
     66     /**
     67      * User-id of a non-system user we use throughout unit tests.
     68      */
     69     public static final int CALLER_USER_HANDLE = 20;
     70 
     71     /**
     72      * UID corresponding to {@link #CALLER_USER_HANDLE}.
     73      */
     74     public static final int CALLER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 20123);
     75 
     76     /**
     77      * UID used when a caller is on the system user.
     78      */
     79     public static final int CALLER_SYSTEM_USER_UID = 20321;
     80 
     81     /**
     82      * PID of the caller.
     83      */
     84     public static final int CALLER_PID = 22222;
     85 
     86     /**
     87      * UID of the system server.
     88      */
     89     public static final int SYSTEM_UID = android.os.Process.SYSTEM_UID;
     90 
     91     /**
     92      * PID of the system server.
     93      */
     94     public static final int SYSTEM_PID = 11111;
     95 
     96     public static class MockBinder {
     97         public int callingUid = CALLER_UID;
     98         public int callingPid = CALLER_PID;
     99 
    100         public long clearCallingIdentity() {
    101             final long token = (((long) callingUid) << 32) | (callingPid);
    102             callingUid = SYSTEM_UID;
    103             callingPid = SYSTEM_PID;
    104             return token;
    105         }
    106 
    107         public void restoreCallingIdentity(long token) {
    108             callingUid = (int) (token >> 32);
    109             callingPid = (int) token;
    110         }
    111 
    112         public int getCallingUid() {
    113             return callingUid;
    114         }
    115 
    116         public int getCallingPid() {
    117             return callingPid;
    118         }
    119 
    120         public UserHandle getCallingUserHandle() {
    121             return new UserHandle(UserHandle.getUserId(getCallingUid()));
    122         }
    123 
    124         public boolean isCallerUidMyUid() {
    125             return callingUid == SYSTEM_UID;
    126         }
    127     }
    128 
    129     public static class EnvironmentForMock {
    130         public File getUserSystemDirectory(int userId) {
    131             return null;
    132         }
    133     }
    134 
    135     public static class PowerManagerForMock {
    136         public WakeLock newWakeLock(int levelAndFlags, String tag) {
    137             return null;
    138         }
    139 
    140         public void goToSleep(long time, int reason, int flags) {
    141         }
    142 
    143         public void reboot(String reason) {
    144         }
    145     }
    146 
    147     public static class SystemPropertiesForMock {
    148         public boolean getBoolean(String key, boolean def) {
    149             return false;
    150         }
    151 
    152         public long getLong(String key, long def) {
    153             return 0;
    154         }
    155 
    156         public String get(String key, String def) {
    157             return null;
    158         }
    159 
    160         public String get(String key) {
    161             return null;
    162         }
    163 
    164         public void set(String key, String value) {
    165         }
    166     }
    167 
    168     public static class UserManagerForMock {
    169         public boolean isSplitSystemUser() {
    170             return false;
    171         }
    172     }
    173 
    174     public static class SettingsForMock {
    175         public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
    176             return 0;
    177         }
    178 
    179         public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
    180         }
    181 
    182         public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
    183         }
    184 
    185         public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
    186         }
    187 
    188         public void settingsSecurePutInt(String name, int value) {
    189         }
    190 
    191         public void settingsGlobalPutInt(String name, int value) {
    192         }
    193 
    194         public void settingsSecurePutString(String name, String value) {
    195         }
    196 
    197         public void settingsGlobalPutString(String name, String value) {
    198         }
    199 
    200         public int settingsGlobalGetInt(String name, int value) {
    201             return 0;
    202         }
    203 
    204         public void securityLogSetLoggingEnabledProperty(boolean enabled) {
    205         }
    206 
    207         public boolean securityLogGetLoggingEnabledProperty() {
    208             return false;
    209         }
    210 
    211         public boolean securityLogIsLoggingEnabled() {
    212             return false;
    213         }
    214     }
    215 
    216     public static class StorageManagerForMock {
    217         public boolean isFileBasedEncryptionEnabled() {
    218             return false;
    219         }
    220 
    221         public boolean isNonDefaultBlockEncrypted() {
    222             return false;
    223         }
    224 
    225         public boolean isEncrypted() {
    226             return false;
    227         }
    228 
    229         public boolean isEncryptable() {
    230             return false;
    231         }
    232     }
    233 
    234     public final Context realTestContext;
    235 
    236     /**
    237      * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}.
    238      * (Spying on {@code this} instance will confuse mockito somehow and I got weired "wrong number
    239      * of arguments" exceptions.)
    240      */
    241     public final Context spiedContext;
    242 
    243     public final File dataDir;
    244     public final File systemUserDataDir;
    245 
    246     public final MockBinder binder;
    247     public final EnvironmentForMock environment;
    248     public final SystemPropertiesForMock systemProperties;
    249     public final UserManager userManager;
    250     public final UserManagerInternal userManagerInternal;
    251     public final PackageManagerInternal packageManagerInternal;
    252     public final UserManagerForMock userManagerForMock;
    253     public final PowerManagerForMock powerManager;
    254     public final PowerManagerInternal powerManagerInternal;
    255     public final NotificationManager notificationManager;
    256     public final IWindowManager iwindowManager;
    257     public final IActivityManager iactivityManager;
    258     public final IPackageManager ipackageManager;
    259     public final IBackupManager ibackupManager;
    260     public final IAudioService iaudioService;
    261     public final LockPatternUtils lockPatternUtils;
    262     public final StorageManagerForMock storageManager;
    263     public final WifiManager wifiManager;
    264     public final SettingsForMock settings;
    265     public final MockContentResolver contentResolver;
    266     public final TelephonyManager telephonyManager;
    267 
    268     /** Note this is a partial mock, not a real mock. */
    269     public final PackageManager packageManager;
    270 
    271     public final List<String> callerPermissions = new ArrayList<>();
    272 
    273     private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
    274 
    275     public DpmMockContext(Context context, File dataDir) {
    276         realTestContext = context;
    277 
    278         this.dataDir = dataDir;
    279         DpmTestUtils.clearDir(dataDir);
    280 
    281         binder = new MockBinder();
    282         environment = mock(EnvironmentForMock.class);
    283         systemProperties= mock(SystemPropertiesForMock.class);
    284         userManager = mock(UserManager.class);
    285         userManagerInternal = mock(UserManagerInternal.class);
    286         userManagerForMock = mock(UserManagerForMock.class);
    287         packageManagerInternal = mock(PackageManagerInternal.class);
    288         powerManager = mock(PowerManagerForMock.class);
    289         powerManagerInternal = mock(PowerManagerInternal.class);
    290         notificationManager = mock(NotificationManager.class);
    291         iwindowManager = mock(IWindowManager.class);
    292         iactivityManager = mock(IActivityManager.class);
    293         ipackageManager = mock(IPackageManager.class);
    294         ibackupManager = mock(IBackupManager.class);
    295         iaudioService = mock(IAudioService.class);
    296         lockPatternUtils = mock(LockPatternUtils.class);
    297         storageManager = mock(StorageManagerForMock.class);
    298         wifiManager = mock(WifiManager.class);
    299         settings = mock(SettingsForMock.class);
    300         telephonyManager = mock(TelephonyManager.class);
    301 
    302         // Package manager is huge, so we use a partial mock instead.
    303         packageManager = spy(context.getPackageManager());
    304 
    305         spiedContext = mock(Context.class);
    306 
    307         contentResolver = new MockContentResolver();
    308 
    309         // Add the system user
    310         systemUserDataDir = addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY);
    311 
    312         // System user is always running.
    313         setUserRunning(UserHandle.USER_SYSTEM, true);
    314     }
    315 
    316     public File addUser(int userId, int flags) {
    317 
    318         // Set up (default) UserInfo for CALLER_USER_HANDLE.
    319         final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
    320         when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
    321 
    322         mUserInfos.add(uh);
    323         when(userManager.getUsers()).thenReturn(mUserInfos);
    324         when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos);
    325         when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
    326         when(userManager.getUserInfo(anyInt())).thenAnswer(
    327                 new Answer<UserInfo>() {
    328                     @Override
    329                     public UserInfo answer(InvocationOnMock invocation) throws Throwable {
    330                         final int userId = (int) invocation.getArguments()[0];
    331                         for (UserInfo ui : mUserInfos) {
    332                             if (ui.id == userId) {
    333                                 return ui;
    334                             }
    335                         }
    336                         return null;
    337                     }
    338                 }
    339         );
    340         when(userManager.getProfiles(anyInt())).thenAnswer(
    341                 new Answer<List<UserInfo>>() {
    342                     @Override
    343                     public List<UserInfo> answer(InvocationOnMock invocation) throws Throwable {
    344                         final int userId = (int) invocation.getArguments()[0];
    345                         return getProfiles(userId);
    346                     }
    347                 }
    348         );
    349         when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
    350                 new Answer<int[]>() {
    351                     @Override
    352                     public int[] answer(InvocationOnMock invocation) throws Throwable {
    353                         final int userId = (int) invocation.getArguments()[0];
    354                         List<UserInfo> profiles = getProfiles(userId);
    355                         int[] results = new int[profiles.size()];
    356                         for (int i = 0; i < results.length; i++) {
    357                             results[i] = profiles.get(i).id;
    358                         }
    359                         return results;
    360                     }
    361                 }
    362         );
    363 
    364 
    365         // Create a data directory.
    366         final File dir = new File(dataDir, "user" + userId);
    367         DpmTestUtils.clearDir(dir);
    368 
    369         when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
    370         return dir;
    371     }
    372 
    373     private List<UserInfo> getProfiles(int userId) {
    374         final ArrayList<UserInfo> ret = new ArrayList<UserInfo>();
    375         UserInfo parent = null;
    376         for (UserInfo ui : mUserInfos) {
    377             if (ui.id == userId) {
    378                 parent = ui;
    379                 break;
    380             }
    381         }
    382         if (parent == null) {
    383             return ret;
    384         }
    385         ret.add(parent);
    386         for (UserInfo ui : mUserInfos) {
    387             if (ui.id == userId) {
    388                 continue;
    389             }
    390             if (ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
    391                     && ui.profileGroupId == parent.profileGroupId) {
    392                 ret.add(ui);
    393             }
    394         }
    395         return ret;
    396     }
    397 
    398     /**
    399      * Add multiple users at once.  They'll all have flag 0.
    400      */
    401     public void addUsers(int... userIds) {
    402         for (int userId : userIds) {
    403             addUser(userId, 0);
    404         }
    405     }
    406 
    407     public void setUserRunning(int userId, boolean isRunning) {
    408         when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
    409                 .thenReturn(isRunning);
    410     }
    411 
    412     @Override
    413     public Object getSystemService(String name) {
    414         switch (name) {
    415             case Context.USER_SERVICE:
    416                 return userManager;
    417             case Context.POWER_SERVICE:
    418                 return powerManager;
    419             case Context.WIFI_SERVICE:
    420                 return wifiManager;
    421         }
    422         throw new UnsupportedOperationException();
    423     }
    424 
    425     @Override
    426     public String getSystemServiceName(Class<?> serviceClass) {
    427         return realTestContext.getSystemServiceName(serviceClass);
    428     }
    429 
    430     @Override
    431     public PackageManager getPackageManager() {
    432         return packageManager;
    433     }
    434 
    435     @Override
    436     public void enforceCallingOrSelfPermission(String permission, String message) {
    437         if (binder.getCallingUid() == SYSTEM_UID) {
    438             return; // Assume system has all permissions.
    439         }
    440         if (!callerPermissions.contains(permission)) {
    441             throw new SecurityException("Caller doesn't have " + permission + " : " + message);
    442         }
    443     }
    444 
    445     @Override
    446     public void sendBroadcast(Intent intent) {
    447         spiedContext.sendBroadcast(intent);
    448     }
    449 
    450     @Override
    451     public void sendBroadcast(Intent intent, String receiverPermission) {
    452         spiedContext.sendBroadcast(intent, receiverPermission);
    453     }
    454 
    455     @Override
    456     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
    457         spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions);
    458     }
    459 
    460     @Override
    461     public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
    462         spiedContext.sendBroadcast(intent, receiverPermission, options);
    463     }
    464 
    465     @Override
    466     public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
    467         spiedContext.sendBroadcast(intent, receiverPermission, appOp);
    468     }
    469 
    470     @Override
    471     public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
    472         spiedContext.sendOrderedBroadcast(intent, receiverPermission);
    473     }
    474 
    475     @Override
    476     public void sendOrderedBroadcast(Intent intent, String receiverPermission,
    477             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    478             String initialData, Bundle initialExtras) {
    479         spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
    480                 initialCode, initialData, initialExtras);
    481     }
    482 
    483     @Override
    484     public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
    485             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    486             String initialData, Bundle initialExtras) {
    487         spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver,
    488                 scheduler,
    489                 initialCode, initialData, initialExtras);
    490     }
    491 
    492     @Override
    493     public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
    494             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    495             String initialData, Bundle initialExtras) {
    496         spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver,
    497                 scheduler,
    498                 initialCode, initialData, initialExtras);
    499     }
    500 
    501     @Override
    502     public void sendBroadcastAsUser(Intent intent, UserHandle user) {
    503         if (binder.callingPid != SYSTEM_PID) {
    504             // Unless called as the system process, can only call if the target user is the
    505             // calling user.
    506             // (The actual check is more complex; we may need to change it later.)
    507             Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier());
    508         }
    509 
    510         spiedContext.sendBroadcastAsUser(intent, user);
    511     }
    512 
    513     @Override
    514     public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) {
    515         spiedContext.sendBroadcastAsUser(intent, user, receiverPermission);
    516     }
    517 
    518     @Override
    519     public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
    520             int appOp) {
    521         spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp);
    522     }
    523 
    524     @Override
    525     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    526             String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
    527             int initialCode, String initialData, Bundle initialExtras) {
    528         spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver,
    529                 scheduler, initialCode, initialData, initialExtras);
    530         resultReceiver.onReceive(spiedContext, intent);
    531     }
    532 
    533     @Override
    534     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    535             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
    536             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    537         spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
    538                 resultReceiver,
    539                 scheduler, initialCode, initialData, initialExtras);
    540     }
    541 
    542     @Override
    543     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    544             String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
    545             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    546         spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options,
    547                 resultReceiver, scheduler, initialCode, initialData, initialExtras);
    548     }
    549 
    550     @Override
    551     public void sendStickyBroadcast(Intent intent) {
    552         spiedContext.sendStickyBroadcast(intent);
    553     }
    554 
    555     @Override
    556     public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver,
    557             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    558         spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode,
    559                 initialData, initialExtras);
    560     }
    561 
    562     @Override
    563     public void removeStickyBroadcast(Intent intent) {
    564         spiedContext.removeStickyBroadcast(intent);
    565     }
    566 
    567     @Override
    568     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
    569         spiedContext.sendStickyBroadcastAsUser(intent, user);
    570     }
    571 
    572     @Override
    573     public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user,
    574             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    575             String initialData, Bundle initialExtras) {
    576         spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode,
    577                 initialData, initialExtras);
    578     }
    579 
    580     @Override
    581     public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
    582         spiedContext.removeStickyBroadcastAsUser(intent, user);
    583     }
    584 
    585     @Override
    586     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    587         return spiedContext.registerReceiver(receiver, filter);
    588     }
    589 
    590     @Override
    591     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
    592             String broadcastPermission, Handler scheduler) {
    593         return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
    594     }
    595 
    596     @Override
    597     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
    598             IntentFilter filter, String broadcastPermission, Handler scheduler) {
    599         return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
    600                 scheduler);
    601     }
    602 
    603     @Override
    604     public void unregisterReceiver(BroadcastReceiver receiver) {
    605         spiedContext.unregisterReceiver(receiver);
    606     }
    607 
    608     @Override
    609     public ContentResolver getContentResolver() {
    610         return contentResolver;
    611     }
    612 }
    613