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