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