• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 package com.android.server.devicepolicy;
17 
18 import static org.mockito.ArgumentMatchers.any;
19 import static org.mockito.ArgumentMatchers.anyInt;
20 import static org.mockito.ArgumentMatchers.eq;
21 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.spy;
24 import static org.mockito.Mockito.when;
25 
26 import android.accounts.Account;
27 import android.accounts.AccountManager;
28 import android.app.ActivityManagerInternal;
29 import android.app.AlarmManager;
30 import android.app.AppOpsManager;
31 import android.app.IActivityManager;
32 import android.app.IActivityTaskManager;
33 import android.app.NotificationManager;
34 import android.app.backup.IBackupManager;
35 import android.app.usage.UsageStatsManagerInternal;
36 import android.content.BroadcastReceiver;
37 import android.content.ComponentName;
38 import android.content.ContentValues;
39 import android.content.Context;
40 import android.content.Intent;
41 import android.content.IntentFilter;
42 import android.content.pm.CrossProfileApps;
43 import android.content.pm.IPackageManager;
44 import android.content.pm.PackageManager;
45 import android.content.pm.PackageManagerInternal;
46 import android.content.pm.UserInfo;
47 import android.database.Cursor;
48 import android.hardware.usb.UsbManager;
49 import android.media.IAudioService;
50 import android.net.ConnectivityManager;
51 import android.net.IIpConnectivityMetrics;
52 import android.net.Uri;
53 import android.net.VpnManager;
54 import android.net.wifi.WifiManager;
55 import android.os.Handler;
56 import android.os.PowerManager;
57 import android.os.PowerManagerInternal;
58 import android.os.UserHandle;
59 import android.os.UserManager;
60 import android.permission.IPermissionManager;
61 import android.provider.Settings;
62 import android.security.KeyChain;
63 import android.telephony.TelephonyManager;
64 import android.test.mock.MockContentProvider;
65 import android.test.mock.MockContentResolver;
66 import android.util.ArrayMap;
67 import android.util.Pair;
68 import android.view.IWindowManager;
69 
70 import com.android.internal.util.test.FakeSettingsProvider;
71 import com.android.internal.widget.LockPatternUtils;
72 import com.android.internal.widget.LockSettingsInternal;
73 import com.android.server.PersistentDataBlockManagerInternal;
74 import com.android.server.net.NetworkPolicyManagerInternal;
75 import com.android.server.pm.UserManagerInternal;
76 import com.android.server.wm.ActivityTaskManagerInternal;
77 
78 import java.io.File;
79 import java.io.IOException;
80 import java.util.ArrayList;
81 import java.util.List;
82 import java.util.Map;
83 import java.util.concurrent.atomic.AtomicReference;
84 
85 /**
86  * System services mocks and some other data that are shared by all contexts during the test.
87  */
88 public class MockSystemServices {
89     public final File systemUserDataDir;
90     public final EnvironmentForMock environment;
91     public final SystemPropertiesForMock systemProperties;
92     public final UserManager userManager;
93     public final UserManagerInternal userManagerInternal;
94     public final UsageStatsManagerInternal usageStatsManagerInternal;
95     public final NetworkPolicyManagerInternal networkPolicyManagerInternal;
96     public final PackageManagerInternal packageManagerInternal;
97     public final UserManagerForMock userManagerForMock;
98     public final PowerManagerForMock powerManager;
99     public final PowerManagerInternal powerManagerInternal;
100     public final RecoverySystemForMock recoverySystem;
101     public final NotificationManager notificationManager;
102     public final IIpConnectivityMetrics iipConnectivityMetrics;
103     public final IWindowManager iwindowManager;
104     public final IActivityManager iactivityManager;
105     public final IActivityTaskManager iactivityTaskManager;
106     public ActivityManagerInternal activityManagerInternal;
107     public ActivityTaskManagerInternal activityTaskManagerInternal;
108     public final IPackageManager ipackageManager;
109     public final IPermissionManager ipermissionManager;
110     public final IBackupManager ibackupManager;
111     public final IAudioService iaudioService;
112     public final LockPatternUtils lockPatternUtils;
113     public final LockSettingsInternal lockSettingsInternal;
114     public final StorageManagerForMock storageManager;
115     public final WifiManager wifiManager;
116     public final SettingsForMock settings;
117     public final MockContentResolver contentResolver;
118     public final TelephonyManager telephonyManager;
119     public final ConnectivityManager connectivityManager;
120     public final AccountManager accountManager;
121     public final AlarmManager alarmManager;
122     public final KeyChain.KeyChainConnection keyChainConnection;
123     public final CrossProfileApps crossProfileApps;
124     public final PersistentDataBlockManagerInternal persistentDataBlockManagerInternal;
125     public final AppOpsManager appOpsManager;
126     public final UsbManager usbManager;
127     public final VpnManager vpnManager;
128     /** Note this is a partial mock, not a real mock. */
129     public final PackageManager packageManager;
130     public final BuildMock buildMock = new BuildMock();
131     public final File dataDir;
132 
MockSystemServices(Context realContext, String name)133     public MockSystemServices(Context realContext, String name) {
134         dataDir = new File(realContext.getCacheDir(), name);
135         DpmTestUtils.clearDir(dataDir);
136 
137         environment = mock(EnvironmentForMock.class);
138         systemProperties = mock(SystemPropertiesForMock.class);
139         userManager = mock(UserManager.class);
140         userManagerInternal = mock(UserManagerInternal.class);
141         usageStatsManagerInternal = mock(UsageStatsManagerInternal.class);
142         networkPolicyManagerInternal = mock(NetworkPolicyManagerInternal.class);
143 
144         userManagerForMock = mock(UserManagerForMock.class);
145         packageManagerInternal = mock(PackageManagerInternal.class);
146         powerManager = mock(PowerManagerForMock.class);
147         powerManagerInternal = mock(PowerManagerInternal.class);
148         recoverySystem = mock(RecoverySystemForMock.class);
149         notificationManager = mock(NotificationManager.class);
150         iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
151         iwindowManager = mock(IWindowManager.class);
152         iactivityManager = mock(IActivityManager.class);
153         iactivityTaskManager = mock(IActivityTaskManager.class);
154         activityManagerInternal = mock(ActivityManagerInternal.class);
155         activityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
156         ipackageManager = mock(IPackageManager.class);
157         ipermissionManager = mock(IPermissionManager.class);
158         ibackupManager = mock(IBackupManager.class);
159         iaudioService = mock(IAudioService.class);
160         lockPatternUtils = mock(LockPatternUtils.class);
161         lockSettingsInternal = mock(LockSettingsInternal.class);
162         storageManager = mock(StorageManagerForMock.class);
163         wifiManager = mock(WifiManager.class);
164         settings = mock(SettingsForMock.class);
165         telephonyManager = mock(TelephonyManager.class);
166         connectivityManager = mock(ConnectivityManager.class);
167         accountManager = mock(AccountManager.class);
168         alarmManager = mock(AlarmManager.class);
169         keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
170         crossProfileApps = mock(CrossProfileApps.class);
171         persistentDataBlockManagerInternal = mock(PersistentDataBlockManagerInternal.class);
172         appOpsManager = mock(AppOpsManager.class);
173         usbManager = mock(UsbManager.class);
174         vpnManager = mock(VpnManager.class);
175 
176         // Package manager is huge, so we use a partial mock instead.
177         packageManager = spy(realContext.getPackageManager());
178         when(packageManagerInternal.getSystemUiServiceComponent()).thenReturn(
179                 new ComponentName("com.android.systemui", ".Service"));
180 
181         contentResolver = new MockContentResolver();
182         contentResolver.addProvider("telephony", new MockContentProvider(realContext) {
183             @Override
184             public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
185                 return 0;
186             }
187 
188             @Override
189             public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
190                     String sortOrder) {
191                 return null;
192             }
193 
194             @Override
195             public int delete(Uri uri, String selection, String[] selectionArgs) {
196                 return 0;
197             }
198         });
199         contentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
200 
201         // Add the system user with a fake profile group already set up (this can happen in the real
202         // world if a managed profile is added and then removed).
203         systemUserDataDir = addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY,
204                 UserManager.USER_TYPE_FULL_SYSTEM, UserHandle.USER_SYSTEM);
205 
206         // System user is always running.
207         setUserRunning(UserHandle.USER_SYSTEM, true);
208     }
209 
210     /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
211     private final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>();
212 
213     private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
214 
215     private final List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>();
216 
registerReceiver( BroadcastReceiver receiver, IntentFilter filter, Handler scheduler)217     public void registerReceiver(
218             BroadcastReceiver receiver, IntentFilter filter, Handler scheduler) {
219         mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
220     }
221 
unregisterReceiver(BroadcastReceiver receiver)222     public void unregisterReceiver(BroadcastReceiver receiver) {
223         mBroadcastReceivers.removeIf(r -> r.receiver == receiver);
224     }
225 
addUser(int userId, int flags, String type)226     public File addUser(int userId, int flags, String type) {
227         return addUser(userId, flags, type, UserInfo.NO_PROFILE_GROUP_ID);
228     }
229 
addUser(int userId, int flags, String type, int profileGroupId)230     public File addUser(int userId, int flags, String type, int profileGroupId) {
231         // Set up (default) UserInfo for CALLER_USER_HANDLE.
232         final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
233 
234         uh.userType = type;
235         uh.profileGroupId = profileGroupId;
236         when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
237         // Ensure there are no duplicate UserInfo records.
238         // TODO: fix tests so that this is not needed.
239         for (int i = 0; i < mUserInfos.size(); i++) {
240             if (mUserInfos.get(i).id == userId) {
241                 mUserInfos.remove(i);
242                 break;
243             }
244         }
245         mUserInfos.add(uh);
246         when(userManager.getUsers()).thenReturn(mUserInfos);
247         when(userManager.getAliveUsers()).thenReturn(mUserInfos);
248         when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
249         when(userManager.getProfileParent(anyInt())).thenAnswer(
250                 invocation -> {
251                     final int userId1 = (int) invocation.getArguments()[0];
252                     final UserInfo ui = getUserInfo(userId1);
253                     return ui == null ? null : getUserInfo(ui.profileGroupId);
254                 }
255         );
256         when(userManager.getProfileParent(any(UserHandle.class))).thenAnswer(
257                 invocation -> {
258                     final UserHandle userHandle = (UserHandle) invocation.getArguments()[0];
259                     final UserInfo ui = getUserInfo(userHandle.getIdentifier());
260                     return ui == null ? UserHandle.USER_NULL : UserHandle.of(ui.profileGroupId);
261                 }
262         );
263         when(userManager.getProfiles(anyInt())).thenAnswer(
264                 invocation -> {
265                     final int userId12 = (int) invocation.getArguments()[0];
266                     return getProfiles(userId12);
267                 }
268         );
269         when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
270                 invocation -> {
271                     final int userId13 = (int) invocation.getArguments()[0];
272                     List<UserInfo> profiles = getProfiles(userId13);
273                     return profiles.stream()
274                             .mapToInt(profile -> profile.id)
275                             .toArray();
276                 }
277         );
278         when(userManagerInternal.getUserInfos()).thenReturn(
279                 mUserInfos.toArray(new UserInfo[mUserInfos.size()]));
280 
281         when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
282 
283         // Create a data directory.
284         final File dir = new File(dataDir, "users/" + userId);
285         DpmTestUtils.clearDir(dir);
286 
287         when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
288         return dir;
289     }
290 
removeUser(int userId)291     public void removeUser(int userId) {
292         for (int i = 0; i < mUserInfos.size(); i++) {
293             if (mUserInfos.get(i).id == userId) {
294                 mUserInfos.remove(i);
295                 break;
296             }
297         }
298         when(userManager.getUserInfo(eq(userId))).thenReturn(null);
299 
300         when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false);
301     }
302 
getUserInfo(int userId)303     private UserInfo getUserInfo(int userId) {
304         for (final UserInfo ui : mUserInfos) {
305             if (ui.id == userId) {
306                 return ui;
307             }
308         }
309         return null;
310     }
311 
getProfiles(int userId)312     private List<UserInfo> getProfiles(int userId) {
313         final ArrayList<UserInfo> ret = new ArrayList<>();
314         UserInfo parent = null;
315         for (final UserInfo ui : mUserInfos) {
316             if (ui.id == userId) {
317                 parent = ui;
318                 break;
319             }
320         }
321         if (parent == null) {
322             return ret;
323         }
324         for (final UserInfo ui : mUserInfos) {
325             if (ui == parent
326                     || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
327                     && ui.profileGroupId == parent.profileGroupId) {
328                 ret.add(ui);
329             }
330         }
331         return ret;
332     }
333 
334     /**
335      * Add multiple users at once.  They'll all have flag 0.
336      */
addUsers(int... userIds)337     public void addUsers(int... userIds) {
338         for (final int userId : userIds) {
339             addUser(userId, 0, "");
340         }
341     }
342 
setUserRunning(int userId, boolean isRunning)343     public void setUserRunning(int userId, boolean isRunning) {
344         when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
345                 .thenReturn(isRunning);
346     }
347 
injectBroadcast(Context context, final Intent intent, int userId)348     public void injectBroadcast(Context context, final Intent intent, int userId) {
349         //final int userId = UserHandle.getUserId(binder.getCallingUid());
350         for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
351             receiver.sendBroadcastIfApplicable(context, userId, intent);
352         }
353     }
354 
rethrowBackgroundBroadcastExceptions()355     public void rethrowBackgroundBroadcastExceptions() throws Exception {
356         for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
357             final Exception e = receiver.backgroundException.getAndSet(null);
358             if (e != null) {
359                 throw e;
360             }
361         }
362     }
363 
addPackageContext(UserHandle user, Context context)364     public void addPackageContext(UserHandle user, Context context) {
365         if (context.getPackageName() == null) {
366             throw new NullPointerException("getPackageName() == null");
367         }
368         userPackageContexts.put(new Pair<>(user, context.getPackageName()), context);
369     }
370 
createPackageContextAsUser(String packageName, int flags, UserHandle user)371     public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
372             throws PackageManager.NameNotFoundException {
373         final Pair<UserHandle, String> key = new Pair<>(user, packageName);
374         if (userPackageContexts.containsKey(key)) {
375             return userPackageContexts.get(key);
376         }
377         throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
378     }
379 
380 
381     public static class EnvironmentForMock {
getUserSystemDirectory(int userId)382         public File getUserSystemDirectory(int userId) {
383             return null;
384         }
385     }
386 
387     public static class BuildMock {
388         public boolean isDebuggable = true;
389     }
390 
391     public static class PowerManagerForMock {
newWakeLock(int levelAndFlags, String tag)392         public PowerManager.WakeLock newWakeLock(int levelAndFlags, String tag) {
393             return null;
394         }
395 
goToSleep(long time, int reason, int flags)396         public void goToSleep(long time, int reason, int flags) {
397         }
398 
reboot(String reason)399         public void reboot(String reason) {
400         }
401     }
402 
403     public static class RecoverySystemForMock {
rebootWipeUserData(boolean shutdown, String reason, boolean force, boolean wipeEuicc, boolean wipeExtRequested, boolean wipeResetProtectionData)404         public boolean rebootWipeUserData(boolean shutdown, String reason, boolean force,
405                 boolean wipeEuicc, boolean wipeExtRequested, boolean wipeResetProtectionData)
406                         throws IOException {
407             return false;
408         }
409     }
410 
411     public static class SystemPropertiesForMock {
getBoolean(String key, boolean def)412         public boolean getBoolean(String key, boolean def) {
413             return false;
414         }
415 
getLong(String key, long def)416         public long getLong(String key, long def) {
417             return 0;
418         }
419 
get(String key, String def)420         public String get(String key, String def) {
421             return null;
422         }
423 
get(String key)424         public String get(String key) {
425             return null;
426         }
427 
set(String key, String value)428         public void set(String key, String value) {
429         }
430     }
431 
432     public static class UserManagerForMock {
isHeadlessSystemUserMode()433         public boolean isHeadlessSystemUserMode() {
434             return false;
435         }
436     }
437 
438     public static class SettingsForMock {
settingsSecureGetIntForUser(String name, int def, int userHandle)439         public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
440             return 0;
441         }
442 
settingsSecureGetStringForUser(String name, int userHandle)443         public String settingsSecureGetStringForUser(String name, int userHandle) {
444             return null;
445         }
446 
settingsSecurePutIntForUser(String name, int value, int userHandle)447         public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
448         }
449 
settingsSecurePutStringForUser(String name, String value, int userHandle)450         public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
451         }
452 
settingsGlobalPutStringForUser(String name, String value, int userHandle)453         public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
454         }
455 
settingsSecurePutInt(String name, int value)456         public void settingsSecurePutInt(String name, int value) {
457         }
458 
settingsGlobalPutInt(String name, int value)459         public void settingsGlobalPutInt(String name, int value) {
460         }
461 
settingsSecurePutString(String name, String value)462         public void settingsSecurePutString(String name, String value) {
463         }
464 
settingsGlobalPutString(String name, String value)465         public void settingsGlobalPutString(String name, String value) {
466         }
467 
settingsSystemPutStringForUser(String name, String value, int callingUserId)468         public void settingsSystemPutStringForUser(String name, String value, int callingUserId) {
469         }
470 
settingsGlobalGetInt(String name, int value)471         public int settingsGlobalGetInt(String name, int value) {
472             return 0;
473         }
474 
settingsGlobalGetString(String name)475         public String settingsGlobalGetString(String name) {
476             return "";
477         }
478 
securityLogSetLoggingEnabledProperty(boolean enabled)479         public void securityLogSetLoggingEnabledProperty(boolean enabled) {
480         }
481 
securityLogGetLoggingEnabledProperty()482         public boolean securityLogGetLoggingEnabledProperty() {
483             return false;
484         }
485 
securityLogIsLoggingEnabled()486         public boolean securityLogIsLoggingEnabled() {
487             return false;
488         }
489     }
490 
491     public static class StorageManagerForMock {
isFileBasedEncryptionEnabled()492         public boolean isFileBasedEncryptionEnabled() {
493             return false;
494         }
495 
isNonDefaultBlockEncrypted()496         public boolean isNonDefaultBlockEncrypted() {
497             return false;
498         }
499 
isEncrypted()500         public boolean isEncrypted() {
501             return false;
502         }
503 
isEncryptable()504         public boolean isEncryptable() {
505             return false;
506         }
507     }
508 
509     // We have to keep track of broadcast receivers registered for a given intent ourselves as the
510     // DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does
511     // not work.
512     private static class BroadcastReceiverRegistration {
513         public final BroadcastReceiver receiver;
514         public final IntentFilter filter;
515         public final Handler scheduler;
516 
517         // Exceptions thrown in a background thread kill the whole test. Save them instead.
518         public final AtomicReference<Exception> backgroundException = new AtomicReference<>();
519 
BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter, Handler scheduler)520         public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter,
521                 Handler scheduler) {
522             this.receiver = receiver;
523             this.filter = filter;
524             this.scheduler = scheduler;
525         }
526 
sendBroadcastIfApplicable(Context context, int userId, Intent intent)527         public void sendBroadcastIfApplicable(Context context, int userId, Intent intent) {
528             final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult(
529                     0 /* resultCode */, null /* resultData */, null /* resultExtras */,
530                     0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId,
531                     0 /* flags */);
532             if (filter.match(null, intent, false, "DpmMockContext") > 0) {
533                 final Runnable send = () -> {
534                     receiver.setPendingResult(result);
535                     receiver.onReceive(context, intent);
536                 };
537                 if (scheduler != null) {
538                     scheduler.post(() -> {
539                         try {
540                             send.run();
541                         } catch (Exception e) {
542                             backgroundException.compareAndSet(null, e);
543                         }
544                     });
545                 } else {
546                     send.run();
547                 }
548             }
549         }
550     }
551 }
552