DevicePolicyManagerTest.java revision 9c6458dd58106538e790bbc702dbc10798e1bd18
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 static android.os.UserManagerInternal.CAMERA_DISABLED_GLOBALLY;
19import static android.os.UserManagerInternal.CAMERA_DISABLED_LOCALLY;
20import static android.os.UserManagerInternal.CAMERA_NOT_DISABLED;
21
22import android.Manifest.permission;
23import android.app.Activity;
24import android.app.Notification;
25import android.app.NotificationManager;
26import android.app.admin.DeviceAdminReceiver;
27import android.app.admin.DevicePolicyManager;
28import android.app.admin.DevicePolicyManagerInternal;
29import android.content.BroadcastReceiver;
30import android.content.ComponentName;
31import android.content.Context;
32import android.content.Intent;
33import android.content.ServiceConnection;
34import android.content.pm.ApplicationInfo;
35import android.content.pm.PackageInfo;
36import android.content.pm.PackageManager;
37import android.content.pm.StringParceledListSlice;
38import android.content.res.Resources;
39import android.graphics.Color;
40import android.net.IIpConnectivityMetrics;
41import android.net.Uri;
42import android.content.pm.UserInfo;
43import android.net.wifi.WifiInfo;
44import android.os.Build.VERSION_CODES;
45import android.os.Bundle;
46import android.os.IBinder;
47import android.os.Process;
48import android.os.UserHandle;
49import android.os.UserManager;
50import android.os.UserManagerInternal;
51import android.provider.Settings;
52import android.security.IKeyChainService;
53import android.security.KeyChain;
54import android.telephony.TelephonyManager;
55import android.test.MoreAsserts;
56import android.test.suitebuilder.annotation.SmallTest;
57import android.util.ArraySet;
58import android.util.Pair;
59
60import com.android.internal.R;
61import com.android.internal.widget.LockPatternUtils;
62import com.android.server.LocalServices;
63import com.android.server.SystemService;
64import com.android.server.pm.UserRestrictionsUtils;
65
66import org.hamcrest.BaseMatcher;
67import org.hamcrest.Description;
68import org.mockito.invocation.InvocationOnMock;
69import org.mockito.stubbing.Answer;
70
71import java.util.ArrayList;
72import java.util.Arrays;
73import java.util.Collections;
74import java.util.HashMap;
75import java.util.List;
76import java.util.Map;
77import java.util.Set;
78import java.util.concurrent.TimeUnit;
79
80import static android.app.admin.DevicePolicyManager.DELEGATION_APP_RESTRICTIONS;
81import static android.app.admin.DevicePolicyManager.DELEGATION_CERT_INSTALL;
82
83import static org.mockito.Matchers.any;
84import static org.mockito.Matchers.anyInt;
85import static org.mockito.Matchers.anyLong;
86import static org.mockito.Matchers.anyObject;
87import static org.mockito.Matchers.anyString;
88import static org.mockito.Matchers.eq;
89import static org.mockito.Matchers.isNull;
90import static org.mockito.Mockito.atLeast;
91import static org.mockito.Mockito.doAnswer;
92import static org.mockito.Mockito.doReturn;
93import static org.mockito.Mockito.mock;
94import static org.mockito.Mockito.never;
95import static org.mockito.Mockito.nullable;
96import static org.mockito.Mockito.reset;
97import static org.mockito.Mockito.timeout;
98import static org.mockito.Mockito.times;
99import static org.mockito.Mockito.verify;
100import static org.mockito.Mockito.verifyZeroInteractions;
101import static org.mockito.Mockito.when;
102import static org.mockito.hamcrest.MockitoHamcrest.argThat;
103
104/**
105 * Tests for DevicePolicyManager( and DevicePolicyManagerService).
106 * You can run them via:
107 m FrameworksServicesTests &&
108 adb install \
109   -r ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
110 adb shell am instrument -e class com.android.server.devicepolicy.DevicePolicyManagerTest \
111   -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
112
113 (mmma frameworks/base/services/tests/servicestests/ for non-ninja build)
114 *
115 * , or:
116 * runtest -c com.android.server.devicepolicy.DevicePolicyManagerTest frameworks-services
117 */
118@SmallTest
119public class DevicePolicyManagerTest extends DpmTestBase {
120    private static final List<String> OWNER_SETUP_PERMISSIONS = Arrays.asList(
121            permission.MANAGE_DEVICE_ADMINS, permission.MANAGE_PROFILE_AND_DEVICE_OWNERS,
122            permission.MANAGE_USERS, permission.INTERACT_ACROSS_USERS_FULL);
123
124    private DpmMockContext mContext;
125    public DevicePolicyManager dpm;
126    public DevicePolicyManagerServiceTestable dpms;
127
128    /*
129     * The CA cert below is the content of cacert.pem as generated by:
130     *
131     * openssl req -new -x509 -days 3650 -extensions v3_ca -keyout cakey.pem -out cacert.pem
132     */
133    private static final String TEST_CA =
134            "-----BEGIN CERTIFICATE-----\n" +
135            "MIIDXTCCAkWgAwIBAgIJAK9Tl/F9V8kSMA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV\n" +
136            "BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX\n" +
137            "aWRnaXRzIFB0eSBMdGQwHhcNMTUwMzA2MTczMjExWhcNMjUwMzAzMTczMjExWjBF\n" +
138            "MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50\n" +
139            "ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB\n" +
140            "CgKCAQEAvItOutsE75WBTgTyNAHt4JXQ3JoseaGqcC3WQij6vhrleWi5KJ0jh1/M\n" +
141            "Rpry7Fajtwwb4t8VZa0NuM2h2YALv52w1xivql88zce/HU1y7XzbXhxis9o6SCI+\n" +
142            "oVQSbPeXRgBPppFzBEh3ZqYTVhAqw451XhwdA4Aqs3wts7ddjwlUzyMdU44osCUg\n" +
143            "kVg7lfPf9sTm5IoHVcfLSCWH5n6Nr9sH3o2ksyTwxuOAvsN11F/a0mmUoPciYPp+\n" +
144            "q7DzQzdi7akRG601DZ4YVOwo6UITGvDyuAAdxl5isovUXqe6Jmz2/myTSpAKxGFs\n" +
145            "jk9oRoG6WXWB1kni490GIPjJ1OceyQIDAQABo1AwTjAdBgNVHQ4EFgQUH1QIlPKL\n" +
146            "p2OQ/AoLOjKvBW4zK3AwHwYDVR0jBBgwFoAUH1QIlPKLp2OQ/AoLOjKvBW4zK3Aw\n" +
147            "DAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAcMi4voMMJHeQLjtq8Oky\n" +
148            "Azpyk8moDwgCd4llcGj7izOkIIFqq/lyqKdtykVKUWz2bSHO5cLrtaOCiBWVlaCV\n" +
149            "DYAnnVLM8aqaA6hJDIfaGs4zmwz0dY8hVMFCuCBiLWuPfiYtbEmjHGSmpQTG6Qxn\n" +
150            "ZJlaK5CZyt5pgh5EdNdvQmDEbKGmu0wpCq9qjZImwdyAul1t/B0DrsWApZMgZpeI\n" +
151            "d2od0VBrCICB1K4p+C51D93xyQiva7xQcCne+TAnGNy9+gjQ/MyR8MRpwRLv5ikD\n" +
152            "u0anJCN8pXo6IMglfMAsoton1J6o5/ae5uhC6caQU8bNUsCK570gpNfjkzo6rbP0\n" +
153            "wQ==\n" +
154            "-----END CERTIFICATE-----\n";
155
156    @Override
157    protected void setUp() throws Exception {
158        super.setUp();
159
160        mContext = getContext();
161        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
162                .thenReturn(true);
163
164        // By default, pretend all users are running and unlocked.
165        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
166
167        initializeDpms();
168
169        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
170        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
171        setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_UID);
172        setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID);
173
174        setUpUserManager();
175    }
176
177    @Override
178    protected void tearDown() throws Exception {
179        flushTasks();
180        super.tearDown();
181    }
182
183    private void initializeDpms() {
184        // Need clearCallingIdentity() to pass permission checks.
185        final long ident = mContext.binder.clearCallingIdentity();
186        try {
187            LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
188
189            dpms = new DevicePolicyManagerServiceTestable(mContext, dataDir);
190
191            dpms.systemReady(SystemService.PHASE_LOCK_SETTINGS_READY);
192            dpms.systemReady(SystemService.PHASE_BOOT_COMPLETED);
193
194            dpm = new DevicePolicyManagerTestable(mContext, dpms);
195        } finally {
196            mContext.binder.restoreCallingIdentity(ident);
197        }
198    }
199
200    private void setUpUserManager() {
201        // Emulate UserManager.set/getApplicationRestriction().
202        final Map<Pair<String, UserHandle>, Bundle> appRestrictions = new HashMap<>();
203
204        // UM.setApplicationRestrictions() will save to appRestrictions.
205        doAnswer(new Answer<Void>() {
206            @Override
207            public Void answer(InvocationOnMock invocation) throws Throwable {
208                String pkg = (String) invocation.getArguments()[0];
209                Bundle bundle = (Bundle) invocation.getArguments()[1];
210                UserHandle user = (UserHandle) invocation.getArguments()[2];
211
212                appRestrictions.put(Pair.create(pkg, user), bundle);
213
214                return null;
215            }
216        }).when(mContext.userManager).setApplicationRestrictions(
217                anyString(), nullable(Bundle.class), any(UserHandle.class));
218
219        // UM.getApplicationRestrictions() will read from appRestrictions.
220        doAnswer(new Answer<Bundle>() {
221            @Override
222            public Bundle answer(InvocationOnMock invocation) throws Throwable {
223                String pkg = (String) invocation.getArguments()[0];
224                UserHandle user = (UserHandle) invocation.getArguments()[1];
225
226                return appRestrictions.get(Pair.create(pkg, user));
227            }
228        }).when(mContext.userManager).getApplicationRestrictions(
229                anyString(), any(UserHandle.class));
230
231        // Add the first secondary user.
232        mContext.addUser(DpmMockContext.CALLER_USER_HANDLE, 0);
233    }
234
235    private void setAsProfileOwner(ComponentName admin) {
236        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
237        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
238
239        // PO needs to be an DA.
240        dpm.setActiveAdmin(admin, /* replace =*/ false);
241
242        // Fire!
243        assertTrue(dpm.setProfileOwner(admin, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
244
245        // Check
246        assertEquals(admin, dpm.getProfileOwnerAsUser(DpmMockContext.CALLER_USER_HANDLE));
247    }
248
249    public void testHasNoFeature() throws Exception {
250        when(mContext.packageManager.hasSystemFeature(eq(PackageManager.FEATURE_DEVICE_ADMIN)))
251                .thenReturn(false);
252
253        LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
254        new DevicePolicyManagerServiceTestable(mContext, dataDir);
255
256        // If the device has no DPMS feature, it shouldn't register the local service.
257        assertNull(LocalServices.getService(DevicePolicyManagerInternal.class));
258    }
259
260    /**
261     * Caller doesn't have proper permissions.
262     */
263    public void testSetActiveAdmin_SecurityException() {
264        // 1. Failure cases.
265
266        // Caller doesn't have MANAGE_DEVICE_ADMINS.
267        try {
268            dpm.setActiveAdmin(admin1, false);
269            fail("Didn't throw SecurityException");
270        } catch (SecurityException expected) {
271        }
272
273        // Caller has MANAGE_DEVICE_ADMINS, but for different user.
274        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
275        try {
276            dpm.setActiveAdmin(admin1, false, DpmMockContext.CALLER_USER_HANDLE + 1);
277            fail("Didn't throw SecurityException");
278        } catch (SecurityException expected) {
279        }
280    }
281
282    /**
283     * Test for:
284     * {@link DevicePolicyManager#setActiveAdmin}
285     * with replace=false and replace=true
286     * {@link DevicePolicyManager#isAdminActive}
287     * {@link DevicePolicyManager#isAdminActiveAsUser}
288     * {@link DevicePolicyManager#getActiveAdmins}
289     * {@link DevicePolicyManager#getActiveAdminsAsUser}
290     */
291    public void testSetActiveAdmin() throws Exception {
292        // 1. Make sure the caller has proper permissions.
293        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
294
295        // 2. Call the API.
296        dpm.setActiveAdmin(admin1, /* replace =*/ false);
297
298        // 3. Verify internal calls.
299
300        // Check if the boradcast is sent.
301        verify(mContext.spiedContext).sendBroadcastAsUser(
302                MockUtils.checkIntentAction(
303                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
304                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
305        verify(mContext.spiedContext).sendBroadcastAsUser(
306                MockUtils.checkIntentAction(
307                        DeviceAdminReceiver.ACTION_DEVICE_ADMIN_ENABLED),
308                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
309
310        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
311                eq(admin1.getPackageName()),
312                eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
313                eq(PackageManager.DONT_KILL_APP),
314                eq(DpmMockContext.CALLER_USER_HANDLE),
315                anyString());
316
317        // TODO Verify other calls too.
318
319        // Make sure it's active admin1.
320        assertTrue(dpm.isAdminActive(admin1));
321        assertFalse(dpm.isAdminActive(admin2));
322        assertFalse(dpm.isAdminActive(admin3));
323
324        // But not admin1 for a different user.
325
326        // For this to work, caller needs android.permission.INTERACT_ACROSS_USERS_FULL.
327        // (Because we're checking a different user's status from CALLER_USER_HANDLE.)
328        mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
329
330        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE + 1));
331        assertFalse(dpm.isAdminActiveAsUser(admin2, DpmMockContext.CALLER_USER_HANDLE + 1));
332
333        mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
334
335        // Next, add one more admin.
336        // Before doing so, update the application info, now it's enabled.
337        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID,
338                PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
339
340        dpm.setActiveAdmin(admin2, /* replace =*/ false);
341
342        // Now we have two admins.
343        assertTrue(dpm.isAdminActive(admin1));
344        assertTrue(dpm.isAdminActive(admin2));
345        assertFalse(dpm.isAdminActive(admin3));
346
347        // Admin2 was already enabled, so setApplicationEnabledSetting() shouldn't have called
348        // again.  (times(1) because it was previously called for admin1)
349        verify(mContext.ipackageManager, times(1)).setApplicationEnabledSetting(
350                eq(admin1.getPackageName()),
351                eq(PackageManager.COMPONENT_ENABLED_STATE_DEFAULT),
352                eq(PackageManager.DONT_KILL_APP),
353                eq(DpmMockContext.CALLER_USER_HANDLE),
354                anyString());
355
356        // 4. Add the same admin1 again without replace, which should throw.
357        try {
358            dpm.setActiveAdmin(admin1, /* replace =*/ false);
359            fail("Didn't throw");
360        } catch (IllegalArgumentException expected) {
361        }
362
363        // 5. Add the same admin1 again with replace, which should succeed.
364        dpm.setActiveAdmin(admin1, /* replace =*/ true);
365
366        // TODO make sure it's replaced.
367
368        // 6. Test getActiveAdmins()
369        List<ComponentName> admins = dpm.getActiveAdmins();
370        assertEquals(2, admins.size());
371        assertEquals(admin1, admins.get(0));
372        assertEquals(admin2, admins.get(1));
373
374        // Another user has no admins.
375        mContext.callerPermissions.add("android.permission.INTERACT_ACROSS_USERS_FULL");
376
377        assertEquals(0, DpmTestUtils.getListSizeAllowingNull(
378                dpm.getActiveAdminsAsUser(DpmMockContext.CALLER_USER_HANDLE + 1)));
379
380        mContext.callerPermissions.remove("android.permission.INTERACT_ACROSS_USERS_FULL");
381    }
382
383    public void testSetActiveAdmin_multiUsers() throws Exception {
384
385        final int ANOTHER_USER_ID = 100;
386        final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 20456);
387
388        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
389
390        // Set up pacakge manager for the other user.
391        setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID);
392
393        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
394
395        dpm.setActiveAdmin(admin1, /* replace =*/ false);
396
397        mMockContext.binder.callingUid = ANOTHER_ADMIN_UID;
398        dpm.setActiveAdmin(admin2, /* replace =*/ false);
399
400
401        mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
402        assertTrue(dpm.isAdminActive(admin1));
403        assertFalse(dpm.isAdminActive(admin2));
404
405        mMockContext.binder.callingUid = ANOTHER_ADMIN_UID;
406        assertFalse(dpm.isAdminActive(admin1));
407        assertTrue(dpm.isAdminActive(admin2));
408    }
409
410    /**
411     * Test for:
412     * {@link DevicePolicyManager#setActiveAdmin}
413     * with replace=false
414     */
415    public void testSetActiveAdmin_twiceWithoutReplace() throws Exception {
416        // 1. Make sure the caller has proper permissions.
417        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
418
419        dpm.setActiveAdmin(admin1, /* replace =*/ false);
420        assertTrue(dpm.isAdminActive(admin1));
421
422        // Add the same admin1 again without replace, which should throw.
423        try {
424            dpm.setActiveAdmin(admin1, /* replace =*/ false);
425            fail("Didn't throw");
426        } catch (IllegalArgumentException expected) {
427        }
428    }
429
430    /**
431     * Test for:
432     * {@link DevicePolicyManager#setActiveAdmin} when the admin isn't protected with
433     * BIND_DEVICE_ADMIN.
434     */
435    public void testSetActiveAdmin_permissionCheck() throws Exception {
436        // 1. Make sure the caller has proper permissions.
437        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
438
439        try {
440            dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
441            fail();
442        } catch (IllegalArgumentException expected) {
443            assertTrue(expected.getMessage().contains(permission.BIND_DEVICE_ADMIN));
444        }
445        assertFalse(dpm.isAdminActive(adminNoPerm));
446
447        // Change the target API level to MNC.  Now it can be set as DA.
448        setUpPackageManagerForAdmin(adminNoPerm, DpmMockContext.CALLER_UID, null,
449                VERSION_CODES.M);
450        dpm.setActiveAdmin(adminNoPerm, /* replace =*/ false);
451        assertTrue(dpm.isAdminActive(adminNoPerm));
452
453        // TODO Test the "load from the file" case where DA will still be loaded even without
454        // BIND_DEVICE_ADMIN and target API is N.
455    }
456
457    /**
458     * Test for:
459     * {@link DevicePolicyManager#removeActiveAdmin}
460     */
461    public void testRemoveActiveAdmin_SecurityException() {
462        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
463
464        // Add admin.
465
466        dpm.setActiveAdmin(admin1, /* replace =*/ false);
467
468        assertTrue(dpm.isAdminActive(admin1));
469
470        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
471
472        // Directly call the DPMS method with a different userid, which should fail.
473        try {
474            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE + 1);
475            fail("Didn't throw SecurityException");
476        } catch (SecurityException expected) {
477        }
478
479        // Try to remove active admin with a different caller userid should fail too, without
480        // having MANAGE_DEVICE_ADMINS.
481        mContext.callerPermissions.clear();
482
483        // Change the caller, and call into DPMS directly with a different user-id.
484
485        mContext.binder.callingUid = 1234567;
486        try {
487            dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
488            fail("Didn't throw SecurityException");
489        } catch (SecurityException expected) {
490        }
491    }
492
493    /**
494     * {@link DevicePolicyManager#removeActiveAdmin} should fail with the user is not unlocked
495     * (because we can't send the remove broadcast).
496     */
497    public void testRemoveActiveAdmin_userNotRunningOrLocked() {
498        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
499
500        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
501
502        // Add admin.
503
504        dpm.setActiveAdmin(admin1, /* replace =*/ false);
505
506        assertTrue(dpm.isAdminActive(admin1));
507
508        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
509
510        // 1. User not unlocked.
511        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
512                .thenReturn(false);
513        try {
514            dpm.removeActiveAdmin(admin1);
515            fail("Didn't throw IllegalStateException");
516        } catch (IllegalStateException expected) {
517            MoreAsserts.assertContainsRegex(
518                    "User must be running and unlocked", expected.getMessage());
519        }
520
521        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
522
523        // 2. User unlocked.
524        when(mContext.userManager.isUserUnlocked(eq(DpmMockContext.CALLER_USER_HANDLE)))
525                .thenReturn(true);
526
527        dpm.removeActiveAdmin(admin1);
528        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
529    }
530
531    /**
532     * Test for:
533     * {@link DevicePolicyManager#removeActiveAdmin}
534     */
535    public void testRemoveActiveAdmin_fromDifferentUserWithINTERACT_ACROSS_USERS_FULL() {
536        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
537
538        // Add admin1.
539
540        dpm.setActiveAdmin(admin1, /* replace =*/ false);
541
542        assertTrue(dpm.isAdminActive(admin1));
543        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
544
545        // Different user, but should work, because caller has proper permissions.
546        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
547
548        // Change the caller, and call into DPMS directly with a different user-id.
549        mContext.binder.callingUid = 1234567;
550
551        dpms.removeActiveAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE);
552        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
553
554        // TODO DO Still can't be removed in this case.
555    }
556
557    /**
558     * Test for:
559     * {@link DevicePolicyManager#removeActiveAdmin}
560     */
561    public void testRemoveActiveAdmin_sameUserNoMANAGE_DEVICE_ADMINS() {
562        // Need MANAGE_DEVICE_ADMINS for setActiveAdmin.  We'll remove it later.
563        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
564
565        // Add admin1.
566
567        dpm.setActiveAdmin(admin1, /* replace =*/ false);
568
569        assertTrue(dpm.isAdminActive(admin1));
570        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
571
572        // Broadcast from saveSettingsLocked().
573        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
574                MockUtils.checkIntentAction(
575                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
576                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
577
578        // Remove.  No permissions, but same user, so it'll work.
579        mContext.callerPermissions.clear();
580        dpm.removeActiveAdmin(admin1);
581
582        verify(mContext.spiedContext).sendOrderedBroadcastAsUser(
583                MockUtils.checkIntentAction(
584                        DeviceAdminReceiver.ACTION_DEVICE_ADMIN_DISABLED),
585                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE),
586                isNull(String.class),
587                any(BroadcastReceiver.class),
588                eq(dpms.mHandler),
589                eq(Activity.RESULT_OK),
590                isNull(String.class),
591                isNull(Bundle.class));
592
593        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
594
595        // Again broadcast from saveSettingsLocked().
596        verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
597                MockUtils.checkIntentAction(
598                        DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED),
599                MockUtils.checkUserHandle(DpmMockContext.CALLER_USER_HANDLE));
600
601        // TODO Check other internal calls.
602    }
603
604    /**
605     * Test for: @{link DevicePolicyManager#setActivePasswordState}
606     *
607     * Validates that when the password for a user changes, the notification broadcast intent
608     * {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is sent to managed profile owners, in
609     * addition to ones in the original user.
610     */
611    public void testSetActivePasswordState_sendToProfiles() throws Exception {
612        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
613
614        final int MANAGED_PROFILE_USER_ID = 78;
615        final int MANAGED_PROFILE_ADMIN_UID =
616                UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID);
617
618        // Setup device owner.
619        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
620        mContext.packageName = admin1.getPackageName();
621        setupDeviceOwner();
622
623        // Add a managed profile belonging to the system user.
624        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
625
626        // Change the parent user's password.
627        dpm.reportPasswordChanged(UserHandle.USER_SYSTEM);
628
629        // Both the device owner and the managed profile owner should receive this broadcast.
630        final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED);
631        intent.setComponent(admin1);
632        intent.putExtra(Intent.EXTRA_USER, UserHandle.of(UserHandle.USER_SYSTEM));
633
634        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
635                MockUtils.checkIntent(intent),
636                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
637        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
638                MockUtils.checkIntent(intent),
639                MockUtils.checkUserHandle(MANAGED_PROFILE_USER_ID));
640    }
641
642    /**
643     * Test for: @{link DevicePolicyManager#setActivePasswordState}
644     *
645     * Validates that when the password for a managed profile changes, the notification broadcast
646     * intent {@link DeviceAdminReceiver#ACTION_PASSWORD_CHANGED} is only sent to the profile, not
647     * its parent.
648     */
649    public void testSetActivePasswordState_notSentToParent() throws Exception {
650        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
651
652        final int MANAGED_PROFILE_USER_ID = 78;
653        final int MANAGED_PROFILE_ADMIN_UID =
654                UserHandle.getUid(MANAGED_PROFILE_USER_ID, DpmMockContext.SYSTEM_UID);
655
656        // Setup device owner.
657        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
658        mContext.packageName = admin1.getPackageName();
659        doReturn(true).when(mContext.lockPatternUtils)
660                .isSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID);
661        setupDeviceOwner();
662
663        // Add a managed profile belonging to the system user.
664        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
665
666        // Change the profile's password.
667        dpm.reportPasswordChanged(MANAGED_PROFILE_USER_ID);
668
669        // Both the device owner and the managed profile owner should receive this broadcast.
670        final Intent intent = new Intent(DeviceAdminReceiver.ACTION_PASSWORD_CHANGED);
671        intent.setComponent(admin1);
672        intent.putExtra(Intent.EXTRA_USER, UserHandle.of(MANAGED_PROFILE_USER_ID));
673
674        verify(mContext.spiedContext, never()).sendBroadcastAsUser(
675                MockUtils.checkIntent(intent),
676                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
677        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
678                MockUtils.checkIntent(intent),
679                MockUtils.checkUserHandle(MANAGED_PROFILE_USER_ID));
680    }
681    /**
682     * Test for: {@link DevicePolicyManager#setDeviceOwner} DO on system user installs successfully.
683     */
684    public void testSetDeviceOwner() throws Exception {
685        setDeviceOwner();
686
687        // Try to set a profile owner on the same user, which should fail.
688        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
689        dpm.setActiveAdmin(admin2, /* refreshing= */ true, UserHandle.USER_SYSTEM);
690        try {
691            dpm.setProfileOwner(admin2, "owner-name", UserHandle.USER_SYSTEM);
692            fail("IllegalStateException not thrown");
693        } catch (IllegalStateException expected) {
694            assertTrue("Message was: " + expected.getMessage(),
695                    expected.getMessage().contains("already has a device owner"));
696        }
697
698        // DO admin can't be deactivated.
699        dpm.removeActiveAdmin(admin1);
700        assertTrue(dpm.isAdminActive(admin1));
701
702        // TODO Test getDeviceOwnerName() too. To do so, we need to change
703        // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
704    }
705
706    private void setDeviceOwner() throws Exception {
707        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
708        mContext.callerPermissions.add(permission.MANAGE_USERS);
709        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
710        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
711
712        // In this test, change the caller user to "system".
713        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
714
715        // Make sure admin1 is installed on system user.
716        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
717
718        // Check various get APIs.
719        checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ false);
720
721        // DO needs to be an DA.
722        dpm.setActiveAdmin(admin1, /* replace =*/ false);
723
724        // Fire!
725        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
726
727        // getDeviceOwnerComponent should return the admin1 component.
728        assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
729        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
730
731        // Check various get APIs.
732        checkGetDeviceOwnerInfoApi(dpm, /* hasDeviceOwner =*/ true);
733
734        // getDeviceOwnerComponent should *NOT* return the admin1 component for other users.
735        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
736        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
737        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
738
739        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
740
741        // Verify internal calls.
742        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
743                eq(admin1.getPackageName()));
744
745        // TODO We should check if the caller has called clearCallerIdentity().
746        verify(mContext.ibackupManager, times(1)).setBackupServiceActive(
747                eq(UserHandle.USER_SYSTEM), eq(false));
748
749        verify(mContext.spiedContext, times(1)).sendBroadcastAsUser(
750                MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
751                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
752
753        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
754    }
755
756    private void checkGetDeviceOwnerInfoApi(DevicePolicyManager dpm, boolean hasDeviceOwner) {
757        final int origCallingUser = mContext.binder.callingUid;
758        final List origPermissions = new ArrayList(mContext.callerPermissions);
759        mContext.callerPermissions.clear();
760
761        mContext.callerPermissions.add(permission.MANAGE_USERS);
762
763        mContext.binder.callingUid = Process.SYSTEM_UID;
764
765        // TODO Test getDeviceOwnerName() too.  To do so, we need to change
766        // DPMS.getApplicationLabel() because Context.createPackageContextAsUser() is not mockable.
767        if (hasDeviceOwner) {
768            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
769            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
770            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
771
772            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
773            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
774            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
775        } else {
776            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
777            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
778            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
779
780            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
781            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
782            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
783        }
784
785        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
786        if (hasDeviceOwner) {
787            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
788            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
789            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
790
791            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
792            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
793            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
794        } else {
795            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
796            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
797            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
798
799            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
800            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
801            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
802        }
803
804        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
805        // Still with MANAGE_USERS.
806        assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
807        assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
808        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
809
810        if (hasDeviceOwner) {
811            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
812            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
813            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
814        } else {
815            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
816            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
817            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
818        }
819
820        mContext.binder.callingUid = Process.SYSTEM_UID;
821        mContext.callerPermissions.remove(permission.MANAGE_USERS);
822        // System can still call "OnAnyUser" without MANAGE_USERS.
823        if (hasDeviceOwner) {
824            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
825            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
826            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
827
828            assertTrue(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
829            assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
830            assertEquals(UserHandle.USER_SYSTEM, dpm.getDeviceOwnerUserId());
831        } else {
832            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
833            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
834            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
835
836            assertFalse(dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName()));
837            assertEquals(null, dpm.getDeviceOwnerComponentOnAnyUser());
838            assertEquals(UserHandle.USER_NULL, dpm.getDeviceOwnerUserId());
839        }
840
841        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
842        // Still no MANAGE_USERS.
843        if (hasDeviceOwner) {
844            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
845            assertTrue(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
846            assertEquals(admin1, dpm.getDeviceOwnerComponentOnCallingUser());
847        } else {
848            assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
849            assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
850            assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
851        }
852
853        try {
854            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
855            fail();
856        } catch (SecurityException expected) {
857        }
858        try {
859            dpm.getDeviceOwnerComponentOnAnyUser();
860            fail();
861        } catch (SecurityException expected) {
862        }
863        try {
864            dpm.getDeviceOwnerUserId();
865            fail();
866        } catch (SecurityException expected) {
867        }
868        try {
869            dpm.getDeviceOwnerNameOnAnyUser();
870            fail();
871        } catch (SecurityException expected) {
872        }
873
874        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
875        // Still no MANAGE_USERS.
876        assertFalse(dpm.isDeviceOwnerApp(admin1.getPackageName()));
877        assertFalse(dpm.isDeviceOwnerAppOnCallingUser(admin1.getPackageName()));
878        assertEquals(null, dpm.getDeviceOwnerComponentOnCallingUser());
879
880        try {
881            dpm.isDeviceOwnerAppOnAnyUser(admin1.getPackageName());
882            fail();
883        } catch (SecurityException expected) {
884        }
885        try {
886            dpm.getDeviceOwnerComponentOnAnyUser();
887            fail();
888        } catch (SecurityException expected) {
889        }
890        try {
891            dpm.getDeviceOwnerUserId();
892            fail();
893        } catch (SecurityException expected) {
894        }
895        try {
896            dpm.getDeviceOwnerNameOnAnyUser();
897            fail();
898        } catch (SecurityException expected) {
899        }
900
901        // Restore.
902        mContext.binder.callingUid = origCallingUser;
903        mContext.callerPermissions.addAll(origPermissions);
904    }
905
906
907    /**
908     * Test for: {@link DevicePolicyManager#setDeviceOwner} Package doesn't exist.
909     */
910    public void testSetDeviceOwner_noSuchPackage() {
911        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
912        mContext.callerPermissions.add(permission.MANAGE_USERS);
913        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
914        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
915
916        // Call from a process on the system user.
917        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
918
919        try {
920            dpm.setDeviceOwner(new ComponentName("a.b.c", ".def"));
921            fail("Didn't throw IllegalArgumentException");
922        } catch (IllegalArgumentException expected) {
923            assertTrue("Message was: " + expected.getMessage(),
924                    expected.getMessage().contains("Invalid component"));
925        }
926    }
927
928    public void testSetDeviceOwner_failures() throws Exception {
929        // TODO Test more failure cases.  Basically test all chacks in enforceCanSetDeviceOwner().
930    }
931
932    public void testClearDeviceOwner() throws Exception {
933        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
934        mContext.callerPermissions.add(permission.MANAGE_USERS);
935        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
936        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
937
938        // Set admin1 as a DA to the secondary user.
939        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
940
941        dpm.setActiveAdmin(admin1, /* replace =*/ false);
942
943        // Set admin 1 as the DO to the system user.
944
945        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
946        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
947        dpm.setActiveAdmin(admin1, /* replace =*/ false);
948        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
949
950        // Verify internal calls.
951        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
952                eq(admin1.getPackageName()));
953
954        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
955
956        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
957        when(mContext.userManager.hasUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
958                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM))).thenReturn(true);
959
960        assertTrue(dpm.isAdminActive(admin1));
961        assertFalse(dpm.isRemovingAdmin(admin1, UserHandle.USER_SYSTEM));
962
963        // Set up other mocks.
964        when(mContext.userManager.getUserRestrictions()).thenReturn(new Bundle());
965
966        // Now call clear.
967        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager).getPackageUidAsUser(
968                eq(admin1.getPackageName()),
969                anyInt());
970
971        // But first pretend the user is locked.  Then it should fail.
972        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(false);
973        try {
974            dpm.clearDeviceOwnerApp(admin1.getPackageName());
975            fail("Didn't throw IllegalStateException");
976        } catch (IllegalStateException expected) {
977            MoreAsserts.assertContainsRegex(
978                    "User must be running and unlocked", expected.getMessage());
979        }
980
981        when(mContext.userManager.isUserUnlocked(anyInt())).thenReturn(true);
982        reset(mContext.userManagerInternal);
983        dpm.clearDeviceOwnerApp(admin1.getPackageName());
984
985        // Now DO shouldn't be set.
986        assertNull(dpm.getDeviceOwnerComponentOnAnyUser());
987
988        verify(mContext.userManager).setUserRestriction(eq(UserManager.DISALLOW_ADD_USER),
989                eq(false),
990                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
991
992        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
993                eq(UserHandle.USER_SYSTEM),
994                eq(null),
995                eq(true), eq(CAMERA_NOT_DISABLED));
996
997        assertFalse(dpm.isAdminActiveAsUser(admin1, UserHandle.USER_SYSTEM));
998
999        // ACTION_DEVICE_OWNER_CHANGED should be sent twice, once for setting the device owner
1000        // and once for clearing it.
1001        verify(mContext.spiedContext, times(2)).sendBroadcastAsUser(
1002                MockUtils.checkIntentAction(DevicePolicyManager.ACTION_DEVICE_OWNER_CHANGED),
1003                MockUtils.checkUserHandle(UserHandle.USER_SYSTEM));
1004        // TODO Check other calls.
1005    }
1006
1007    public void testClearDeviceOwner_fromDifferentUser() throws Exception {
1008        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1009        mContext.callerPermissions.add(permission.MANAGE_USERS);
1010        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1011        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1012
1013        // Set admin1 as a DA to the secondary user.
1014        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
1015
1016        dpm.setActiveAdmin(admin1, /* replace =*/ false);
1017
1018        // Set admin 1 as the DO to the system user.
1019
1020        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1021        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1022        dpm.setActiveAdmin(admin1, /* replace =*/ false);
1023        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
1024
1025        // Verify internal calls.
1026        verify(mContext.iactivityManager, times(1)).updateDeviceOwner(
1027                eq(admin1.getPackageName()));
1028
1029        assertEquals(admin1, dpm.getDeviceOwnerComponentOnAnyUser());
1030
1031        // Now call clear from the secondary user, which should throw.
1032        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1033
1034        // Now call clear.
1035        doReturn(DpmMockContext.CALLER_UID).when(mContext.packageManager).getPackageUidAsUser(
1036                eq(admin1.getPackageName()),
1037                anyInt());
1038        try {
1039            dpm.clearDeviceOwnerApp(admin1.getPackageName());
1040            fail("Didn't throw");
1041        } catch (SecurityException e) {
1042            assertEquals("clearDeviceOwner can only be called by the device owner", e.getMessage());
1043        }
1044
1045        // DO shouldn't be removed.
1046        assertTrue(dpm.isDeviceManaged());
1047    }
1048
1049    public void testSetProfileOwner() throws Exception {
1050        setAsProfileOwner(admin1);
1051
1052        // PO admin can't be deactivated.
1053        dpm.removeActiveAdmin(admin1);
1054        assertTrue(dpm.isAdminActive(admin1));
1055
1056        // Try setting DO on the same user, which should fail.
1057        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
1058        dpm.setActiveAdmin(admin2, /* refreshing= */ true, DpmMockContext.CALLER_USER_HANDLE);
1059        try {
1060            dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE);
1061            fail("IllegalStateException not thrown");
1062        } catch (IllegalStateException expected) {
1063            assertTrue("Message was: " + expected.getMessage(),
1064                    expected.getMessage().contains("already has a profile owner"));
1065        }
1066    }
1067
1068    public void testClearProfileOwner() throws Exception {
1069        setAsProfileOwner(admin1);
1070
1071        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1072
1073        assertTrue(dpm.isProfileOwnerApp(admin1.getPackageName()));
1074        assertFalse(dpm.isRemovingAdmin(admin1, DpmMockContext.CALLER_USER_HANDLE));
1075
1076        // First try when the user is locked, which should fail.
1077        when(mContext.userManager.isUserUnlocked(anyInt()))
1078                .thenReturn(false);
1079        try {
1080            dpm.clearProfileOwner(admin1);
1081            fail("Didn't throw IllegalStateException");
1082        } catch (IllegalStateException expected) {
1083            MoreAsserts.assertContainsRegex(
1084                    "User must be running and unlocked", expected.getMessage());
1085        }
1086        // Clear, really.
1087        when(mContext.userManager.isUserUnlocked(anyInt()))
1088                .thenReturn(true);
1089        dpm.clearProfileOwner(admin1);
1090
1091        // Check
1092        assertFalse(dpm.isProfileOwnerApp(admin1.getPackageName()));
1093        assertFalse(dpm.isAdminActiveAsUser(admin1, DpmMockContext.CALLER_USER_HANDLE));
1094    }
1095
1096    public void testSetProfileOwner_failures() throws Exception {
1097        // TODO Test more failure cases.  Basically test all chacks in enforceCanSetProfileOwner().
1098    }
1099
1100    public void testGetDeviceOwnerAdminLocked() throws Exception {
1101        checkDeviceOwnerWithMultipleDeviceAdmins();
1102    }
1103
1104    private void checkDeviceOwnerWithMultipleDeviceAdmins() throws Exception {
1105        // In ths test, we use 3 users (system + 2 secondary users), set some device admins to them,
1106        // set admin2 on CALLER_USER_HANDLE as DO, then call getDeviceOwnerAdminLocked() to
1107        // make sure it gets the right component from the right user.
1108
1109        final int ANOTHER_USER_ID = 100;
1110        final int ANOTHER_ADMIN_UID = UserHandle.getUid(ANOTHER_USER_ID, 456);
1111
1112        mMockContext.addUser(ANOTHER_USER_ID, 0); // Add one more user.
1113
1114        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1115        mContext.callerPermissions.add(permission.MANAGE_USERS);
1116        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1117        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1118
1119        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1120
1121        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
1122
1123        // Make sure the admin packge is installed to each user.
1124        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1125        setUpPackageManagerForAdmin(admin3, DpmMockContext.CALLER_SYSTEM_USER_UID);
1126
1127        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
1128        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_UID);
1129
1130        setUpPackageManagerForAdmin(admin2, ANOTHER_ADMIN_UID);
1131
1132
1133        // Set active admins to the users.
1134        dpm.setActiveAdmin(admin1, /* replace =*/ false);
1135        dpm.setActiveAdmin(admin3, /* replace =*/ false);
1136
1137        dpm.setActiveAdmin(admin1, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE);
1138        dpm.setActiveAdmin(admin2, /* replace =*/ false, DpmMockContext.CALLER_USER_HANDLE);
1139
1140        dpm.setActiveAdmin(admin2, /* replace =*/ false, ANOTHER_USER_ID);
1141
1142        // Set DO on the first non-system user.
1143        mContext.setUserRunning(DpmMockContext.CALLER_USER_HANDLE, true);
1144        assertTrue(dpm.setDeviceOwner(admin2, "owner-name", DpmMockContext.CALLER_USER_HANDLE));
1145
1146        assertEquals(admin2, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
1147
1148        // Then check getDeviceOwnerAdminLocked().
1149        assertEquals(admin2, dpms.getDeviceOwnerAdminLocked().info.getComponent());
1150        assertEquals(DpmMockContext.CALLER_UID, dpms.getDeviceOwnerAdminLocked().getUid());
1151    }
1152
1153    /**
1154     * This essentially tests
1155     * {@code DevicePolicyManagerService.findOwnerComponentIfNecessaryLocked()}. (which is
1156     * private.)
1157     *
1158     * We didn't use to persist the DO component class name, but now we do, and the above method
1159     * finds the right component from a package name upon migration.
1160     */
1161    public void testDeviceOwnerMigration() throws Exception {
1162        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
1163        checkDeviceOwnerWithMultipleDeviceAdmins();
1164
1165        // Overwrite the device owner setting and clears the clas name.
1166        dpms.mOwners.setDeviceOwner(
1167                new ComponentName(admin2.getPackageName(), ""),
1168                "owner-name", DpmMockContext.CALLER_USER_HANDLE);
1169        dpms.mOwners.writeDeviceOwner();
1170
1171        // Make sure the DO component name doesn't have a class name.
1172        assertEquals("", dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false).getClassName());
1173
1174        // Then create a new DPMS to have it load the settings from files.
1175        when(mContext.userManager.getUserRestrictions(any(UserHandle.class)))
1176                .thenReturn(new Bundle());
1177        initializeDpms();
1178
1179        // Now the DO component name is a full name.
1180        // *BUT* because both admin1 and admin2 belong to the same package, we think admin1 is the
1181        // DO.
1182        assertEquals(admin1, dpms.getDeviceOwnerComponent(/* callingUserOnly =*/ false));
1183    }
1184
1185    public void testSetGetApplicationRestriction() {
1186        setAsProfileOwner(admin1);
1187        mContext.packageName = admin1.getPackageName();
1188
1189        {
1190            Bundle rest = new Bundle();
1191            rest.putString("KEY_STRING", "Foo1");
1192            dpm.setApplicationRestrictions(admin1, "pkg1", rest);
1193        }
1194
1195        {
1196            Bundle rest = new Bundle();
1197            rest.putString("KEY_STRING", "Foo2");
1198            dpm.setApplicationRestrictions(admin1, "pkg2", rest);
1199        }
1200
1201        {
1202            Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg1");
1203            assertNotNull(returned);
1204            assertEquals(returned.size(), 1);
1205            assertEquals(returned.get("KEY_STRING"), "Foo1");
1206        }
1207
1208        {
1209            Bundle returned = dpm.getApplicationRestrictions(admin1, "pkg2");
1210            assertNotNull(returned);
1211            assertEquals(returned.size(), 1);
1212            assertEquals(returned.get("KEY_STRING"), "Foo2");
1213        }
1214
1215        dpm.setApplicationRestrictions(admin1, "pkg2", new Bundle());
1216        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg2").size());
1217    }
1218
1219    /**
1220     * Setup a package in the package manager mock for {@link DpmMockContext#CALLER_USER_HANDLE}.
1221     * Useful for faking installed applications.
1222     *
1223     * @param packageName the name of the package to be setup
1224     * @param appId the application ID to be given to the package
1225     * @return the UID of the package as known by the mock package manager
1226     */
1227    private int setupPackageInPackageManager(final String packageName, final int appId)
1228            throws Exception {
1229        return setupPackageInPackageManager(
1230                packageName, DpmMockContext.CALLER_USER_HANDLE, appId,
1231                ApplicationInfo.FLAG_HAS_CODE);
1232    }
1233
1234    /**
1235     * Setup a package in the package manager mock. Useful for faking installed applications.
1236     *
1237     * @param packageName the name of the package to be setup
1238     * @param userId the user id where the package will be "installed"
1239     * @param appId the application ID to be given to the package
1240     * @param flags flags to set in the ApplicationInfo for this package
1241     * @return the UID of the package as known by the mock package manager
1242     */
1243    private int setupPackageInPackageManager(
1244            final String packageName, int userId, final int appId, int flags)
1245            throws Exception {
1246        // Make the PackageManager return the package instead of throwing a NameNotFoundException
1247        final PackageInfo pi = new PackageInfo();
1248        pi.applicationInfo = new ApplicationInfo();
1249        pi.applicationInfo.flags = flags;
1250        doReturn(pi).when(mContext.ipackageManager).getPackageInfo(
1251                eq(packageName),
1252                anyInt(),
1253                eq(userId));
1254        doReturn(pi.applicationInfo).when(mContext.ipackageManager).getApplicationInfo(
1255                eq(packageName),
1256                anyInt(),
1257                eq(userId));
1258
1259        // Setup application UID with the PackageManager
1260        final int uid = UserHandle.getUid(userId, appId);
1261        doReturn(uid).when(mContext.packageManager).getPackageUidAsUser(
1262                eq(packageName),
1263                eq(userId));
1264        // Associate packageName to uid
1265        doReturn(packageName).when(mContext.ipackageManager).getNameForUid(eq(uid));
1266        doReturn(new String[]{packageName})
1267            .when(mContext.ipackageManager).getPackagesForUid(eq(uid));
1268        return uid;
1269    }
1270
1271    public void testCertificateDisclosure() throws Exception {
1272        final int userId = DpmMockContext.CALLER_USER_HANDLE;
1273        final UserHandle user = UserHandle.of(userId);
1274
1275        mContext.applicationInfo = new ApplicationInfo();
1276        mContext.callerPermissions.add(permission.MANAGE_USERS);
1277        mContext.packageName = "com.android.frameworks.servicestests";
1278        mContext.addPackageContext(user, mContext);
1279        when(mContext.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
1280
1281        StringParceledListSlice oneCert = asSlice(new String[] {"1"});
1282        StringParceledListSlice fourCerts = asSlice(new String[] {"1", "2", "3", "4"});
1283
1284        final String TEST_STRING = "Test for exactly 2 certs out of 4";
1285        doReturn(TEST_STRING).when(mContext.resources).getQuantityText(anyInt(), eq(2));
1286
1287        // Given that we have exactly one certificate installed,
1288        when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(oneCert);
1289        // when that certificate is approved,
1290        dpms.approveCaCert(oneCert.getList().get(0), userId, true);
1291        // a notification should not be shown.
1292        verify(mContext.notificationManager, timeout(1000))
1293                .cancelAsUser(anyString(), anyInt(), eq(user));
1294
1295        // Given that we have four certificates installed,
1296        when(mContext.keyChainConnection.getService().getUserCaAliases()).thenReturn(fourCerts);
1297        // when two of them are approved (one of them approved twice hence no action),
1298        dpms.approveCaCert(fourCerts.getList().get(0), userId, true);
1299        dpms.approveCaCert(fourCerts.getList().get(1), userId, true);
1300        // a notification should be shown saying that there are two certificates left to approve.
1301        verify(mContext.notificationManager, timeout(1000))
1302                .notifyAsUser(anyString(), anyInt(), argThat(
1303                        new BaseMatcher<Notification>() {
1304                            @Override
1305                            public boolean matches(Object item) {
1306                                final Notification noti = (Notification) item;
1307                                return TEST_STRING.equals(
1308                                        noti.extras.getString(Notification.EXTRA_TITLE));
1309                            }
1310                            @Override
1311                            public void describeTo(Description description) {
1312                                description.appendText(
1313                                        "Notification{title=\"" + TEST_STRING + "\"}");
1314                            }
1315                        }), eq(user));
1316    }
1317
1318    /**
1319     * Simple test for delegate set/get and general delegation. Tests verifying that delegated
1320     * privileges can acually be exercised by a delegate are not covered here.
1321     */
1322    public void testDelegation() throws Exception {
1323        setAsProfileOwner(admin1);
1324
1325        final int userHandle = DpmMockContext.CALLER_USER_HANDLE;
1326
1327        // Given two packages
1328        final String CERT_DELEGATE = "com.delegate.certs";
1329        final String RESTRICTIONS_DELEGATE = "com.delegate.apprestrictions";
1330        final int CERT_DELEGATE_UID = setupPackageInPackageManager(CERT_DELEGATE, 20988);
1331        final int RESTRICTIONS_DELEGATE_UID = setupPackageInPackageManager(RESTRICTIONS_DELEGATE,
1332                20989);
1333
1334        // On delegation
1335        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1336        mContext.packageName = admin1.getPackageName();
1337        dpm.setCertInstallerPackage(admin1, CERT_DELEGATE);
1338        dpm.setApplicationRestrictionsManagingPackage(admin1, RESTRICTIONS_DELEGATE);
1339
1340        // DPMS correctly stores and retrieves the delegates
1341        DevicePolicyManagerService.DevicePolicyData policy = dpms.mUserData.get(userHandle);
1342        assertEquals(2, policy.mDelegationMap.size());
1343        MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(CERT_DELEGATE),
1344            DELEGATION_CERT_INSTALL);
1345        MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, CERT_DELEGATE),
1346            DELEGATION_CERT_INSTALL);
1347        assertEquals(CERT_DELEGATE, dpm.getCertInstallerPackage(admin1));
1348        MoreAsserts.assertContentsInAnyOrder(policy.mDelegationMap.get(RESTRICTIONS_DELEGATE),
1349            DELEGATION_APP_RESTRICTIONS);
1350        MoreAsserts.assertContentsInAnyOrder(dpm.getDelegatedScopes(admin1, RESTRICTIONS_DELEGATE),
1351            DELEGATION_APP_RESTRICTIONS);
1352        assertEquals(RESTRICTIONS_DELEGATE, dpm.getApplicationRestrictionsManagingPackage(admin1));
1353
1354        // On calling install certificate APIs from an unauthorized process
1355        mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID;
1356        mContext.packageName = RESTRICTIONS_DELEGATE;
1357
1358        // DPMS throws a SecurityException
1359        try {
1360            dpm.installCaCert(null, null);
1361            fail("Didn't throw SecurityException on unauthorized access");
1362        } catch (SecurityException expected) {
1363        }
1364
1365        // On calling install certificate APIs from an authorized process
1366        mContext.binder.callingUid = CERT_DELEGATE_UID;
1367        mContext.packageName = CERT_DELEGATE;
1368
1369        // DPMS executes without a SecurityException
1370        try {
1371            dpm.installCaCert(null, null);
1372        } catch (SecurityException unexpected) {
1373            fail("Threw SecurityException on authorized access");
1374        } catch (NullPointerException expected) {
1375        }
1376
1377        // On removing a delegate
1378        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1379        mContext.packageName = admin1.getPackageName();
1380        dpm.setCertInstallerPackage(admin1, null);
1381
1382        // DPMS does not allow access to ex-delegate
1383        mContext.binder.callingUid = CERT_DELEGATE_UID;
1384        mContext.packageName = CERT_DELEGATE;
1385        try {
1386            dpm.installCaCert(null, null);
1387            fail("Didn't throw SecurityException on unauthorized access");
1388        } catch (SecurityException expected) {
1389        }
1390
1391        // But still allows access to other existing delegates
1392        mContext.binder.callingUid = RESTRICTIONS_DELEGATE_UID;
1393        mContext.packageName = RESTRICTIONS_DELEGATE;
1394        try {
1395            dpm.getApplicationRestrictions(null, "pkg");
1396        } catch (SecurityException expected) {
1397            fail("Threw SecurityException on authorized access");
1398        }
1399    }
1400
1401    public void testApplicationRestrictionsManagingApp() throws Exception {
1402        setAsProfileOwner(admin1);
1403
1404        final String nonExistAppRestrictionsManagerPackage = "com.google.app.restrictions.manager2";
1405        final String appRestrictionsManagerPackage = "com.google.app.restrictions.manager";
1406        final int appRestrictionsManagerAppId = 20987;
1407        final int appRestrictionsManagerUid = setupPackageInPackageManager(
1408                appRestrictionsManagerPackage, appRestrictionsManagerAppId);
1409
1410        // appRestrictionsManager package shouldn't be able to manage restrictions as the PO hasn't
1411        // delegated that permission yet.
1412        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1413        mContext.packageName = admin1.getPackageName();
1414        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
1415        Bundle rest = new Bundle();
1416        rest.putString("KEY_STRING", "Foo1");
1417        try {
1418            dpm.setApplicationRestrictions(null, "pkg1", rest);
1419            fail("Didn't throw expected SecurityException");
1420        } catch (SecurityException expected) {
1421            MoreAsserts.assertContainsRegex(
1422                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
1423                    expected.getMessage());
1424        }
1425        try {
1426            dpm.getApplicationRestrictions(null, "pkg1");
1427            fail("Didn't throw expected SecurityException");
1428        } catch (SecurityException expected) {
1429            MoreAsserts.assertContainsRegex(
1430                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
1431                    expected.getMessage());
1432        }
1433
1434        // Check via the profile owner that no restrictions were set.
1435        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1436        mContext.packageName = admin1.getPackageName();
1437        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
1438
1439        // Check the API does not allow setting a non-existent package
1440        try {
1441            dpm.setApplicationRestrictionsManagingPackage(admin1,
1442                    nonExistAppRestrictionsManagerPackage);
1443            fail("Non-existent app set as app restriction manager.");
1444        } catch (PackageManager.NameNotFoundException expected) {
1445            MoreAsserts.assertContainsRegex(
1446                    nonExistAppRestrictionsManagerPackage, expected.getMessage());
1447        }
1448
1449        // Let appRestrictionsManagerPackage manage app restrictions
1450        dpm.setApplicationRestrictionsManagingPackage(admin1, appRestrictionsManagerPackage);
1451        assertEquals(appRestrictionsManagerPackage,
1452                dpm.getApplicationRestrictionsManagingPackage(admin1));
1453
1454        // Now that package should be able to set and retrieve app restrictions.
1455        mContext.binder.callingUid = appRestrictionsManagerUid;
1456        mContext.packageName = appRestrictionsManagerPackage;
1457        assertTrue(dpm.isCallerApplicationRestrictionsManagingPackage());
1458        dpm.setApplicationRestrictions(null, "pkg1", rest);
1459        Bundle returned = dpm.getApplicationRestrictions(null, "pkg1");
1460        assertEquals(1, returned.size(), 1);
1461        assertEquals("Foo1", returned.get("KEY_STRING"));
1462
1463        // The same app running on a separate user shouldn't be able to manage app restrictions.
1464        mContext.binder.callingUid = UserHandle.getUid(
1465                UserHandle.USER_SYSTEM, appRestrictionsManagerAppId);
1466        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
1467        try {
1468            dpm.setApplicationRestrictions(null, "pkg1", rest);
1469            fail("Didn't throw expected SecurityException");
1470        } catch (SecurityException expected) {
1471            MoreAsserts.assertContainsRegex(
1472                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
1473                    expected.getMessage());
1474        }
1475
1476        // The DPM is still able to manage app restrictions, even if it allowed another app to do it
1477        // too.
1478        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
1479        mContext.packageName = admin1.getPackageName();
1480        assertEquals(returned, dpm.getApplicationRestrictions(admin1, "pkg1"));
1481        dpm.setApplicationRestrictions(admin1, "pkg1", null);
1482        assertEquals(0, dpm.getApplicationRestrictions(admin1, "pkg1").size());
1483
1484        // Removing the ability for the package to manage app restrictions.
1485        dpm.setApplicationRestrictionsManagingPackage(admin1, null);
1486        assertNull(dpm.getApplicationRestrictionsManagingPackage(admin1));
1487        mContext.binder.callingUid = appRestrictionsManagerUid;
1488        mContext.packageName = appRestrictionsManagerPackage;
1489        assertFalse(dpm.isCallerApplicationRestrictionsManagingPackage());
1490        try {
1491            dpm.setApplicationRestrictions(null, "pkg1", null);
1492            fail("Didn't throw expected SecurityException");
1493        } catch (SecurityException expected) {
1494            MoreAsserts.assertContainsRegex(
1495                    "Caller with uid \\d+ is not a delegate of scope delegation-app-restrictions.",
1496                    expected.getMessage());
1497        }
1498    }
1499
1500    public void testSetUserRestriction_asDo() throws Exception {
1501        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1502        mContext.callerPermissions.add(permission.MANAGE_USERS);
1503        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1504        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1505
1506        // First, set DO.
1507
1508        // Call from a process on the system user.
1509        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1510
1511        // Make sure admin1 is installed on system user.
1512        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1513
1514        // Call.
1515        dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM);
1516        assertTrue(dpm.setDeviceOwner(admin1, "owner-name",
1517                UserHandle.USER_SYSTEM));
1518
1519        // Check that the user restrictions that are enabled by default are set. Then unset them.
1520        String[] defaultRestrictions = UserRestrictionsUtils
1521                .getDefaultEnabledForDeviceOwner().toArray(new String[0]);
1522        DpmTestUtils.assertRestrictions(
1523                DpmTestUtils.newRestrictions(defaultRestrictions),
1524                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1525        );
1526        DpmTestUtils.assertRestrictions(
1527                DpmTestUtils.newRestrictions(defaultRestrictions),
1528                dpm.getUserRestrictions(admin1)
1529        );
1530        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1531                eq(UserHandle.USER_SYSTEM),
1532                MockUtils.checkUserRestrictions(defaultRestrictions),
1533                eq(true) /* isDeviceOwner */,
1534                eq(CAMERA_NOT_DISABLED)
1535        );
1536        reset(mContext.userManagerInternal);
1537
1538        for (String restriction : defaultRestrictions) {
1539            dpm.clearUserRestriction(admin1, restriction);
1540        }
1541
1542        assertNoDeviceOwnerRestrictions();
1543        reset(mContext.userManagerInternal);
1544
1545        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
1546        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1547                eq(UserHandle.USER_SYSTEM),
1548                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
1549                eq(true), eq(CAMERA_NOT_DISABLED));
1550        reset(mContext.userManagerInternal);
1551
1552        dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1553        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1554                eq(UserHandle.USER_SYSTEM),
1555                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS,
1556                        UserManager.DISALLOW_ADD_USER),
1557                eq(true), eq(CAMERA_NOT_DISABLED));
1558        reset(mContext.userManagerInternal);
1559
1560        DpmTestUtils.assertRestrictions(
1561                DpmTestUtils.newRestrictions(
1562                        UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS),
1563                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1564        );
1565        DpmTestUtils.assertRestrictions(
1566                DpmTestUtils.newRestrictions(
1567                        UserManager.DISALLOW_ADD_USER, UserManager.DISALLOW_OUTGOING_CALLS),
1568                dpm.getUserRestrictions(admin1)
1569        );
1570
1571        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
1572        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1573                eq(UserHandle.USER_SYSTEM),
1574                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1575                eq(true), eq(CAMERA_NOT_DISABLED));
1576        reset(mContext.userManagerInternal);
1577
1578        DpmTestUtils.assertRestrictions(
1579                DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1580                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1581        );
1582        DpmTestUtils.assertRestrictions(
1583                DpmTestUtils.newRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1584                dpm.getUserRestrictions(admin1)
1585        );
1586
1587        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1588        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1589                eq(UserHandle.USER_SYSTEM),
1590                MockUtils.checkUserRestrictions(),
1591                eq(true), eq(CAMERA_NOT_DISABLED));
1592        reset(mContext.userManagerInternal);
1593
1594        assertNoDeviceOwnerRestrictions();
1595
1596        // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE are PO restrictions, but when
1597        // DO sets them, the scope is global.
1598        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
1599        reset(mContext.userManagerInternal);
1600        dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1601        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1602                eq(UserHandle.USER_SYSTEM),
1603                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
1604                        UserManager.DISALLOW_UNMUTE_MICROPHONE),
1605                eq(true), eq(CAMERA_NOT_DISABLED));
1606        reset(mContext.userManagerInternal);
1607
1608        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
1609        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1610        reset(mContext.userManagerInternal);
1611
1612        // More tests.
1613        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADD_USER);
1614        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1615                eq(UserHandle.USER_SYSTEM),
1616                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADD_USER),
1617                eq(true), eq(CAMERA_NOT_DISABLED));
1618        reset(mContext.userManagerInternal);
1619
1620        dpm.addUserRestriction(admin1, UserManager.DISALLOW_FUN);
1621        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1622                eq(UserHandle.USER_SYSTEM),
1623                MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
1624                        UserManager.DISALLOW_ADD_USER),
1625                eq(true), eq(CAMERA_NOT_DISABLED));
1626        reset(mContext.userManagerInternal);
1627
1628        dpm.setCameraDisabled(admin1, true);
1629        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1630                eq(UserHandle.USER_SYSTEM),
1631                // DISALLOW_CAMERA will be applied to both local and global.
1632                MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
1633                        UserManager.DISALLOW_ADD_USER),
1634                eq(true), eq(CAMERA_DISABLED_GLOBALLY));
1635        reset(mContext.userManagerInternal);
1636
1637        // Set up another DA and let it disable camera.  Now DISALLOW_CAMERA will only be applied
1638        // locally.
1639        dpm.setCameraDisabled(admin1, false);
1640        reset(mContext.userManagerInternal);
1641
1642        setUpPackageManagerForAdmin(admin2, DpmMockContext.CALLER_SYSTEM_USER_UID);
1643        dpm.setActiveAdmin(admin2, /* replace =*/ false, UserHandle.USER_SYSTEM);
1644        dpm.setCameraDisabled(admin2, true);
1645
1646        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1647                eq(UserHandle.USER_SYSTEM),
1648                // DISALLOW_CAMERA will be applied to both local and global. <- TODO: fix this
1649                MockUtils.checkUserRestrictions(UserManager.DISALLOW_FUN,
1650                        UserManager.DISALLOW_ADD_USER),
1651                eq(true), eq(CAMERA_DISABLED_LOCALLY));
1652        reset(mContext.userManagerInternal);
1653        // TODO Make sure restrictions are written to the file.
1654    }
1655
1656    public void testSetUserRestriction_asPo() {
1657        setAsProfileOwner(admin1);
1658
1659        DpmTestUtils.assertRestrictions(
1660                DpmTestUtils.newRestrictions(),
1661                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1662                        .ensureUserRestrictions()
1663        );
1664
1665        dpm.addUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
1666        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1667                eq(DpmMockContext.CALLER_USER_HANDLE),
1668                MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES),
1669                eq(false), eq(CAMERA_NOT_DISABLED));
1670        reset(mContext.userManagerInternal);
1671
1672        dpm.addUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1673        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1674                eq(DpmMockContext.CALLER_USER_HANDLE),
1675                MockUtils.checkUserRestrictions(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
1676                        UserManager.DISALLOW_OUTGOING_CALLS),
1677                eq(false), eq(CAMERA_NOT_DISABLED));
1678        reset(mContext.userManagerInternal);
1679
1680        DpmTestUtils.assertRestrictions(
1681                DpmTestUtils.newRestrictions(
1682                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
1683                        UserManager.DISALLOW_OUTGOING_CALLS
1684                ),
1685                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1686                        .ensureUserRestrictions()
1687        );
1688        DpmTestUtils.assertRestrictions(
1689                DpmTestUtils.newRestrictions(
1690                        UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
1691                        UserManager.DISALLOW_OUTGOING_CALLS
1692                ),
1693                dpm.getUserRestrictions(admin1)
1694        );
1695
1696        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
1697        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1698                eq(DpmMockContext.CALLER_USER_HANDLE),
1699                MockUtils.checkUserRestrictions(UserManager.DISALLOW_OUTGOING_CALLS),
1700                eq(false), eq(CAMERA_NOT_DISABLED));
1701        reset(mContext.userManagerInternal);
1702
1703        DpmTestUtils.assertRestrictions(
1704                DpmTestUtils.newRestrictions(
1705                        UserManager.DISALLOW_OUTGOING_CALLS
1706                ),
1707                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1708                        .ensureUserRestrictions()
1709        );
1710        DpmTestUtils.assertRestrictions(
1711                DpmTestUtils.newRestrictions(
1712                        UserManager.DISALLOW_OUTGOING_CALLS
1713                ),
1714                dpm.getUserRestrictions(admin1)
1715        );
1716
1717        dpm.clearUserRestriction(admin1, UserManager.DISALLOW_OUTGOING_CALLS);
1718        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1719                eq(DpmMockContext.CALLER_USER_HANDLE),
1720                MockUtils.checkUserRestrictions(),
1721                eq(false), eq(CAMERA_NOT_DISABLED));
1722        reset(mContext.userManagerInternal);
1723
1724        DpmTestUtils.assertRestrictions(
1725                DpmTestUtils.newRestrictions(),
1726                dpms.getProfileOwnerAdminLocked(DpmMockContext.CALLER_USER_HANDLE)
1727                        .ensureUserRestrictions()
1728        );
1729        DpmTestUtils.assertRestrictions(
1730                DpmTestUtils.newRestrictions(),
1731                dpm.getUserRestrictions(admin1)
1732        );
1733
1734        // DISALLOW_ADJUST_VOLUME and DISALLOW_UNMUTE_MICROPHONE can be set by PO too, even
1735        // though when DO sets them they'll be applied globally.
1736        dpm.addUserRestriction(admin1, UserManager.DISALLOW_ADJUST_VOLUME);
1737        reset(mContext.userManagerInternal);
1738        dpm.addUserRestriction(admin1, UserManager.DISALLOW_UNMUTE_MICROPHONE);
1739        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1740                eq(DpmMockContext.CALLER_USER_HANDLE),
1741                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
1742                        UserManager.DISALLOW_UNMUTE_MICROPHONE),
1743                eq(false), eq(CAMERA_NOT_DISABLED));
1744        reset(mContext.userManagerInternal);
1745
1746        dpm.setCameraDisabled(admin1, true);
1747        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1748                eq(DpmMockContext.CALLER_USER_HANDLE),
1749                MockUtils.checkUserRestrictions(UserManager.DISALLOW_ADJUST_VOLUME,
1750                        UserManager.DISALLOW_UNMUTE_MICROPHONE),
1751                eq(false), eq(CAMERA_DISABLED_LOCALLY));
1752        reset(mContext.userManagerInternal);
1753
1754        // TODO Make sure restrictions are written to the file.
1755    }
1756
1757
1758    public void testDefaultEnabledUserRestrictions() throws Exception {
1759        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1760        mContext.callerPermissions.add(permission.MANAGE_USERS);
1761        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1762        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1763
1764        // First, set DO.
1765
1766        // Call from a process on the system user.
1767        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1768
1769        // Make sure admin1 is installed on system user.
1770        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1771
1772        dpm.setActiveAdmin(admin1, /* replace =*/ false, UserHandle.USER_SYSTEM);
1773        assertTrue(dpm.setDeviceOwner(admin1, "owner-name",
1774                UserHandle.USER_SYSTEM));
1775
1776        // Check that the user restrictions that are enabled by default are set. Then unset them.
1777        String[] defaultRestrictions = UserRestrictionsUtils
1778                .getDefaultEnabledForDeviceOwner().toArray(new String[0]);
1779        assertTrue(defaultRestrictions.length > 0);
1780        DpmTestUtils.assertRestrictions(
1781                DpmTestUtils.newRestrictions(defaultRestrictions),
1782                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1783        );
1784        DpmTestUtils.assertRestrictions(
1785                DpmTestUtils.newRestrictions(defaultRestrictions),
1786                dpm.getUserRestrictions(admin1)
1787        );
1788        verify(mContext.userManagerInternal).setDevicePolicyUserRestrictions(
1789                eq(UserHandle.USER_SYSTEM),
1790                MockUtils.checkUserRestrictions(defaultRestrictions),
1791                eq(true) /* isDeviceOwner */,
1792                eq(CAMERA_NOT_DISABLED)
1793        );
1794        reset(mContext.userManagerInternal);
1795
1796        for (String restriction : defaultRestrictions) {
1797            dpm.clearUserRestriction(admin1, restriction);
1798        }
1799
1800        assertNoDeviceOwnerRestrictions();
1801
1802        // Initialize DPMS again and check that the user restriction wasn't enabled again.
1803        reset(mContext.userManagerInternal);
1804        initializeDpms();
1805        assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
1806        assertNotNull(dpms.getDeviceOwnerAdminLocked());
1807
1808        assertNoDeviceOwnerRestrictions();
1809
1810        // Add a new restriction to the default set, initialize DPMS, and check that the restriction
1811        // is set as it wasn't enabled during setDeviceOwner.
1812        final String newDefaultEnabledRestriction = UserManager.DISALLOW_REMOVE_MANAGED_PROFILE;
1813        assertFalse(UserRestrictionsUtils
1814                .getDefaultEnabledForDeviceOwner().contains(newDefaultEnabledRestriction));
1815        UserRestrictionsUtils
1816                .getDefaultEnabledForDeviceOwner().add(newDefaultEnabledRestriction);
1817        try {
1818            reset(mContext.userManagerInternal);
1819            initializeDpms();
1820            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
1821            assertNotNull(dpms.getDeviceOwnerAdminLocked());
1822
1823            DpmTestUtils.assertRestrictions(
1824                DpmTestUtils.newRestrictions(newDefaultEnabledRestriction),
1825                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1826            );
1827            DpmTestUtils.assertRestrictions(
1828                DpmTestUtils.newRestrictions(newDefaultEnabledRestriction),
1829                dpm.getUserRestrictions(admin1)
1830            );
1831            verify(mContext.userManagerInternal, atLeast(1)).setDevicePolicyUserRestrictions(
1832                eq(UserHandle.USER_SYSTEM),
1833                MockUtils.checkUserRestrictions(newDefaultEnabledRestriction),
1834                eq(true) /* isDeviceOwner */,
1835                eq(CAMERA_NOT_DISABLED)
1836            );
1837            reset(mContext.userManagerInternal);
1838
1839            // Remove the restriction.
1840            dpm.clearUserRestriction(admin1, newDefaultEnabledRestriction);
1841
1842            // Initialize DPMS again. The restriction shouldn't be enabled for a second time.
1843            initializeDpms();
1844            assertTrue(dpm.isDeviceOwnerApp(admin1.getPackageName()));
1845            assertNotNull(dpms.getDeviceOwnerAdminLocked());
1846            assertNoDeviceOwnerRestrictions();
1847        } finally {
1848            UserRestrictionsUtils
1849                .getDefaultEnabledForDeviceOwner().remove(newDefaultEnabledRestriction);
1850        }
1851    }
1852
1853    private void assertNoDeviceOwnerRestrictions() {
1854        DpmTestUtils.assertRestrictions(
1855                DpmTestUtils.newRestrictions(),
1856                dpms.getDeviceOwnerAdminLocked().ensureUserRestrictions()
1857        );
1858        DpmTestUtils.assertRestrictions(
1859                DpmTestUtils.newRestrictions(),
1860                dpm.getUserRestrictions(admin1)
1861        );
1862    }
1863
1864    public void testGetMacAddress() throws Exception {
1865        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1866        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1867        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
1868
1869        // In this test, change the caller user to "system".
1870        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1871
1872        // Make sure admin1 is installed on system user.
1873        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1874
1875        // Test 1. Caller doesn't have DO or DA.
1876        try {
1877            dpm.getWifiMacAddress(admin1);
1878            fail();
1879        } catch (SecurityException e) {
1880            MoreAsserts.assertContainsRegex("No active admin", e.getMessage());
1881        }
1882
1883        // DO needs to be an DA.
1884        dpm.setActiveAdmin(admin1, /* replace =*/ false);
1885        assertTrue(dpm.isAdminActive(admin1));
1886
1887        // Test 2. Caller has DA, but not DO.
1888        try {
1889            dpm.getWifiMacAddress(admin1);
1890            fail();
1891        } catch (SecurityException e) {
1892            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
1893        }
1894
1895        // Test 3. Caller has PO, but not DO.
1896        assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
1897        try {
1898            dpm.getWifiMacAddress(admin1);
1899            fail();
1900        } catch (SecurityException e) {
1901            MoreAsserts.assertContainsRegex("does not own the device", e.getMessage());
1902        }
1903
1904        // Remove PO.
1905        dpm.clearProfileOwner(admin1);
1906        dpm.setActiveAdmin(admin1, false);
1907        // Test 4, Caller is DO now.
1908        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
1909
1910        // 4-1.  But no WifiInfo.
1911        assertNull(dpm.getWifiMacAddress(admin1));
1912
1913        // 4-2.  Returns WifiInfo, but with the default MAC.
1914        when(mContext.wifiManager.getConnectionInfo()).thenReturn(new WifiInfo());
1915        assertNull(dpm.getWifiMacAddress(admin1));
1916
1917        // 4-3. With a real MAC address.
1918        final WifiInfo wi = new WifiInfo();
1919        wi.setMacAddress("11:22:33:44:55:66");
1920        when(mContext.wifiManager.getConnectionInfo()).thenReturn(wi);
1921        assertEquals("11:22:33:44:55:66", dpm.getWifiMacAddress(admin1));
1922    }
1923
1924    public void testReboot() throws Exception {
1925        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1926        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
1927
1928        // In this test, change the caller user to "system".
1929        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
1930
1931        // Make sure admin1 is installed on system user.
1932        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
1933
1934        // Set admin1 as DA.
1935        dpm.setActiveAdmin(admin1, false);
1936        assertTrue(dpm.isAdminActive(admin1));
1937        try {
1938            dpm.reboot(admin1);
1939            fail("DA calls DPM.reboot(), did not throw expected SecurityException");
1940        } catch (SecurityException expected) {
1941            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
1942        }
1943
1944        // Set admin1 as PO.
1945        assertTrue(dpm.setProfileOwner(admin1, null, UserHandle.USER_SYSTEM));
1946        try {
1947            dpm.reboot(admin1);
1948            fail("PO calls DPM.reboot(), did not throw expected SecurityException");
1949        } catch (SecurityException expected) {
1950            MoreAsserts.assertContainsRegex("does not own the device", expected.getMessage());
1951        }
1952
1953        // Remove PO and add DO.
1954        dpm.clearProfileOwner(admin1);
1955        dpm.setActiveAdmin(admin1, false);
1956        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
1957
1958        // admin1 is DO.
1959        // Set current call state of device to ringing.
1960        when(mContext.telephonyManager.getCallState())
1961                .thenReturn(TelephonyManager.CALL_STATE_RINGING);
1962        try {
1963            dpm.reboot(admin1);
1964            fail("DPM.reboot() called when receiveing a call, should thrown IllegalStateException");
1965        } catch (IllegalStateException expected) {
1966            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
1967        }
1968
1969        // Set current call state of device to dialing/active.
1970        when(mContext.telephonyManager.getCallState())
1971                .thenReturn(TelephonyManager.CALL_STATE_OFFHOOK);
1972        try {
1973            dpm.reboot(admin1);
1974            fail("DPM.reboot() called when dialing, should thrown IllegalStateException");
1975        } catch (IllegalStateException expected) {
1976            MoreAsserts.assertContainsRegex("ongoing call on the device", expected.getMessage());
1977        }
1978
1979        // Set current call state of device to idle.
1980        when(mContext.telephonyManager.getCallState()).thenReturn(TelephonyManager.CALL_STATE_IDLE);
1981        dpm.reboot(admin1);
1982    }
1983
1984    public void testSetGetSupportText() {
1985        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
1986        dpm.setActiveAdmin(admin1, true);
1987        dpm.setActiveAdmin(admin2, true);
1988        mContext.callerPermissions.remove(permission.MANAGE_DEVICE_ADMINS);
1989
1990        // Null default support messages.
1991        {
1992            assertNull(dpm.getLongSupportMessage(admin1));
1993            assertNull(dpm.getShortSupportMessage(admin1));
1994            mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
1995            assertNull(dpm.getShortSupportMessageForUser(admin1,
1996                    DpmMockContext.CALLER_USER_HANDLE));
1997            assertNull(dpm.getLongSupportMessageForUser(admin1,
1998                    DpmMockContext.CALLER_USER_HANDLE));
1999            mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
2000        }
2001
2002        // Only system can call the per user versions.
2003        {
2004            try {
2005                dpm.getShortSupportMessageForUser(admin1,
2006                        DpmMockContext.CALLER_USER_HANDLE);
2007                fail("Only system should be able to call getXXXForUser versions");
2008            } catch (SecurityException expected) {
2009                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
2010            }
2011            try {
2012                dpm.getLongSupportMessageForUser(admin1,
2013                        DpmMockContext.CALLER_USER_HANDLE);
2014                fail("Only system should be able to call getXXXForUser versions");
2015            } catch (SecurityException expected) {
2016                MoreAsserts.assertContainsRegex("message for user", expected.getMessage());
2017            }
2018        }
2019
2020        // Can't set message for admin in another uid.
2021        {
2022            mContext.binder.callingUid = DpmMockContext.CALLER_UID + 1;
2023            try {
2024                dpm.setShortSupportMessage(admin1, "Some text");
2025                fail("Admins should only be able to change their own support text.");
2026            } catch (SecurityException expected) {
2027                MoreAsserts.assertContainsRegex("is not owned by uid", expected.getMessage());
2028            }
2029            mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2030        }
2031
2032        // Set/Get short returns what it sets and other admins text isn't changed.
2033        {
2034            final String supportText = "Some text to test with.";
2035            dpm.setShortSupportMessage(admin1, supportText);
2036            assertEquals(supportText, dpm.getShortSupportMessage(admin1));
2037            assertNull(dpm.getLongSupportMessage(admin1));
2038            assertNull(dpm.getShortSupportMessage(admin2));
2039
2040            mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
2041            assertEquals(supportText, dpm.getShortSupportMessageForUser(admin1,
2042                    DpmMockContext.CALLER_USER_HANDLE));
2043            assertNull(dpm.getShortSupportMessageForUser(admin2,
2044                    DpmMockContext.CALLER_USER_HANDLE));
2045            assertNull(dpm.getLongSupportMessageForUser(admin1,
2046                    DpmMockContext.CALLER_USER_HANDLE));
2047            mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
2048
2049            dpm.setShortSupportMessage(admin1, null);
2050            assertNull(dpm.getShortSupportMessage(admin1));
2051        }
2052
2053        // Set/Get long returns what it sets and other admins text isn't changed.
2054        {
2055            final String supportText = "Some text to test with.\nWith more text.";
2056            dpm.setLongSupportMessage(admin1, supportText);
2057            assertEquals(supportText, dpm.getLongSupportMessage(admin1));
2058            assertNull(dpm.getShortSupportMessage(admin1));
2059            assertNull(dpm.getLongSupportMessage(admin2));
2060
2061            mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
2062            assertEquals(supportText, dpm.getLongSupportMessageForUser(admin1,
2063                    DpmMockContext.CALLER_USER_HANDLE));
2064            assertNull(dpm.getLongSupportMessageForUser(admin2,
2065                    DpmMockContext.CALLER_USER_HANDLE));
2066            assertNull(dpm.getShortSupportMessageForUser(admin1,
2067                    DpmMockContext.CALLER_USER_HANDLE));
2068            mMockContext.binder.callingUid = DpmMockContext.CALLER_UID;
2069
2070            dpm.setLongSupportMessage(admin1, null);
2071            assertNull(dpm.getLongSupportMessage(admin1));
2072        }
2073    }
2074
2075    public void testCreateAdminSupportIntent() throws Exception {
2076        // Setup device owner.
2077        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2078        setupDeviceOwner();
2079
2080        // Nonexisting permission returns null
2081        Intent intent = dpm.createAdminSupportIntent("disallow_nothing");
2082        assertNull(intent);
2083
2084        // Existing permission that is not set returns null
2085        intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
2086        assertNull(intent);
2087
2088        // Existing permission that is not set by device/profile owner returns null
2089        when(mContext.userManager.hasUserRestriction(
2090                eq(UserManager.DISALLOW_ADJUST_VOLUME),
2091                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2092                .thenReturn(true);
2093        intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
2094        assertNull(intent);
2095
2096        // Permission that is set by device owner returns correct intent
2097        when(mContext.userManager.getUserRestrictionSource(
2098                eq(UserManager.DISALLOW_ADJUST_VOLUME),
2099                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2100                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
2101        intent = dpm.createAdminSupportIntent(UserManager.DISALLOW_ADJUST_VOLUME);
2102        assertNotNull(intent);
2103        assertEquals(Settings.ACTION_SHOW_ADMIN_SUPPORT_DETAILS, intent.getAction());
2104        assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
2105                intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
2106        assertEquals(admin1,
2107                (ComponentName) intent.getParcelableExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN));
2108        assertEquals(UserManager.DISALLOW_ADJUST_VOLUME,
2109                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
2110
2111        // Try with POLICY_DISABLE_CAMERA and POLICY_DISABLE_SCREEN_CAPTURE, which are not
2112        // user restrictions
2113
2114        // Camera is not disabled
2115        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
2116        assertNull(intent);
2117
2118        // Camera is disabled
2119        dpm.setCameraDisabled(admin1, true);
2120        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
2121        assertNotNull(intent);
2122        assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA,
2123                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
2124
2125        // Screen capture is not disabled
2126        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
2127        assertNull(intent);
2128
2129        // Screen capture is disabled
2130        dpm.setScreenCaptureDisabled(admin1, true);
2131        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
2132        assertNotNull(intent);
2133        assertEquals(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE,
2134                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
2135
2136        // Same checks for different user
2137        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2138        // Camera should be disabled by device owner
2139        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_CAMERA);
2140        assertNotNull(intent);
2141        assertEquals(DevicePolicyManager.POLICY_DISABLE_CAMERA,
2142                intent.getStringExtra(DevicePolicyManager.EXTRA_RESTRICTION));
2143        assertEquals(UserHandle.getUserId(DpmMockContext.CALLER_SYSTEM_USER_UID),
2144                intent.getIntExtra(Intent.EXTRA_USER_ID, -1));
2145        // ScreenCapture should not be disabled by device owner
2146        intent = dpm.createAdminSupportIntent(DevicePolicyManager.POLICY_DISABLE_SCREEN_CAPTURE);
2147        assertNull(intent);
2148    }
2149
2150    /**
2151     * Test for:
2152     * {@link DevicePolicyManager#setAffiliationIds}
2153     * {@link DevicePolicyManager#getAffiliationIds}
2154     * {@link DevicePolicyManager#isAffiliatedUser}
2155     */
2156    public void testUserAffiliation() throws Exception {
2157        mContext.callerPermissions.add(permission.MANAGE_DEVICE_ADMINS);
2158        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2159        mContext.callerPermissions.add(permission.INTERACT_ACROSS_USERS_FULL);
2160
2161        // Check that the system user is unaffiliated.
2162        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2163        assertFalse(dpm.isAffiliatedUser());
2164
2165        // Set a device owner on the system user. Check that the system user becomes affiliated.
2166        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
2167        dpm.setActiveAdmin(admin1, /* replace =*/ false);
2168        assertTrue(dpm.setDeviceOwner(admin1, "owner-name"));
2169        assertTrue(dpm.isAffiliatedUser());
2170        assertTrue(dpm.getAffiliationIds(admin1).isEmpty());
2171
2172        // Install a profile owner. Check that the test user is unaffiliated.
2173        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2174        setAsProfileOwner(admin2);
2175        assertFalse(dpm.isAffiliatedUser());
2176        assertTrue(dpm.getAffiliationIds(admin2).isEmpty());
2177
2178        // Have the profile owner specify a set of affiliation ids. Check that the test user remains
2179        // unaffiliated.
2180        final Set<String> userAffiliationIds = new ArraySet<>();
2181        userAffiliationIds.add("red");
2182        userAffiliationIds.add("green");
2183        userAffiliationIds.add("blue");
2184        dpm.setAffiliationIds(admin2, userAffiliationIds);
2185        MoreAsserts.assertContentsInAnyOrder(dpm.getAffiliationIds(admin2), "red", "green", "blue");
2186        assertFalse(dpm.isAffiliatedUser());
2187
2188        // Have the device owner specify a set of affiliation ids that do not intersect with those
2189        // specified by the profile owner. Check that the test user remains unaffiliated.
2190        final Set<String> deviceAffiliationIds = new ArraySet<>();
2191        deviceAffiliationIds.add("cyan");
2192        deviceAffiliationIds.add("yellow");
2193        deviceAffiliationIds.add("magenta");
2194        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2195        dpm.setAffiliationIds(admin1, deviceAffiliationIds);
2196        MoreAsserts.assertContentsInAnyOrder(
2197            dpm.getAffiliationIds(admin1), "cyan", "yellow", "magenta");
2198        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2199        assertFalse(dpm.isAffiliatedUser());
2200
2201        // Have the profile owner specify a set of affiliation ids that intersect with those
2202        // specified by the device owner. Check that the test user becomes affiliated.
2203        userAffiliationIds.add("yellow");
2204        dpm.setAffiliationIds(admin2, userAffiliationIds);
2205        MoreAsserts.assertContentsInAnyOrder(
2206            dpm.getAffiliationIds(admin2), "red", "green", "blue", "yellow");
2207        assertTrue(dpm.isAffiliatedUser());
2208
2209        // Clear affiliation ids for the profile owner. The user becomes unaffiliated.
2210        dpm.setAffiliationIds(admin2, Collections.emptySet());
2211        assertTrue(dpm.getAffiliationIds(admin2).isEmpty());
2212        assertFalse(dpm.isAffiliatedUser());
2213
2214        // Set affiliation ids again, then clear PO to check that the user becomes unaffiliated
2215        dpm.setAffiliationIds(admin2, userAffiliationIds);
2216        assertTrue(dpm.isAffiliatedUser());
2217        dpm.clearProfileOwner(admin2);
2218        assertFalse(dpm.isAffiliatedUser());
2219
2220        // Check that the system user remains affiliated.
2221        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2222        assertTrue(dpm.isAffiliatedUser());
2223
2224        // Clear the device owner - the user becomes unaffiliated.
2225        clearDeviceOwner();
2226        assertFalse(dpm.isAffiliatedUser());
2227    }
2228
2229    public void testGetUserProvisioningState_defaultResult() {
2230        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
2231    }
2232
2233    public void testSetUserProvisioningState_permission() throws Exception {
2234        setupProfileOwner();
2235        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2236
2237        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2238                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2239    }
2240
2241    public void testSetUserProvisioningState_unprivileged() throws Exception {
2242        setupProfileOwner();
2243        try {
2244            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
2245                    DpmMockContext.CALLER_USER_HANDLE);
2246            fail("Expected SecurityException");
2247        } catch (SecurityException expected) {
2248        }
2249    }
2250
2251    public void testSetUserProvisioningState_noManagement() {
2252        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2253        try {
2254            dpm.setUserProvisioningState(DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
2255                    DpmMockContext.CALLER_USER_HANDLE);
2256            fail("IllegalStateException expected");
2257        } catch (IllegalStateException e) {
2258            MoreAsserts.assertContainsRegex("change provisioning state unless a .* owner is set",
2259                    e.getMessage());
2260        }
2261        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
2262    }
2263
2264    public void testSetUserProvisioningState_deviceOwnerFromSetupWizard() throws Exception {
2265        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2266        setupDeviceOwner();
2267        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2268
2269        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
2270                DevicePolicyManager.STATE_USER_SETUP_COMPLETE,
2271                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2272    }
2273
2274    public void testSetUserProvisioningState_deviceOwnerFromSetupWizardAlternative()
2275            throws Exception {
2276        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2277        setupDeviceOwner();
2278        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2279
2280        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
2281                DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
2282                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2283    }
2284
2285    public void testSetUserProvisioningState_deviceOwnerWithoutSetupWizard() throws Exception {
2286        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2287        setupDeviceOwner();
2288        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2289
2290        exerciseUserProvisioningTransitions(UserHandle.USER_SYSTEM,
2291                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2292    }
2293
2294    public void testSetUserProvisioningState_managedProfileFromSetupWizard_primaryUser()
2295            throws Exception {
2296        setupProfileOwner();
2297        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2298
2299        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2300                DevicePolicyManager.STATE_USER_PROFILE_COMPLETE,
2301                DevicePolicyManager.STATE_USER_UNMANAGED);
2302    }
2303
2304    public void testSetUserProvisioningState_managedProfileFromSetupWizard_managedProfile()
2305            throws Exception {
2306        setupProfileOwner();
2307        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2308
2309        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2310                DevicePolicyManager.STATE_USER_SETUP_COMPLETE,
2311                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2312    }
2313
2314    public void testSetUserProvisioningState_managedProfileWithoutSetupWizard() throws Exception {
2315        setupProfileOwner();
2316        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2317
2318        exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2319                DevicePolicyManager.STATE_USER_SETUP_FINALIZED);
2320    }
2321
2322    public void testSetUserProvisioningState_illegalTransitionOutOfFinalized1() throws Exception {
2323        setupProfileOwner();
2324        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2325
2326        try {
2327            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2328                    DevicePolicyManager.STATE_USER_SETUP_FINALIZED,
2329                    DevicePolicyManager.STATE_USER_UNMANAGED);
2330            fail("Expected IllegalStateException");
2331        } catch (IllegalStateException e) {
2332            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
2333                    e.getMessage());
2334        }
2335    }
2336
2337    public void testSetUserProvisioningState_illegalTransitionToAnotherInProgressState()
2338            throws Exception {
2339        setupProfileOwner();
2340        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2341
2342        try {
2343            exerciseUserProvisioningTransitions(DpmMockContext.CALLER_USER_HANDLE,
2344                    DevicePolicyManager.STATE_USER_SETUP_INCOMPLETE,
2345                    DevicePolicyManager.STATE_USER_SETUP_COMPLETE);
2346            fail("Expected IllegalStateException");
2347        } catch (IllegalStateException e) {
2348            MoreAsserts.assertContainsRegex("Cannot move to user provisioning state",
2349                    e.getMessage());
2350        }
2351    }
2352
2353    private void exerciseUserProvisioningTransitions(int userId, int... states) {
2354        assertEquals(DevicePolicyManager.STATE_USER_UNMANAGED, dpm.getUserProvisioningState());
2355        for (int state : states) {
2356            dpm.setUserProvisioningState(state, userId);
2357            assertEquals(state, dpm.getUserProvisioningState());
2358        }
2359    }
2360
2361    private void setupProfileOwner() throws Exception {
2362        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
2363
2364        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_UID);
2365        dpm.setActiveAdmin(admin1, false);
2366        assertTrue(dpm.setProfileOwner(admin1, null, DpmMockContext.CALLER_USER_HANDLE));
2367
2368        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
2369    }
2370
2371    private void setupDeviceOwner() throws Exception {
2372        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
2373
2374        setUpPackageManagerForAdmin(admin1, DpmMockContext.CALLER_SYSTEM_USER_UID);
2375        dpm.setActiveAdmin(admin1, false);
2376        assertTrue(dpm.setDeviceOwner(admin1, null, UserHandle.USER_SYSTEM));
2377
2378        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
2379    }
2380
2381    public void testSetMaximumTimeToLock() {
2382        mContext.callerPermissions.add(android.Manifest.permission.MANAGE_DEVICE_ADMINS);
2383
2384        dpm.setActiveAdmin(admin1, /* replace =*/ false);
2385        dpm.setActiveAdmin(admin2, /* replace =*/ false);
2386
2387        reset(mMockContext.powerManagerInternal);
2388        reset(mMockContext.settings);
2389
2390        dpm.setMaximumTimeToLock(admin1, 0);
2391        verifyScreenTimeoutCall(null, false);
2392        reset(mMockContext.powerManagerInternal);
2393        reset(mMockContext.settings);
2394
2395        dpm.setMaximumTimeToLock(admin1, 1);
2396        verifyScreenTimeoutCall(1, true);
2397        reset(mMockContext.powerManagerInternal);
2398        reset(mMockContext.settings);
2399
2400        dpm.setMaximumTimeToLock(admin2, 10);
2401        verifyScreenTimeoutCall(null, false);
2402        reset(mMockContext.powerManagerInternal);
2403        reset(mMockContext.settings);
2404
2405        dpm.setMaximumTimeToLock(admin1, 5);
2406        verifyScreenTimeoutCall(5, true);
2407        reset(mMockContext.powerManagerInternal);
2408        reset(mMockContext.settings);
2409
2410        dpm.setMaximumTimeToLock(admin2, 4);
2411        verifyScreenTimeoutCall(4, true);
2412        reset(mMockContext.powerManagerInternal);
2413        reset(mMockContext.settings);
2414
2415        dpm.setMaximumTimeToLock(admin1, 0);
2416        reset(mMockContext.powerManagerInternal);
2417        reset(mMockContext.settings);
2418
2419        dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE);
2420        verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
2421        reset(mMockContext.powerManagerInternal);
2422        reset(mMockContext.settings);
2423
2424        dpm.setMaximumTimeToLock(admin2, Integer.MAX_VALUE + 1);
2425        verifyScreenTimeoutCall(Integer.MAX_VALUE, true);
2426        reset(mMockContext.powerManagerInternal);
2427        reset(mMockContext.settings);
2428
2429        dpm.setMaximumTimeToLock(admin2, 10);
2430        verifyScreenTimeoutCall(10, true);
2431        reset(mMockContext.powerManagerInternal);
2432        reset(mMockContext.settings);
2433
2434        // There's no restriction; shold be set to MAX.
2435        dpm.setMaximumTimeToLock(admin2, 0);
2436        verifyScreenTimeoutCall(Integer.MAX_VALUE, false);
2437    }
2438
2439    public void testSetRequiredStrongAuthTimeout_DeviceOwner() throws Exception {
2440        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2441        setupDeviceOwner();
2442        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2443
2444        final long MINIMUM_STRONG_AUTH_TIMEOUT_MS = TimeUnit.HOURS.toMillis(1);
2445        final long ONE_MINUTE = TimeUnit.MINUTES.toMillis(1);
2446        final long MIN_PLUS_ONE_MINUTE = MINIMUM_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE;
2447        final long MAX_MINUS_ONE_MINUTE = DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS
2448                - ONE_MINUTE;
2449
2450        // verify that the minimum timeout cannot be modified on user builds (system property is
2451        // not being read)
2452        mContext.buildMock.isDebuggable = false;
2453
2454        dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE);
2455        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE);
2456        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE);
2457
2458        verify(mContext.systemProperties, never()).getLong(anyString(), anyLong());
2459
2460        // restore to the debuggable build state
2461        mContext.buildMock.isDebuggable = true;
2462
2463        // Always return the default (second arg) when getting system property for long type
2464        when(mContext.systemProperties.getLong(anyString(), anyLong())).thenAnswer(
2465                new Answer<Long>() {
2466                    @Override
2467                    public Long answer(InvocationOnMock invocation) throws Throwable {
2468                        return (Long) invocation.getArguments()[1];
2469                    }
2470                }
2471        );
2472
2473        // reset to default (0 means the admin is not participating, so default should be returned)
2474        dpm.setRequiredStrongAuthTimeout(admin1, 0);
2475
2476        // aggregation should be the default if unset by any admin
2477        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
2478                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2479
2480        // admin not participating by default
2481        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0);
2482
2483        //clamping from the top
2484        dpm.setRequiredStrongAuthTimeout(admin1,
2485                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS + ONE_MINUTE);
2486        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1),
2487                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2488        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
2489                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2490
2491        // 0 means the admin is not participating, so default should be returned
2492        dpm.setRequiredStrongAuthTimeout(admin1, 0);
2493        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0);
2494        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
2495                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2496
2497        // clamping from the bottom
2498        dpm.setRequiredStrongAuthTimeout(admin1, MINIMUM_STRONG_AUTH_TIMEOUT_MS - ONE_MINUTE);
2499        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MINIMUM_STRONG_AUTH_TIMEOUT_MS);
2500        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MINIMUM_STRONG_AUTH_TIMEOUT_MS);
2501
2502        // values within range
2503        dpm.setRequiredStrongAuthTimeout(admin1, MIN_PLUS_ONE_MINUTE);
2504        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MIN_PLUS_ONE_MINUTE);
2505        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MIN_PLUS_ONE_MINUTE);
2506
2507        dpm.setRequiredStrongAuthTimeout(admin1, MAX_MINUS_ONE_MINUTE);
2508        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), MAX_MINUS_ONE_MINUTE);
2509        assertEquals(dpm.getRequiredStrongAuthTimeout(null), MAX_MINUS_ONE_MINUTE);
2510
2511        // reset to default
2512        dpm.setRequiredStrongAuthTimeout(admin1, 0);
2513        assertEquals(dpm.getRequiredStrongAuthTimeout(admin1), 0);
2514        assertEquals(dpm.getRequiredStrongAuthTimeout(null),
2515                DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS);
2516
2517        // negative value
2518        try {
2519            dpm.setRequiredStrongAuthTimeout(admin1, -ONE_MINUTE);
2520            fail("Didn't throw IllegalArgumentException");
2521        } catch (IllegalArgumentException iae) {
2522        }
2523    }
2524
2525    private void verifyScreenTimeoutCall(Integer expectedTimeout,
2526            boolean shouldStayOnWhilePluggedInBeCleared) {
2527        if (expectedTimeout == null) {
2528            verify(mMockContext.powerManagerInternal, times(0))
2529                    .setMaximumScreenOffTimeoutFromDeviceAdmin(anyInt());
2530        } else {
2531            verify(mMockContext.powerManagerInternal, times(1))
2532                    .setMaximumScreenOffTimeoutFromDeviceAdmin(eq(expectedTimeout));
2533        }
2534        // TODO Verify calls to settingsGlobalPutInt.  Tried but somehow mockito threw
2535        // UnfinishedVerificationException.
2536    }
2537
2538    private void setup_DeviceAdminFeatureOff() throws Exception {
2539        when(mContext.packageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
2540                .thenReturn(false);
2541        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2542                .thenReturn(false);
2543        initializeDpms();
2544        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
2545        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2546                .thenReturn(true);
2547        setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
2548
2549        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2550    }
2551
2552    public void testIsProvisioningAllowed_DeviceAdminFeatureOff() throws Exception {
2553        setup_DeviceAdminFeatureOff();
2554        mContext.packageName = admin1.getPackageName();
2555        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2556        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false);
2557        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
2558        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2559                false);
2560        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
2561    }
2562
2563    public void testCheckProvisioningPreCondition_DeviceAdminFeatureOff() throws Exception {
2564        setup_DeviceAdminFeatureOff();
2565        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2566        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2567                DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED);
2568        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2569                DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED);
2570        assertCheckProvisioningPreCondition(
2571                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2572                DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED);
2573        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2574                DevicePolicyManager.CODE_DEVICE_ADMIN_NOT_SUPPORTED);
2575    }
2576
2577    private void setup_ManagedProfileFeatureOff() throws Exception {
2578        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2579                .thenReturn(false);
2580        initializeDpms();
2581        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
2582        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2583                .thenReturn(true);
2584        setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
2585
2586        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2587    }
2588
2589    public void testIsProvisioningAllowed_ManagedProfileFeatureOff() throws Exception {
2590        setup_ManagedProfileFeatureOff();
2591        mContext.packageName = admin1.getPackageName();
2592        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2593        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2594        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
2595        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2596                false);
2597        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
2598
2599        // Test again when split user is on
2600        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2601        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2602        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
2603        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2604                true);
2605        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, false);
2606    }
2607
2608    public void testCheckProvisioningPreCondition_ManagedProfileFeatureOff() throws Exception {
2609        setup_ManagedProfileFeatureOff();
2610        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2611        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2612                DevicePolicyManager.CODE_OK);
2613        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2614                DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
2615        assertCheckProvisioningPreCondition(
2616                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2617                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2618        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2619                DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
2620
2621        // Test again when split user is on
2622        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2623        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2624                DevicePolicyManager.CODE_OK);
2625        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2626                DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
2627        assertCheckProvisioningPreCondition(
2628                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2629                DevicePolicyManager.CODE_OK);
2630        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2631                DevicePolicyManager.CODE_MANAGED_USERS_NOT_SUPPORTED);
2632    }
2633
2634    private void setup_nonSplitUser_firstBoot_primaryUser() throws Exception {
2635        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2636                .thenReturn(true);
2637        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
2638        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2639                .thenReturn(true);
2640        setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
2641
2642        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2643    }
2644
2645    public void testIsProvisioningAllowed_nonSplitUser_firstBoot_primaryUser() throws Exception {
2646        setup_nonSplitUser_firstBoot_primaryUser();
2647        mContext.packageName = admin1.getPackageName();
2648        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2649        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2650        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2651        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2652                false /* because of non-split user */);
2653        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2654                false /* because of non-split user */);
2655    }
2656
2657    public void testCheckProvisioningPreCondition_nonSplitUser_firstBoot_primaryUser()
2658            throws Exception {
2659        setup_nonSplitUser_firstBoot_primaryUser();
2660        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2661        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2662                DevicePolicyManager.CODE_OK);
2663        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2664                DevicePolicyManager.CODE_OK);
2665        assertCheckProvisioningPreCondition(
2666                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2667                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2668        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2669                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2670    }
2671
2672    private void setup_nonSplitUser_afterDeviceSetup_primaryUser() throws Exception {
2673        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2674                .thenReturn(true);
2675        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(false);
2676        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2677                .thenReturn(true);
2678        setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
2679
2680        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2681    }
2682
2683    private void setup_nonSplitUser_withDo_primaryUser() throws Exception {
2684        setDeviceOwner();
2685        setup_nonSplitUser_afterDeviceSetup_primaryUser();
2686        setUpPackageManagerForFakeAdmin(adminAnotherPackage, DpmMockContext.ANOTHER_UID, admin2);
2687    }
2688
2689    private void setup_nonSplitUser_withDo_primaryUser_ManagedProfile() throws Exception {
2690        setup_nonSplitUser_withDo_primaryUser();
2691        final int MANAGED_PROFILE_USER_ID = 18;
2692        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 1308);
2693        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
2694        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
2695                false /* we can't remove a managed profile */)).thenReturn(false);
2696        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM,
2697                true)).thenReturn(true);
2698    }
2699
2700    public void testIsProvisioningAllowed_nonSplitUser_afterDeviceSetup_primaryUser()
2701            throws Exception {
2702        setup_nonSplitUser_afterDeviceSetup_primaryUser();
2703        mContext.packageName = admin1.getPackageName();
2704        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2705        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2706                false/* because of completed device setup */);
2707        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2708        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2709                false/* because of non-split user */);
2710        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2711                false/* because of non-split user */);
2712    }
2713
2714    public void testCheckProvisioningPreCondition_nonSplitUser_afterDeviceSetup_primaryUser()
2715            throws Exception {
2716        setup_nonSplitUser_afterDeviceSetup_primaryUser();
2717        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2718        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2719                DevicePolicyManager.CODE_USER_SETUP_COMPLETED);
2720        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2721                DevicePolicyManager.CODE_OK);
2722        assertCheckProvisioningPreCondition(
2723                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2724                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2725        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2726                DevicePolicyManager.CODE_NOT_SYSTEM_USER_SPLIT);
2727    }
2728
2729    public void testProvisioning_nonSplitUser_withDo_primaryUser() throws Exception {
2730        setup_nonSplitUser_withDo_primaryUser();
2731        mContext.packageName = admin1.getPackageName();
2732        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2733
2734        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2735                DevicePolicyManager.CODE_HAS_DEVICE_OWNER);
2736        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, false);
2737
2738        // COMP mode is allowed.
2739        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2740                DevicePolicyManager.CODE_OK);
2741        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2742
2743        // And other DPCs can also provision a managed profile (DO + BYOD case).
2744        assertCheckProvisioningPreCondition(
2745                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2746                DpmMockContext.ANOTHER_PACKAGE_NAME,
2747                DevicePolicyManager.CODE_OK);
2748        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true,
2749                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2750    }
2751
2752    public void testProvisioning_nonSplitUser_withDo_primaryUser_restrictedByDo() throws Exception {
2753        setup_nonSplitUser_withDo_primaryUser();
2754        mContext.packageName = admin1.getPackageName();
2755        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2756        // The DO should be allowed to initiate provisioning if it set the restriction itself, but
2757        // other packages should be forbidden.
2758        when(mContext.userManager.hasUserRestriction(
2759                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
2760                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2761                .thenReturn(true);
2762        when(mContext.userManager.getUserRestrictionSource(
2763                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
2764                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2765                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
2766        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2767                DevicePolicyManager.CODE_OK);
2768        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2769        assertCheckProvisioningPreCondition(
2770                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2771                DpmMockContext.ANOTHER_PACKAGE_NAME,
2772                DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED);
2773        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false,
2774                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2775    }
2776
2777    public void testProvisioning_nonSplitUser_withDo_primaryUser_restrictedBySystem()
2778            throws Exception {
2779        setup_nonSplitUser_withDo_primaryUser();
2780        mContext.packageName = admin1.getPackageName();
2781        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2782        // The DO should not be allowed to initiate provisioning if the restriction is set by
2783        // another entity.
2784        when(mContext.userManager.hasUserRestriction(
2785                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
2786                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2787                .thenReturn(true);
2788        when(mContext.userManager.getUserRestrictionSource(
2789                eq(UserManager.DISALLOW_ADD_MANAGED_PROFILE),
2790                eq(UserHandle.getUserHandleForUid(mContext.binder.callingUid))))
2791                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
2792        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2793                DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED);
2794        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
2795
2796        assertCheckProvisioningPreCondition(
2797                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2798                DpmMockContext.ANOTHER_PACKAGE_NAME,
2799                DevicePolicyManager.CODE_ADD_MANAGED_PROFILE_DISALLOWED);
2800        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false,
2801                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2802    }
2803
2804    public void testCheckProvisioningPreCondition_nonSplitUser_comp() throws Exception {
2805        setup_nonSplitUser_withDo_primaryUser_ManagedProfile();
2806        mContext.packageName = admin1.getPackageName();
2807        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2808
2809        // We can delete the managed profile to create a new one, so provisioning is allowed.
2810        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2811                DevicePolicyManager.CODE_OK);
2812        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2813        assertCheckProvisioningPreCondition(
2814                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2815                DpmMockContext.ANOTHER_PACKAGE_NAME,
2816                DevicePolicyManager.CODE_OK);
2817        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true,
2818                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2819    }
2820
2821    public void testCheckProvisioningPreCondition_nonSplitUser_comp_cannot_remove_profile()
2822            throws Exception {
2823        setup_nonSplitUser_withDo_primaryUser_ManagedProfile();
2824        mContext.packageName = admin1.getPackageName();
2825        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2826        when(mContext.userManager.hasUserRestriction(
2827                eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
2828                eq(UserHandle.SYSTEM)))
2829                .thenReturn(true);
2830        when(mContext.userManager.getUserRestrictionSource(
2831                eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
2832                eq(UserHandle.SYSTEM)))
2833                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
2834
2835        // We can't remove the profile to create a new one.
2836        assertCheckProvisioningPreCondition(
2837                DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2838                DpmMockContext.ANOTHER_PACKAGE_NAME,
2839                DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE);
2840        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false,
2841                DpmMockContext.ANOTHER_PACKAGE_NAME, DpmMockContext.ANOTHER_UID);
2842
2843        // But the device owner can still do it because it has set the restriction itself.
2844        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2845                DevicePolicyManager.CODE_OK);
2846        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2847    }
2848
2849    private void setup_splitUser_firstBoot_systemUser() throws Exception {
2850        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2851                .thenReturn(true);
2852        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2853        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2854                .thenReturn(false);
2855        setUserSetupCompleteForUser(false, UserHandle.USER_SYSTEM);
2856
2857        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2858    }
2859
2860    public void testIsProvisioningAllowed_splitUser_firstBoot_systemUser() throws Exception {
2861        setup_splitUser_firstBoot_systemUser();
2862        mContext.packageName = admin1.getPackageName();
2863        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2864        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2865        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2866                false /* because canAddMoreManagedProfiles returns false */);
2867        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2868                true);
2869        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2870                false/* because calling uid is system user */);
2871    }
2872
2873    public void testCheckProvisioningPreCondition_splitUser_firstBoot_systemUser()
2874            throws Exception {
2875        setup_splitUser_firstBoot_systemUser();
2876        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2877        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2878                DevicePolicyManager.CODE_OK);
2879        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2880                DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER);
2881        assertCheckProvisioningPreCondition(
2882                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2883                DevicePolicyManager.CODE_OK);
2884        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2885                DevicePolicyManager.CODE_SYSTEM_USER);
2886    }
2887
2888    private void setup_splitUser_afterDeviceSetup_systemUser() throws Exception {
2889        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2890                .thenReturn(true);
2891        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2892        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
2893                .thenReturn(false);
2894        setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
2895
2896        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
2897    }
2898
2899    public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_systemUser() throws Exception {
2900        setup_splitUser_afterDeviceSetup_systemUser();
2901        mContext.packageName = admin1.getPackageName();
2902        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2903        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2904                true/* it's undefined behavior. Can be changed into false in the future */);
2905        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2906                false /* because canAddMoreManagedProfiles returns false */);
2907        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2908                true/* it's undefined behavior. Can be changed into false in the future */);
2909        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2910                false/* because calling uid is system user */);
2911    }
2912
2913    public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_systemUser()
2914            throws Exception {
2915        setup_splitUser_afterDeviceSetup_systemUser();
2916        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2917        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2918                DevicePolicyManager.CODE_OK);
2919        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2920                DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER);
2921        assertCheckProvisioningPreCondition(
2922                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2923                DevicePolicyManager.CODE_OK);
2924        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2925                DevicePolicyManager.CODE_SYSTEM_USER);
2926    }
2927
2928    private void setup_splitUser_firstBoot_primaryUser() throws Exception {
2929        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2930                .thenReturn(true);
2931        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2932        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
2933                true)).thenReturn(true);
2934        setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
2935
2936        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2937    }
2938
2939    public void testIsProvisioningAllowed_splitUser_firstBoot_primaryUser() throws Exception {
2940        setup_splitUser_firstBoot_primaryUser();
2941        mContext.packageName = admin1.getPackageName();
2942        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2943        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE, true);
2944        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2945        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2946                true);
2947        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER, true);
2948    }
2949
2950    public void testCheckProvisioningPreCondition_splitUser_firstBoot_primaryUser()
2951            throws Exception {
2952        setup_splitUser_firstBoot_primaryUser();
2953        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2954        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2955                DevicePolicyManager.CODE_OK);
2956        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2957                DevicePolicyManager.CODE_OK);
2958        assertCheckProvisioningPreCondition(
2959                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2960                DevicePolicyManager.CODE_OK);
2961        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2962                DevicePolicyManager.CODE_OK);
2963    }
2964
2965    private void setup_splitUser_afterDeviceSetup_primaryUser() throws Exception {
2966        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
2967                .thenReturn(true);
2968        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
2969        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
2970                true)).thenReturn(true);
2971        setUserSetupCompleteForUser(true, DpmMockContext.CALLER_USER_HANDLE);
2972
2973        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
2974    }
2975
2976    public void testIsProvisioningAllowed_splitUser_afterDeviceSetup_primaryUser()
2977            throws Exception {
2978        setup_splitUser_afterDeviceSetup_primaryUser();
2979        mContext.packageName = admin1.getPackageName();
2980        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
2981        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2982                true/* it's undefined behavior. Can be changed into false in the future */);
2983        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
2984        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
2985                true/* it's undefined behavior. Can be changed into false in the future */);
2986        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
2987                false/* because user setup completed */);
2988    }
2989
2990    public void testCheckProvisioningPreCondition_splitUser_afterDeviceSetup_primaryUser()
2991            throws Exception {
2992        setup_splitUser_afterDeviceSetup_primaryUser();
2993        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
2994        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE,
2995                DevicePolicyManager.CODE_OK);
2996        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
2997                DevicePolicyManager.CODE_OK);
2998        assertCheckProvisioningPreCondition(
2999                DevicePolicyManager.ACTION_PROVISION_MANAGED_SHAREABLE_DEVICE,
3000                DevicePolicyManager.CODE_OK);
3001        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_USER,
3002                DevicePolicyManager.CODE_USER_SETUP_COMPLETED);
3003    }
3004
3005    private void setup_provisionManagedProfileWithDeviceOwner_systemUser() throws Exception {
3006        setDeviceOwner();
3007
3008        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
3009                .thenReturn(true);
3010        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
3011        when(mContext.userManager.canAddMoreManagedProfiles(UserHandle.USER_SYSTEM, true))
3012                .thenReturn(false);
3013        setUserSetupCompleteForUser(true, UserHandle.USER_SYSTEM);
3014
3015        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3016    }
3017
3018    public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_systemUser()
3019            throws Exception {
3020        setup_provisionManagedProfileWithDeviceOwner_systemUser();
3021        mContext.packageName = admin1.getPackageName();
3022        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
3023        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
3024                false /* can't provision managed profile on system user */);
3025    }
3026
3027    public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_systemUser()
3028            throws Exception {
3029        setup_provisionManagedProfileWithDeviceOwner_systemUser();
3030        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3031        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
3032                DevicePolicyManager.CODE_SPLIT_SYSTEM_USER_DEVICE_SYSTEM_USER);
3033    }
3034
3035    private void setup_provisionManagedProfileWithDeviceOwner_primaryUser() throws Exception {
3036        setDeviceOwner();
3037
3038        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
3039                .thenReturn(true);
3040        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
3041        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
3042                true)).thenReturn(true);
3043        setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
3044
3045        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
3046    }
3047
3048    public void testIsProvisioningAllowed_provisionManagedProfileWithDeviceOwner_primaryUser()
3049            throws Exception {
3050        setup_provisionManagedProfileWithDeviceOwner_primaryUser();
3051        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
3052        mContext.packageName = admin1.getPackageName();
3053        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, true);
3054    }
3055
3056    public void testCheckProvisioningPreCondition_provisionManagedProfileWithDeviceOwner_primaryUser()
3057            throws Exception {
3058        setup_provisionManagedProfileWithDeviceOwner_primaryUser();
3059        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3060
3061        // COMP mode is allowed.
3062        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
3063                DevicePolicyManager.CODE_OK);
3064    }
3065
3066    private void setup_provisionManagedProfileCantRemoveUser_primaryUser() throws Exception {
3067        setDeviceOwner();
3068
3069        when(mContext.ipackageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS, 0))
3070                .thenReturn(true);
3071        when(mContext.userManagerForMock.isSplitSystemUser()).thenReturn(true);
3072        when(mContext.userManager.hasUserRestriction(
3073                eq(UserManager.DISALLOW_REMOVE_MANAGED_PROFILE),
3074                eq(UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))))
3075                .thenReturn(true);
3076        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
3077                false /* we can't remove a managed profile */)).thenReturn(false);
3078        when(mContext.userManager.canAddMoreManagedProfiles(DpmMockContext.CALLER_USER_HANDLE,
3079                true)).thenReturn(true);
3080        setUserSetupCompleteForUser(false, DpmMockContext.CALLER_USER_HANDLE);
3081
3082        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
3083    }
3084
3085    public void testIsProvisioningAllowed_provisionManagedProfileCantRemoveUser_primaryUser()
3086            throws Exception {
3087        setup_provisionManagedProfileCantRemoveUser_primaryUser();
3088        mContext.packageName = admin1.getPackageName();
3089        setUpPackageManagerForAdmin(admin1, mContext.binder.callingUid);
3090        assertProvisioningAllowed(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, false);
3091    }
3092
3093    public void testCheckProvisioningPreCondition_provisionManagedProfileCantRemoveUser_primaryUser()
3094            throws Exception {
3095        setup_provisionManagedProfileCantRemoveUser_primaryUser();
3096        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3097        assertCheckProvisioningPreCondition(DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE,
3098                DevicePolicyManager.CODE_CANNOT_ADD_MANAGED_PROFILE);
3099    }
3100
3101    public void testCheckProvisioningPreCondition_permission() {
3102        // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
3103        try {
3104            dpm.checkProvisioningPreCondition(
3105                    DevicePolicyManager.ACTION_PROVISION_MANAGED_PROFILE, "some.package");
3106            fail("Didn't throw SecurityException");
3107        } catch (SecurityException expected) {
3108        }
3109    }
3110
3111    public void testForceUpdateUserSetupComplete_permission() {
3112        // GIVEN the permission MANAGE_PROFILE_AND_DEVICE_OWNERS is not granted
3113        try {
3114            dpm.forceUpdateUserSetupComplete();
3115            fail("Didn't throw SecurityException");
3116        } catch (SecurityException expected) {
3117        }
3118    }
3119
3120    public void testForceUpdateUserSetupComplete_systemUser() {
3121        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3122        // GIVEN calling from user 20
3123        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
3124        try {
3125            dpm.forceUpdateUserSetupComplete();
3126            fail("Didn't throw SecurityException");
3127        } catch (SecurityException expected) {
3128        }
3129    }
3130
3131    public void testForceUpdateUserSetupComplete_userbuild() {
3132        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3133        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3134
3135        final int userId = UserHandle.USER_SYSTEM;
3136        // GIVEN userComplete is false in SettingsProvider
3137        setUserSetupCompleteForUser(false, userId);
3138
3139        // GIVEN userComplete is true in DPM
3140        DevicePolicyManagerService.DevicePolicyData userData =
3141                new DevicePolicyManagerService.DevicePolicyData(userId);
3142        userData.mUserSetupComplete = true;
3143        dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
3144
3145        // GIVEN it's user build
3146        mContext.buildMock.isDebuggable = false;
3147
3148        assertTrue(dpms.hasUserSetupCompleted());
3149
3150        dpm.forceUpdateUserSetupComplete();
3151
3152        // THEN the state in dpms is not changed
3153        assertTrue(dpms.hasUserSetupCompleted());
3154    }
3155
3156    public void testForceUpdateUserSetupComplete_userDebugbuild() {
3157        mContext.callerPermissions.add(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
3158        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3159
3160        final int userId = UserHandle.USER_SYSTEM;
3161        // GIVEN userComplete is false in SettingsProvider
3162        setUserSetupCompleteForUser(false, userId);
3163
3164        // GIVEN userComplete is true in DPM
3165        DevicePolicyManagerService.DevicePolicyData userData =
3166                new DevicePolicyManagerService.DevicePolicyData(userId);
3167        userData.mUserSetupComplete = true;
3168        dpms.mUserData.put(UserHandle.USER_SYSTEM, userData);
3169
3170        // GIVEN it's userdebug build
3171        mContext.buildMock.isDebuggable = true;
3172
3173        assertTrue(dpms.hasUserSetupCompleted());
3174
3175        dpm.forceUpdateUserSetupComplete();
3176
3177        // THEN the state in dpms is not changed
3178        assertFalse(dpms.hasUserSetupCompleted());
3179    }
3180
3181    private void clearDeviceOwner() throws Exception {
3182        final long ident = mContext.binder.clearCallingIdentity();
3183        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3184        doReturn(DpmMockContext.CALLER_SYSTEM_USER_UID).when(mContext.packageManager)
3185                .getPackageUidAsUser(eq(admin1.getPackageName()), anyInt());
3186        dpm.clearDeviceOwnerApp(admin1.getPackageName());
3187        mContext.binder.restoreCallingIdentity(ident);
3188    }
3189
3190    public void testGetLastSecurityLogRetrievalTime() throws Exception {
3191        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3192        setupDeviceOwner();
3193
3194        // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
3195        // feature is disabled because there are non-affiliated secondary users.
3196        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
3197        when(mContext.resources.getBoolean(R.bool.config_supportPreRebootSecurityLogs))
3198                .thenReturn(true);
3199
3200        // No logs were retrieved so far.
3201        assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
3202
3203        // Enabling logging should not change the timestamp.
3204        dpm.setSecurityLoggingEnabled(admin1, true);
3205        verify(mContext.settings)
3206                .securityLogSetLoggingEnabledProperty(true);
3207        when(mContext.settings.securityLogGetLoggingEnabledProperty())
3208                .thenReturn(true);
3209        assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
3210
3211        // Retrieving the logs should update the timestamp.
3212        final long beforeRetrieval = System.currentTimeMillis();
3213        dpm.retrieveSecurityLogs(admin1);
3214        final long firstSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
3215        final long afterRetrieval = System.currentTimeMillis();
3216        assertTrue(firstSecurityLogRetrievalTime >= beforeRetrieval);
3217        assertTrue(firstSecurityLogRetrievalTime <= afterRetrieval);
3218
3219        // Retrieving the pre-boot logs should update the timestamp.
3220        Thread.sleep(2);
3221        dpm.retrievePreRebootSecurityLogs(admin1);
3222        final long secondSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
3223        assertTrue(secondSecurityLogRetrievalTime > firstSecurityLogRetrievalTime);
3224
3225        // Checking the timestamp again should not change it.
3226        Thread.sleep(2);
3227        assertEquals(secondSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3228
3229        // Retrieving the logs again should update the timestamp.
3230        dpm.retrieveSecurityLogs(admin1);
3231        final long thirdSecurityLogRetrievalTime = dpm.getLastSecurityLogRetrievalTime();
3232        assertTrue(thirdSecurityLogRetrievalTime > secondSecurityLogRetrievalTime);
3233
3234        // Disabling logging should not change the timestamp.
3235        Thread.sleep(2);
3236        dpm.setSecurityLoggingEnabled(admin1, false);
3237        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3238
3239        // Restarting the DPMS should not lose the timestamp.
3240        initializeDpms();
3241        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3242
3243        // Any uid holding MANAGE_USERS permission can retrieve the timestamp.
3244        mContext.binder.callingUid = 1234567;
3245        mContext.callerPermissions.add(permission.MANAGE_USERS);
3246        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3247        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3248
3249        // System can retrieve the timestamp.
3250        mContext.binder.clearCallingIdentity();
3251        assertEquals(thirdSecurityLogRetrievalTime, dpm.getLastSecurityLogRetrievalTime());
3252
3253        // Removing the device owner should clear the timestamp.
3254        clearDeviceOwner();
3255        assertEquals(-1, dpm.getLastSecurityLogRetrievalTime());
3256    }
3257
3258    public void testGetLastBugReportRequestTime() throws Exception {
3259        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3260        setupDeviceOwner();
3261
3262        mContext.packageName = admin1.getPackageName();
3263        mContext.applicationInfo = new ApplicationInfo();
3264        when(mContext.resources.getColor(eq(R.color.notification_action_list), anyObject()))
3265                .thenReturn(Color.WHITE);
3266        when(mContext.resources.getColor(eq(R.color.notification_material_background_color),
3267                anyObject())).thenReturn(Color.WHITE);
3268
3269        // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
3270        // feature is disabled because there are non-affiliated secondary users.
3271        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
3272
3273        // No bug reports were requested so far.
3274        assertEquals(-1, dpm.getLastBugReportRequestTime());
3275
3276        // Requesting a bug report should update the timestamp.
3277        final long beforeRequest = System.currentTimeMillis();
3278        dpm.requestBugreport(admin1);
3279        final long bugReportRequestTime = dpm.getLastBugReportRequestTime();
3280        final long afterRequest = System.currentTimeMillis();
3281        assertTrue(bugReportRequestTime >= beforeRequest);
3282        assertTrue(bugReportRequestTime <= afterRequest);
3283
3284        // Checking the timestamp again should not change it.
3285        Thread.sleep(2);
3286        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
3287
3288        // Restarting the DPMS should not lose the timestamp.
3289        initializeDpms();
3290        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
3291
3292        // Any uid holding MANAGE_USERS permission can retrieve the timestamp.
3293        mContext.binder.callingUid = 1234567;
3294        mContext.callerPermissions.add(permission.MANAGE_USERS);
3295        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
3296        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3297
3298        // System can retrieve the timestamp.
3299        mContext.binder.clearCallingIdentity();
3300        assertEquals(bugReportRequestTime, dpm.getLastBugReportRequestTime());
3301
3302        // Removing the device owner should clear the timestamp.
3303        clearDeviceOwner();
3304        assertEquals(-1, dpm.getLastBugReportRequestTime());
3305    }
3306
3307    public void testGetLastNetworkLogRetrievalTime() throws Exception {
3308        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3309        setupDeviceOwner();
3310        mContext.packageName = admin1.getPackageName();
3311        mContext.applicationInfo = new ApplicationInfo();
3312        when(mContext.resources.getColor(eq(R.color.notification_action_list), anyObject()))
3313                .thenReturn(Color.WHITE);
3314        when(mContext.resources.getColor(eq(R.color.notification_material_background_color),
3315                anyObject())).thenReturn(Color.WHITE);
3316
3317        // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
3318        // feature is disabled because there are non-affiliated secondary users.
3319        mContext.removeUser(DpmMockContext.CALLER_USER_HANDLE);
3320        when(mContext.iipConnectivityMetrics.registerNetdEventCallback(anyObject()))
3321                .thenReturn(true);
3322
3323        // No logs were retrieved so far.
3324        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
3325
3326        // Attempting to retrieve logs without enabling logging should not change the timestamp.
3327        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
3328        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
3329
3330        // Enabling logging should not change the timestamp.
3331        dpm.setNetworkLoggingEnabled(admin1, true);
3332        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
3333
3334        // Retrieving the logs should update the timestamp.
3335        final long beforeRetrieval = System.currentTimeMillis();
3336        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
3337        final long firstNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime();
3338        final long afterRetrieval = System.currentTimeMillis();
3339        assertTrue(firstNetworkLogRetrievalTime >= beforeRetrieval);
3340        assertTrue(firstNetworkLogRetrievalTime <= afterRetrieval);
3341
3342        // Checking the timestamp again should not change it.
3343        Thread.sleep(2);
3344        assertEquals(firstNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3345
3346        // Retrieving the logs again should update the timestamp.
3347        dpm.retrieveNetworkLogs(admin1, 0 /* batchToken */);
3348        final long secondNetworkLogRetrievalTime = dpm.getLastNetworkLogRetrievalTime();
3349        assertTrue(secondNetworkLogRetrievalTime > firstNetworkLogRetrievalTime);
3350
3351        // Disabling logging should not change the timestamp.
3352        Thread.sleep(2);
3353        dpm.setNetworkLoggingEnabled(admin1, false);
3354        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3355
3356        // Restarting the DPMS should not lose the timestamp.
3357        initializeDpms();
3358        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3359
3360        // Any uid holding MANAGE_USERS permission can retrieve the timestamp.
3361        mContext.binder.callingUid = 1234567;
3362        mContext.callerPermissions.add(permission.MANAGE_USERS);
3363        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3364        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3365
3366        // System can retrieve the timestamp.
3367        mContext.binder.clearCallingIdentity();
3368        assertEquals(secondNetworkLogRetrievalTime, dpm.getLastNetworkLogRetrievalTime());
3369
3370        // Removing the device owner should clear the timestamp.
3371        clearDeviceOwner();
3372        assertEquals(-1, dpm.getLastNetworkLogRetrievalTime());
3373    }
3374
3375    public void testGetBindDeviceAdminTargetUsers() throws Exception {
3376        // Setup device owner.
3377        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3378        setupDeviceOwner();
3379
3380        // Only device owner is setup, the result list should be empty.
3381        List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3382        MoreAsserts.assertEmpty(targetUsers);
3383
3384        // Setup a managed profile managed by the same admin.
3385        final int MANAGED_PROFILE_USER_ID = 15;
3386        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456);
3387        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3388
3389        // Add a secondary user, it should never talk with.
3390        final int ANOTHER_USER_ID = 36;
3391        mContext.addUser(ANOTHER_USER_ID, 0);
3392
3393        // Since the managed profile is not affiliated, they should not be allowed to talk to each
3394        // other.
3395        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3396        MoreAsserts.assertEmpty(targetUsers);
3397
3398        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3399        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3400        MoreAsserts.assertEmpty(targetUsers);
3401
3402        // Setting affiliation ids
3403        final Set<String> userAffiliationIds = Collections.singleton("some.affiliation-id");
3404        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3405        dpm.setAffiliationIds(admin1, userAffiliationIds);
3406
3407        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3408        dpm.setAffiliationIds(admin1, userAffiliationIds);
3409
3410        // Calling from device owner admin, the result list should just contain the managed
3411        // profile user id.
3412        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3413        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3414        MoreAsserts.assertContentsInAnyOrder(targetUsers, UserHandle.of(MANAGED_PROFILE_USER_ID));
3415
3416        // Calling from managed profile admin, the result list should just contain the system
3417        // user id.
3418        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3419        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3420        MoreAsserts.assertContentsInAnyOrder(targetUsers, UserHandle.SYSTEM);
3421
3422        // Changing affiliation ids in one
3423        dpm.setAffiliationIds(admin1, Collections.singleton("some-different-affiliation-id"));
3424
3425        // Since the managed profile is not affiliated any more, they should not be allowed to talk
3426        // to each other.
3427        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3428        MoreAsserts.assertEmpty(targetUsers);
3429
3430        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3431        targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3432        MoreAsserts.assertEmpty(targetUsers);
3433    }
3434
3435    public void testGetBindDeviceAdminTargetUsers_differentPackage() throws Exception {
3436        // Setup a device owner.
3437        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3438        setupDeviceOwner();
3439
3440        // Set up a managed profile managed by different package.
3441        final int MANAGED_PROFILE_USER_ID = 15;
3442        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456);
3443        final ComponentName adminDifferentPackage =
3444                new ComponentName("another.package", "whatever.class");
3445        addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2);
3446
3447        // Setting affiliation ids
3448        final Set<String> userAffiliationIds = Collections.singleton("some-affiliation-id");
3449        dpm.setAffiliationIds(admin1, userAffiliationIds);
3450
3451        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3452        dpm.setAffiliationIds(adminDifferentPackage, userAffiliationIds);
3453
3454        // Calling from device owner admin, we should get zero bind device admin target users as
3455        // their packages are different.
3456        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3457        List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(admin1);
3458        MoreAsserts.assertEmpty(targetUsers);
3459
3460        // Calling from managed profile admin, we should still get zero target users for the same
3461        // reason.
3462        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3463        targetUsers = dpm.getBindDeviceAdminTargetUsers(adminDifferentPackage);
3464        MoreAsserts.assertEmpty(targetUsers);
3465    }
3466
3467    public void testLockTaskPackagesAllowedForAffiliatedUsers() throws Exception {
3468        // Setup a device owner.
3469        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3470        setupDeviceOwner();
3471        // Lock task packages are updated when loading user data.
3472        verify(mContext.iactivityManager)
3473                .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(new String[0]));
3474
3475        // Set up a managed profile managed by different package (package name shouldn't matter)
3476        final int MANAGED_PROFILE_USER_ID = 15;
3477        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 20456);
3478        final ComponentName adminDifferentPackage =
3479                new ComponentName("another.package", "whatever.class");
3480        addManagedProfile(adminDifferentPackage, MANAGED_PROFILE_ADMIN_UID, admin2);
3481        verify(mContext.iactivityManager)
3482                .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
3483
3484        // The DO can still set lock task packages
3485        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3486        final String[] doPackages = {"doPackage1", "doPackage2"};
3487        dpm.setLockTaskPackages(admin1, doPackages);
3488        MoreAsserts.assertEquals(doPackages, dpm.getLockTaskPackages(admin1));
3489        assertTrue(dpm.isLockTaskPermitted("doPackage1"));
3490        assertFalse(dpm.isLockTaskPermitted("anotherPackage"));
3491        verify(mContext.iactivityManager)
3492                .updateLockTaskPackages(eq(UserHandle.USER_SYSTEM), eq(doPackages));
3493
3494        // Managed profile is unaffiliated - shouldn't be able to setLockTaskPackages.
3495        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3496        final String[] poPackages = {"poPackage1", "poPackage2"};
3497        try {
3498            dpm.setLockTaskPackages(adminDifferentPackage, poPackages);
3499            fail("Didn't throw expected security exception.");
3500        } catch (SecurityException expected) {
3501        }
3502        try {
3503            dpm.getLockTaskPackages(adminDifferentPackage);
3504            fail("Didn't throw expected security exception.");
3505        } catch (SecurityException expected) {
3506        }
3507        assertFalse(dpm.isLockTaskPermitted("doPackage1"));
3508
3509        // Setting same affiliation ids
3510        final Set<String> userAffiliationIds = Collections.singleton("some-affiliation-id");
3511        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3512        dpm.setAffiliationIds(admin1, userAffiliationIds);
3513
3514        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3515        dpm.setAffiliationIds(adminDifferentPackage, userAffiliationIds);
3516
3517        // Now the managed profile can set lock task packages.
3518        dpm.setLockTaskPackages(adminDifferentPackage, poPackages);
3519        MoreAsserts.assertEquals(poPackages, dpm.getLockTaskPackages(adminDifferentPackage));
3520        assertTrue(dpm.isLockTaskPermitted("poPackage1"));
3521        assertFalse(dpm.isLockTaskPermitted("doPackage2"));
3522        verify(mContext.iactivityManager)
3523                .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(poPackages));
3524
3525        // Unaffiliate the profile, lock task mode no longer available on the profile.
3526        dpm.setAffiliationIds(adminDifferentPackage, Collections.emptySet());
3527        assertFalse(dpm.isLockTaskPermitted("poPackage1"));
3528        // Lock task packages cleared when loading user data and when the user becomes unaffiliated.
3529        verify(mContext.iactivityManager, times(2))
3530                .updateLockTaskPackages(eq(MANAGED_PROFILE_USER_ID), eq(new String[0]));
3531
3532        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3533        assertTrue(dpm.isLockTaskPermitted("doPackage1"));
3534    }
3535
3536    public void testIsDeviceManaged() throws Exception {
3537        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3538        setupDeviceOwner();
3539
3540        // The device owner itself, any uid holding MANAGE_USERS permission and the system can
3541        // find out that the device has a device owner.
3542        assertTrue(dpm.isDeviceManaged());
3543        mContext.binder.callingUid = 1234567;
3544        mContext.callerPermissions.add(permission.MANAGE_USERS);
3545        assertTrue(dpm.isDeviceManaged());
3546        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3547        mContext.binder.clearCallingIdentity();
3548        assertTrue(dpm.isDeviceManaged());
3549
3550        clearDeviceOwner();
3551
3552        // Any uid holding MANAGE_USERS permission and the system can find out that the device does
3553        // not have a device owner.
3554        mContext.binder.callingUid = 1234567;
3555        mContext.callerPermissions.add(permission.MANAGE_USERS);
3556        assertFalse(dpm.isDeviceManaged());
3557        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3558        mContext.binder.clearCallingIdentity();
3559        assertFalse(dpm.isDeviceManaged());
3560    }
3561
3562    public void testDeviceOwnerOrganizationName() throws Exception {
3563        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3564        setupDeviceOwner();
3565
3566        dpm.setOrganizationName(admin1, "organization");
3567
3568        // Device owner can retrieve organization managing the device.
3569        assertEquals("organization", dpm.getDeviceOwnerOrganizationName());
3570
3571        // Any uid holding MANAGE_USERS permission can retrieve organization managing the device.
3572        mContext.binder.callingUid = 1234567;
3573        mContext.callerPermissions.add(permission.MANAGE_USERS);
3574        assertEquals("organization", dpm.getDeviceOwnerOrganizationName());
3575        mContext.callerPermissions.remove(permission.MANAGE_USERS);
3576
3577        // System can retrieve organization managing the device.
3578        mContext.binder.clearCallingIdentity();
3579        assertEquals("organization", dpm.getDeviceOwnerOrganizationName());
3580
3581        // Removing the device owner clears the organization managing the device.
3582        clearDeviceOwner();
3583        assertNull(dpm.getDeviceOwnerOrganizationName());
3584    }
3585
3586    public void testWipeDataManagedProfile() throws Exception {
3587        final int MANAGED_PROFILE_USER_ID = 15;
3588        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
3589        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3590        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3591
3592        // Even if the caller is the managed profile, the current user is the user 0
3593        when(mContext.iactivityManager.getCurrentUser())
3594                .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
3595
3596        dpm.wipeData(0);
3597        verify(mContext.userManagerInternal).removeUserEvenWhenDisallowed(
3598                MANAGED_PROFILE_USER_ID);
3599    }
3600
3601    public void testWipeDataManagedProfileDisallowed() throws Exception {
3602        final int MANAGED_PROFILE_USER_ID = 15;
3603        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
3604        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3605
3606        // Even if the caller is the managed profile, the current user is the user 0
3607        when(mContext.iactivityManager.getCurrentUser())
3608                .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
3609
3610        when(mContext.userManager.getUserRestrictionSource(
3611                UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
3612                UserHandle.of(MANAGED_PROFILE_USER_ID)))
3613                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
3614        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3615        try {
3616            // The PO is not allowed to remove the profile if the user restriction was set on the
3617            // profile by the system
3618            dpm.wipeData(0);
3619            fail("SecurityException not thrown");
3620        } catch (SecurityException expected) {
3621        }
3622    }
3623
3624    public void testWipeDataDeviceOwner() throws Exception {
3625        setDeviceOwner();
3626        when(mContext.userManager.getUserRestrictionSource(
3627                UserManager.DISALLOW_FACTORY_RESET,
3628                UserHandle.SYSTEM))
3629                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
3630
3631        dpm.wipeData(0);
3632        verify(mContext.recoverySystem).rebootWipeUserData(
3633                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
3634    }
3635
3636    public void testWipeDataDeviceOwnerDisallowed() throws Exception {
3637        setDeviceOwner();
3638        when(mContext.userManager.getUserRestrictionSource(
3639                UserManager.DISALLOW_FACTORY_RESET,
3640                UserHandle.SYSTEM))
3641                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
3642        try {
3643            // The DO is not allowed to wipe the device if the user restriction was set
3644            // by the system
3645            dpm.wipeData(0);
3646            fail("SecurityException not thrown");
3647        } catch (SecurityException expected) {
3648        }
3649    }
3650
3651    public void testMaximumFailedPasswordAttemptsReachedManagedProfile() throws Exception {
3652        final int MANAGED_PROFILE_USER_ID = 15;
3653        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
3654        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3655
3656        // Even if the caller is the managed profile, the current user is the user 0
3657        when(mContext.iactivityManager.getCurrentUser())
3658                .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
3659
3660        when(mContext.userManager.getUserRestrictionSource(
3661                UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
3662                UserHandle.of(MANAGED_PROFILE_USER_ID)))
3663                .thenReturn(UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
3664
3665        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3666        dpm.setMaximumFailedPasswordsForWipe(admin1, 3);
3667
3668        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3669        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
3670        // Failed password attempts on the parent user are taken into account, as there isn't a
3671        // separate work challenge.
3672        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3673        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3674        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3675
3676        // The profile should be wiped even if DISALLOW_REMOVE_MANAGED_PROFILE is enabled, because
3677        // both the user restriction and the policy were set by the PO.
3678        verify(mContext.userManagerInternal).removeUserEvenWhenDisallowed(
3679                MANAGED_PROFILE_USER_ID);
3680        verifyZeroInteractions(mContext.recoverySystem);
3681    }
3682
3683    public void testMaximumFailedPasswordAttemptsReachedManagedProfileDisallowed()
3684            throws Exception {
3685        final int MANAGED_PROFILE_USER_ID = 15;
3686        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
3687        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
3688
3689        // Even if the caller is the managed profile, the current user is the user 0
3690        when(mContext.iactivityManager.getCurrentUser())
3691                .thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
3692
3693        when(mContext.userManager.getUserRestrictionSource(
3694                UserManager.DISALLOW_REMOVE_MANAGED_PROFILE,
3695                UserHandle.of(MANAGED_PROFILE_USER_ID)))
3696                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
3697
3698        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
3699        dpm.setMaximumFailedPasswordsForWipe(admin1, 3);
3700
3701        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3702        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
3703        // Failed password attempts on the parent user are taken into account, as there isn't a
3704        // separate work challenge.
3705        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3706        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3707        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3708
3709        // DISALLOW_REMOVE_MANAGED_PROFILE was set by the system, not the PO, so the profile is
3710        // not wiped.
3711        verify(mContext.userManagerInternal, never())
3712                .removeUserEvenWhenDisallowed(anyInt());
3713        verifyZeroInteractions(mContext.recoverySystem);
3714    }
3715
3716    public void testMaximumFailedPasswordAttemptsReachedDeviceOwner() throws Exception {
3717        setDeviceOwner();
3718        when(mContext.userManager.getUserRestrictionSource(
3719                UserManager.DISALLOW_FACTORY_RESET,
3720                UserHandle.SYSTEM))
3721                .thenReturn(UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
3722
3723        dpm.setMaximumFailedPasswordsForWipe(admin1, 3);
3724
3725        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3726        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
3727        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3728        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3729        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3730
3731        // The device should be wiped even if DISALLOW_FACTORY_RESET is enabled, because both the
3732        // user restriction and the policy were set by the DO.
3733        verify(mContext.recoverySystem).rebootWipeUserData(
3734                /*shutdown=*/ eq(false), anyString(), /*force=*/ eq(true));
3735    }
3736
3737    public void testMaximumFailedPasswordAttemptsReachedDeviceOwnerDisallowed() throws Exception {
3738        setDeviceOwner();
3739        when(mContext.userManager.getUserRestrictionSource(
3740                UserManager.DISALLOW_FACTORY_RESET,
3741                UserHandle.SYSTEM))
3742                .thenReturn(UserManager.RESTRICTION_SOURCE_SYSTEM);
3743
3744        dpm.setMaximumFailedPasswordsForWipe(admin1, 3);
3745
3746        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3747        mContext.callerPermissions.add(permission.BIND_DEVICE_ADMIN);
3748        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3749        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3750        dpm.reportFailedPasswordAttempt(UserHandle.USER_SYSTEM);
3751
3752        // DISALLOW_FACTORY_RESET was set by the system, not the DO, so the device is not wiped.
3753        verifyZeroInteractions(mContext.recoverySystem);
3754        verify(mContext.userManagerInternal, never())
3755                .removeUserEvenWhenDisallowed(anyInt());
3756    }
3757
3758    public void testGetPermissionGrantState() throws Exception {
3759        final String permission = "some.permission";
3760        final String app1 = "com.example.app1";
3761        final String app2 = "com.example.app2";
3762
3763        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app1), anyInt()))
3764                .thenReturn(PackageManager.PERMISSION_GRANTED);
3765        doReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED).when(mContext.packageManager)
3766                .getPermissionFlags(permission, app1, UserHandle.SYSTEM);
3767        when(mContext.packageManager.getPermissionFlags(permission, app1,
3768                UserHandle.of(DpmMockContext.CALLER_USER_HANDLE)))
3769                .thenReturn(PackageManager.FLAG_PERMISSION_POLICY_FIXED);
3770        when(mContext.ipackageManager.checkPermission(eq(permission), eq(app2), anyInt()))
3771                .thenReturn(PackageManager.PERMISSION_DENIED);
3772        doReturn(0).when(mContext.packageManager).getPermissionFlags(permission, app2,
3773                UserHandle.SYSTEM);
3774        when(mContext.packageManager.getPermissionFlags(permission, app2,
3775                UserHandle.of(DpmMockContext.CALLER_USER_HANDLE))).thenReturn(0);
3776
3777        // System can retrieve permission grant state.
3778        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
3779        mContext.packageName = "com.example.system";
3780        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
3781                dpm.getPermissionGrantState(null, app1, permission));
3782        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT,
3783                dpm.getPermissionGrantState(null, app2, permission));
3784
3785        // A regular app cannot retrieve permission grant state.
3786        mContext.binder.callingUid = setupPackageInPackageManager(app1, 1);
3787        mContext.packageName = app1;
3788        try {
3789            dpm.getPermissionGrantState(null, app1, permission);
3790            fail("Didn't throw SecurityException");
3791        } catch (SecurityException expected) {
3792        }
3793
3794        // Profile owner can retrieve permission grant state.
3795        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
3796        mContext.packageName = admin1.getPackageName();
3797        setAsProfileOwner(admin1);
3798        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_GRANTED,
3799                dpm.getPermissionGrantState(admin1, app1, permission));
3800        assertEquals(DevicePolicyManager.PERMISSION_GRANT_STATE_DEFAULT,
3801                dpm.getPermissionGrantState(admin1, app2, permission));
3802    }
3803
3804    public void testResetPasswordWithToken() throws Exception {
3805        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3806        setupDeviceOwner();
3807        // test token validation
3808        try {
3809            dpm.setResetPasswordToken(admin1, new byte[31]);
3810            fail("should not have accepted tokens too short");
3811        } catch (IllegalArgumentException expected) {
3812        }
3813        // test adding a token
3814        final byte[] token = new byte[32];
3815        final long handle = 123456;
3816        final String password = "password";
3817        when(mContext.lockPatternUtils.addEscrowToken(eq(token), eq(UserHandle.USER_SYSTEM)))
3818            .thenReturn(handle);
3819        assertTrue(dpm.setResetPasswordToken(admin1, token));
3820
3821        // test password activation
3822        when(mContext.lockPatternUtils.isEscrowTokenActive(eq(handle), eq(UserHandle.USER_SYSTEM)))
3823            .thenReturn(true);
3824        assertTrue(dpm.isResetPasswordTokenActive(admin1));
3825
3826        // test reset password with token
3827        when(mContext.lockPatternUtils.setLockCredentialWithToken(eq(password),
3828                eq(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), eq(handle), eq(token),
3829                eq(UserHandle.USER_SYSTEM)))
3830                .thenReturn(true);
3831        assertTrue(dpm.resetPasswordWithToken(admin1, password, token, 0));
3832
3833        // test removing a token
3834        when(mContext.lockPatternUtils.removeEscrowToken(eq(handle), eq(UserHandle.USER_SYSTEM)))
3835                .thenReturn(true);
3836        assertTrue(dpm.clearResetPasswordToken(admin1));
3837    }
3838
3839    public void testIsCurrentInputMethodSetByOwnerForDeviceOwner() throws Exception {
3840        final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD;
3841        final Uri currentImeUri = Settings.Secure.getUriFor(currentIme);
3842        final int deviceOwnerUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
3843        final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM,
3844                DpmMockContext.SYSTEM_UID);
3845        final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
3846                DpmMockContext.SYSTEM_UID);
3847
3848        // Set up a device owner.
3849        mContext.binder.callingUid = deviceOwnerUid;
3850        setupDeviceOwner();
3851
3852        // First and second user set IMEs manually.
3853        mContext.binder.callingUid = firstUserSystemUid;
3854        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3855        mContext.binder.callingUid = secondUserSystemUid;
3856        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3857
3858        // Device owner changes IME for first user.
3859        mContext.binder.callingUid = deviceOwnerUid;
3860        when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
3861                .thenReturn("ime1");
3862        dpm.setSecureSetting(admin1, currentIme, "ime2");
3863        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2",
3864                UserHandle.USER_SYSTEM);
3865        reset(mContext.settings);
3866        dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
3867        mContext.binder.callingUid = firstUserSystemUid;
3868        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3869        mContext.binder.callingUid = secondUserSystemUid;
3870        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3871
3872        // Second user changes IME manually.
3873        dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
3874        mContext.binder.callingUid = firstUserSystemUid;
3875        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3876        mContext.binder.callingUid = secondUserSystemUid;
3877        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3878
3879        // First user changes IME manually.
3880        dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
3881        mContext.binder.callingUid = firstUserSystemUid;
3882        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3883        mContext.binder.callingUid = secondUserSystemUid;
3884        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3885
3886        // Device owner changes IME for first user again.
3887        mContext.binder.callingUid = deviceOwnerUid;
3888        when(mContext.settings.settingsSecureGetStringForUser(currentIme, UserHandle.USER_SYSTEM))
3889                .thenReturn("ime2");
3890        dpm.setSecureSetting(admin1, currentIme, "ime3");
3891        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3",
3892                UserHandle.USER_SYSTEM);
3893        dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
3894        mContext.binder.callingUid = firstUserSystemUid;
3895        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3896        mContext.binder.callingUid = secondUserSystemUid;
3897        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3898
3899        // Restarting the DPMS should not lose information.
3900        initializeDpms();
3901        mContext.binder.callingUid = firstUserSystemUid;
3902        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3903        mContext.binder.callingUid = secondUserSystemUid;
3904        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3905
3906        // Device owner can find out whether it set the current IME itself.
3907        mContext.binder.callingUid = deviceOwnerUid;
3908        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3909
3910        // Removing the device owner should clear the information that it set the current IME.
3911        clearDeviceOwner();
3912        mContext.binder.callingUid = firstUserSystemUid;
3913        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3914        mContext.binder.callingUid = secondUserSystemUid;
3915        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3916    }
3917
3918    public void testIsCurrentInputMethodSetByOwnerForProfileOwner() throws Exception {
3919        final String currentIme = Settings.Secure.DEFAULT_INPUT_METHOD;
3920        final Uri currentImeUri = Settings.Secure.getUriFor(currentIme);
3921        final int profileOwnerUid = DpmMockContext.CALLER_UID;
3922        final int firstUserSystemUid = UserHandle.getUid(UserHandle.USER_SYSTEM,
3923                DpmMockContext.SYSTEM_UID);
3924        final int secondUserSystemUid = UserHandle.getUid(DpmMockContext.CALLER_USER_HANDLE,
3925                DpmMockContext.SYSTEM_UID);
3926
3927        // Set up a profile owner.
3928        mContext.binder.callingUid = profileOwnerUid;
3929        setupProfileOwner();
3930
3931        // First and second user set IMEs manually.
3932        mContext.binder.callingUid = firstUserSystemUid;
3933        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3934        mContext.binder.callingUid = secondUserSystemUid;
3935        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3936
3937        // Profile owner changes IME for second user.
3938        mContext.binder.callingUid = profileOwnerUid;
3939        when(mContext.settings.settingsSecureGetStringForUser(currentIme,
3940                DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime1");
3941        dpm.setSecureSetting(admin1, currentIme, "ime2");
3942        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime2",
3943                DpmMockContext.CALLER_USER_HANDLE);
3944        reset(mContext.settings);
3945        dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
3946        mContext.binder.callingUid = firstUserSystemUid;
3947        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3948        mContext.binder.callingUid = secondUserSystemUid;
3949        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3950
3951        // First user changes IME manually.
3952        dpms.notifyChangeToContentObserver(currentImeUri, UserHandle.USER_SYSTEM);
3953        mContext.binder.callingUid = firstUserSystemUid;
3954        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3955        mContext.binder.callingUid = secondUserSystemUid;
3956        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3957
3958        // Second user changes IME manually.
3959        dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
3960        mContext.binder.callingUid = firstUserSystemUid;
3961        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3962        mContext.binder.callingUid = secondUserSystemUid;
3963        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3964
3965        // Profile owner changes IME for second user again.
3966        mContext.binder.callingUid = profileOwnerUid;
3967        when(mContext.settings.settingsSecureGetStringForUser(currentIme,
3968                DpmMockContext.CALLER_USER_HANDLE)).thenReturn("ime2");
3969        dpm.setSecureSetting(admin1, currentIme, "ime3");
3970        verify(mContext.settings).settingsSecurePutStringForUser(currentIme, "ime3",
3971                DpmMockContext.CALLER_USER_HANDLE);
3972        dpms.notifyChangeToContentObserver(currentImeUri, DpmMockContext.CALLER_USER_HANDLE);
3973        mContext.binder.callingUid = firstUserSystemUid;
3974        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3975        mContext.binder.callingUid = secondUserSystemUid;
3976        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3977
3978        // Restarting the DPMS should not lose information.
3979        initializeDpms();
3980        mContext.binder.callingUid = firstUserSystemUid;
3981        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3982        mContext.binder.callingUid = secondUserSystemUid;
3983        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3984
3985        // Profile owner can find out whether it set the current IME itself.
3986        mContext.binder.callingUid = profileOwnerUid;
3987        assertTrue(dpm.isCurrentInputMethodSetByOwner());
3988
3989        // Removing the profile owner should clear the information that it set the current IME.
3990        dpm.clearProfileOwner(admin1);
3991        mContext.binder.callingUid = firstUserSystemUid;
3992        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3993        mContext.binder.callingUid = secondUserSystemUid;
3994        assertFalse(dpm.isCurrentInputMethodSetByOwner());
3995    }
3996
3997    public void testSetPermittedCrossProfileNotificationListeners_unavailableForDo()
3998            throws Exception {
3999        // Set up a device owner.
4000        mContext.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
4001        setupDeviceOwner();
4002        assertSetPermittedCrossProfileNotificationListenersUnavailable(mContext.binder.callingUid);
4003    }
4004
4005    public void testSetPermittedCrossProfileNotificationListeners_unavailableForPoOnUser()
4006            throws Exception {
4007        // Set up a profile owner.
4008        mContext.binder.callingUid = DpmMockContext.CALLER_UID;
4009        setupProfileOwner();
4010        assertSetPermittedCrossProfileNotificationListenersUnavailable(mContext.binder.callingUid);
4011    }
4012
4013    private void assertSetPermittedCrossProfileNotificationListenersUnavailable(
4014            int adminUid) throws Exception {
4015        mContext.binder.callingUid = adminUid;
4016        final int userId = UserHandle.getUserId(adminUid);
4017
4018        final String packageName = "some.package";
4019        assertFalse(dpms.setPermittedCrossProfileNotificationListeners(
4020                admin1, Collections.singletonList(packageName)));
4021        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
4022
4023        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4024        assertTrue(dpms.isNotificationListenerServicePermitted(packageName, userId));
4025
4026        // Attempt to set to empty list (which means no listener is whitelisted)
4027        mContext.binder.callingUid = adminUid;
4028        assertFalse(dpms.setPermittedCrossProfileNotificationListeners(
4029                admin1, Collections.<String>emptyList()));
4030        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
4031
4032        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4033        assertTrue(dpms.isNotificationListenerServicePermitted(packageName, userId));
4034    }
4035
4036    public void testIsNotificationListenerServicePermitted_onlySystemCanCall() throws Exception {
4037        // Set up a managed profile
4038        final int MANAGED_PROFILE_USER_ID = 15;
4039        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
4040        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
4041        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
4042
4043        final String permittedListener = "some.package";
4044        setupPackageInPackageManager(
4045                permittedListener,
4046                UserHandle.USER_SYSTEM, // We check the packageInfo from the primary user.
4047                /*appId=*/ 12345, /*flags=*/ 0);
4048
4049        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
4050                admin1, Collections.singletonList(permittedListener)));
4051
4052        try {
4053            dpms.isNotificationListenerServicePermitted(
4054                permittedListener, MANAGED_PROFILE_USER_ID);
4055            fail("isNotificationListenerServicePermitted should throw if not called from System");
4056        } catch (SecurityException expected) {
4057        }
4058
4059        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4060        assertTrue(dpms.isNotificationListenerServicePermitted(
4061                permittedListener, MANAGED_PROFILE_USER_ID));
4062    }
4063
4064    public void testSetPermittedCrossProfileNotificationListeners_managedProfile()
4065            throws Exception {
4066        // Set up a managed profile
4067        final int MANAGED_PROFILE_USER_ID = 15;
4068        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
4069        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
4070        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
4071
4072        final String permittedListener = "permitted.package";
4073        int appId = 12345;
4074        setupPackageInPackageManager(
4075                permittedListener,
4076                UserHandle.USER_SYSTEM,  // We check the packageInfo from the primary user.
4077                appId, /*flags=*/ 0);
4078
4079        final String notPermittedListener = "not.permitted.package";
4080        setupPackageInPackageManager(
4081                notPermittedListener,
4082                UserHandle.USER_SYSTEM,  // We check the packageInfo from the primary user.
4083                ++appId, /*flags=*/ 0);
4084
4085        final String systemListener = "system.package";
4086        setupPackageInPackageManager(
4087                systemListener,
4088                UserHandle.USER_SYSTEM,  // We check the packageInfo from the primary user.
4089                ++appId, ApplicationInfo.FLAG_SYSTEM);
4090
4091        // By default all packages are allowed
4092        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
4093
4094        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4095        assertTrue(dpms.isNotificationListenerServicePermitted(
4096                permittedListener, MANAGED_PROFILE_USER_ID));
4097        assertTrue(dpms.isNotificationListenerServicePermitted(
4098                notPermittedListener, MANAGED_PROFILE_USER_ID));
4099        assertTrue(dpms.isNotificationListenerServicePermitted(
4100                systemListener, MANAGED_PROFILE_USER_ID));
4101
4102        // Setting only one package in the whitelist
4103        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
4104        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
4105                admin1, Collections.singletonList(permittedListener)));
4106        List<String> permittedListeners =
4107                dpms.getPermittedCrossProfileNotificationListeners(admin1);
4108        assertEquals(1, permittedListeners.size());
4109        assertEquals(permittedListener, permittedListeners.get(0));
4110
4111        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4112        assertTrue(dpms.isNotificationListenerServicePermitted(
4113                permittedListener, MANAGED_PROFILE_USER_ID));
4114        assertFalse(dpms.isNotificationListenerServicePermitted(
4115                notPermittedListener, MANAGED_PROFILE_USER_ID));
4116        // System packages are always allowed (even if not in the whitelist)
4117        assertTrue(dpms.isNotificationListenerServicePermitted(
4118                systemListener, MANAGED_PROFILE_USER_ID));
4119
4120        // Setting an empty whitelist - only system listeners allowed
4121        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
4122        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
4123                admin1, Collections.<String>emptyList()));
4124        assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size());
4125
4126        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4127        assertFalse(dpms.isNotificationListenerServicePermitted(
4128                permittedListener, MANAGED_PROFILE_USER_ID));
4129        assertFalse(dpms.isNotificationListenerServicePermitted(
4130                notPermittedListener, MANAGED_PROFILE_USER_ID));
4131        // System packages are always allowed (even if not in the whitelist)
4132        assertTrue(dpms.isNotificationListenerServicePermitted(
4133                systemListener, MANAGED_PROFILE_USER_ID));
4134
4135        // Setting a null whitelist - all listeners allowed
4136        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
4137        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(admin1, null));
4138        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
4139
4140        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4141        assertTrue(dpms.isNotificationListenerServicePermitted(
4142                permittedListener, MANAGED_PROFILE_USER_ID));
4143        assertTrue(dpms.isNotificationListenerServicePermitted(
4144                notPermittedListener, MANAGED_PROFILE_USER_ID));
4145        assertTrue(dpms.isNotificationListenerServicePermitted(
4146                systemListener, MANAGED_PROFILE_USER_ID));
4147    }
4148
4149    public void testSetPermittedCrossProfileNotificationListeners_doesNotAffectPrimaryProfile()
4150            throws Exception {
4151        // Set up a managed profile
4152        final int MANAGED_PROFILE_USER_ID = 15;
4153        final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436);
4154        addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
4155        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
4156
4157        final String nonSystemPackage = "non.system.package";
4158        int appId = 12345;
4159        setupPackageInPackageManager(
4160                nonSystemPackage,
4161                UserHandle.USER_SYSTEM,  // We check the packageInfo from the primary user.
4162                appId, /*flags=*/ 0);
4163
4164        final String systemListener = "system.package";
4165        setupPackageInPackageManager(
4166                systemListener,
4167                UserHandle.USER_SYSTEM,  // We check the packageInfo from the primary user.
4168                ++appId, ApplicationInfo.FLAG_SYSTEM);
4169
4170        // By default all packages are allowed (for all profiles)
4171        assertNull(dpms.getPermittedCrossProfileNotificationListeners(admin1));
4172
4173        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4174        assertTrue(dpms.isNotificationListenerServicePermitted(
4175                nonSystemPackage, MANAGED_PROFILE_USER_ID));
4176        assertTrue(dpms.isNotificationListenerServicePermitted(
4177                systemListener, MANAGED_PROFILE_USER_ID));
4178        assertTrue(dpms.isNotificationListenerServicePermitted(
4179                nonSystemPackage, UserHandle.USER_SYSTEM));
4180        assertTrue(dpms.isNotificationListenerServicePermitted(
4181                systemListener, UserHandle.USER_SYSTEM));
4182
4183        // Setting an empty whitelist - only system listeners allowed in managed profile, but
4184        // all allowed in primary profile
4185        mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
4186        assertTrue(dpms.setPermittedCrossProfileNotificationListeners(
4187                admin1, Collections.<String>emptyList()));
4188        assertEquals(0, dpms.getPermittedCrossProfileNotificationListeners(admin1).size());
4189
4190        mContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4191        assertFalse(dpms.isNotificationListenerServicePermitted(
4192                nonSystemPackage, MANAGED_PROFILE_USER_ID));
4193        assertTrue(dpms.isNotificationListenerServicePermitted(
4194                systemListener, MANAGED_PROFILE_USER_ID));
4195        assertTrue(dpms.isNotificationListenerServicePermitted(
4196                nonSystemPackage, UserHandle.USER_SYSTEM));
4197        assertTrue(dpms.isNotificationListenerServicePermitted(
4198                systemListener, UserHandle.USER_SYSTEM));
4199    }
4200
4201    public void testGetOwnerInstalledCaCertsForDeviceOwner() throws Exception {
4202        mContext.packageName = mRealTestContext.getPackageName();
4203        setDeviceOwner();
4204
4205        final DpmMockContext caller = new DpmMockContext(mRealTestContext, "test-caller");
4206        caller.packageName = admin1.getPackageName();
4207        caller.binder.callingUid = DpmMockContext.CALLER_SYSTEM_USER_UID;
4208
4209        verifyCanGetOwnerInstalledCaCerts(admin1, caller);
4210    }
4211
4212    public void testGetOwnerInstalledCaCertsForProfileOwner() throws Exception {
4213        mContext.packageName = mRealTestContext.getPackageName();
4214        setAsProfileOwner(admin1);
4215
4216        final DpmMockContext caller = new DpmMockContext(mRealTestContext, "test-caller");
4217        caller.packageName = admin1.getPackageName();
4218        caller.binder.callingUid = DpmMockContext.CALLER_UID;
4219
4220        verifyCanGetOwnerInstalledCaCerts(admin1, caller);
4221        verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(admin1, caller);
4222    }
4223
4224    public void testGetOwnerInstalledCaCertsForDelegate() throws Exception {
4225        mContext.packageName = mRealTestContext.getPackageName();
4226        setAsProfileOwner(admin1);
4227
4228        final String delegate = "com.example.delegate";
4229        final int delegateUid = setupPackageInPackageManager(delegate, 20988);
4230        dpm.setCertInstallerPackage(admin1, delegate);
4231
4232        final DpmMockContext caller = new DpmMockContext(mRealTestContext, "test-caller");
4233        caller.packageName = delegate;
4234        caller.binder.callingUid = delegateUid;
4235
4236        verifyCanGetOwnerInstalledCaCerts(null, caller);
4237        verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(null, caller);
4238    }
4239
4240    private void verifyCanGetOwnerInstalledCaCerts(
4241            final ComponentName caller, final DpmMockContext callerContext) throws Exception {
4242        final String alias = "cert";
4243        final byte[] caCert = TEST_CA.getBytes();
4244
4245        // device admin (used for posting the tls notification)
4246        final DpmMockContext admin1Context;
4247        if (admin1.getPackageName().equals(callerContext.getPackageName())) {
4248            admin1Context = callerContext;
4249        } else {
4250            admin1Context = new DpmMockContext(mRealTestContext, "test-admin");
4251            admin1Context.packageName = admin1.getPackageName();
4252            admin1Context.applicationInfo = new ApplicationInfo();
4253        }
4254        when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
4255
4256        // caller: device admin or delegated certificate installer
4257        callerContext.applicationInfo = new ApplicationInfo();
4258        final UserHandle callerUser = callerContext.binder.getCallingUserHandle();
4259
4260        // system_server
4261        final DpmMockContext serviceContext = mContext;
4262        serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4263        serviceContext.addPackageContext(callerUser, admin1Context);
4264        serviceContext.addPackageContext(callerUser, callerContext);
4265
4266        // Install a CA cert.
4267        runAsCaller(callerContext, dpms, (dpm) -> {
4268            when(mContext.keyChainConnection.getService().installCaCertificate(caCert))
4269                        .thenReturn(alias);
4270            assertTrue(dpm.installCaCert(caller, caCert));
4271            when(mContext.keyChainConnection.getService().getUserCaAliases())
4272                    .thenReturn(asSlice(new String[] {alias}));
4273
4274        });
4275
4276        serviceContext.injectBroadcast(new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
4277                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()));
4278        flushTasks();
4279
4280        final List<String> ownerInstalledCaCerts = new ArrayList<>();
4281
4282        // Device Owner / Profile Owner can find out which CA certs were installed by itself.
4283        runAsCaller(admin1Context, dpms, (dpm) -> {
4284            final List<String> installedCaCerts = dpm.getOwnerInstalledCaCerts(callerUser);
4285            assertEquals(Arrays.asList(alias), installedCaCerts);
4286            ownerInstalledCaCerts.addAll(installedCaCerts);
4287        });
4288
4289        // Restarting the DPMS should not lose information.
4290        initializeDpms();
4291        runAsCaller(admin1Context, dpms, (dpm) -> {
4292            assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser));
4293        });
4294
4295        // System can find out which CA certs were installed by the Device Owner / Profile Owner.
4296        runAsCaller(serviceContext, dpms, (dpm) -> {
4297            assertEquals(ownerInstalledCaCerts, dpm.getOwnerInstalledCaCerts(callerUser));
4298
4299            // Remove the CA cert.
4300            reset(mContext.keyChainConnection.getService());
4301        });
4302
4303        serviceContext.injectBroadcast(new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
4304                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()));
4305        flushTasks();
4306
4307        // Verify that the CA cert is no longer reported as installed by the Device Owner / Profile
4308        // Owner.
4309        runAsCaller(admin1Context, dpms, (dpm) -> {
4310            MoreAsserts.assertEmpty(dpm.getOwnerInstalledCaCerts(callerUser));
4311        });
4312    }
4313
4314    private void verifyCantGetOwnerInstalledCaCertsProfileOwnerRemoval(
4315            final ComponentName callerName, final DpmMockContext callerContext) throws Exception {
4316        final String alias = "cert";
4317        final byte[] caCert = TEST_CA.getBytes();
4318
4319        // device admin (used for posting the tls notification)
4320        final DpmMockContext admin1Context;
4321        if (admin1.getPackageName().equals(callerContext.getPackageName())) {
4322            admin1Context = callerContext;
4323        } else {
4324            admin1Context = new DpmMockContext(mRealTestContext, "test-admin");
4325            admin1Context.packageName = admin1.getPackageName();
4326            admin1Context.applicationInfo = new ApplicationInfo();
4327        }
4328        when(admin1Context.resources.getColor(anyInt(), anyObject())).thenReturn(Color.WHITE);
4329
4330        // caller: device admin or delegated certificate installer
4331        callerContext.applicationInfo = new ApplicationInfo();
4332        final UserHandle callerUser = callerContext.binder.getCallingUserHandle();
4333
4334        // system_server
4335        final DpmMockContext serviceContext = mContext;
4336        serviceContext.binder.callingUid = DpmMockContext.SYSTEM_UID;
4337        serviceContext.addPackageContext(callerUser, admin1Context);
4338        serviceContext.addPackageContext(callerUser, callerContext);
4339
4340        // Install a CA cert as caller
4341        runAsCaller(callerContext, dpms, (dpm) -> {
4342            when(mContext.keyChainConnection.getService().installCaCertificate(caCert))
4343                    .thenReturn(alias);
4344            assertTrue(dpm.installCaCert(callerName, caCert));
4345        });
4346
4347        // Fake the CA cert as having been installed
4348        when(serviceContext.keyChainConnection.getService().getUserCaAliases())
4349                .thenReturn(asSlice(new String[] {alias}));
4350        serviceContext.injectBroadcast(new Intent(KeyChain.ACTION_TRUST_STORE_CHANGED)
4351                .putExtra(Intent.EXTRA_USER_HANDLE, callerUser.getIdentifier()));
4352        flushTasks();
4353
4354        // Removing the Profile Owner should clear the information on which CA certs were installed
4355        runAsCaller(admin1Context, dpms, (dpm) -> {
4356            dpm.clearProfileOwner(admin1);
4357        });
4358
4359        runAsCaller(serviceContext, dpms, (dpm) -> {
4360            final List<String> ownerInstalledCaCerts = dpm.getOwnerInstalledCaCerts(callerUser);
4361            assertNotNull(ownerInstalledCaCerts);
4362            assertTrue(ownerInstalledCaCerts.isEmpty());
4363        });
4364    }
4365
4366    private void setUserSetupCompleteForUser(boolean isUserSetupComplete, int userhandle) {
4367        when(mContext.settings.settingsSecureGetIntForUser(Settings.Secure.USER_SETUP_COMPLETE, 0,
4368                userhandle)).thenReturn(isUserSetupComplete ? 1 : 0);
4369        dpms.notifyChangeToContentObserver(
4370                Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), userhandle);
4371    }
4372
4373    private void assertProvisioningAllowed(String action, boolean expected) {
4374        assertEquals("isProvisioningAllowed(" + action + ") returning unexpected result", expected,
4375                dpm.isProvisioningAllowed(action));
4376    }
4377
4378    private void assertProvisioningAllowed(String action, boolean expected, String packageName,
4379            int uid) {
4380        String previousPackageName = mContext.packageName;
4381        int previousUid = mMockContext.binder.callingUid;
4382
4383        // Call assertProvisioningAllowed with the packageName / uid passed as arguments.
4384        mContext.packageName = packageName;
4385        mMockContext.binder.callingUid = uid;
4386        assertProvisioningAllowed(action, expected);
4387
4388        // Set the previous package name / calling uid to go back to the initial state.
4389        mContext.packageName = previousPackageName;
4390        mMockContext.binder.callingUid = previousUid;
4391    }
4392
4393    private void assertCheckProvisioningPreCondition(String action, int provisioningCondition) {
4394        assertCheckProvisioningPreCondition(action, admin1.getPackageName(), provisioningCondition);
4395    }
4396
4397    private void assertCheckProvisioningPreCondition(
4398            String action, String packageName, int provisioningCondition) {
4399        assertEquals("checkProvisioningPreCondition("
4400                        + action + ", " + packageName + ") returning unexpected result",
4401                provisioningCondition, dpm.checkProvisioningPreCondition(action, packageName));
4402    }
4403
4404    /**
4405     * Setup a managed profile with the specified admin and its uid.
4406     * @param admin ComponentName that's visible to the test code, which doesn't have to exist.
4407     * @param adminUid uid of the admin package.
4408     * @param copyFromAdmin package information for {@code admin} will be built based on this
4409     *     component's information.
4410     */
4411    private void addManagedProfile(
4412            ComponentName admin, int adminUid, ComponentName copyFromAdmin) throws Exception {
4413        final int userId = UserHandle.getUserId(adminUid);
4414        mContext.addUser(userId, UserInfo.FLAG_MANAGED_PROFILE, UserHandle.USER_SYSTEM);
4415        mContext.callerPermissions.addAll(OWNER_SETUP_PERMISSIONS);
4416        setUpPackageManagerForFakeAdmin(admin, adminUid, copyFromAdmin);
4417        dpm.setActiveAdmin(admin, false, userId);
4418        assertTrue(dpm.setProfileOwner(admin, null, userId));
4419        mContext.callerPermissions.removeAll(OWNER_SETUP_PERMISSIONS);
4420    }
4421
4422    /**
4423     * Convert String[] to StringParceledListSlice.
4424     */
4425    private static StringParceledListSlice asSlice(String[] s) {
4426        return new StringParceledListSlice(Arrays.asList(s));
4427    }
4428
4429    private void flushTasks() throws Exception {
4430        dpms.mHandler.runWithScissors(() -> {}, 0 /*now*/);
4431        dpms.mBackgroundHandler.runWithScissors(() -> {}, 0 /*now*/);
4432
4433        // We can't let exceptions happen on the background thread. Throw them here if they happen
4434        // so they still cause the test to fail despite being suppressed.
4435        mContext.rethrowBackgroundBroadcastExceptions();
4436    }
4437}
4438