DevicePolicyManagerTest.java revision 97e89c624e19c0a0ebe3d76506a493cfe29c0558
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 */
16package com.android.server.devicepolicy;
17
18import android.Manifest.permission;
19import android.app.Activity;
20import android.app.admin.DeviceAdminReceiver;
21import android.app.admin.DevicePolicyManager;
22import android.app.admin.DevicePolicyManagerInternal;
23import android.content.BroadcastReceiver;
24import android.content.ComponentName;
25import android.content.pm.ApplicationInfo;
26import android.content.pm.PackageInfo;
27import android.content.pm.PackageManager;
28import android.net.wifi.WifiInfo;
29import android.os.Build.VERSION_CODES;
30import android.os.Build;
31import android.os.Bundle;
32import android.os.Process;
33import android.os.UserHandle;
34import android.os.UserManager;
35import android.provider.Settings;
36import android.test.MoreAsserts;
37import android.test.suitebuilder.annotation.SmallTest;
38import android.util.ArraySet;
39import android.util.Pair;
40
41import com.android.server.LocalServices;
42import com.android.server.SystemService;
43
44import org.mockito.ArgumentCaptor;
45import org.mockito.invocation.InvocationOnMock;
46import org.mockito.stubbing.Answer;
47
48import java.util.ArrayList;
49import java.util.Arrays;
50import java.util.HashMap;
51import java.util.List;
52import java.util.Map;
53import java.util.Set;
54
55import static org.mockito.Matchers.any;
56import static org.mockito.Matchers.anyInt;
57import static org.mockito.Matchers.anyString;
58import static org.mockito.Matchers.eq;
59import static org.mockito.Matchers.isNull;
60import static org.mockito.Mockito.doAnswer;
61import static org.mockito.Mockito.doReturn;
62import static org.mockito.Mockito.reset;
63import static org.mockito.Mockito.times;
64import static org.mockito.Mockito.validateMockitoUsage;
65import static org.mockito.Mockito.verify;
66import static org.mockito.Mockito.when;
67
68/**
69 * Tests for DevicePolicyManager( and DevicePolicyManagerService).
70 *
71 m FrameworksServicesTests &&
72 adb install \
73   -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
74 adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest \
75   -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
76
77 (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
78 */
79@SmallTest
80public class DevicePolicyManagerTest extends DpmTestBase {
81    private static final List<String> OWNER_SETUP_PERMISSIONS = Arrays.asList(
82            permission.MANAGE_DEVICE_ADMINS, permission.MANAGE_PROFILE_AND_DEVICE_OWNERS,
83            permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL);
84
85    private DpmMockContext mContext;
86    public DevicePolicyManager dpm;
87    public DevicePolicyManagerServiceTestable dpms;
88
89    @Override
90    protected void setUp() throws Exception {
91        super.setUp();
92
93        mContext = getContext();
94
95        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
96                .thenReturn(true);
97
98        // By default, pretend all users are running and unlocked.
99        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
100
101        initializeDpms();
102
103        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
104        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
105        setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID);
106        setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID);
107
108        setUpUserManager();
109    }
110
111    private void initializeDpms() {
112        // Need clearCallingIdentity() to pass permission checks.
113        final long ident = mContext.binder.clearCallingIdentity();
114        try {
115            LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
116
117            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
118
119            dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
120            dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
121
122            dpm = new DevicePolicyManagerTestable(mContext, dpms);
123        } finally {
124            mContext.binder.restoreCallingIdentity(ident);
125        }
126    }
127
128    private void setUpUserManager() {
129        // Emulate UserManager.set/getApplicationRestriction().
130        final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>();
131
132        // UM.setApplicationRestrictions() will save to appRestrictions.
133        doAnswer(new Answer<Void>() {
134            @Override
135            public Void answer(InvocationOnMock invocation) throws Throwable {
136                String pkg = (String) invocation.getArguments()[0];
137                Bundle bundle = (Bundle) invocation.getArguments()[1];
138                UserHandle user = (UserHandle) invocation.getArguments()[2];
139
140                appRestrictions.put(Pair.create(pkg, user), bundle);
141
142                return null;
143            }
144        }).when(mContext.userManager).setApplicationRestrictions(
145                anyString(), any(Bundle.class), any(UserHandle.class));
146
147        // UM.getApplicationRestrictions() will read from appRestrictions.
148        doAnswer(new Answer<Bundle>() {
149            @Override
150            public Bundle answer(InvocationOnMock invocation) throws Throwable {
151                String pkg = (String) invocation.getArguments()[0];
152                UserHandle user = (UserHandle) invocation.getArguments()[1];
153
154                return appRestrictions.get(Pair.create(pkg, user));
155            }
156        }).when(mContext.userManager).getApplicationRestrictions(
157                anyString(), any(UserHandle.class));
158
159        // Add the first secondary user.
160        mContext.addUser(DpmMockContext.CALLER_USER_HANDLE, 0);
161    }
162
163    private void setAsProfileOwner(ComponentName admin) {
164        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
165        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
166
167        // PO needs to be an DA.
168        dpm.setActiveAdmin(admin, /* replace =*/ false);
169
170        // Fire!
171        assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
172
173        // Check
174        assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
175    }
176
177    public void testHasNoFeature() throws Exception {
178        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
179                .thenReturn(false);
180
181        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
182        new DevicePolicyManagerServiceTestable(mContext, dataDir);
183
184        // If the device has no DPMS feature, it shouldn't register the local service.
185        assertNull(LocalServices.getService(DevicePolicyManagerInternal.class));
186    }
187
188    /**
189     * Caller doesn't have proper permissions.
190     */
191    public void testSetActiveAdmin_SecurityException() {
192        // 1. Failure cases.
193
194        // Caller doesn't have MANAGE_DEVICE_ADMINS.
195        try {
196            dpm.setActiveAdmin(admin1, false);
197            fail("Didn't throw SecurityException");
198        } catch (SecurityException expected) {
199        }
200
201        // Caller has MANAGE_DEVICE_ADMINS, but for different user.
202        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
203        try {
204            dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1);
205            fail("Didn't throw SecurityException");
206        } catch (SecurityException expected) {
207        }
208    }
209
210    /**
211     * Test for:
212     * {@link DevicePolicyManager#setActiveAdmin}
213     * with replace=false and replace=true
214     * {@link DevicePolicyManager#isAdminActive}
215     * {@link DevicePolicyManager#isAdminActiveAsUser}
216     * {@link DevicePolicyManager#getActiveAdmins}
217     * {@link DevicePolicyManager#getActiveAdminsAsUser}
218     */
219    public void testSetActiveAdmin() throws Exception {
220        // 1. Make sure the caller has proper permissions.
221        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
222
223        // 2. Call the API.
224        dpm.setActiveAdmin(admin1, /* replace =*/ false);
225
226        // 3. Verify internal calls.
227
228        // Check if the boradcast is sent.
229        verify(mContext.spiedContext).sendBroadcastAsUser(
230                MockUtils.checkIntentAction(
231                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
232                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
233        verify(mContext.spiedContext).sendBroadcastAsUser(
234                MockUtils.checkIntentAction(
235                        DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
236                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
237
238        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
239                eq(admin1.getPackageName()),
240                eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
241                eq(PackageManager.DONT_KILL_APP),
242                eq(DpmMockContext.CALLER_USER_HANDLE),
243                anyString());
244
245        // TODO Verify other calls too.
246
247        // Make sure it's active admin1.
248        assertTrue(dpm.isAdminActive(admin1));
249        assertFalse(dpm.isAdminActive(admin2));
250        assertFalse(dpm.isAdminActive(admin3));
251
252        // But not admin1 for a different user.
253
254        // For this to work, caller needs android.permission.INTERACT_ACROSS_USERS_FULL.
255        // (Because we're checking a different user's status from CALLER_USER_HANDLE.)
256        mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
257
258        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE + 1));
259        assertFalse(dpm.isAdminActiveAsUser(admin2, DpmMockContext.CALLER_USER_HANDLE + 1));
260
261        mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
262
263        // Next, add one more admin.
264        // Before doing so, update the application info, now it's enabled.
265        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID,
266                PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
267
268        dpm.setActiveAdmin(admin2, /* replace =*/ false);
269
270        // Now we have two admins.
271        assertTrue(dpm.isAdminActive(admin1));
272        assertTrue(dpm.isAdminActive(admin2));
273        assertFalse(dpm.isAdminActive(admin3));
274
275        // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called
276        // again.  (times(1) because it was previously called for admin1)
277        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
278                eq(admin1.getPackageName()),
279                eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
280                eq(PackageManager.DONT_KILL_APP),
281                eq(DpmMockContext.CALLER_USER_HANDLE),
282                anyString());
283
284        // 4. Add the same admin1 again without replace, which should throw.
285        try {
286            dpm.setActiveAdmin(admin1, /* replace =*/ false);
287            fail("Didn't throw");
288        } catch (IllegalArgumentException expected) {
289        }
290
291        // 5. Add the same admin1 again with replace, which should succeed.
292        dpm.setActiveAdmin(admin1, /* replace =*/ true);
293
294        // TODO make sure it's replaced.
295
296        // 6. Test getActiveAdmins()
297        List<ComponentName> admins = dpm.getActiveAdmins();
298        assertEquals(2, admins.size());
299        assertEquals(admin1, admins.get(0));
300        assertEquals(admin2, admins.get(1));
301
302        // Another user has no admins.
303        mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
304
305        assertEquals(0, DpmTestUtils.getListSizeAllowingNull(
306                dpm.getActiveAdminsAsUser(DpmMockContext.CALLER_USER_HANDLE + 1)));
307
308        mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
309    }
310
311    public void testSetActiveAdmin_multiUsers() throws Exception {
312
313        final int ANOTHER_USER_ID = 100;
314        final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 20456);
315
316        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
317
318        // Set up pacakge manager for the other user.
319        setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID);
320
321        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
322
323        dpm.setActiveAdmin(admin1, /* replace =*/ false);
324
325        mMockContext.binder.callingUid = ANOTHER_ADMIN_UID;
326        dpm.setActiveAdmin(admin2, /* replace =*/ false);
327
328
329        mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
330        assertTrue(dpm.isAdminActive(admin1));
331        assertFalse(dpm.isAdminActive(admin2));
332
333        mMockContext.binder.callingUid = ANOTHER_ADMIN_UID;
334        assertFalse(dpm.isAdminActive(admin1));
335        assertTrue(dpm.isAdminActive(admin2));
336    }
337
338    /**
339     * Test for:
340     * {@link DevicePolicyManager#setActiveAdmin}
341     * with replace=false
342     */
343    public void testSetActiveAdmin_twiceWithoutReplace() throws Exception {
344        // 1. Make sure the caller has proper permissions.
345        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
346
347        dpm.setActiveAdmin(admin1, /* replace =*/ false);
348        assertTrue(dpm.isAdminActive(admin1));
349
350        // Add the same admin1 again without replace, which should throw.
351        try {
352            dpm.setActiveAdmin(admin1, /* replace =*/ false);
353            fail("Didn't throw");
354        } catch (IllegalArgumentException expected) {
355        }
356    }
357
358    /**
359     * Test for:
360     * {@link DevicePolicyManager#setActiveAdmin} when the admin isn't protected with
361     * BIND_DEVICE_ADMIN.
362     */
363    public void testSetActiveAdmin_permissionCheck() throws Exception {
364        // 1. Make sure the caller has proper permissions.
365        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
366
367        try {
368            dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
369            fail();
370        } catch (IllegalArgumentException expected) {
371            assertTrue(expected.getMessage().contains(permission.BIND_DEVICE_ADMIN));
372        }
373        assertFalse(dpm.isAdminActive(adminNoPerm));
374
375        // Change the target API level to MNC.  Now it can be set as DA.
376        setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID, null,
377                VERSION_CODES.M);
378        dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
379        assertTrue(dpm.isAdminActive(adminNoPerm));
380
381        // TODO Test the "load from the file" case where DA will still be loaded even without
382        // BIND_DEVICE_ADMIN and target API is N.
383    }
384
385    /**
386     * Test for:
387     * {@link DevicePolicyManager#removeActiveAdmin}
388     */
389    public void testRemoveActiveAdmin_SecurityException() {
390        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
391
392        // Add admin.
393
394        dpm.setActiveAdmin(admin1, /* replace =*/ false);
395
396        assertTrue(dpm.isAdminActive(admin1));
397
398        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
399
400        // Directly call the DPMS method with a different userid, which should fail.
401        try {
402            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1);
403            fail("Didn't throw SecurityException");
404        } catch (SecurityException expected) {
405        }
406
407        // Try to remove active admin with a different caller userid should fail too, without
408        // having MANAGE_DEVICE_ADMINS.
409        mContext.callerPermissions.clear();
410
411        // Change the caller, and call into DPMS directly with a different user-id.
412
413        mContext.binder.callingUid = 1234567;
414        try {
415            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
416            fail("Didn't throw SecurityException");
417        } catch (SecurityException expected) {
418        }
419    }
420
421    /**
422     * {@link DevicePolicyManager#removeActiveAdmin} should fail with the user is not unlocked
423     * (because we can't send the remove broadcast).
424     */
425    public void testRemoveActiveAdmin_userNotRunningOrLocked() {
426        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
427
428        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
429
430        // Add admin.
431
432        dpm.setActiveAdmin(admin1, /* replace =*/ false);
433
434        assertTrue(dpm.isAdminActive(admin1));
435
436        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
437
438        // 1. User not unlocked.
439        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
440                .thenReturn(false);
441        try {
442            dpm.removeActiveAdmin(admin1);
443            fail("Didn't throw IllegalStateException");
444        } catch (IllegalStateException expected) {
445            MoreAsserts.assertContainsRegex(
446                    "User must be running and unlocked", expected.getMessage());
447        }
448
449        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
450
451        // 2. User unlocked.
452        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
453                .thenReturn(true);
454
455        dpm.removeActiveAdmin(admin1);
456
457        assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
458    }
459
460    /**
461     * Test for:
462     * {@link DevicePolicyManager#removeActiveAdmin}
463     */
464    public void testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL() {
465        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
466
467        // Add admin1.
468
469        dpm.setActiveAdmin(admin1, /* replace =*/ false);
470
471        assertTrue(dpm.isAdminActive(admin1));
472        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
473
474        // Different user, but should work, because caller has proper permissions.
475        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
476
477        // Change the caller, and call into DPMS directly with a different user-id.
478        mContext.binder.callingUid = 1234567;
479
480        dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
481
482        assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
483
484        // TODO DO Still can't be removed in this case.
485    }
486
487    /**
488     * Test for:
489     * {@link DevicePolicyManager#removeActiveAdmin}
490     */
491    public void testRemoveActiveAdmin_sameUserNoMANAGE_DEVICE_ADMINS() {
492        // Need MANAGE_DEVICE_ADMINS for setActiveAdmin.  We'll remove it later.
493        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
494
495        // Add admin1.
496
497        dpm.setActiveAdmin(admin1, /* replace =*/ false);
498
499        assertTrue(dpm.isAdminActive(admin1));
500        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
501
502        // Broadcast from saveSettingsLocked().
503        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
504                MockUtils.checkIntentAction(
505                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
506                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
507
508        // Remove.  No permissions, but same user, so it'll work.
509        mContext.callerPermissions.clear();
510        dpm.removeActiveAdmin(admin1);
511
512        final ArgumentCaptor<BroadcastReceiver> brCap =
513                ArgumentCaptor.forClass(BroadcastReceiver.class);
514
515        // Is removing now, but not removed yet.
516        assertTrue(dpm.isAdminActive(admin1));
517        assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
518
519        verify(mContext.spiedContext).sendOrderedBroadcastAsUser(
520                MockUtils.checkIntentAction(
521                        DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED),
522                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
523                isNull(String.class),
524                brCap.capture(),
525                eq(dpms.mHandler),
526                eq(Activity.RESULT_OK),
527                isNull(String.class),
528                isNull(Bundle.class));
529
530        brCap.getValue().onReceive(mContext, null);
531
532        assertFalse(dpm.isAdminActive(admin1));
533        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
534
535        // Again broadcast from saveSettingsLocked().
536        verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
537                MockUtils.checkIntentAction(
538                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
539                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
540
541        // TODO Check other internal calls.
542    }
543
544    /**
545     * Test for: {@link DevicePolicyManager#setDeviceOwner} DO on system user installs
546     * successfully.
547     */
548    public void testSetDeviceOwner() throws Exception {
549        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
550        mContext.callerPermissions.add(permission.MANAGE_USERS);
551        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
552        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
553
554        // In this test, change the caller user to "system".
555        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
556
557        // Make sure admin1 is installed on system user.
558        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
559
560        // Check various get APIs.
561        checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ false);
562
563        // DO needs to be an DA.
564        dpm.setActiveAdmin(admin1, /* replace =*/ false);
565
566        // Fire!
567        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
568
569        // getDeviceOwnerComponent should return the admin1 component.
570        assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
571        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
572
573        // Check various get APIs.
574        checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ true);
575
576        // getDeviceOwnerComponent should *NOT* return the admin1 component for other users.
577        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
578        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
579        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
580
581        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
582
583        // Verify internal calls.
584        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
585                eq(admin1.getPackageName()));
586
587        // TODO We should check if the caller has called clearCallerIdentity().
588        verify(mContext.ibackupManager, times(1)).setBackupServiceActive(
589                eq(UserHandle.USER_SYSTEM), eq(false));
590
591        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
592                MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
593                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
594
595        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
596
597        // Try to set a profile owner on the same user, which should fail.
598        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
599        dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM);
600        try {
601            dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM);
602            fail("IllegalStateException not thrown");
603        } catch (IllegalStateException expected) {
604            assertTrue("Message was: " + expected.getMessage(),
605                    expected.getMessage().contains("already has a device owner"));
606        }
607
608        // DO admin can't be deactivated.
609        dpm.removeActiveAdmin(admin1);
610        assertTrue(dpm.isAdminActive(admin1));
611
612        // TODO Test getDeviceOwnerName() too.  To do so, we need to change
613        // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
614    }
615
616    private void checkGetDeviceOwnerInfoApi(DevicePolicyManager dpm, boolean hasDeviceOwner) {
617        final int origCallingUser = mContext.binder.callingUid;
618        final List origPermissions = new ArrayList(mContext.callerPermissions);
619        mContext.callerPermissions.clear();
620
621        mContext.callerPermissions.add(permission.MANAGE_USERS);
622
623        mContext.binder.callingUid = Process.SYSTEM_UID;
624
625        // TODO Test getDeviceOwnerName() too.  To do so, we need to change
626        // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
627        if (hasDeviceOwner) {
628            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
629            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
630            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
631
632            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
633            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
634            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
635        } else {
636            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
637            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
638            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
639
640            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
641            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
642            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
643        }
644
645        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
646        if (hasDeviceOwner) {
647            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
648            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
649            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
650
651            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
652            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
653            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
654        } else {
655            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
656            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
657            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
658
659            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
660            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
661            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
662        }
663
664        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
665        // Still with MANAGE_USERS.
666        assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
667        assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
668        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
669
670        if (hasDeviceOwner) {
671            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
672            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
673            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
674        } else {
675            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
676            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
677            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
678        }
679
680        mContext.binder.callingUid = Process.SYSTEM_UID;
681        mContext.callerPermissions.remove(permission.MANAGE_USERS);
682        // System can still call "OnAnyUser" without MANAGE_USERS.
683        if (hasDeviceOwner) {
684            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
685            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
686            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
687
688            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
689            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
690            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
691        } else {
692            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
693            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
694            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
695
696            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
697            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
698            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
699        }
700
701        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
702        // Still no MANAGE_USERS.
703        if (hasDeviceOwner) {
704            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
705            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
706            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
707        } else {
708            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
709            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
710            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
711        }
712
713        try {
714            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
715            fail();
716        } catch (SecurityException expected) {
717        }
718        try {
719            dpm.getDeviceOwnerComponentOnAnyUser();
720            fail();
721        } catch (SecurityException expected) {
722        }
723        try {
724            dpm.getDeviceOwnerUserId();
725            fail();
726        } catch (SecurityException expected) {
727        }
728        try {
729            dpm.getDeviceOwnerNameOnAnyUser();
730            fail();
731        } catch (SecurityException expected) {
732        }
733
734        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
735        // Still no MANAGE_USERS.
736        assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
737        assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
738        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
739
740        try {
741            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
742            fail();
743        } catch (SecurityException expected) {
744        }
745        try {
746            dpm.getDeviceOwnerComponentOnAnyUser();
747            fail();
748        } catch (SecurityException expected) {
749        }
750        try {
751            dpm.getDeviceOwnerUserId();
752            fail();
753        } catch (SecurityException expected) {
754        }
755        try {
756            dpm.getDeviceOwnerNameOnAnyUser();
757            fail();
758        } catch (SecurityException expected) {
759        }
760
761        // Restore.
762        mContext.binder.callingUid = origCallingUser;
763        mContext.callerPermissions.addAll(origPermissions);
764    }
765
766
767    /**
768     * Test for: {@link DevicePolicyManager#setDeviceOwner} Package doesn't exist.
769     */
770    public void testSetDeviceOwner_noSuchPackage() {
771        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
772        mContext.callerPermissions.add(permission.MANAGE_USERS);
773        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
774        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
775
776        // Call from a process on the system user.
777        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
778
779        try {
780            dpm.setDeviceOwner(new ComponentName("a.b.c", ".def"));
781            fail("Didn't throw IllegalArgumentException");
782        } catch (IllegalArgumentException expected) {
783            assertTrue("Message was: " + expected.getMessage(),
784                    expected.getMessage().contains("Invalid component"));
785        }
786    }
787
788    public void testSetDeviceOwner_failures() throws Exception {
789        // TODO Test more failure cases.  Basically test all chacks in enforceCanSetDeviceOwner().
790    }
791
792    public void testClearDeviceOwner() throws Exception {
793        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
794        mContext.callerPermissions.add(permission.MANAGE_USERS);
795        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
796        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
797
798        // Set admin1 as a DA to the secondary user.
799        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
800
801        dpm.setActiveAdmin(admin1, /* replace =*/ false);
802
803        // Set admin 1 as the DO to the system user.
804
805        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
806        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
807        dpm.setActiveAdmin(admin1, /* replace =*/ false);
808        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
809
810        // Verify internal calls.
811        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
812                eq(admin1.getPackageName()));
813
814        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
815
816        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
817
818        assertTrue(dpm.isAdminActive(admin1));
819        assertFalse(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM));
820
821        // Set up other mocks.
822        when(mContext.userManager.getUserRestrictions()).thenReturn(new Bundle());
823
824        // Now call clear.
825        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager).getPackageUidAsUser(
826                eq(admin1.getPackageName()),
827                anyInt());
828
829        // But first pretend the user is locked.  Then it should fail.
830        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(false);
831        try {
832            dpm.clearDeviceOwnerApp(admin1.getPackageName());
833            fail("Didn't throw IllegalStateException");
834        } catch (IllegalStateException expected) {
835            MoreAsserts.assertContainsRegex(
836                    "User must be running and unlocked", expected.getMessage());
837        }
838
839        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
840        reset(mContext.userManagerInternal);
841        dpm.clearDeviceOwnerApp(admin1.getPackageName());
842
843        // Now DO shouldn't be set.
844        assertNull(dpm.getDeviceOwnerComponentOnAnyUser());
845
846        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
847                eq(UserHandle.USER_SYSTEM),
848                MockUtils.checkUserRestrictions(),
849                MockUtils.checkUserRestrictions()
850        );
851
852        assertTrue(dpm.isAdminActive(admin1));
853        assertTrue(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM));
854
855        // TODO Check other calls.
856    }
857
858    public void testClearDeviceOwner_fromDifferentUser() throws Exception {
859        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
860        mContext.callerPermissions.add(permission.MANAGE_USERS);
861        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
862        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
863
864        // Set admin1 as a DA to the secondary user.
865        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
866
867        dpm.setActiveAdmin(admin1, /* replace =*/ false);
868
869        // Set admin 1 as the DO to the system user.
870
871        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
872        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
873        dpm.setActiveAdmin(admin1, /* replace =*/ false);
874        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
875
876        // Verify internal calls.
877        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
878                eq(admin1.getPackageName()));
879
880        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
881
882        // Now call clear from the secondary user, which should throw.
883        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
884
885        // Now call clear.
886        doReturn(DpmMockContext.CALLER_UID).when(mContext.packageManager).getPackageUidAsUser(
887                eq(admin1.getPackageName()),
888                anyInt());
889        try {
890            dpm.clearDeviceOwnerApp(admin1.getPackageName());
891            fail("Didn't throw");
892        } catch (SecurityException e) {
893            assertEquals("clearDeviceOwner can only be called by the device owner", e.getMessage());
894        }
895
896        // DO shouldn't be removed.
897        assertTrue(dpm.isDeviceManaged());
898    }
899
900    public void testSetProfileOwner() throws Exception {
901        setAsProfileOwner(admin1);
902
903        // PO admin can't be deactivated.
904        dpm.removeActiveAdmin(admin1);
905        assertTrue(dpm.isAdminActive(admin1));
906
907        // Try setting DO on the same user, which should fail.
908        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
909        dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
910        try {
911            dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE);
912            fail("IllegalStateException not thrown");
913        } catch (IllegalStateException expected) {
914            assertTrue("Message was: " + expected.getMessage(),
915                    expected.getMessage().contains("already has a profile owner"));
916        }
917    }
918
919    public void testClearProfileOwner() throws Exception {
920        setAsProfileOwner(admin1);
921
922        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
923
924        assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName()));
925        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
926
927        // First try when the user is locked, which should fail.
928        when(mContext.userManager.isUserUnlocked(anyInt()))
929                .thenReturn(false);
930        try {
931            dpm.clearProfileOwner(admin1);
932            fail("Didn't throw IllegalStateException");
933        } catch (IllegalStateException expected) {
934            MoreAsserts.assertContainsRegex(
935                    "User must be running and unlocked", expected.getMessage());
936        }
937        // Clear, really.
938        when(mContext.userManager.isUserUnlocked(anyInt()))
939                .thenReturn(true);
940        dpm.clearProfileOwner(admin1);
941
942        // Check
943        assertFalse(dpm.isProfileOwnerApp(admin1.getPackageName()));
944        assertTrue(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
945    }
946
947    public void testSetProfileOwner_failures() throws Exception {
948        // TODO Test more failure cases.  Basically test all chacks in enforceCanSetProfileOwner().
949    }
950
951    public void testGetDeviceOwnerAdminLocked() throws Exception {
952        checkDeviceOwnerWithMultipleDeviceAdmins();
953    }
954
955    private void checkDeviceOwnerWithMultipleDeviceAdmins() throws Exception {
956        // In ths test, we use 3 users (system + 2 secondary users), set some device admins to them,
957        // set admin2 on CALLER_USER_HANDLE as DO, then call getDeviceOwnerAdminLocked() to
958        // make sure it gets the right component from the right user.
959
960        final int ANOTHER_USER_ID = 100;
961        final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 456);
962
963        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
964
965        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
966        mContext.callerPermissions.add(permission.MANAGE_USERS);
967        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
968        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
969
970        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
971
972        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
973
974        // Make sure the admin packge is installed to each user.
975        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
976        setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_SYSTEM_USER_UID);
977
978        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
979        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
980
981        setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID);
982
983
984        // Set active admins to the users.
985        dpm.setActiveAdmin(admin1, /* replace =*/ false);
986        dpm.setActiveAdmin(admin3, /* replace =*/ false);
987
988        dpm.setActiveAdmin(admin1, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE);
989        dpm.setActiveAdmin(admin2, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE);
990
991        dpm.setActiveAdmin(admin2, /* replace =*/ false, ANOTHER_USER_ID);
992
993        // Set DO on the first non-system user.
994        mContext.setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true);
995        assertTrue(dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
996
997        assertEquals(admin2, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
998
999        // Then check getDeviceOwnerAdminLocked().
1000        assertEquals(admin2, dpms.getDeviceOwnerAdminLocked().info.getComponent());
1001        assertEquals(DpmMockContext.CALLER_UID, dpms.getDeviceOwnerAdminLocked().getUid());
1002    }
1003
1004    /**
1005     * This essentially tests
1006     * {@code DevicePolicyManagerService.findOwnerComponentIfNecessaryLocked()}. (which is
1007     * private.)
1008     *
1009     * We didn't use to persist the DO component class name, but now we do, and the above method
1010     * finds the right component from a package name upon migration.
1011     */
1012    public void testDeviceOwnerMigration() throws Exception {
1013        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
1014        checkDeviceOwnerWithMultipleDeviceAdmins();
1015
1016        // Overwrite the device owner setting and clears the clas name.
1017        dpms.mOwners.setDeviceOwner(
1018                new ComponentName(admin2.getPackageName(), ""),
1019                "owner-name", DpmMockContext.CALLER_USER_HANDLE);
1020        dpms.mOwners.writeDeviceOwner();
1021
1022        // Make sure the DO component name doesn't have a class name.
1023        assertEquals("", dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false).getClassName());
1024
1025        // Then create a new DPMS to have it load the settings from files.
1026        when(mContext.userManager.getUserRestrictions(any(UserHandle.class)))
1027                .thenReturn(new Bundle());
1028        initializeDpms();
1029
1030        // Now the DO component name is a full name.
1031        // *BUT* because both admin1 and admin2 belong to the same package, we think admin1 is the
1032        // DO.
1033        assertEquals(admin1, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
1034    }
1035
1036    public void testSetGetApplicationRestriction() {
1037        setAsProfileOwner(admin1);
1038
1039        {
1040            Bundle rest = new Bundle();
1041            rest.putString("KEY_STRING", "Foo1");
1042            dpm.setApplicationRestrictions(admin1, "pkg1", rest);
1043        }
1044
1045        {
1046            Bundle rest = new Bundle();
1047            rest.putString("KEY_STRING", "Foo2");
1048            dpm.setApplicationRestrictions(admin1, "pkg2", rest);
1049        }
1050
1051        {
1052            Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg1");
1053            assertNotNull(returned);
1054            assertEquals(returned.size(), 1);
1055            assertEquals(returned.get("KEY_STRING"), "Foo1");
1056        }
1057
1058        {
1059            Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg2");
1060            assertNotNull(returned);
1061            assertEquals(returned.size(), 1);
1062            assertEquals(returned.get("KEY_STRING"), "Foo2");
1063        }
1064
1065        dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle());
1066        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg2").size());
1067    }
1068
1069    public void testApplicationRestrictionsManagingApp() throws Exception {
1070        setAsProfileOwner(admin1);
1071
1072        final String nonExistAppRestrictionsManagerPackage = "com.google.app.restrictions.manager2";
1073        final String appRestrictionsManagerPackage = "com.google.app.restrictions.manager";
1074        final int appRestrictionsManagerAppId = 20987;
1075        final int appRestrictionsManagerUid = UserHandle.getUid(
1076                DpmMockContext.CALLER_USER_HANDLE, appRestrictionsManagerAppId);
1077        doReturn(appRestrictionsManagerUid).when(mContext.packageManager).getPackageUidAsUser(
1078                eq(appRestrictionsManagerPackage),
1079                eq(DpmMockContext.CALLER_USER_HANDLE));
1080        mContext.binder.callingUid = appRestrictionsManagerUid;
1081
1082        final PackageInfo pi = new PackageInfo();
1083        pi.applicationInfo = new ApplicationInfo();
1084        pi.applicationInfo.flags = ApplicationInfo.FLAG_HAS_CODE;
1085        doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
1086                eq(appRestrictionsManagerPackage),
1087                anyInt(),
1088                eq(DpmMockContext.CALLER_USER_HANDLE));
1089
1090        // appRestrictionsManager package shouldn't be able to manage restrictions as the PO hasn't
1091        // delegated that permission yet.
1092        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
1093        Bundle rest = new Bundle();
1094        rest.putString("KEY_STRING", "Foo1");
1095        try {
1096            dpm.setApplicationRestrictions(null, "pkg1", rest);
1097            fail("Didn't throw expected SecurityException");
1098        } catch (SecurityException expected) {
1099            MoreAsserts.assertContainsRegex(
1100                    "caller cannot manage application restrictions", expected.getMessage());
1101        }
1102        try {
1103            dpm.getApplicationRestrictions(null, "pkg1");
1104            fail("Didn't throw expected SecurityException");
1105        } catch (SecurityException expected) {
1106            MoreAsserts.assertContainsRegex(
1107                    "caller cannot manage application restrictions", expected.getMessage());
1108        }
1109
1110        // Check via the profile owner that no restrictions were set.
1111        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1112        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
1113
1114        // Check the API does not allow setting a non-existent package
1115        try {
1116            dpm.setApplicationRestrictionsManagingPackage(admin1,
1117                    nonExistAppRestrictionsManagerPackage);
1118            fail("Non-existent app set as app restriction manager.");
1119        } catch (IllegalArgumentException expected) {
1120            MoreAsserts.assertContainsRegex(
1121                    "is not installed on the current user", expected.getMessage());
1122        }
1123
1124        // Let appRestrictionsManagerPackage manage app restrictions
1125        dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage);
1126        assertEquals(appRestrictionsManagerPackage,
1127                dpm.getApplicationRestrictionsManagingPackage(admin1));
1128
1129        // Now that package should be able to set and retrieve app restrictions.
1130        mContext.binder.callingUid = appRestrictionsManagerUid;
1131        assertTrue(dpm.isCallerApplicationRestrictionsManagingPackage());
1132        dpm.setApplicationRestrictions(null, "pkg1", rest);
1133        Bundle returned = dpm.getApplicationRestrictions(null, "pkg1");
1134        assertEquals(1, returned.size(), 1);
1135        assertEquals("Foo1", returned.get("KEY_STRING"));
1136
1137        // The same app running on a separate user shouldn't be able to manage app restrictions.
1138        mContext.binder.callingUid = UserHandle.getUid(
1139                UserHandle.USER_SYSTEM, appRestrictionsManagerAppId);
1140        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
1141        try {
1142            dpm.setApplicationRestrictions(null, "pkg1", rest);
1143            fail("Didn't throw expected SecurityException");
1144        } catch (SecurityException expected) {
1145            MoreAsserts.assertContainsRegex(
1146                    "caller cannot manage application restrictions", expected.getMessage());
1147        }
1148
1149        // The DPM is still able to manage app restrictions, even if it allowed another app to do it
1150        // too.
1151        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1152        assertEquals(returned, dpm.getApplicationRestrictions(admin1, "pkg1"));
1153        dpm.setApplicationRestrictions(admin1, "pkg1", null);
1154        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
1155
1156        // Removing the ability for the package to manage app restrictions.
1157        dpm.setApplicationRestrictionsManagingPackage(admin1, null);
1158        assertNull(dpm.getApplicationRestrictionsManagingPackage(admin1));
1159        mContext.binder.callingUid = appRestrictionsManagerUid;
1160        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
1161        try {
1162            dpm.setApplicationRestrictions(null, "pkg1", null);
1163            fail("Didn't throw expected SecurityException");
1164        } catch (SecurityException expected) {
1165            MoreAsserts.assertContainsRegex(
1166                    "caller cannot manage application restrictions", expected.getMessage());
1167        }
1168    }
1169
1170    public void testSetUserRestriction_asDo() throws Exception {
1171        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1172        mContext.callerPermissions.add(permission.MANAGE_USERS);
1173        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1174        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1175
1176        // First, set DO.
1177
1178        // Call from a process on the system user.
1179        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1180
1181        // Make sure admin1 is installed on system user.
1182        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1183
1184        // Call.
1185        dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM);
1186        assertTrue(dpm.setDeviceOwner(admin1, "owner-name",
1187                UserHandle.USER_SYSTEM));
1188
1189        DpmTestUtils.assertRestrictions(
1190                DpmTestUtils.newRestrictions(),
1191                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1192        );
1193        DpmTestUtils.assertRestrictions(
1194                DpmTestUtils.newRestrictions(),
1195                dpm.getUserRestrictions(admin1)
1196        );
1197
1198        reset(mContext.userManagerInternal);
1199
1200        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
1201        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1202                eq(UserHandle.USER_SYSTEM),
1203                MockUtils.checkUserRestrictions(),
1204                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER)
1205        );
1206        reset(mContext.userManagerInternal);
1207
1208        dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1209        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1210                eq(UserHandle.USER_SYSTEM),
1211                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1212                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER)
1213        );
1214        reset(mContext.userManagerInternal);
1215
1216        DpmTestUtils.assertRestrictions(
1217                DpmTestUtils.newRestrictions(
1218                        UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS),
1219                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1220        );
1221        DpmTestUtils.assertRestrictions(
1222                DpmTestUtils.newRestrictions(
1223                        UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS),
1224                dpm.getUserRestrictions(admin1)
1225        );
1226
1227        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
1228        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1229                eq(UserHandle.USER_SYSTEM),
1230                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1231                MockUtils.checkUserRestrictions()
1232        );
1233        reset(mContext.userManagerInternal);
1234
1235        DpmTestUtils.assertRestrictions(
1236                DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1237                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1238        );
1239        DpmTestUtils.assertRestrictions(
1240                DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1241                dpm.getUserRestrictions(admin1)
1242        );
1243
1244        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1245        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1246                eq(UserHandle.USER_SYSTEM),
1247                MockUtils.checkUserRestrictions(),
1248                MockUtils.checkUserRestrictions()
1249        );
1250        reset(mContext.userManagerInternal);
1251
1252        DpmTestUtils.assertRestrictions(
1253                DpmTestUtils.newRestrictions(),
1254                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1255        );
1256        DpmTestUtils.assertRestrictions(
1257                DpmTestUtils.newRestrictions(),
1258                dpm.getUserRestrictions(admin1)
1259        );
1260
1261        // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE are PO restrictions, but when
1262        // DO sets them, the scope is global.
1263        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
1264        reset(mContext.userManagerInternal);
1265        dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1266        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1267                eq(UserHandle.USER_SYSTEM),
1268                MockUtils.checkUserRestrictions(),
1269                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
1270                        UserManager.DISALLOW_UNMUTE_MICROPHONE)
1271        );
1272        reset(mContext.userManagerInternal);
1273
1274        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
1275        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1276
1277
1278        // More tests.
1279        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
1280        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1281                eq(UserHandle.USER_SYSTEM),
1282                MockUtils.checkUserRestrictions(),
1283                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER)
1284        );
1285        reset(mContext.userManagerInternal);
1286
1287        dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN);
1288        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1289                eq(UserHandle.USER_SYSTEM),
1290                MockUtils.checkUserRestrictions(),
1291                MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
1292                        UserManager.DISALLOW_ADD_USER)
1293        );
1294        reset(mContext.userManagerInternal);
1295
1296        dpm.setCameraDisabled(admin1, true);
1297        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1298                eq(UserHandle.USER_SYSTEM),
1299                // DISALLOW_CAMERA will be applied to both local and global.
1300                MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA),
1301                MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
1302                        UserManager.DISALLOW_CAMERA, UserManager.DISALLOW_ADD_USER)
1303        );
1304        reset(mContext.userManagerInternal);
1305
1306        // Set up another DA and let it disable camera.  Now DISALLOW_CAMERA will only be applied
1307        // locally.
1308        dpm.setCameraDisabled(admin1, false);
1309        reset(mContext.userManagerInternal);
1310
1311        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
1312        dpm.setActiveAdmin(admin2, /* replace =*/ false, UserHandle.USER_SYSTEM);
1313        dpm.setCameraDisabled(admin2, true);
1314
1315        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1316                eq(UserHandle.USER_SYSTEM),
1317                // DISALLOW_CAMERA will be applied to both local and global.
1318                MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA),
1319                MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
1320                        UserManager.DISALLOW_ADD_USER)
1321        );
1322        reset(mContext.userManagerInternal);
1323        // TODO Make sure restrictions are written to the file.
1324    }
1325
1326    public void testSetUserRestriction_asPo() {
1327        setAsProfileOwner(admin1);
1328
1329        DpmTestUtils.assertRestrictions(
1330                DpmTestUtils.newRestrictions(),
1331                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1332                        .ensureUserRestrictions()
1333        );
1334
1335        dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
1336        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1337                eq(DpmMockContext.CALLER_USER_HANDLE),
1338                MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
1339                isNull(Bundle.class)
1340        );
1341        reset(mContext.userManagerInternal);
1342
1343        dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1344        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1345                eq(DpmMockContext.CALLER_USER_HANDLE),
1346                MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
1347                        UserManager.DISALLOW_OUTGOING_CALLS),
1348                isNull(Bundle.class)
1349        );
1350        reset(mContext.userManagerInternal);
1351
1352        DpmTestUtils.assertRestrictions(
1353                DpmTestUtils.newRestrictions(
1354                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
1355                        UserManager.DISALLOW_OUTGOING_CALLS
1356                ),
1357                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1358                        .ensureUserRestrictions()
1359        );
1360        DpmTestUtils.assertRestrictions(
1361                DpmTestUtils.newRestrictions(
1362                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
1363                        UserManager.DISALLOW_OUTGOING_CALLS
1364                ),
1365                dpm.getUserRestrictions(admin1)
1366        );
1367
1368        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
1369        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1370                eq(DpmMockContext.CALLER_USER_HANDLE),
1371                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1372                isNull(Bundle.class)
1373        );
1374        reset(mContext.userManagerInternal);
1375
1376        DpmTestUtils.assertRestrictions(
1377                DpmTestUtils.newRestrictions(
1378                        UserManager.DISALLOW_OUTGOING_CALLS
1379                ),
1380                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1381                        .ensureUserRestrictions()
1382        );
1383        DpmTestUtils.assertRestrictions(
1384                DpmTestUtils.newRestrictions(
1385                        UserManager.DISALLOW_OUTGOING_CALLS
1386                ),
1387                dpm.getUserRestrictions(admin1)
1388        );
1389
1390        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1391        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1392                eq(DpmMockContext.CALLER_USER_HANDLE),
1393                MockUtils.checkUserRestrictions(),
1394                isNull(Bundle.class)
1395        );
1396        reset(mContext.userManagerInternal);
1397
1398        DpmTestUtils.assertRestrictions(
1399                DpmTestUtils.newRestrictions(),
1400                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1401                        .ensureUserRestrictions()
1402        );
1403        DpmTestUtils.assertRestrictions(
1404                DpmTestUtils.newRestrictions(),
1405                dpm.getUserRestrictions(admin1)
1406        );
1407
1408        // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE can be set by PO too, even
1409        // though when DO sets them they'll be applied globally.
1410        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
1411        reset(mContext.userManagerInternal);
1412        dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1413        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1414                eq(DpmMockContext.CALLER_USER_HANDLE),
1415                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
1416                        UserManager.DISALLOW_UNMUTE_MICROPHONE),
1417                isNull(Bundle.class)
1418        );
1419        reset(mContext.userManagerInternal);
1420
1421        dpm.setCameraDisabled(admin1, true);
1422        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1423                eq(DpmMockContext.CALLER_USER_HANDLE),
1424                MockUtils.checkUserRestrictions(UserManager.DISALLOW_CAMERA,
1425                        UserManager.DISALLOW_ADJUST_VOLUME,
1426                        UserManager.DISALLOW_UNMUTE_MICROPHONE),
1427                isNull(Bundle.class)
1428        );
1429        reset(mContext.userManagerInternal);
1430
1431        // TODO Make sure restrictions are written to the file.
1432    }
1433
1434    public void testGetMacAddress() throws Exception {
1435        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1436        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1437        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1438
1439        // In this test, change the caller user to "system".
1440        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1441
1442        // Make sure admin1 is installed on system user.
1443        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1444
1445        // Test 1. Caller doesn't have DO or DA.
1446        try {
1447            dpm.getWifiMacAddress(admin1);
1448            fail();
1449        } catch (SecurityException e) {
1450            MoreAsserts.assertContainsRegex("No active admin", e.getMessage());
1451        }
1452
1453        // DO needs to be an DA.
1454        dpm.setActiveAdmin(admin1, /* replace =*/ false);
1455        assertTrue(dpm.isAdminActive(admin1));
1456
1457        // Test 2. Caller has DA, but not DO.
1458        try {
1459            dpm.getWifiMacAddress(admin1);
1460            fail();
1461        } catch (SecurityException e) {
1462            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
1463        }
1464
1465        // Test 3. Caller has PO, but not DO.
1466        assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
1467        try {
1468            dpm.getWifiMacAddress(admin1);
1469            fail();
1470        } catch (SecurityException e) {
1471            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
1472        }
1473
1474        // Remove PO.
1475        dpm.clearProfileOwner(admin1);
1476
1477        // Test 4, Caller is DO now.
1478        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
1479
1480        // 4-1.  But no WifiInfo.
1481        assertNull(dpm.getWifiMacAddress(admin1));
1482
1483        // 4-2.  Returns WifiInfo, but with the default MAC.
1484        when(mContext.wifiManager.getConnectionInfo()).thenReturn(new WifiInfo());
1485        assertNull(dpm.getWifiMacAddress(admin1));
1486
1487        // 4-3. With a real MAC address.
1488        final WifiInfo wi = new WifiInfo();
1489        wi.setMacAddress("11:22:33:44:55:66");
1490        when(mContext.wifiManager.getConnectionInfo()).thenReturn(wi);
1491        assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
1492    }
1493
1494    public void testRebootCanOnlyBeCalledByDeviceOwner() throws Exception {
1495        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1496        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1497
1498        // In this test, change the caller user to "system".
1499        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1500
1501        // Make sure admin1 is installed on system user.
1502        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1503
1504        // Set admin1 as DA.
1505        dpm.setActiveAdmin(admin1, false);
1506        assertTrue(dpm.isAdminActive(admin1));
1507        try {
1508            dpm.reboot(admin1);
1509            fail("DA calls DPM.reboot(), did not throw expected SecurityException");
1510        } catch (SecurityException expected) {
1511            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
1512        }
1513
1514        // Set admin1 as PO.
1515        assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
1516        try {
1517            dpm.reboot(admin1);
1518            fail("PO calls DPM.reboot(), did not throw expected SecurityException");
1519        } catch (SecurityException expected) {
1520            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
1521        }
1522
1523        // Remove PO and add DO.
1524        dpm.clearProfileOwner(admin1);
1525        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
1526
1527        dpm.reboot(admin1);
1528    }
1529
1530    public void testSetGetSupportText() {
1531        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1532        dpm.setActiveAdmin(admin1, true);
1533        dpm.setActiveAdmin(admin2, true);
1534        mContext.callerPermissions.remove(permission.MANAGE_DEVICE_ADMINS);
1535
1536        // Null default support messages.
1537        {
1538            assertNull(dpm.getLongSupportMessage(admin1));
1539            assertNull(dpm.getShortSupportMessage(admin1));
1540            mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
1541            assertNull(dpm.getShortSupportMessageForUser(admin1,
1542                    DpmMockContext.CALLER_USER_HANDLE));
1543            assertNull(dpm.getLongSupportMessageForUser(admin1,
1544                    DpmMockContext.CALLER_USER_HANDLE));
1545            mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
1546        }
1547
1548        // Only system can call the per user versions.
1549        {
1550            try {
1551                dpm.getShortSupportMessageForUser(admin1,
1552                        DpmMockContext.CALLER_USER_HANDLE);
1553                fail("Only system should be able to call getXXXForUser versions");
1554            } catch (SecurityException expected) {
1555                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
1556            }
1557            try {
1558                dpm.getLongSupportMessageForUser(admin1,
1559                        DpmMockContext.CALLER_USER_HANDLE);
1560                fail("Only system should be able to call getXXXForUser versions");
1561            } catch (SecurityException expected) {
1562                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
1563            }
1564        }
1565
1566        // Can't set message for admin in another uid.
1567        {
1568            mContext.binder.callingUid = DpmMockContext.CALLER_UID + 1;
1569            try {
1570                dpm.setShortSupportMessage(admin1, "Some text");
1571                fail("Admins should only be able to change their own support text.");
1572            } catch (SecurityException expected) {
1573                MoreAsserts.assertContainsRegex("is not owned by uid", expected.getMessage());
1574            }
1575            mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1576        }
1577
1578        // Set/Get short returns what it sets and other admins text isn't changed.
1579        {
1580            final String supportText = "Some text to test with.";
1581            dpm.setShortSupportMessage(admin1, supportText);
1582            assertEquals(supportText, dpm.getShortSupportMessage(admin1));
1583            assertNull(dpm.getLongSupportMessage(admin1));
1584            assertNull(dpm.getShortSupportMessage(admin2));
1585
1586            mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
1587            assertEquals(supportText, dpm.getShortSupportMessageForUser(admin1,
1588                    DpmMockContext.CALLER_USER_HANDLE));
1589            assertNull(dpm.getShortSupportMessageForUser(admin2,
1590                    DpmMockContext.CALLER_USER_HANDLE));
1591            assertNull(dpm.getLongSupportMessageForUser(admin1,
1592                    DpmMockContext.CALLER_USER_HANDLE));
1593            mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
1594
1595            dpm.setShortSupportMessage(admin1, null);
1596            assertNull(dpm.getShortSupportMessage(admin1));
1597        }
1598
1599        // Set/Get long returns what it sets and other admins text isn't changed.
1600        {
1601            final String supportText = "Some text to test with.\nWith more text.";
1602            dpm.setLongSupportMessage(admin1, supportText);
1603            assertEquals(supportText, dpm.getLongSupportMessage(admin1));
1604            assertNull(dpm.getShortSupportMessage(admin1));
1605            assertNull(dpm.getLongSupportMessage(admin2));
1606
1607            mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
1608            assertEquals(supportText, dpm.getLongSupportMessageForUser(admin1,
1609                    DpmMockContext.CALLER_USER_HANDLE));
1610            assertNull(dpm.getLongSupportMessageForUser(admin2,
1611                    DpmMockContext.CALLER_USER_HANDLE));
1612            assertNull(dpm.getShortSupportMessageForUser(admin1,
1613                    DpmMockContext.CALLER_USER_HANDLE));
1614            mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
1615
1616            dpm.setLongSupportMessage(admin1, null);
1617            assertNull(dpm.getLongSupportMessage(admin1));
1618        }
1619    }
1620
1621    /**
1622     * Test for:
1623     * {@link DevicePolicyManager#setAffiliationIds}
1624     * {@link DevicePolicyManager#isAffiliatedUser}
1625     */
1626    public void testUserAffiliation() throws Exception {
1627        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1628        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1629        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1630
1631        // Check that the system user is unaffiliated.
1632        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1633        assertFalse(dpm.isAffiliatedUser());
1634
1635        // Set a device owner on the system user. Check that the system user becomes affiliated.
1636        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1637        dpm.setActiveAdmin(admin1, /* replace =*/ false);
1638        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
1639        assertTrue(dpm.isAffiliatedUser());
1640
1641        // Install a profile owner whose package name matches the device owner on a test user. Check
1642        // that the test user is unaffiliated.
1643        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1644        setAsProfileOwner(admin2);
1645        assertFalse(dpm.isAffiliatedUser());
1646
1647        // Have the profile owner specify a set of affiliation ids. Check that the test user remains
1648        // unaffiliated.
1649        final Set<String> userAffiliationIds = new ArraySet<>();
1650        userAffiliationIds.add("red");
1651        userAffiliationIds.add("green");
1652        userAffiliationIds.add("blue");
1653        dpm.setAffiliationIds(admin2, userAffiliationIds);
1654        assertFalse(dpm.isAffiliatedUser());
1655
1656        // Have the device owner specify a set of affiliation ids that do not intersect with those
1657        // specified by the profile owner. Check that the test user remains unaffiliated.
1658        final Set<String> deviceAffiliationIds = new ArraySet<>();
1659        deviceAffiliationIds.add("cyan");
1660        deviceAffiliationIds.add("yellow");
1661        deviceAffiliationIds.add("magenta");
1662        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1663        dpm.setAffiliationIds(admin1, deviceAffiliationIds);
1664        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1665        assertFalse(dpm.isAffiliatedUser());
1666
1667        // Have the profile owner specify a set of affiliation ids that intersect with those
1668        // specified by the device owner. Check that the test user becomes affiliated.
1669        userAffiliationIds.add("yellow");
1670        dpm.setAffiliationIds(admin2, userAffiliationIds);
1671        assertTrue(dpm.isAffiliatedUser());
1672
1673        // Change the profile owner to one whose package name does not match the device owner. Check
1674        // that the test user is not affiliated anymore.
1675        dpm.clearProfileOwner(admin2);
1676        final ComponentName admin = new ComponentName("test", "test");
1677
1678        setUpPackageManagerForFakeAdmin(admin, DpmMockContext.CALLER_UID,
1679                /* enabledSetting =*/ PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
1680                /* appTargetSdk = */ null, admin2);
1681
1682        dpm.setActiveAdmin(admin, /* refreshing =*/ true, DpmMockContext.CALLER_USER_HANDLE);
1683        assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
1684        assertFalse(dpm.isAffiliatedUser());
1685
1686        // Check that the system user remains affiliated.
1687        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1688        assertTrue(dpm.isAffiliatedUser());
1689    }
1690
1691    public void testGetUserProvisioningState_defaultResult() {
1692        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
1693    }
1694
1695    public void testSetUserProvisioningState_permission() throws Exception {
1696        setupProfileOwner();
1697        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1698
1699        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
1700                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
1701    }
1702
1703    public void testSetUserProvisioningState_unprivileged() throws Exception {
1704        setupProfileOwner();
1705        try {
1706            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
1707                    DpmMockContext.CALLER_USER_HANDLE);
1708            fail("Expected SecurityException");
1709        } catch (SecurityException expected) {
1710        }
1711    }
1712
1713    public void testSetUserProvisioningState_noManagement() {
1714        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1715        try {
1716            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
1717                    DpmMockContext.CALLER_USER_HANDLE);
1718            fail("IllegalStateException expected");
1719        } catch (IllegalStateException e) {
1720            MoreAsserts.assertContainsRegex("change provisioning state unless a .* owner is set",
1721                    e.getMessage());
1722        }
1723        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
1724    }
1725
1726    public void testSetUserProvisioningState_deviceOwnerFromSetupWizard() throws Exception {
1727        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1728        setupDeviceOwner();
1729        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1730
1731        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
1732                DevicePolicyManager.STATE_USER_SETUP_COMPLETE,
1733                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
1734    }
1735
1736    public void testSetUserProvisioningState_deviceOwnerFromSetupWizardAlternative()
1737            throws Exception {
1738        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1739        setupDeviceOwner();
1740        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1741
1742        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
1743                DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
1744                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
1745    }
1746
1747    public void testSetUserProvisioningState_deviceOwnerWithoutSetupWizard() throws Exception {
1748        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1749        setupDeviceOwner();
1750        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1751
1752        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
1753                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
1754    }
1755
1756    public void testSetUserProvisioningState_managedProfileFromSetupWizard_primaryUser()
1757            throws Exception {
1758        setupProfileOwner();
1759        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1760
1761        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
1762                DevicePolicyManager.STATE_USER_PROFILE_COMPLETE,
1763                DevicePolicyManager.STATE_USER_UNMANAGED);
1764    }
1765
1766    public void testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile()
1767            throws Exception {
1768        setupProfileOwner();
1769        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1770
1771        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
1772                DevicePolicyManager.STATE_USER_SETUP_COMPLETE,
1773                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
1774    }
1775
1776    public void testSetUserProvisioningState_managedProfileWithoutSetupWizard() throws Exception {
1777        setupProfileOwner();
1778        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1779
1780        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
1781                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
1782    }
1783
1784    public void testSetUserProvisioningState_illegalTransitionOutOfFinalized1() throws Exception {
1785        setupProfileOwner();
1786        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1787
1788        try {
1789            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
1790                    DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
1791                    DevicePolicyManager.STATE_USER_UNMANAGED);
1792            fail("Expected IllegalStateException");
1793        } catch (IllegalStateException e) {
1794            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
1795                    e.getMessage());
1796        }
1797    }
1798
1799    public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState()
1800            throws Exception {
1801        setupProfileOwner();
1802        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1803
1804        try {
1805            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
1806                    DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
1807                    DevicePolicyManager.STATE_USER_SETUP_COMPLETE);
1808            fail("Expected IllegalStateException");
1809        } catch (IllegalStateException e) {
1810            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
1811                    e.getMessage());
1812        }
1813    }
1814
1815    private void exerciseUserProvisioningTransitions(int userId, int... states) {
1816        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
1817        for (int state : states) {
1818            dpm.setUserProvisioningState(state, userId);
1819            assertEquals(state, dpm.getUserProvisioningState());
1820        }
1821    }
1822
1823    private void setupProfileOwner() throws Exception {
1824        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
1825
1826        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
1827        dpm.setActiveAdmin(admin1, false);
1828        assertTrue(dpm.setProfileOwner(admin1, null, DpmMockContext.CALLER_USER_HANDLE));
1829
1830        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
1831    }
1832
1833    private void setupDeviceOwner() throws Exception {
1834        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
1835
1836        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1837        dpm.setActiveAdmin(admin1, false);
1838        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
1839
1840        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
1841    }
1842
1843    public void testSetMaximumTimeToLock() {
1844        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
1845
1846        dpm.setActiveAdmin(admin1, /* replace =*/ false);
1847        dpm.setActiveAdmin(admin2, /* replace =*/ false);
1848
1849        reset(mMockContext.powerManagerInternal);
1850        reset(mMockContext.settings);
1851
1852        dpm.setMaximumTimeToLock(admin1, 0);
1853        verifyScreenTimeoutCall(null, false);
1854        reset(mMockContext.powerManagerInternal);
1855        reset(mMockContext.settings);
1856
1857        dpm.setMaximumTimeToLock(admin1, 1);
1858        verifyScreenTimeoutCall(1, true);
1859        reset(mMockContext.powerManagerInternal);
1860        reset(mMockContext.settings);
1861
1862        dpm.setMaximumTimeToLock(admin2, 10);
1863        verifyScreenTimeoutCall(null, false);
1864        reset(mMockContext.powerManagerInternal);
1865        reset(mMockContext.settings);
1866
1867        dpm.setMaximumTimeToLock(admin1, 5);
1868        verifyScreenTimeoutCall(5, true);
1869        reset(mMockContext.powerManagerInternal);
1870        reset(mMockContext.settings);
1871
1872        dpm.setMaximumTimeToLock(admin2, 4);
1873        verifyScreenTimeoutCall(4, true);
1874        reset(mMockContext.powerManagerInternal);
1875        reset(mMockContext.settings);
1876
1877        dpm.setMaximumTimeToLock(admin1, 0);
1878        reset(mMockContext.powerManagerInternal);
1879        reset(mMockContext.settings);
1880
1881        dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE);
1882        verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
1883        reset(mMockContext.powerManagerInternal);
1884        reset(mMockContext.settings);
1885
1886        dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE + 1);
1887        verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
1888        reset(mMockContext.powerManagerInternal);
1889        reset(mMockContext.settings);
1890
1891        dpm.setMaximumTimeToLock(admin2, 10);
1892        verifyScreenTimeoutCall(10, true);
1893        reset(mMockContext.powerManagerInternal);
1894        reset(mMockContext.settings);
1895
1896        // There's no restriction; shold be set to MAX.
1897        dpm.setMaximumTimeToLock(admin2, 0);
1898        verifyScreenTimeoutCall(Integer.MAX_VALUE, false);
1899    }
1900
1901    private void verifyScreenTimeoutCall(Integer expectedTimeout,
1902            boolean shouldStayOnWhilePluggedInBeCleared) {
1903        if (expectedTimeout == null) {
1904            verify(mMockContext.powerManagerInternal, times(0))
1905                    .setMaximumScreenOffTimeoutFromDeviceAdmin(anyInt());
1906        } else {
1907            verify(mMockContext.powerManagerInternal, times(1))
1908                    .setMaximumScreenOffTimeoutFromDeviceAdmin(eq(expectedTimeout));
1909        }
1910        // TODO Verify calls to settingsGlobalPutInt.  Tried but somehow mockito threw
1911        // UnfinishedVerificationException.
1912    }
1913}
1914
1915