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