blob: 5b2379833ad69e879610731e9ae19add76324fb5 [file] [log] [blame]
Makoto Onukicc4bbeb2015-09-17 10:28:24 -07001/*
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 */
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070016package com.android.server.devicepolicy;
17
18import com.android.server.LocalServices;
19
Makoto Onukif76b06a2015-09-22 15:03:44 -070020import android.Manifest.permission;
21import android.app.Activity;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070022import android.app.admin.DeviceAdminReceiver;
23import android.app.admin.DevicePolicyManager;
24import android.app.admin.DevicePolicyManagerInternal;
Makoto Onukif76b06a2015-09-22 15:03:44 -070025import android.content.BroadcastReceiver;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070026import android.content.ComponentName;
27import android.content.Intent;
Makoto Onukif76b06a2015-09-22 15:03:44 -070028import android.content.pm.ApplicationInfo;
29import android.content.pm.IPackageManager;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070030import android.content.pm.PackageManager;
31import android.content.pm.ResolveInfo;
Makoto Onukif76b06a2015-09-22 15:03:44 -070032import android.os.Bundle;
Makoto Onukib643fb02015-09-22 15:03:44 -070033import android.content.pm.PackageInfo;
34import android.content.pm.UserInfo;
35import android.os.UserHandle;
36import android.util.Pair;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070037
38import org.mockito.ArgumentCaptor;
Makoto Onukib643fb02015-09-22 15:03:44 -070039import org.mockito.invocation.InvocationOnMock;
40import org.mockito.stubbing.Answer;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070041
Makoto Onukib643fb02015-09-22 15:03:44 -070042import java.util.HashMap;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070043import java.util.List;
Makoto Onukib643fb02015-09-22 15:03:44 -070044import java.util.Map;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070045
46import static org.mockito.Matchers.any;
Makoto Onukif76b06a2015-09-22 15:03:44 -070047import static org.mockito.Matchers.anyString;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070048import static org.mockito.Matchers.eq;
Makoto Onukif76b06a2015-09-22 15:03:44 -070049import static org.mockito.Matchers.isNull;
Makoto Onukib643fb02015-09-22 15:03:44 -070050import static org.mockito.Mockito.doAnswer;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070051import static org.mockito.Mockito.doReturn;
52import static org.mockito.Mockito.times;
53import static org.mockito.Mockito.verify;
54import static org.mockito.Mockito.when;
55
56/**
Makoto Onukif76b06a2015-09-22 15:03:44 -070057 * Tests for DevicePolicyManager( and DevicePolicyManagerService).
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070058 *
59 m FrameworksServicesTests &&
60 adb install \
61 -r out/target/product/hammerhead/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
62 adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest \
63 -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
64
65 (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
66 */
67public class DevicePolicyManagerTest extends DpmTestBase {
68
Makoto Onukif76b06a2015-09-22 15:03:44 -070069
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070070 private DpmMockContext mContext;
71 public DevicePolicyManager dpm;
72 public DevicePolicyManagerServiceTestable dpms;
Makoto Onukif76b06a2015-09-22 15:03:44 -070073 public ComponentName admin1;
74 public ComponentName admin2;
75 public ComponentName admin3;
Makoto Onukicc4bbeb2015-09-17 10:28:24 -070076
77 @Override
78 protected void setUp() throws Exception {
79 super.setUp();
80
81 mContext = getContext();
82
83 when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
84 .thenReturn(true);
85
86 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
87 dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
88 dpm = new DevicePolicyManagerTestable(mContext, dpms);
Makoto Onukif76b06a2015-09-22 15:03:44 -070089
90 admin1 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin1.class);
91 admin2 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin2.class);
92 admin3 = new ComponentName(mRealTestContext, DummyDeviceAdmins.Admin3.class);
93
Makoto Onukid932f762015-09-29 16:53:38 -070094 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
95 setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
96 setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID);
Makoto Onukif76b06a2015-09-22 15:03:44 -070097
Makoto Onukid932f762015-09-29 16:53:38 -070098 setUpApplicationInfo(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
99 DpmMockContext.CALLER_UID);
100
Makoto Onukib643fb02015-09-22 15:03:44 -0700101 setUpPackageInfo();
102 setUpUserManager();
Makoto Onukif76b06a2015-09-22 15:03:44 -0700103 }
104
105 /**
106 * Set up a mock result for {@link PackageManager#queryBroadcastReceivers}. We'll return
107 * the actual ResolveInfo for the admin component, but we need to mock PM so it'll return
108 * it for user {@link DpmMockContext#CALLER_USER_HANDLE}.
109 */
Makoto Onukid932f762015-09-29 16:53:38 -0700110 private void setUpPackageManagerForAdmin(ComponentName admin, int packageUid) {
Makoto Onukif76b06a2015-09-22 15:03:44 -0700111 final Intent resolveIntent = new Intent();
112 resolveIntent.setComponent(admin);
113 final List<ResolveInfo> realResolveInfo =
114 mRealTestContext.getPackageManager().queryBroadcastReceivers(
115 resolveIntent,
116 PackageManager.GET_META_DATA);
117 assertNotNull(realResolveInfo);
118 assertEquals(1, realResolveInfo.size());
119
Makoto Onukid932f762015-09-29 16:53:38 -0700120 // We need to change AI, so set a clone.
121 realResolveInfo.set(0, DpmTestUtils.cloneParcelable(realResolveInfo.get(0)));
122
Makoto Onukif76b06a2015-09-22 15:03:44 -0700123 // We need to rewrite the UID in the activity info.
Makoto Onukid932f762015-09-29 16:53:38 -0700124 realResolveInfo.get(0).activityInfo.applicationInfo.uid = packageUid;
Makoto Onukif76b06a2015-09-22 15:03:44 -0700125
126 doReturn(realResolveInfo).when(mContext.packageManager).queryBroadcastReceivers(
127 MockUtils.checkIntentComponent(admin),
128 eq(PackageManager.GET_META_DATA
129 | PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS),
Makoto Onukid932f762015-09-29 16:53:38 -0700130 eq(UserHandle.getUserId(packageUid)));
Makoto Onukif76b06a2015-09-22 15:03:44 -0700131 }
132
133 /**
134 * Set up a mock result for {@link IPackageManager#getApplicationInfo} for user
135 * {@link DpmMockContext#CALLER_USER_HANDLE}.
136 */
Makoto Onukid932f762015-09-29 16:53:38 -0700137 private void setUpApplicationInfo(int enabledSetting, int packageUid) throws Exception {
138 final ApplicationInfo ai = DpmTestUtils.cloneParcelable(
139 mRealTestContext.getPackageManager().getApplicationInfo(
140 admin1.getPackageName(),
141 PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS));
Makoto Onukif76b06a2015-09-22 15:03:44 -0700142
143 ai.enabledSetting = enabledSetting;
Makoto Onukid932f762015-09-29 16:53:38 -0700144 ai.uid = packageUid;
Makoto Onukif76b06a2015-09-22 15:03:44 -0700145
146 doReturn(ai).when(mContext.ipackageManager).getApplicationInfo(
147 eq(admin1.getPackageName()),
148 eq(PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS),
Makoto Onukid932f762015-09-29 16:53:38 -0700149 eq(UserHandle.getUserId(packageUid)));
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700150 }
151
Makoto Onukib643fb02015-09-22 15:03:44 -0700152 /**
153 * Set up a mock result for {@link IPackageManager#getPackageInfo(String, int, int)} for user
154 * {@link DpmMockContext#CALLER_USER_HANDLE} as well as the system user.
155 */
156 private void setUpPackageInfo() throws Exception {
157 final PackageInfo pi = mRealTestContext.getPackageManager().getPackageInfo(
158 admin1.getPackageName(), 0);
159 assertTrue(pi.applicationInfo.flags != 0);
160
161 doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
162 eq(admin1.getPackageName()),
163 eq(0),
164 eq(DpmMockContext.CALLER_USER_HANDLE));
165 doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
166 eq(admin1.getPackageName()),
167 eq(0),
168 eq(UserHandle.USER_SYSTEM));
169 }
170
171 private void setUpUserManager() {
172 // Emulate UserManager.set/getApplicationRestriction().
173 final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>();
174
175 // UM.setApplicationRestrictions() will save to appRestrictions.
176 doAnswer(new Answer<Void>() {
177 @Override
178 public Void answer(InvocationOnMock invocation) throws Throwable {
179 String pkg = (String) invocation.getArguments()[0];
180 Bundle bundle = (Bundle) invocation.getArguments()[1];
181 UserHandle user = (UserHandle) invocation.getArguments()[2];
182
183 appRestrictions.put(Pair.create(pkg, user), bundle);
184
185 return null;
186 }
187 }).when(mContext.userManager).setApplicationRestrictions(
188 anyString(), any(Bundle.class), any(UserHandle.class));
189
190 // UM.getApplicationRestrictions() will read from appRestrictions.
191 doAnswer(new Answer<Bundle>() {
192 @Override
193 public Bundle answer(InvocationOnMock invocation) throws Throwable {
194 String pkg = (String) invocation.getArguments()[0];
195 UserHandle user = (UserHandle) invocation.getArguments()[1];
196
197 return appRestrictions.get(Pair.create(pkg, user));
198 }
199 }).when(mContext.userManager).getApplicationRestrictions(
200 anyString(), any(UserHandle.class));
201
Makoto Onukid932f762015-09-29 16:53:38 -0700202 // Add the first secondary user.
203 mContext.addUser(DpmMockContext.CALLER_USER_HANDLE, 0);
Makoto Onukib643fb02015-09-22 15:03:44 -0700204 }
205
206 private void setAsProfileOwner(ComponentName admin) {
207 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
208 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
209
210 final UserInfo uh = new UserInfo(DpmMockContext.CALLER_USER_HANDLE, "user", 0);
211
212 // DO needs to be an DA.
213 dpm.setActiveAdmin(admin, /* replace =*/ false);
214
215 // Fire!
216 assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
217
218 // Check
219 assertEquals(admin1, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
220 }
221
222 public void testHasNoFeature() throws Exception {
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700223 when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
224 .thenReturn(false);
225
226 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
227 new DevicePolicyManagerServiceTestable(mContext, dataDir);
228
229 // If the device has no DPMS feature, it shouldn't register the local service.
230 assertNull(LocalServices.getService(DevicePolicyManagerInternal.class));
231 }
232
233 /**
234 * Caller doesn't have proper permissions.
235 */
236 public void testSetActiveAdmin_SecurityException() {
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700237 // 1. Failure cases.
238
239 // Caller doesn't have MANAGE_DEVICE_ADMINS.
240 try {
Makoto Onukif76b06a2015-09-22 15:03:44 -0700241 dpm.setActiveAdmin(admin1, false);
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700242 fail("Didn't throw SecurityException");
243 } catch (SecurityException expected) {
244 }
245
246 // Caller has MANAGE_DEVICE_ADMINS, but for different user.
247 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
248 try {
Makoto Onukif76b06a2015-09-22 15:03:44 -0700249 dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1);
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700250 fail("Didn't throw SecurityException");
251 } catch (SecurityException expected) {
252 }
253 }
254
Makoto Onukif76b06a2015-09-22 15:03:44 -0700255 /**
256 * Test for:
257 * {@link DevicePolicyManager#setActiveAdmin}
258 * with replace=false and replace=true
259 * {@link DevicePolicyManager#isAdminActive}
260 * {@link DevicePolicyManager#isAdminActiveAsUser}
261 * {@link DevicePolicyManager#getActiveAdmins}
262 * {@link DevicePolicyManager#getActiveAdminsAsUser}
263 */
264 public void testSetActiveAdmin() throws Exception {
265 // 1. Make sure the caller has proper permissions.
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700266 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
267
Makoto Onukif76b06a2015-09-22 15:03:44 -0700268 // 2. Call the API.
269 dpm.setActiveAdmin(admin1, /* replace =*/ false);
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700270
271 // 3. Verify internal calls.
272
273 // Check if the boradcast is sent.
Makoto Onukif76b06a2015-09-22 15:03:44 -0700274 verify(mContext.spiedContext).sendBroadcastAsUser(
275 MockUtils.checkIntentAction(
276 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
277 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
278 verify(mContext.spiedContext).sendBroadcastAsUser(
279 MockUtils.checkIntentAction(
280 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700281 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
282
Makoto Onukif76b06a2015-09-22 15:03:44 -0700283 verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
284 eq(admin1.getPackageName()),
285 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
286 eq(PackageManager.DONT_KILL_APP),
287 eq(DpmMockContext.CALLER_USER_HANDLE),
288 anyString());
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700289
290 // TODO Verify other calls too.
Makoto Onukif76b06a2015-09-22 15:03:44 -0700291
292 // Make sure it's active admin1.
293 assertTrue(dpm.isAdminActive(admin1));
294 assertFalse(dpm.isAdminActive(admin2));
295 assertFalse(dpm.isAdminActive(admin3));
296
297 // But not admin1 for a different user.
298
299 // For this to work, caller needs android.permission.INTERACT_ACROSS_USERS_FULL.
300 // (Because we're checking a different user's status from CALLER_USER_HANDLE.)
301 mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
302
303 assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE + 1));
304 assertFalse(dpm.isAdminActiveAsUser(admin2, DpmMockContext.CALLER_USER_HANDLE + 1));
305
306 mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
307
308 // Next, add one more admin.
309 // Before doing so, update the application info, now it's enabled.
Makoto Onukid932f762015-09-29 16:53:38 -0700310 setUpApplicationInfo(PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
311 DpmMockContext.CALLER_UID);
Makoto Onukif76b06a2015-09-22 15:03:44 -0700312
313 dpm.setActiveAdmin(admin2, /* replace =*/ false);
314
315 // Now we have two admins.
316 assertTrue(dpm.isAdminActive(admin1));
317 assertTrue(dpm.isAdminActive(admin2));
318 assertFalse(dpm.isAdminActive(admin3));
319
320 // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called
321 // again. (times(1) because it was previously called for admin1)
322 verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
323 eq(admin1.getPackageName()),
324 eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
325 eq(PackageManager.DONT_KILL_APP),
326 eq(DpmMockContext.CALLER_USER_HANDLE),
327 anyString());
328
329 // 4. Add the same admin1 again without replace, which should throw.
330 try {
331 dpm.setActiveAdmin(admin1, /* replace =*/ false);
332 fail("Didn't throw");
333 } catch (IllegalArgumentException expected) {
334 }
335
336 // 5. Add the same admin1 again with replace, which should succeed.
337 dpm.setActiveAdmin(admin1, /* replace =*/ true);
338
339 // TODO make sure it's replaced.
340
341 // 6. Test getActiveAdmins()
342 List<ComponentName> admins = dpm.getActiveAdmins();
343 assertEquals(2, admins.size());
344 assertEquals(admin1, admins.get(0));
345 assertEquals(admin2, admins.get(1));
346
347 // Another user has no admins.
348 mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
349
350 assertEquals(0, DpmTestUtils.getListSizeAllowingNull(
351 dpm.getActiveAdminsAsUser(DpmMockContext.CALLER_USER_HANDLE + 1)));
352
353 mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
354 }
355
Makoto Onukid932f762015-09-29 16:53:38 -0700356 public void testSetActiveAdmin_multiUsers() throws Exception {
357
358 final int ANOTHER_USER_ID = 100;
359 final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 20456);
360
361 mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
362
363 // Set up pacakge manager for the other user.
364 setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID);
365 setUpApplicationInfo(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
366 ANOTHER_ADMIN_UID);
367
368 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
369
370 dpm.setActiveAdmin(admin1, /* replace =*/ false);
371
372 mMockContext.binder.callingUid = ANOTHER_ADMIN_UID;
373 dpm.setActiveAdmin(admin2, /* replace =*/ false);
374
375
376 mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
377 assertTrue(dpm.isAdminActive(admin1));
378 assertFalse(dpm.isAdminActive(admin2));
379
380 mMockContext.binder.callingUid = ANOTHER_ADMIN_UID;
381 assertFalse(dpm.isAdminActive(admin1));
382 assertTrue(dpm.isAdminActive(admin2));
383 }
384
Makoto Onukif76b06a2015-09-22 15:03:44 -0700385 /**
386 * Test for:
387 * {@link DevicePolicyManager#setActiveAdmin}
388 * with replace=false
389 */
390 public void testSetActiveAdmin_twiceWithoutReplace() throws Exception {
391 // 1. Make sure the caller has proper permissions.
392 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
393
394 dpm.setActiveAdmin(admin1, /* replace =*/ false);
395 assertTrue(dpm.isAdminActive(admin1));
396
397 // Add the same admin1 again without replace, which should throw.
398 try {
399 dpm.setActiveAdmin(admin1, /* replace =*/ false);
400 fail("Didn't throw");
401 } catch (IllegalArgumentException expected) {
402 }
403 }
404
405 /**
406 * Test for:
407 * {@link DevicePolicyManager#removeActiveAdmin}
408 */
409 public void testRemoveActiveAdmin_SecurityException() {
410 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
411
412 // Add admin.
413
414 dpm.setActiveAdmin(admin1, /* replace =*/ false);
415
416 assertTrue(dpm.isAdminActive(admin1));
417
418 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
419
420 // Directly call the DPMS method with a different userid, which should fail.
421 try {
422 dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1);
423 fail("Didn't throw SecurityException");
424 } catch (SecurityException expected) {
425 }
426
427 // Try to remove active admin with a different caller userid should fail too, without
428 // having MANAGE_DEVICE_ADMINS.
429 mContext.callerPermissions.clear();
430
Makoto Onukid932f762015-09-29 16:53:38 -0700431 // Change the caller, and call into DPMS directly with a different user-id.
432
Makoto Onukif76b06a2015-09-22 15:03:44 -0700433 mContext.binder.callingUid = 1234567;
434 try {
Makoto Onukid932f762015-09-29 16:53:38 -0700435 dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
Makoto Onukif76b06a2015-09-22 15:03:44 -0700436 fail("Didn't throw SecurityException");
437 } catch (SecurityException expected) {
438 }
439 }
440
441 /**
442 * Test for:
443 * {@link DevicePolicyManager#removeActiveAdmin}
444 */
Makoto Onukid932f762015-09-29 16:53:38 -0700445 public void testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL() {
Makoto Onukif76b06a2015-09-22 15:03:44 -0700446 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
447
448 // Add admin1.
449
450 dpm.setActiveAdmin(admin1, /* replace =*/ false);
451
452 assertTrue(dpm.isAdminActive(admin1));
453 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
454
455 // Different user, but should work, because caller has proper permissions.
456 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
Makoto Onukid932f762015-09-29 16:53:38 -0700457
458 // Change the caller, and call into DPMS directly with a different user-id.
Makoto Onukif76b06a2015-09-22 15:03:44 -0700459 mContext.binder.callingUid = 1234567;
Makoto Onukid932f762015-09-29 16:53:38 -0700460
461 dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
Makoto Onukif76b06a2015-09-22 15:03:44 -0700462
463 assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
464
465 // TODO DO Still can't be removed in this case.
466 }
467
468 /**
469 * Test for:
470 * {@link DevicePolicyManager#removeActiveAdmin}
471 */
472 public void testRemoveActiveAdmin_sameUserNoMANAGE_DEVICE_ADMINS() {
473 // Need MANAGE_DEVICE_ADMINS for setActiveAdmin. We'll remove it later.
474 mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
475
476 // Add admin1.
477
478 dpm.setActiveAdmin(admin1, /* replace =*/ false);
479
480 assertTrue(dpm.isAdminActive(admin1));
481 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
482
483 // Broadcast from saveSettingsLocked().
484 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
485 MockUtils.checkIntentAction(
486 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
487 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
488
489 // Remove. No permissions, but same user, so it'll work.
490 mContext.callerPermissions.clear();
491 dpm.removeActiveAdmin(admin1);
492
493 final ArgumentCaptor<BroadcastReceiver> brCap =
494 ArgumentCaptor.forClass(BroadcastReceiver.class);
495
496 // Is removing now, but not removed yet.
497 assertTrue(dpm.isAdminActive(admin1));
498 assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
499
500 verify(mContext.spiedContext).sendOrderedBroadcastAsUser(
501 MockUtils.checkIntentAction(
502 DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED),
503 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
504 isNull(String.class),
505 brCap.capture(),
506 eq(dpms.mHandler),
507 eq(Activity.RESULT_OK),
508 isNull(String.class),
509 isNull(Bundle.class));
510
511 brCap.getValue().onReceive(mContext, null);
512
513 assertFalse(dpm.isAdminActive(admin1));
514 assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
515
516 // Again broadcast from saveSettingsLocked().
517 verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
518 MockUtils.checkIntentAction(
519 DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
520 MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
521
522 // TODO Check other internal calls.
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700523 }
Makoto Onukib643fb02015-09-22 15:03:44 -0700524
525 /**
526 * Test for: {@link DevicePolicyManager#setDeviceOwner} DO on system user installs
527 * successfully.
528 */
529 public void testSetDeviceOwner() throws Exception {
530 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
531 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
532 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
533
Makoto Onukid932f762015-09-29 16:53:38 -0700534 // In this test, change the caller user to "system".
Makoto Onukib643fb02015-09-22 15:03:44 -0700535 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
536
Makoto Onukid932f762015-09-29 16:53:38 -0700537 // Make sure admin1 is installed on system user.
538 setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
539 setUpApplicationInfo(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED,
540 DpmMockContext.CALLER_SYSTEM_USER_UID);
541
Makoto Onukib643fb02015-09-22 15:03:44 -0700542 // DO needs to be an DA.
543 dpm.setActiveAdmin(admin1, /* replace =*/ false);
544
545 // Fire!
546 assertTrue(dpm.setDeviceOwner(admin1.getPackageName(), "owner-name"));
547
548 // Verify internal calls.
549 verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
550 eq(admin1.getPackageName()));
551
552 // TODO We should check if the caller has called clearCallerIdentity().
553 verify(mContext.ibackupManager, times(1)).setBackupServiceActive(
554 eq(UserHandle.USER_SYSTEM), eq(false));
555
556 verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
557 MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
558 MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
559
560 assertEquals(admin1.getPackageName(), dpm.getDeviceOwner());
561
562 // TODO Test getDeviceOwnerName() too. To do so, we need to change
563 // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
564 }
565
566 /**
567 * Test for: {@link DevicePolicyManager#setDeviceOwner} Package doesn't exist.
568 */
569 public void testSetDeviceOwner_noSuchPackage() {
570 mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
571 mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
572 mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
573
574 // Call from a process on the system user.
575 mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
576
Makoto Onukib643fb02015-09-22 15:03:44 -0700577 try {
578 dpm.setDeviceOwner("a.b.c");
579 fail("Didn't throw IllegalArgumentException");
580 } catch (IllegalArgumentException expected) {
581 }
582 }
583
584 public void testSetDeviceOwner_failures() throws Exception {
585 // TODO Test more failure cases. Basically test all chacks in enforceCanSetDeviceOwner().
586 }
587
588 public void testSetProfileOwner() throws Exception {
589 setAsProfileOwner(admin1);
590 }
591
592 public void testSetProfileOwner_failures() throws Exception {
593 // TODO Test more failure cases. Basically test all chacks in enforceCanSetProfileOwner().
594 }
595
596 public void testSetGetApplicationRestriction() {
597 setAsProfileOwner(admin1);
598
599 {
600 Bundle rest = new Bundle();
601 rest.putString("KEY_STRING", "Foo1");
602 dpm.setApplicationRestrictions(admin1, "pkg1", rest);
603 }
604
605 {
606 Bundle rest = new Bundle();
607 rest.putString("KEY_STRING", "Foo2");
608 dpm.setApplicationRestrictions(admin1, "pkg2", rest);
609 }
610
611 {
612 Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg1");
613 assertNotNull(returned);
614 assertEquals(returned.size(), 1);
615 assertEquals(returned.get("KEY_STRING"), "Foo1");
616 }
617
618 {
619 Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg2");
620 assertNotNull(returned);
621 assertEquals(returned.size(), 1);
622 assertEquals(returned.get("KEY_STRING"), "Foo2");
623 }
624
625 dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle());
626 assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg2").size());
627 }
Makoto Onukicc4bbeb2015-09-17 10:28:24 -0700628}