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