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