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