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