blob: b208f828ee85cc01142bce272a9ca18945eaf4e3 [file] [log] [blame]
Pavel Grafov75c0a892017-05-18 17:28:27 +01001/*
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 */
16package com.android.server.devicepolicy;
17
18import static org.mockito.ArgumentMatchers.anyBoolean;
19import static org.mockito.ArgumentMatchers.anyInt;
20import static org.mockito.ArgumentMatchers.eq;
21import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
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;
Alex Chaub6ef8692018-01-09 14:16:36 +000028import android.app.ActivityManagerInternal;
Pavel Grafov75c0a892017-05-18 17:28:27 +010029import android.app.AlarmManager;
30import android.app.IActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070031import android.app.IActivityTaskManager;
Pavel Grafov75c0a892017-05-18 17:28:27 +010032import android.app.NotificationManager;
33import android.app.backup.IBackupManager;
Neil Fuller3aedd492019-11-23 11:33:57 +000034import android.app.timedetector.TimeDetector;
Sudheer Shanka101c3532018-01-08 16:28:42 -080035import android.app.usage.UsageStatsManagerInternal;
Pavel Grafov75c0a892017-05-18 17:28:27 +010036import android.content.BroadcastReceiver;
yuemingwe3d9c092018-01-11 12:11:44 +000037import android.content.ContentValues;
Pavel Grafov75c0a892017-05-18 17:28:27 +010038import android.content.Context;
39import android.content.Intent;
40import android.content.IntentFilter;
41import android.content.pm.IPackageManager;
42import android.content.pm.PackageManager;
43import android.content.pm.PackageManagerInternal;
44import android.content.pm.UserInfo;
yuemingwe3d9c092018-01-11 12:11:44 +000045import android.database.Cursor;
Pavel Grafov75c0a892017-05-18 17:28:27 +010046import android.media.IAudioService;
47import android.net.IIpConnectivityMetrics;
yuemingwe3d9c092018-01-11 12:11:44 +000048import android.net.Uri;
Pavel Grafov75c0a892017-05-18 17:28:27 +010049import android.net.wifi.WifiManager;
50import android.os.Handler;
51import android.os.PowerManager;
52import android.os.PowerManagerInternal;
53import android.os.UserHandle;
54import android.os.UserManager;
55import android.os.UserManagerInternal;
Christine Franks9a18f5f2017-08-07 14:28:35 -070056import android.provider.Settings;
Pavel Grafov75c0a892017-05-18 17:28:27 +010057import android.security.KeyChain;
58import android.telephony.TelephonyManager;
yuemingwe3d9c092018-01-11 12:11:44 +000059import android.test.mock.MockContentProvider;
Pavel Grafov75c0a892017-05-18 17:28:27 +010060import android.test.mock.MockContentResolver;
61import android.util.ArrayMap;
62import android.util.Pair;
63import android.view.IWindowManager;
64
Christine Franks9a18f5f2017-08-07 14:28:35 -070065import com.android.internal.util.test.FakeSettingsProvider;
Pavel Grafov75c0a892017-05-18 17:28:27 +010066import com.android.internal.widget.LockPatternUtils;
Sudheer Shankac53c47f2018-01-16 12:01:00 -080067import com.android.server.net.NetworkPolicyManagerInternal;
Michal Karpinski4026cae2019-02-12 11:51:47 +000068import com.android.server.wm.ActivityTaskManagerInternal;
Pavel Grafov75c0a892017-05-18 17:28:27 +010069
70import java.io.File;
71import java.io.IOException;
72import java.util.ArrayList;
73import java.util.List;
74import java.util.Map;
75import java.util.concurrent.atomic.AtomicReference;
76
77/**
78 * System services mocks and some other data that are shared by all contexts during the test.
79 */
80public class MockSystemServices {
81 public final File systemUserDataDir;
82 public final EnvironmentForMock environment;
83 public final SystemPropertiesForMock systemProperties;
84 public final UserManager userManager;
85 public final UserManagerInternal userManagerInternal;
Sudheer Shanka101c3532018-01-08 16:28:42 -080086 public final UsageStatsManagerInternal usageStatsManagerInternal;
Sudheer Shankac53c47f2018-01-16 12:01:00 -080087 public final NetworkPolicyManagerInternal networkPolicyManagerInternal;
Pavel Grafov75c0a892017-05-18 17:28:27 +010088 public final PackageManagerInternal packageManagerInternal;
89 public final UserManagerForMock userManagerForMock;
90 public final PowerManagerForMock powerManager;
91 public final PowerManagerInternal powerManagerInternal;
92 public final RecoverySystemForMock recoverySystem;
93 public final NotificationManager notificationManager;
94 public final IIpConnectivityMetrics iipConnectivityMetrics;
95 public final IWindowManager iwindowManager;
96 public final IActivityManager iactivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070097 public final IActivityTaskManager iactivityTaskManager;
Alex Chaub6ef8692018-01-09 14:16:36 +000098 public ActivityManagerInternal activityManagerInternal;
Michal Karpinski4026cae2019-02-12 11:51:47 +000099 public ActivityTaskManagerInternal activityTaskManagerInternal;
Pavel Grafov75c0a892017-05-18 17:28:27 +0100100 public final IPackageManager ipackageManager;
101 public final IBackupManager ibackupManager;
102 public final IAudioService iaudioService;
103 public final LockPatternUtils lockPatternUtils;
104 public final StorageManagerForMock storageManager;
105 public final WifiManager wifiManager;
106 public final SettingsForMock settings;
107 public final MockContentResolver contentResolver;
108 public final TelephonyManager telephonyManager;
109 public final AccountManager accountManager;
110 public final AlarmManager alarmManager;
Neil Fuller3aedd492019-11-23 11:33:57 +0000111 public final TimeDetector timeDetector;
Pavel Grafov75c0a892017-05-18 17:28:27 +0100112 public final KeyChain.KeyChainConnection keyChainConnection;
113 /** Note this is a partial mock, not a real mock. */
114 public final PackageManager packageManager;
115 public final BuildMock buildMock = new BuildMock();
116 public final File dataDir;
117
118 public MockSystemServices(Context realContext, String name) {
119 dataDir = new File(realContext.getCacheDir(), name);
120 DpmTestUtils.clearDir(dataDir);
121
122 environment = mock(EnvironmentForMock.class);
123 systemProperties = mock(SystemPropertiesForMock.class);
124 userManager = mock(UserManager.class);
125 userManagerInternal = mock(UserManagerInternal.class);
Sudheer Shanka101c3532018-01-08 16:28:42 -0800126 usageStatsManagerInternal = mock(UsageStatsManagerInternal.class);
Sudheer Shankac53c47f2018-01-16 12:01:00 -0800127 networkPolicyManagerInternal = mock(NetworkPolicyManagerInternal.class);
128
Pavel Grafov75c0a892017-05-18 17:28:27 +0100129 userManagerForMock = mock(UserManagerForMock.class);
130 packageManagerInternal = mock(PackageManagerInternal.class);
131 powerManager = mock(PowerManagerForMock.class);
132 powerManagerInternal = mock(PowerManagerInternal.class);
133 recoverySystem = mock(RecoverySystemForMock.class);
134 notificationManager = mock(NotificationManager.class);
135 iipConnectivityMetrics = mock(IIpConnectivityMetrics.class);
136 iwindowManager = mock(IWindowManager.class);
137 iactivityManager = mock(IActivityManager.class);
Wale Ogunwale04d9cb52018-04-30 13:55:07 -0700138 iactivityTaskManager = mock(IActivityTaskManager.class);
Alex Chaub6ef8692018-01-09 14:16:36 +0000139 activityManagerInternal = mock(ActivityManagerInternal.class);
Michal Karpinski4026cae2019-02-12 11:51:47 +0000140 activityTaskManagerInternal = mock(ActivityTaskManagerInternal.class);
Pavel Grafov75c0a892017-05-18 17:28:27 +0100141 ipackageManager = mock(IPackageManager.class);
142 ibackupManager = mock(IBackupManager.class);
143 iaudioService = mock(IAudioService.class);
144 lockPatternUtils = mock(LockPatternUtils.class);
145 storageManager = mock(StorageManagerForMock.class);
146 wifiManager = mock(WifiManager.class);
147 settings = mock(SettingsForMock.class);
148 telephonyManager = mock(TelephonyManager.class);
149 accountManager = mock(AccountManager.class);
150 alarmManager = mock(AlarmManager.class);
Neil Fuller3aedd492019-11-23 11:33:57 +0000151 timeDetector = mock(TimeDetector.class);
Pavel Grafov75c0a892017-05-18 17:28:27 +0100152 keyChainConnection = mock(KeyChain.KeyChainConnection.class, RETURNS_DEEP_STUBS);
153
154 // Package manager is huge, so we use a partial mock instead.
155 packageManager = spy(realContext.getPackageManager());
156
157 contentResolver = new MockContentResolver();
yuemingwe3d9c092018-01-11 12:11:44 +0000158 contentResolver.addProvider("telephony", new MockContentProvider(realContext) {
159 @Override
160 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
161 return 0;
162 }
163
164 @Override
165 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
166 String sortOrder) {
167 return null;
168 }
169
170 @Override
171 public int delete(Uri uri, String selection, String[] selectionArgs) {
172 return 0;
173 }
174 });
Christine Franks9a18f5f2017-08-07 14:28:35 -0700175 contentResolver.addProvider(Settings.AUTHORITY, new FakeSettingsProvider());
Pavel Grafov75c0a892017-05-18 17:28:27 +0100176
177 // Add the system user with a fake profile group already set up (this can happen in the real
178 // world if a managed profile is added and then removed).
179 systemUserDataDir =
180 addUser(UserHandle.USER_SYSTEM, UserInfo.FLAG_PRIMARY, UserHandle.USER_SYSTEM);
181
182 // System user is always running.
183 setUserRunning(UserHandle.USER_SYSTEM, true);
184 }
185
186 /** Optional mapping of other user contexts for {@link #createPackageContextAsUser} to return */
187 private final Map<Pair<UserHandle, String>, Context> userPackageContexts = new ArrayMap<>();
188
189 private final ArrayList<UserInfo> mUserInfos = new ArrayList<>();
190
191 private final List<BroadcastReceiverRegistration> mBroadcastReceivers = new ArrayList<>();
192
193 public void registerReceiver(
194 BroadcastReceiver receiver, IntentFilter filter, Handler scheduler) {
195 mBroadcastReceivers.add(new BroadcastReceiverRegistration(receiver, filter, scheduler));
196 }
197
198 public void unregisterReceiver(BroadcastReceiver receiver) {
199 mBroadcastReceivers.removeIf(r -> r.receiver == receiver);
200 }
201
202 public File addUser(int userId, int flags) {
203 return addUser(userId, flags, UserInfo.NO_PROFILE_GROUP_ID);
204 }
205
206 public File addUser(int userId, int flags, int profileGroupId) {
207 // Set up (default) UserInfo for CALLER_USER_HANDLE.
208 final UserInfo uh = new UserInfo(userId, "user" + userId, flags);
209 uh.profileGroupId = profileGroupId;
210 when(userManager.getUserInfo(eq(userId))).thenReturn(uh);
211
212 mUserInfos.add(uh);
213 when(userManager.getUsers()).thenReturn(mUserInfos);
214 when(userManager.getUsers(anyBoolean())).thenReturn(mUserInfos);
215 when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(true);
216 when(userManager.getUserInfo(anyInt())).thenAnswer(
217 invocation -> {
218 final int userId1 = (int) invocation.getArguments()[0];
219 return getUserInfo(userId1);
220 }
221 );
Pavel Grafov28939982017-10-03 15:11:52 +0100222 when(userManager.getProfileParent(anyInt())).thenAnswer(
223 invocation -> {
224 final int userId1 = (int) invocation.getArguments()[0];
225 final UserInfo ui = getUserInfo(userId1);
226 return ui == null ? null : getUserInfo(ui.profileGroupId);
227 }
228 );
Pavel Grafov75c0a892017-05-18 17:28:27 +0100229 when(userManager.getProfiles(anyInt())).thenAnswer(
230 invocation -> {
231 final int userId12 = (int) invocation.getArguments()[0];
232 return getProfiles(userId12);
233 }
234 );
235 when(userManager.getProfileIdsWithDisabled(anyInt())).thenAnswer(
236 invocation -> {
237 final int userId13 = (int) invocation.getArguments()[0];
238 List<UserInfo> profiles = getProfiles(userId13);
239 return profiles.stream()
240 .mapToInt(profile -> profile.id)
241 .toArray();
242 }
243 );
244 when(accountManager.getAccountsAsUser(anyInt())).thenReturn(new Account[0]);
245
246 // Create a data directory.
247 final File dir = new File(dataDir, "users/" + userId);
248 DpmTestUtils.clearDir(dir);
249
250 when(environment.getUserSystemDirectory(eq(userId))).thenReturn(dir);
251 return dir;
252 }
253
254 public void removeUser(int userId) {
255 for (int i = 0; i < mUserInfos.size(); i++) {
256 if (mUserInfos.get(i).id == userId) {
257 mUserInfos.remove(i);
258 break;
259 }
260 }
261 when(userManager.getUserInfo(eq(userId))).thenReturn(null);
262
263 when(userManager.isUserRunning(eq(new UserHandle(userId)))).thenReturn(false);
264 }
265
266 private UserInfo getUserInfo(int userId) {
267 for (final UserInfo ui : mUserInfos) {
268 if (ui.id == userId) {
269 return ui;
270 }
271 }
272 return null;
273 }
274
275 private List<UserInfo> getProfiles(int userId) {
276 final ArrayList<UserInfo> ret = new ArrayList<>();
277 UserInfo parent = null;
278 for (final UserInfo ui : mUserInfos) {
279 if (ui.id == userId) {
280 parent = ui;
281 break;
282 }
283 }
284 if (parent == null) {
285 return ret;
286 }
287 for (final UserInfo ui : mUserInfos) {
288 if (ui == parent
289 || ui.profileGroupId != UserInfo.NO_PROFILE_GROUP_ID
290 && ui.profileGroupId == parent.profileGroupId) {
291 ret.add(ui);
292 }
293 }
294 return ret;
295 }
296
297 /**
298 * Add multiple users at once. They'll all have flag 0.
299 */
300 public void addUsers(int... userIds) {
301 for (final int userId : userIds) {
302 addUser(userId, 0);
303 }
304 }
305
306 public void setUserRunning(int userId, boolean isRunning) {
307 when(userManager.isUserRunning(MockUtils.checkUserHandle(userId)))
308 .thenReturn(isRunning);
309 }
310
311 public void injectBroadcast(Context context, final Intent intent, int userId) {
312 //final int userId = UserHandle.getUserId(binder.getCallingUid());
313 for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
314 receiver.sendBroadcastIfApplicable(context, userId, intent);
315 }
316 }
317
318 public void rethrowBackgroundBroadcastExceptions() throws Exception {
319 for (final BroadcastReceiverRegistration receiver : mBroadcastReceivers) {
320 final Exception e = receiver.backgroundException.getAndSet(null);
321 if (e != null) {
322 throw e;
323 }
324 }
325 }
326
327 public void addPackageContext(UserHandle user, Context context) {
328 if (context.getPackageName() == null) {
329 throw new NullPointerException("getPackageName() == null");
330 }
331 userPackageContexts.put(new Pair<>(user, context.getPackageName()), context);
332 }
333
334 public Context createPackageContextAsUser(String packageName, int flags, UserHandle user)
335 throws PackageManager.NameNotFoundException {
336 final Pair<UserHandle, String> key = new Pair<>(user, packageName);
337 if (userPackageContexts.containsKey(key)) {
338 return userPackageContexts.get(key);
339 }
340 throw new UnsupportedOperationException("No package " + packageName + " for user " + user);
341 }
342
343
344 public static class EnvironmentForMock {
345 public File getUserSystemDirectory(int userId) {
346 return null;
347 }
348 }
349
350 public static class BuildMock {
351 public boolean isDebuggable = true;
352 }
353
354 public static class PowerManagerForMock {
355 public PowerManager.WakeLock newWakeLock(int levelAndFlags, String tag) {
356 return null;
357 }
358
359 public void goToSleep(long time, int reason, int flags) {
360 }
361
362 public void reboot(String reason) {
363 }
364 }
365
366 public static class RecoverySystemForMock {
yinxuf4f9cec2017-06-19 10:28:19 -0700367 public void rebootWipeUserData(boolean shutdown, String reason, boolean force,
368 boolean wipeEuicc) throws IOException {
Pavel Grafov75c0a892017-05-18 17:28:27 +0100369 }
370 }
371
372 public static class SystemPropertiesForMock {
373 public boolean getBoolean(String key, boolean def) {
374 return false;
375 }
376
377 public long getLong(String key, long def) {
378 return 0;
379 }
380
381 public String get(String key, String def) {
382 return null;
383 }
384
385 public String get(String key) {
386 return null;
387 }
388
389 public void set(String key, String value) {
390 }
391 }
392
393 public static class UserManagerForMock {
394 public boolean isSplitSystemUser() {
395 return false;
396 }
397 }
398
399 public static class SettingsForMock {
400 public int settingsSecureGetIntForUser(String name, int def, int userHandle) {
401 return 0;
402 }
403
404 public String settingsSecureGetStringForUser(String name, int userHandle) {
405 return null;
406 }
407
408 public void settingsSecurePutIntForUser(String name, int value, int userHandle) {
409 }
410
411 public void settingsSecurePutStringForUser(String name, String value, int userHandle) {
412 }
413
414 public void settingsGlobalPutStringForUser(String name, String value, int userHandle) {
415 }
416
417 public void settingsSecurePutInt(String name, int value) {
418 }
419
420 public void settingsGlobalPutInt(String name, int value) {
421 }
422
423 public void settingsSecurePutString(String name, String value) {
424 }
425
426 public void settingsGlobalPutString(String name, String value) {
427 }
428
yuemingwc0281f12018-03-28 15:58:49 +0100429 public void settingsSystemPutStringForUser(String name, String value, int callingUserId) {
yuemingw0de748d2017-11-15 19:22:27 +0000430 }
431
Pavel Grafov75c0a892017-05-18 17:28:27 +0100432 public int settingsGlobalGetInt(String name, int value) {
433 return 0;
434 }
435
436 public String settingsGlobalGetString(String name) {
437 return "";
438 }
439
440 public void securityLogSetLoggingEnabledProperty(boolean enabled) {
441 }
442
443 public boolean securityLogGetLoggingEnabledProperty() {
444 return false;
445 }
446
447 public boolean securityLogIsLoggingEnabled() {
448 return false;
449 }
450 }
451
452 public static class StorageManagerForMock {
453 public boolean isFileBasedEncryptionEnabled() {
454 return false;
455 }
456
457 public boolean isNonDefaultBlockEncrypted() {
458 return false;
459 }
460
461 public boolean isEncrypted() {
462 return false;
463 }
464
465 public boolean isEncryptable() {
466 return false;
467 }
468 }
469
470 // We have to keep track of broadcast receivers registered for a given intent ourselves as the
471 // DPM unit tests mock out the package manager and PackageManager.queryBroadcastReceivers() does
472 // not work.
473 private static class BroadcastReceiverRegistration {
474 public final BroadcastReceiver receiver;
475 public final IntentFilter filter;
476 public final Handler scheduler;
477
478 // Exceptions thrown in a background thread kill the whole test. Save them instead.
479 public final AtomicReference<Exception> backgroundException = new AtomicReference<>();
480
481 public BroadcastReceiverRegistration(BroadcastReceiver receiver, IntentFilter filter,
482 Handler scheduler) {
483 this.receiver = receiver;
484 this.filter = filter;
485 this.scheduler = scheduler;
486 }
487
488 public void sendBroadcastIfApplicable(Context context, int userId, Intent intent) {
489 final BroadcastReceiver.PendingResult result = new BroadcastReceiver.PendingResult(
490 0 /* resultCode */, null /* resultData */, null /* resultExtras */,
491 0 /* type */, false /* ordered */, false /* sticky */, null /* token */, userId,
492 0 /* flags */);
493 if (filter.match(null, intent, false, "DpmMockContext") > 0) {
494 final Runnable send = () -> {
495 receiver.setPendingResult(result);
496 receiver.onReceive(context, intent);
497 };
498 if (scheduler != null) {
499 scheduler.post(() -> {
500 try {
501 send.run();
502 } catch (Exception e) {
503 backgroundException.compareAndSet(null, e);
504 }
505 });
506 } else {
507 send.run();
508 }
509 }
510 }
511 }
512}