1 /*
2  * Copyright (C) 2016 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  */
16 
17 package com.android.settingslib;
18 
19 import static android.app.admin.DevicePolicyManager.EXTRA_RESTRICTION;
20 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE;
21 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT;
22 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT;
23 import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS;
24 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
25 import static com.google.common.truth.Truth.assertThat;
26 import static org.mockito.ArgumentMatchers.any;
27 import static org.mockito.ArgumentMatchers.eq;
28 import static org.mockito.Mockito.doReturn;
29 import static org.mockito.Mockito.verify;
30 import static org.mockito.Mockito.when;
31 
32 import android.app.admin.DevicePolicyManager;
33 import android.content.ComponentName;
34 import android.content.Context;
35 import android.content.Intent;
36 import android.content.pm.PackageManager;
37 import android.content.pm.UserInfo;
38 import android.os.UserHandle;
39 import android.os.UserManager;
40 
41 import org.junit.Before;
42 import org.junit.Test;
43 import org.junit.runner.RunWith;
44 import org.mockito.Answers;
45 import org.mockito.ArgumentCaptor;
46 import org.mockito.Mock;
47 import org.mockito.MockitoAnnotations;
48 import org.robolectric.RobolectricTestRunner;
49 
50 import java.util.Arrays;
51 import java.util.Collections;
52 
53 @RunWith(RobolectricTestRunner.class)
54 public class RestrictedLockUtilsTest {
55 
56     @Mock
57     private Context mContext;
58     @Mock
59     private DevicePolicyManager mDevicePolicyManager;
60     @Mock
61     private UserManager mUserManager;
62     @Mock
63     private PackageManager mPackageManager;
64     @Mock(answer = Answers.RETURNS_DEEP_STUBS)
65     private RestrictedLockUtilsInternal.Proxy mProxy;
66 
67     private final int mUserId = 194;
68     private final int mProfileId = 160;
69     private final ComponentName mAdmin1 = new ComponentName("admin1", "admin1class");
70     private final ComponentName mAdmin2 = new ComponentName("admin2", "admin2class");
71 
72     @Before
setUp()73     public void setUp() {
74         MockitoAnnotations.initMocks(this);
75 
76         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE))
77                 .thenReturn(mDevicePolicyManager);
78         when(mContext.getSystemService(DevicePolicyManager.class))
79                 .thenReturn(mDevicePolicyManager);
80         when(mContext.getSystemService(Context.USER_SERVICE))
81                 .thenReturn(mUserManager);
82         when(mContext.getPackageManager())
83                 .thenReturn(mPackageManager);
84 
85         RestrictedLockUtilsInternal.sProxy = mProxy;
86     }
87 
88     @Test
checkIfRestrictionEnforced_deviceOwner()89     public void checkIfRestrictionEnforced_deviceOwner()
90             throws PackageManager.NameNotFoundException {
91         UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
92                 UserManager.RESTRICTION_SOURCE_DEVICE_OWNER);
93         final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
94         when(mUserManager.getUserRestrictionSources(userRestriction,
95                 UserHandle.of(mUserId))).
96                 thenReturn(Collections.singletonList(enforcingUser));
97 
98         when(mContext.createPackageContextAsUser(any(), eq(0),
99                 eq(UserHandle.of(mUserId))))
100                 .thenReturn(mContext);
101 
102         setUpDeviceOwner(mAdmin1, mUserId);
103 
104         EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
105                 .checkIfRestrictionEnforced(mContext, userRestriction, mUserId);
106 
107         assertThat(enforcedAdmin).isNotNull();
108         assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
109         assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
110     }
111 
112     @Test
checkIfRestrictionEnforced_profileOwner()113     public void checkIfRestrictionEnforced_profileOwner()
114             throws PackageManager.NameNotFoundException {
115         UserManager.EnforcingUser enforcingUser = new UserManager.EnforcingUser(mUserId,
116                 UserManager.RESTRICTION_SOURCE_PROFILE_OWNER);
117         final String userRestriction = UserManager.DISALLOW_UNINSTALL_APPS;
118         when(mUserManager.getUserRestrictionSources(userRestriction,
119                 UserHandle.of(mUserId))).
120                 thenReturn(Collections.singletonList(enforcingUser));
121 
122         when(mContext.createPackageContextAsUser(any(), eq(0),
123                 eq(UserHandle.of(mUserId))))
124                 .thenReturn(mContext);
125 
126         setUpProfileOwner(mAdmin1);
127 
128         EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
129                 .checkIfRestrictionEnforced(mContext, userRestriction, mUserId);
130 
131         assertThat(enforcedAdmin).isNotNull();
132         assertThat(enforcedAdmin.enforcedRestriction).isEqualTo(userRestriction);
133         assertThat(enforcedAdmin.component).isEqualTo(mAdmin1);
134     }
135 
136     @Test
checkIfDevicePolicyServiceDisabled_noEnforceAdminForManagedProfile()137     public void checkIfDevicePolicyServiceDisabled_noEnforceAdminForManagedProfile() {
138         when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)).thenReturn(null);
139         final EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
140                 .checkIfAccountManagementDisabled(mContext, "account_type", mUserId);
141 
142         assertThat(enforcedAdmin).isEqualTo(null);
143     }
144 
145     @Test
checkIfDeviceAdminFeatureDisabled_noEnforceAdminForManagedProfile()146     public void checkIfDeviceAdminFeatureDisabled_noEnforceAdminForManagedProfile() {
147         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_DEVICE_ADMIN))
148                 .thenReturn(false);
149         final EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
150                 .checkIfAccountManagementDisabled(mContext, "account_type", mUserId);
151 
152         assertThat(enforcedAdmin).isEqualTo(null);
153     }
154 
155     @Test
checkIfKeyguardFeaturesDisabled_noEnforcedAdminForManagedProfile()156     public void checkIfKeyguardFeaturesDisabled_noEnforcedAdminForManagedProfile() {
157         setUpManagedProfile(mUserId, new ComponentName[] {mAdmin1, mAdmin2});
158 
159         final EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
160                 .checkIfKeyguardFeaturesDisabled(mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId);
161 
162         assertThat(enforcedAdmin).isEqualTo(null);
163     }
164 
165     @Test
checkIfKeyguardFeaturesDisabled_oneEnforcedAdminForManagedProfile()166     public void checkIfKeyguardFeaturesDisabled_oneEnforcedAdminForManagedProfile() {
167         setUpManagedProfile(mUserId, new ComponentName[] {mAdmin1, mAdmin2});
168 
169         when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId))
170                 .thenReturn(KEYGUARD_DISABLE_FINGERPRINT);
171 
172         final EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
173                 .checkIfKeyguardFeaturesDisabled(mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId);
174 
175         assertThat(enforcedAdmin).isEqualTo(new EnforcedAdmin(mAdmin1, UserHandle.of(mUserId)));
176     }
177 
178     @Test
checkIfKeyguardFeaturesDisabled_multipleEnforcedAdminForManagedProfile()179     public void checkIfKeyguardFeaturesDisabled_multipleEnforcedAdminForManagedProfile() {
180         setUpManagedProfile(mUserId, new ComponentName[] {mAdmin1, mAdmin2});
181 
182         when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId))
183                 .thenReturn(KEYGUARD_DISABLE_REMOTE_INPUT);
184         when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin2, mUserId))
185                 .thenReturn(KEYGUARD_DISABLE_REMOTE_INPUT);
186 
187         final EnforcedAdmin enforcedAdmin = RestrictedLockUtilsInternal
188                 .checkIfKeyguardFeaturesDisabled(mContext, KEYGUARD_DISABLE_REMOTE_INPUT, mUserId);
189 
190         assertThat(enforcedAdmin).isEqualTo(EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN);
191     }
192 
193     @Test
checkIfKeyguardFeaturesAreDisabled_doesMatchAllowedFeature_unifiedManagedProfile()194     public void checkIfKeyguardFeaturesAreDisabled_doesMatchAllowedFeature_unifiedManagedProfile() {
195         UserInfo userInfo = setUpUser(mUserId, new ComponentName[] {mAdmin1});
196         UserInfo profileInfo = setUpManagedProfile(mProfileId, new ComponentName[] {mAdmin2});
197         when(mUserManager.getProfiles(mUserId)).thenReturn(Arrays.asList(userInfo, profileInfo));
198 
199         when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId))
200                 .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE);
201         when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin2, mProfileId))
202                 .thenReturn(KEYGUARD_DISABLE_FINGERPRINT);
203 
204         // Querying the parent should return the policy, since it affects the parent.
205         EnforcedAdmin parent = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
206                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId);
207         assertThat(parent).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
208 
209         // Querying the child should return that too.
210         EnforcedAdmin profile = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
211                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mProfileId);
212         assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
213 
214         // Querying for some unrelated feature should return nothing. Nothing!
215         assertThat(RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
216                 mContext, KEYGUARD_DISABLE_REMOTE_INPUT, mUserId)).isNull();
217         assertThat(RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
218                 mContext, KEYGUARD_DISABLE_REMOTE_INPUT, mProfileId)).isNull();
219     }
220 
221     @Test
checkIfKeyguardFeaturesAreDisabled_notMatchOtherFeatures_unifiedManagedProfile()222     public void checkIfKeyguardFeaturesAreDisabled_notMatchOtherFeatures_unifiedManagedProfile() {
223         UserInfo userInfo = setUpUser(mUserId, new ComponentName[] {mAdmin1});
224         UserInfo profileInfo = setUpManagedProfile(mProfileId, new ComponentName[] {mAdmin2});
225         when(mUserManager.getProfiles(mUserId)).thenReturn(Arrays.asList(userInfo, profileInfo));
226 
227         when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId))
228                 .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE);
229         when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin2, mProfileId))
230                 .thenReturn(KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS);
231 
232         // Querying the parent should not return the policy, because it's not a policy that should
233         // affect parents even when the lock screen is unified.
234         EnforcedAdmin primary = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
235                 mContext, KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS, mUserId);
236         assertThat(primary).isNull();
237 
238         // Querying the child should still return the policy.
239         EnforcedAdmin profile = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
240                 mContext, KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS, mProfileId);
241         assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
242     }
243 
244     @Test
checkIfKeyguardFeaturesAreDisabled_onlyMatchesProfile_separateManagedProfile()245     public void checkIfKeyguardFeaturesAreDisabled_onlyMatchesProfile_separateManagedProfile() {
246         UserInfo userInfo = setUpUser(mUserId, new ComponentName[] {mAdmin1});
247         UserInfo profileInfo = setUpManagedProfile(mProfileId, new ComponentName[] {mAdmin2});
248         when(mUserManager.getProfiles(mUserId)).thenReturn(Arrays.asList(userInfo, profileInfo));
249 
250         when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId))
251                 .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE);
252         when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin2, mProfileId))
253                 .thenReturn(KEYGUARD_DISABLE_FINGERPRINT);
254 
255         // Crucially for this test, isSeparateWorkChallengeEnabled => true.
256         doReturn(true).when(mProxy).isSeparateProfileChallengeEnabled(any(), eq(mProfileId));
257 
258         // Querying the parent should not return the policy, even though it's shared by default,
259         // because the parent doesn't share a lock screen with the profile any more.
260         EnforcedAdmin parent = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
261                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId);
262         assertThat(parent).isNull();
263 
264         // Querying the child should still return the policy.
265         EnforcedAdmin profile = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
266                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mProfileId);
267         assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
268     }
269 
270     /**
271      * This test works great. The real world implementation is sketchy though.
272      * <p>
273      * DevicePolicyManager.getParentProfileInstance(UserInfo) does not do what it looks like it does
274      * (which would be to get an instance for the parent of the user that's passed in to it.)
275      * <p>
276      * Instead it just always returns a parent instance for the current user.
277      * <p>
278      * Still, the test works.
279      */
280     @Test
checkIfKeyguardFeaturesAreDisabled_onlyMatchesParent_profileParentPolicy()281     public void checkIfKeyguardFeaturesAreDisabled_onlyMatchesParent_profileParentPolicy() {
282         UserInfo userInfo = setUpUser(mUserId, new ComponentName[] {mAdmin1});
283         UserInfo profileInfo = setUpManagedProfile(mProfileId, new ComponentName[] {mAdmin2});
284         when(mUserManager.getProfiles(mUserId)).thenReturn(Arrays.asList(userInfo, profileInfo));
285 
286         when(mProxy.getParentProfileInstance(any(DevicePolicyManager.class), any())
287                 .getKeyguardDisabledFeatures(mAdmin2, mProfileId))
288                 .thenReturn(KEYGUARD_DISABLE_FINGERPRINT);
289 
290         // Parent should get the policy.
291         EnforcedAdmin parent = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
292                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId);
293         assertThat(parent).isEqualTo(new EnforcedAdmin(mAdmin2, UserHandle.of(mProfileId)));
294 
295         // Profile should not get the policy.
296         EnforcedAdmin profile = RestrictedLockUtilsInternal.checkIfKeyguardFeaturesDisabled(
297                 mContext, KEYGUARD_DISABLE_FINGERPRINT, mProfileId);
298         assertThat(profile).isNull();
299     }
300 
301     @Test
sendShowAdminSupportDetailsIntent_extraRestrictionProvided()302     public void sendShowAdminSupportDetailsIntent_extraRestrictionProvided() {
303         EnforcedAdmin enforcedAdmin = new EnforcedAdmin();
304         enforcedAdmin.enforcedRestriction = "Fake";
305         RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, enforcedAdmin);
306 
307         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
308         verify(mContext).startActivityAsUser(intentCaptor.capture(), any());
309         assertThat(intentCaptor.getValue().getExtra(EXTRA_RESTRICTION)).isEqualTo("Fake");
310     }
311 
312     @Test
sendShowAdminSupportDetailsIntent_noExtraRestriction()313     public void sendShowAdminSupportDetailsIntent_noExtraRestriction() {
314         RestrictedLockUtils.sendShowAdminSupportDetailsIntent(mContext, null);
315 
316         ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
317         verify(mContext).startActivityAsUser(intentCaptor.capture(), any());
318         assertThat(intentCaptor.getValue().getExtra(EXTRA_RESTRICTION)).isNull();
319     }
320 
setUpUser(int userId, ComponentName[] admins)321     private UserInfo setUpUser(int userId, ComponentName[] admins) {
322         UserInfo userInfo = new UserInfo(userId, "primary", 0);
323         when(mUserManager.getUserInfo(userId)).thenReturn(userInfo);
324         setUpActiveAdmins(userId, admins);
325         return userInfo;
326     }
327 
setUpManagedProfile(int userId, ComponentName[] admins)328     private UserInfo setUpManagedProfile(int userId, ComponentName[] admins) {
329         UserInfo userInfo = new UserInfo(userId, "profile", UserInfo.FLAG_MANAGED_PROFILE);
330         when(mUserManager.getUserInfo(userId)).thenReturn(userInfo);
331         setUpActiveAdmins(userId, admins);
332         return userInfo;
333     }
334 
setUpActiveAdmins(int userId, ComponentName[] activeAdmins)335     private void setUpActiveAdmins(int userId, ComponentName[] activeAdmins) {
336         when(mDevicePolicyManager.getActiveAdminsAsUser(userId))
337                 .thenReturn(Arrays.asList(activeAdmins));
338     }
339 
setUpDeviceOwner(ComponentName admin, int userId)340     private void setUpDeviceOwner(ComponentName admin, int userId) {
341         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(admin);
342         when(mDevicePolicyManager.getDeviceOwnerUser()).thenReturn(UserHandle.of(userId));
343     }
344 
setUpProfileOwner(ComponentName admin)345     private void setUpProfileOwner(ComponentName admin) {
346         when(mDevicePolicyManager.getProfileOwner()).thenReturn(admin);
347     }
348 }
349