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