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