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