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 android.accounts.Account;
     20 import android.accounts.AccountManager;
     21 import android.app.AlarmManager;
     22 import android.app.IActivityManager;
     23 import android.app.NotificationManager;
     24 import android.app.backup.IBackupManager;
     25 import android.content.BroadcastReceiver;
     26 import android.content.ContentResolver;
     27 import android.content.Context;
     28 import android.content.Intent;
     29 import android.content.IntentFilter;
     30 import android.content.pm.ApplicationInfo;
     31 import android.content.pm.IPackageManager;
     32 import android.content.pm.PackageManager;
     33 import android.content.pm.PackageManagerInternal;
     34 import android.content.pm.UserInfo;
     35 import android.content.res.Resources;
     36 import android.media.IAudioService;
     37 import android.net.IIpConnectivityMetrics;
     38 import android.net.wifi.WifiManager;
     39 import android.os.Bundle;
     40 import android.os.Handler;
     41 import android.os.PowerManager.WakeLock;
     42 import android.os.PowerManagerInternal;
     43 import android.os.UserHandle;
     44 import android.os.UserManager;
     45 import android.os.UserManagerInternal;
     46 import android.security.KeyChain;
     47 import android.telephony.TelephonyManager;
     48 import android.test.mock.MockContentResolver;
     49 import android.test.mock.MockContext;
     50 import android.util.ArrayMap;
     51 import android.util.Pair;
     52 import android.view.IWindowManager;
     53 
     54 import com.android.internal.widget.LockPatternUtils;
     55 
     56 import org.junit.Assert;
     57 import org.mockito.invocation.InvocationOnMock;
     58 import org.mockito.stubbing.Answer;
     59 
     60 import java.io.File;
     61 import java.io.IOException;
     62 import java.util.ArrayList;
     63 import java.util.List;
     64 import java.util.Map;
     65 import java.util.concurrent.atomic.AtomicReference;
     66 
     67 import static org.mockito.Matchers.anyBoolean;
     68 import static org.mockito.Matchers.anyInt;
     69 import static org.mockito.Matchers.eq;
     70 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
     71 import static org.mockito.Mockito.mock;
     72 import static org.mockito.Mockito.spy;
     73 import static org.mockito.Mockito.when;
     74 
     75 /**
     76  * Context used throughout DPMS tests.
     77  */
     78 public class DpmMockContext extends MockContext {
     79     /**
     80      * User-id of a non-system user we use throughout unit tests.
     81      */
     82     public static final int CALLER_USER_HANDLE = 20;
     83 
     84     /**
     85      * UID corresponding to {@link #CALLER_USER_HANDLE}.
     86      */
     87     public static final int CALLER_UID = UserHandle.getUid(CALLER_USER_HANDLE, 20123);
     88 
     89     /**
     90      * UID used when a caller is on the system user.
     91      */
     92     public static final int CALLER_SYSTEM_USER_UID = 20321;
     93 
     94     /**
     95      * PID of the caller.
     96      */
     97     public static final int CALLER_PID = 22222;
     98 
     99     /**
    100      * UID of the system server.
    101      */
    102     public static final int SYSTEM_UID = android.os.Process.SYSTEM_UID;
    103 
    104     /**
    105      * PID of the system server.
    106      */
    107     public static final int SYSTEM_PID = 11111;
    108 
    109     public static final String ANOTHER_PACKAGE_NAME = "com.another.package.name";
    110 
    111     public static final int ANOTHER_UID = UserHandle.getUid(UserHandle.USER_SYSTEM, 18434);
    112 
    113     public static class MockBinder {
    114         public int callingUid = CALLER_UID;
    115         public int callingPid = CALLER_PID;
    116         public final Map<Integer, List<String>> callingPermissions = new ArrayMap<>();
    117 
    118         public long clearCallingIdentity() {
    119             final long token = (((long) callingUid) << 32) | (callingPid);
    120             callingUid = SYSTEM_UID;
    121             callingPid = SYSTEM_PID;
    122             return token;
    123         }
    124 
    125         public void restoreCallingIdentity(long token) {
    126             callingUid = (int) (token >> 32);
    127             callingPid = (int) token;
    128         }
    129 
    130         public int getCallingUid() {
    131             return callingUid;
    132         }
    133 
    134         public int getCallingPid() {
    135             return callingPid;
    136         }
    137 
    138         public UserHandle getCallingUserHandle() {
    139             return new UserHandle(UserHandle.getUserId(getCallingUid()));
    140         }
    141 
    142         public boolean isCallerUidMyUid() {
    143             return callingUid == SYSTEM_UID;
    144         }
    145     }
    146 
    147     public static class EnvironmentForMock {
    148         public File getUserSystemDirectory(int userId) {
    149             return null;
    150         }
    151     }
    152 
    153     public static class BuildMock {
    154         public boolean isDebuggable = true;
    155     }
    156 
    157     public static class PowerManagerForMock {
    158         public WakeLock newWakeLock(int levelAndFlags, String tag) {
    159             return null;
    160         }
    161 
    162         public void goToSleep(long time, int reason, int flags) {
    163         }
    164 
    165         public void reboot(String reason) {
    166         }
    167     }
    168 
    169     public static class RecoverySystemForMock {
    170         public void rebootWipeUserData(
    171                 boolean shutdown, String reason, boolean force) throws IOException {
    172         }
    173     }
    174 
    175     public static class SystemPropertiesForMock {
    176         public boolean getBoolean(String key, boolean def) {
    177             return false;
    178         }
    179 
    180         public long getLong(String key, long def) {
    181             return 0;
    182         }
    183 
    184         public String get(String key, String def) {
    185             return null;
    186         }
    187 
    188         public String get(String key) {
    189             return null;
    190         }
    191 
    192         public void set(String key, String value) {
    193         }
    194     }
    195 
    196     public static class UserManagerForMock {
    197         public boolean isSplitSystemUser() {
    198             return false;
    199         }
    200     }
    201 
    202     public static class SettingsForMock {
    203         public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
    204             return 0;
    205         }
    206 
    207         public String settingsSecureGetStringForUser(String name, int userHandle) {
    208             return null;
    209         }
    210 
    211         public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
    212         }
    213 
    214         public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
    215         }
    216 
    217         public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
    218         }
    219 
    220         public void settingsSecurePutInt(String name, int value) {
    221         }
    222 
    223         public void settingsGlobalPutInt(String name, int value) {
    224         }
    225 
    226         public void settingsSecurePutString(String name, String value) {
    227         }
    228 
    229         public void settingsGlobalPutString(String name, String value) {
    230         }
    231 
    232         public int settingsGlobalGetInt(String name, int value) {
    233             return 0;
    234         }
    235 
    236         public String settingsGlobalGetString(String name) {
    237             return "";
    238         }
    239 
    240         public void securityLogSetLoggingEnabledProperty(boolean enabled) {
    241         }
    242 
    243         public boolean securityLogGetLoggingEnabledProperty() {
    244             return false;
    245         }
    246 
    247         public boolean securityLogIsLoggingEnabled() {
    248             return false;
    249         }
    250     }
    251 
    252     public static class StorageManagerForMock {
    253         public boolean isFileBasedEncryptionEnabled() {
    254             return false;
    255         }
    256 
    257         public boolean isNonDefaultBlockEncrypted() {
    258             return false;
    259         }
    260 
    261         public boolean isEncrypted() {
    262             return false;
    263         }
    264 
    265         public boolean isEncryptable() {
    266             return false;
    267         }
    268     }
    269 
    270     public final Context realTestContext;
    271 
    272     /**
    273      * Use this instance to verify unimplemented methods such as {@link #sendBroadcast}.
    274      * (Spying on {@code this} instance will confuse mockito somehow and I got weired "wrong number
    275      * of arguments" exceptions.)
    276      */
    277     public final Context spiedContext;
    278 
    279     public final File dataDir;
    280     public final File systemUserDataDir;
    281 
    282     public final MockBinder binder;
    283     public final EnvironmentForMock environment;
    284     public final Resources resources;
    285     public final SystemPropertiesForMock systemProperties;
    286     public final UserManager userManager;
    287     public final UserManagerInternal userManagerInternal;
    288     public final PackageManagerInternal packageManagerInternal;
    289     public final UserManagerForMock userManagerForMock;
    290     public final PowerManagerForMock powerManager;
    291     public final PowerManagerInternal powerManagerInternal;
    292     public final RecoverySystemForMock recoverySystem;
    293     public final NotificationManager notificationManager;
    294     public final IIpConnectivityMetrics iipConnectivityMetrics;
    295     public final IWindowManager iwindowManager;
    296     public final IActivityManager iactivityManager;
    297     public final IPackageManager ipackageManager;
    298     public final IBackupManager ibackupManager;
    299     public final IAudioService iaudioService;
    300     public final LockPatternUtils lockPatternUtils;
    301     public final StorageManagerForMock storageManager;
    302     public final WifiManager wifiManager;
    303     public final SettingsForMock settings;
    304     public final MockContentResolver contentResolver;
    305     public final TelephonyManager telephonyManager;
    306     public final AccountManager accountManager;
    307     public final AlarmManager alarmManager;
    308     public final KeyChain.KeyChainConnection keyChainConnection;
    309 
    310     /** Note this is a partial mock, not a real mock. */
    311     public final PackageManager packageManager;
    312 
    313     /** TODO: Migrate everything to use {@link #permissions} to avoid confusion. */
    314     @Deprecated
    315     public final List<String> callerPermissions = new ArrayList<>();
    316 
    317     /** Less confusing alias for {@link #callerPermissions}. */
    318     public final List<String> permissions = callerPermissions;
    319 
    320     private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
    321 
    322     public final BuildMock buildMock = new BuildMock();
    323 
    324     /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
    325     public final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>();
    326 
    327     public String packageName = null;
    328 
    329     public ApplicationInfo applicationInfo = null;
    330 
    331     // We have to keep track of broadcast receivers registered for a given intent ourselves as the
    332     // DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does
    333     // not work.
    334     private class BroadcastReceiverRegistration {
    335         public final BroadcastReceiver receiver;
    336         public final IntentFilter filter;
    337         public final Handler scheduler;
    338 
    339         // Exceptions thrown in a background thread kill the whole test. Save them instead.
    340         public final AtomicReference<Exception> backgroundException = new AtomicReference<>();
    341 
    342         public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter,
    343                 Handler scheduler) {
    344             this.receiver = receiver;
    345             this.filter = filter;
    346             this.scheduler = scheduler;
    347         }
    348 
    349         public void sendBroadcastIfApplicable(int userId, Intent intent) {
    350             final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult(
    351                     0 /* resultCode */, null /* resultData */, null /* resultExtras */,
    352                     0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId,
    353                     0 /* flags */);
    354             if (filter.match(null, intent, false, "DpmMockContext") > 0) {
    355                 final Runnable send = () -> {
    356                     receiver.setPendingResult(result);
    357                     receiver.onReceive(DpmMockContext.this, intent);
    358                 };
    359                 if (scheduler != null) {
    360                     scheduler.post(() -> {
    361                         try {
    362                             send.run();
    363                         } catch (Exception e) {
    364                             backgroundException.compareAndSet(null, e);
    365                         }
    366                     });
    367                 } else {
    368                     send.run();
    369                 }
    370             }
    371         }
    372     }
    373     private List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>();
    374 
    375     public DpmMockContext(Context realTestContext, String name) {
    376         this(realTestContext, new File(realTestContext.getCacheDir(), name));
    377     }
    378 
    379     public DpmMockContext(Context context, File dataDir) {
    380         realTestContext = context;
    381 
    382         this.dataDir = dataDir;
    383         DpmTestUtils.clearDir(dataDir);
    384 
    385         binder = new MockBinder();
    386         environment = mock(EnvironmentForMock.class);
    387         resources = mock(Resources.class);
    388         systemProperties = mock(SystemPropertiesForMock.class);
    389         userManager = mock(UserManager.class);
    390         userManagerInternal = mock(UserManagerInternal.class);
    391         userManagerForMock = mock(UserManagerForMock.class);
    392         packageManagerInternal = mock(PackageManagerInternal.class);
    393         powerManager = mock(PowerManagerForMock.class);
    394         powerManagerInternal = mock(PowerManagerInternal.class);
    395         recoverySystem = mock(RecoverySystemForMock.class);
    396         notificationManager = mock(NotificationManager.class);
    397         iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
    398         iwindowManager = mock(IWindowManager.class);
    399         iactivityManager = mock(IActivityManager.class);
    400         ipackageManager = mock(IPackageManager.class);
    401         ibackupManager = mock(IBackupManager.class);
    402         iaudioService = mock(IAudioService.class);
    403         lockPatternUtils = mock(LockPatternUtils.class);
    404         storageManager = mock(StorageManagerForMock.class);
    405         wifiManager = mock(WifiManager.class);
    406         settings = mock(SettingsForMock.class);
    407         telephonyManager = mock(TelephonyManager.class);
    408         accountManager = mock(AccountManager.class);
    409         alarmManager = mock(AlarmManager.class);
    410         keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
    411 
    412         // Package manager is huge, so we use a partial mock instead.
    413         packageManager = spy(context.getPackageManager());
    414 
    415         spiedContext = mock(Context.class);
    416 
    417         contentResolver = new MockContentResolver();
    418 
    419         // Add the system user with a fake profile group already set up (this can happen in the real
    420         // world if a managed profile is added and then removed).
    421         systemUserDataDir =
    422                 addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM);
    423 
    424         // System user is always running.
    425         setUserRunning(UserHandle.USER_SYSTEM, true);
    426     }
    427 
    428     public File addUser(int userId, int flags) {
    429         return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID);
    430     }
    431 
    432     public File addUser(int userId, int flags, int profileGroupId) {
    433         // Set up (default) UserInfo for CALLER_USER_HANDLE.
    434         final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
    435         uh.profileGroupId = profileGroupId;
    436         when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
    437 
    438         mUserInfos.add(uh);
    439         when(userManager.getUsers()).thenReturn(mUserInfos);
    440         when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos);
    441         when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
    442         when(userManager.getUserInfo(anyInt())).thenAnswer(
    443                 new Answer<UserInfo>() {
    444                     @Override
    445                     public UserInfo answer(InvocationOnMock invocation) throws Throwable {
    446                         final int userId = (int) invocation.getArguments()[0];
    447                         return getUserInfo(userId);
    448                     }
    449                 }
    450         );
    451         when(userManager.getProfiles(anyInt())).thenAnswer(
    452                 new Answer<List<UserInfo>>() {
    453                     @Override
    454                     public List<UserInfo> answer(InvocationOnMock invocation) throws Throwable {
    455                         final int userId = (int) invocation.getArguments()[0];
    456                         return getProfiles(userId);
    457                     }
    458                 }
    459         );
    460         when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
    461                 new Answer<int[]>() {
    462                     @Override
    463                     public int[] answer(InvocationOnMock invocation) throws Throwable {
    464                         final int userId = (int) invocation.getArguments()[0];
    465                         List<UserInfo> profiles = getProfiles(userId);
    466                         return profiles.stream()
    467                                 .mapToInt(profile -> profile.id)
    468                                 .toArray();
    469                     }
    470                 }
    471         );
    472         when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
    473 
    474         // Create a data directory.
    475         final File dir = new File(dataDir, "users/" + userId);
    476         DpmTestUtils.clearDir(dir);
    477 
    478         when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
    479         return dir;
    480     }
    481 
    482     public void removeUser(int userId) {
    483         for (int i = 0; i < mUserInfos.size(); i++) {
    484             if (mUserInfos.get(i).id == userId) {
    485                 mUserInfos.remove(i);
    486                 break;
    487             }
    488         }
    489         when(userManager.getUserInfo(eq(userId))).thenReturn(null);
    490 
    491         when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false);
    492     }
    493 
    494     private UserInfo getUserInfo(int userId) {
    495         for (UserInfo ui : mUserInfos) {
    496             if (ui.id == userId) {
    497                 return ui;
    498             }
    499         }
    500         return null;
    501     }
    502 
    503     private List<UserInfo> getProfiles(int userId) {
    504         final ArrayList<UserInfo> ret = new ArrayList<UserInfo>();
    505         UserInfo parent = null;
    506         for (UserInfo ui : mUserInfos) {
    507             if (ui.id == userId) {
    508                 parent = ui;
    509                 break;
    510             }
    511         }
    512         if (parent == null) {
    513             return ret;
    514         }
    515         for (UserInfo ui : mUserInfos) {
    516             if (ui == parent
    517                     || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
    518                     && ui.profileGroupId == parent.profileGroupId) {
    519                 ret.add(ui);
    520             }
    521         }
    522         return ret;
    523     }
    524 
    525     /**
    526      * Add multiple users at once.  They'll all have flag 0.
    527      */
    528     public void addUsers(int... userIds) {
    529         for (int userId : userIds) {
    530             addUser(userId, 0);
    531         }
    532     }
    533 
    534     public void setUserRunning(int userId, boolean isRunning) {
    535         when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
    536                 .thenReturn(isRunning);
    537     }
    538 
    539     public void injectBroadcast(final Intent intent) {
    540         final int userId = UserHandle.getUserId(binder.getCallingUid());
    541         for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
    542             receiver.sendBroadcastIfApplicable(userId, intent);
    543         }
    544     }
    545 
    546     public void rethrowBackgroundBroadcastExceptions() throws Exception {
    547         for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
    548             final Exception e = receiver.backgroundException.getAndSet(null);
    549             if (e != null) {
    550                 throw e;
    551             }
    552         }
    553     }
    554 
    555     public void addPackageContext(UserHandle user, Context context) {
    556         if (context.getPackageName() == null) {
    557             throw new NullPointerException("getPackageName() == null");
    558         }
    559         userPackageContexts.put(new Pair<>(user, context.getPackageName()), context);
    560     }
    561 
    562     @Override
    563     public Resources getResources() {
    564         return resources;
    565     }
    566 
    567     @Override
    568     public Resources.Theme getTheme() {
    569         return spiedContext.getTheme();
    570     }
    571 
    572     @Override
    573     public String getPackageName() {
    574         if (packageName != null) {
    575             return packageName;
    576         }
    577         return super.getPackageName();
    578     }
    579 
    580     @Override
    581     public ApplicationInfo getApplicationInfo() {
    582         if (applicationInfo != null) {
    583             return applicationInfo;
    584         }
    585         return super.getApplicationInfo();
    586     }
    587 
    588     @Override
    589     public Object getSystemService(String name) {
    590         switch (name) {
    591             case Context.ALARM_SERVICE:
    592                 return alarmManager;
    593             case Context.USER_SERVICE:
    594                 return userManager;
    595             case Context.POWER_SERVICE:
    596                 return powerManager;
    597             case Context.WIFI_SERVICE:
    598                 return wifiManager;
    599             case Context.ACCOUNT_SERVICE:
    600                 return accountManager;
    601         }
    602         throw new UnsupportedOperationException();
    603     }
    604 
    605     @Override
    606     public String getSystemServiceName(Class<?> serviceClass) {
    607         return realTestContext.getSystemServiceName(serviceClass);
    608     }
    609 
    610     @Override
    611     public PackageManager getPackageManager() {
    612         return packageManager;
    613     }
    614 
    615     @Override
    616     public void enforceCallingOrSelfPermission(String permission, String message) {
    617         if (binder.getCallingUid() == SYSTEM_UID) {
    618             return; // Assume system has all permissions.
    619         }
    620 
    621         List<String> permissions = binder.callingPermissions.get(binder.getCallingUid());
    622         if (permissions == null) {
    623             // TODO: delete the following line. to do this without breaking any tests, first it's
    624             //       necessary to remove all tests that set it directly.
    625             permissions = callerPermissions;
    626 //            throw new UnsupportedOperationException(
    627 //                    "Caller UID " + binder.getCallingUid() + " doesn't exist");
    628         }
    629         if (!permissions.contains(permission)) {
    630             throw new SecurityException("Caller doesn't have " + permission + " : " + message);
    631         }
    632     }
    633 
    634     @Override
    635     public void sendBroadcast(Intent intent) {
    636         spiedContext.sendBroadcast(intent);
    637     }
    638 
    639     @Override
    640     public void sendBroadcast(Intent intent, String receiverPermission) {
    641         spiedContext.sendBroadcast(intent, receiverPermission);
    642     }
    643 
    644     @Override
    645     public void sendBroadcastMultiplePermissions(Intent intent, String[] receiverPermissions) {
    646         spiedContext.sendBroadcastMultiplePermissions(intent, receiverPermissions);
    647     }
    648 
    649     @Override
    650     public void sendBroadcast(Intent intent, String receiverPermission, Bundle options) {
    651         spiedContext.sendBroadcast(intent, receiverPermission, options);
    652     }
    653 
    654     @Override
    655     public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
    656         spiedContext.sendBroadcast(intent, receiverPermission, appOp);
    657     }
    658 
    659     @Override
    660     public void sendOrderedBroadcast(Intent intent, String receiverPermission) {
    661         spiedContext.sendOrderedBroadcast(intent, receiverPermission);
    662     }
    663 
    664     @Override
    665     public void sendOrderedBroadcast(Intent intent, String receiverPermission,
    666             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    667             String initialData, Bundle initialExtras) {
    668         spiedContext.sendOrderedBroadcast(intent, receiverPermission, resultReceiver, scheduler,
    669                 initialCode, initialData, initialExtras);
    670     }
    671 
    672     @Override
    673     public void sendOrderedBroadcast(Intent intent, String receiverPermission, Bundle options,
    674             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    675             String initialData, Bundle initialExtras) {
    676         spiedContext.sendOrderedBroadcast(intent, receiverPermission, options, resultReceiver,
    677                 scheduler,
    678                 initialCode, initialData, initialExtras);
    679     }
    680 
    681     @Override
    682     public void sendOrderedBroadcast(Intent intent, String receiverPermission, int appOp,
    683             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    684             String initialData, Bundle initialExtras) {
    685         spiedContext.sendOrderedBroadcast(intent, receiverPermission, appOp, resultReceiver,
    686                 scheduler,
    687                 initialCode, initialData, initialExtras);
    688     }
    689 
    690     @Override
    691     public void sendBroadcastAsUser(Intent intent, UserHandle user) {
    692         if (binder.callingPid != SYSTEM_PID) {
    693             // Unless called as the system process, can only call if the target user is the
    694             // calling user.
    695             // (The actual check is more complex; we may need to change it later.)
    696             Assert.assertEquals(UserHandle.getUserId(binder.getCallingUid()), user.getIdentifier());
    697         }
    698 
    699         spiedContext.sendBroadcastAsUser(intent, user);
    700     }
    701 
    702     @Override
    703     public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission) {
    704         spiedContext.sendBroadcastAsUser(intent, user, receiverPermission);
    705     }
    706 
    707     @Override
    708     public void sendBroadcastAsUser(Intent intent, UserHandle user, String receiverPermission,
    709             int appOp) {
    710         spiedContext.sendBroadcastAsUser(intent, user, receiverPermission, appOp);
    711     }
    712 
    713     @Override
    714     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    715             String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
    716             int initialCode, String initialData, Bundle initialExtras) {
    717         spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, resultReceiver,
    718                 scheduler, initialCode, initialData, initialExtras);
    719         resultReceiver.onReceive(spiedContext, intent);
    720     }
    721 
    722     @Override
    723     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    724             String receiverPermission, int appOp, BroadcastReceiver resultReceiver,
    725             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    726         spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp,
    727                 resultReceiver,
    728                 scheduler, initialCode, initialData, initialExtras);
    729     }
    730 
    731     @Override
    732     public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
    733             String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
    734             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    735         spiedContext.sendOrderedBroadcastAsUser(intent, user, receiverPermission, appOp, options,
    736                 resultReceiver, scheduler, initialCode, initialData, initialExtras);
    737     }
    738 
    739     @Override
    740     public void sendStickyBroadcast(Intent intent) {
    741         spiedContext.sendStickyBroadcast(intent);
    742     }
    743 
    744     @Override
    745     public void sendStickyOrderedBroadcast(Intent intent, BroadcastReceiver resultReceiver,
    746             Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
    747         spiedContext.sendStickyOrderedBroadcast(intent, resultReceiver, scheduler, initialCode,
    748                 initialData, initialExtras);
    749     }
    750 
    751     @Override
    752     public void removeStickyBroadcast(Intent intent) {
    753         spiedContext.removeStickyBroadcast(intent);
    754     }
    755 
    756     @Override
    757     public void sendStickyBroadcastAsUser(Intent intent, UserHandle user) {
    758         spiedContext.sendStickyBroadcastAsUser(intent, user);
    759     }
    760 
    761     @Override
    762     public void sendStickyOrderedBroadcastAsUser(Intent intent, UserHandle user,
    763             BroadcastReceiver resultReceiver, Handler scheduler, int initialCode,
    764             String initialData, Bundle initialExtras) {
    765         spiedContext.sendStickyOrderedBroadcastAsUser(intent, user, resultReceiver, scheduler, initialCode,
    766                 initialData, initialExtras);
    767     }
    768 
    769     @Override
    770     public void removeStickyBroadcastAsUser(Intent intent, UserHandle user) {
    771         spiedContext.removeStickyBroadcastAsUser(intent, user);
    772     }
    773 
    774     @Override
    775     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    776         mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, null));
    777         return spiedContext.registerReceiver(receiver, filter);
    778     }
    779 
    780     @Override
    781     public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
    782             String broadcastPermission, Handler scheduler) {
    783         mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
    784         return spiedContext.registerReceiver(receiver, filter, broadcastPermission, scheduler);
    785     }
    786 
    787     @Override
    788     public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
    789             IntentFilter filter, String broadcastPermission, Handler scheduler) {
    790         mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
    791         return spiedContext.registerReceiverAsUser(receiver, user, filter, broadcastPermission,
    792                 scheduler);
    793     }
    794 
    795     @Override
    796     public void unregisterReceiver(BroadcastReceiver receiver) {
    797         mBroadcastReceivers.removeIf(r -> r.receiver == receiver);
    798         spiedContext.unregisterReceiver(receiver);
    799     }
    800 
    801     @Override
    802     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
    803             throws PackageManager.NameNotFoundException {
    804         final Pair<UserHandle, String> key = new Pair<>(user, packageName);
    805         if (userPackageContexts.containsKey(key)) {
    806             return userPackageContexts.get(key);
    807         }
    808         throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
    809     }
    810 
    811     @Override
    812     public ContentResolver getContentResolver() {
    813         return contentResolver;
    814     }
    815 
    816     @Override
    817     public int getUserId() {
    818         return UserHandle.getUserId(binder.getCallingUid());
    819     }
    820 }
    821