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 17package com.android.settingslib; 18 19import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NONE; 20import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT; 21import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_REMOTE_INPUT; 22import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS; 23import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; 24import static com.google.common.truth.Truth.assertThat; 25import static org.mockito.Matchers.any; 26import static org.mockito.Matchers.eq; 27import static org.mockito.Mockito.doReturn; 28import static org.mockito.Mockito.when; 29 30import android.app.admin.DevicePolicyManager; 31import android.content.ComponentName; 32import android.content.Context; 33import android.content.pm.UserInfo; 34import android.os.UserManager; 35 36import org.junit.Before; 37import org.junit.Test; 38import org.junit.runner.RunWith; 39import org.mockito.Answers; 40import org.mockito.Mock; 41import org.mockito.MockitoAnnotations; 42import org.robolectric.annotation.Config; 43 44import java.util.Arrays; 45 46@RunWith(SettingLibRobolectricTestRunner.class) 47@Config(manifest = TestConfig.MANIFEST_PATH, sdk = TestConfig.SDK_VERSION) 48public class RestrictedLockUtilsTest { 49 50 @Mock 51 private Context mContext; 52 @Mock 53 private DevicePolicyManager mDevicePolicyManager; 54 @Mock 55 private UserManager mUserManager; 56 @Mock(answer = Answers.RETURNS_DEEP_STUBS) 57 private RestrictedLockUtils.Proxy mProxy; 58 59 private static final int mUserId = 194; 60 private static final int mProfileId = 160; 61 private static final ComponentName mAdmin1 = new ComponentName("admin1", "admin1class"); 62 private static final ComponentName mAdmin2 = new ComponentName("admin2", "admin2class"); 63 64 @Before 65 public void setUp() { 66 MockitoAnnotations.initMocks(this); 67 68 when(mContext.getSystemService(Context.DEVICE_POLICY_SERVICE)) 69 .thenReturn(mDevicePolicyManager); 70 when(mContext.getSystemService(Context.USER_SERVICE)) 71 .thenReturn(mUserManager); 72 73 RestrictedLockUtils.sProxy = mProxy; 74 } 75 76 @Test 77 public void checkIfKeyguardFeaturesDisabled_noEnforcedAdminForManagedProfile() { 78 setUpManagedProfile(mUserId, new ComponentName[] {mAdmin1, mAdmin2}); 79 80 final EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 81 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId); 82 83 assertThat(enforcedAdmin).isEqualTo(null); 84 } 85 86 @Test 87 public void checkIfKeyguardFeaturesDisabled_oneEnforcedAdminForManagedProfile() { 88 setUpManagedProfile(mUserId, new ComponentName[] {mAdmin1, mAdmin2}); 89 90 when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId)) 91 .thenReturn(KEYGUARD_DISABLE_FINGERPRINT); 92 93 final EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 94 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId); 95 96 assertThat(enforcedAdmin).isEqualTo(new EnforcedAdmin(mAdmin1, mUserId)); 97 } 98 99 @Test 100 public void checkIfKeyguardFeaturesDisabled_multipleEnforcedAdminForManagedProfile() { 101 setUpManagedProfile(mUserId, new ComponentName[] {mAdmin1, mAdmin2}); 102 103 when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId)) 104 .thenReturn(KEYGUARD_DISABLE_REMOTE_INPUT); 105 when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin2, mUserId)) 106 .thenReturn(KEYGUARD_DISABLE_REMOTE_INPUT); 107 108 final EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 109 mContext, KEYGUARD_DISABLE_REMOTE_INPUT, mUserId); 110 111 assertThat(enforcedAdmin).isEqualTo(EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN); 112 } 113 114 @Test 115 public void checkIfKeyguardFeaturesAreDisabled_doesMatchAllowedFeature_unifiedManagedProfile() { 116 UserInfo userInfo = setUpUser(mUserId, new ComponentName[] {mAdmin1}); 117 UserInfo profileInfo = setUpManagedProfile(mProfileId, new ComponentName[] {mAdmin2}); 118 when(mUserManager.getProfiles(mUserId)).thenReturn(Arrays.asList(new UserInfo[] { 119 userInfo, profileInfo})); 120 121 when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId)) 122 .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE); 123 when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin2, mProfileId)) 124 .thenReturn(KEYGUARD_DISABLE_FINGERPRINT); 125 126 // Querying the parent should return the policy, since it affects the parent. 127 EnforcedAdmin parent = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 128 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId); 129 assertThat(parent).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId)); 130 131 // Querying the child should return that too. 132 EnforcedAdmin profile = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 133 mContext, KEYGUARD_DISABLE_FINGERPRINT, mProfileId); 134 assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId)); 135 136 // Querying for some unrelated feature should return nothing. Nothing! 137 assertThat(RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 138 mContext, KEYGUARD_DISABLE_REMOTE_INPUT, mUserId)).isNull(); 139 assertThat(RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 140 mContext, KEYGUARD_DISABLE_REMOTE_INPUT, mProfileId)).isNull(); 141 } 142 143 @Test 144 public void checkIfKeyguardFeaturesAreDisabled_notMatchOtherFeatures_unifiedManagedProfile() { 145 UserInfo userInfo = setUpUser(mUserId, new ComponentName[] {mAdmin1}); 146 UserInfo profileInfo = setUpManagedProfile(mProfileId, new ComponentName[] {mAdmin2}); 147 when(mUserManager.getProfiles(mUserId)).thenReturn(Arrays.asList(new UserInfo[] { 148 userInfo, profileInfo})); 149 150 when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId)) 151 .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE); 152 when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin2, mProfileId)) 153 .thenReturn(KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS); 154 155 // Querying the parent should not return the policy, because it's not a policy that should 156 // affect parents even when the lock screen is unified. 157 EnforcedAdmin primary = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 158 mContext, KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS, mUserId); 159 assertThat(primary).isNull(); 160 161 // Querying the child should still return the policy. 162 EnforcedAdmin profile = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 163 mContext, KEYGUARD_DISABLE_UNREDACTED_NOTIFICATIONS, mProfileId); 164 assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId)); 165 } 166 167 @Test 168 public void checkIfKeyguardFeaturesAreDisabled_onlyMatchesProfile_separateManagedProfile() { 169 UserInfo userInfo = setUpUser(mUserId, new ComponentName[] {mAdmin1}); 170 UserInfo profileInfo = setUpManagedProfile(mProfileId, new ComponentName[] {mAdmin2}); 171 when(mUserManager.getProfiles(mUserId)).thenReturn(Arrays.asList(new UserInfo[] { 172 userInfo, profileInfo})); 173 174 when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin1, mUserId)) 175 .thenReturn(KEYGUARD_DISABLE_FEATURES_NONE); 176 when(mDevicePolicyManager.getKeyguardDisabledFeatures(mAdmin2, mProfileId)) 177 .thenReturn(KEYGUARD_DISABLE_FINGERPRINT); 178 179 // Crucially for this test, isSeparateWorkChallengeEnabled => true. 180 doReturn(true).when(mProxy).isSeparateProfileChallengeEnabled(any(), eq(mProfileId)); 181 182 // Querying the parent should not return the policy, even though it's shared by default, 183 // because the parent doesn't share a lock screen with the profile any more. 184 EnforcedAdmin parent = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 185 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId); 186 assertThat(parent).isNull(); 187 188 // Querying the child should still return the policy. 189 EnforcedAdmin profile = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 190 mContext, KEYGUARD_DISABLE_FINGERPRINT, mProfileId); 191 assertThat(profile).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId)); 192 } 193 194 /** 195 * This test works great. The real world implementation is sketchy though. 196 * <p> 197 * DevicePolicyManager.getParentProfileInstance(UserInfo) does not do what it looks like it does 198 * (which would be to get an instance for the parent of the user that's passed in to it.) 199 * <p> 200 * Instead it just always returns a parent instance for the current user. 201 * <p> 202 * Still, the test works. 203 */ 204 @Test 205 public void checkIfKeyguardFeaturesAreDisabled_onlyMatchesParent_profileParentPolicy() { 206 UserInfo userInfo = setUpUser(mUserId, new ComponentName[] {mAdmin1}); 207 UserInfo profileInfo = setUpManagedProfile(mProfileId, new ComponentName[] {mAdmin2}); 208 when(mUserManager.getProfiles(mUserId)).thenReturn(Arrays.asList(new UserInfo[] { 209 userInfo, profileInfo})); 210 211 when(mProxy.getParentProfileInstance(any(DevicePolicyManager.class), any()) 212 .getKeyguardDisabledFeatures(mAdmin2, mProfileId)) 213 .thenReturn(KEYGUARD_DISABLE_FINGERPRINT); 214 215 // Parent should get the policy. 216 EnforcedAdmin parent = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 217 mContext, KEYGUARD_DISABLE_FINGERPRINT, mUserId); 218 assertThat(parent).isEqualTo(new EnforcedAdmin(mAdmin2, mProfileId)); 219 220 // Profile should not get the policy. 221 EnforcedAdmin profile = RestrictedLockUtils.checkIfKeyguardFeaturesDisabled( 222 mContext, KEYGUARD_DISABLE_FINGERPRINT, mProfileId); 223 assertThat(profile).isNull(); 224 } 225 226 private UserInfo setUpUser(int userId, ComponentName[] admins) { 227 UserInfo userInfo = new UserInfo(userId, "primary", 0); 228 when(mUserManager.getUserInfo(userId)).thenReturn(userInfo); 229 setUpActiveAdmins(userId, admins); 230 return userInfo; 231 } 232 233 private UserInfo setUpManagedProfile(int userId, ComponentName[] admins) { 234 UserInfo userInfo = new UserInfo(userId, "profile", UserInfo.FLAG_MANAGED_PROFILE); 235 when(mUserManager.getUserInfo(userId)).thenReturn(userInfo); 236 setUpActiveAdmins(userId, admins); 237 return userInfo; 238 } 239 240 private void setUpActiveAdmins(int userId, ComponentName[] activeAdmins) { 241 when(mDevicePolicyManager.getActiveAdminsAsUser(userId)) 242 .thenReturn(Arrays.asList(activeAdmins)); 243 } 244} 245