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.server.locksettings; 18 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.ArgumentMatchers.eq; 24 import static org.mockito.Mockito.doAnswer; 25 import static org.mockito.Mockito.mock; 26 import static org.mockito.Mockito.when; 27 28 import android.app.IActivityManager; 29 import android.app.KeyguardManager; 30 import android.app.NotificationManager; 31 import android.app.admin.DevicePolicyManager; 32 import android.app.admin.DevicePolicyManagerInternal; 33 import android.app.admin.DeviceStateCache; 34 import android.app.trust.TrustManager; 35 import android.content.ComponentName; 36 import android.content.Context; 37 import android.content.pm.PackageManager; 38 import android.content.pm.UserInfo; 39 import android.content.res.Resources; 40 import android.hardware.authsecret.IAuthSecret; 41 import android.hardware.face.FaceManager; 42 import android.hardware.fingerprint.FingerprintManager; 43 import android.os.FileUtils; 44 import android.os.IProgressListener; 45 import android.os.RemoteException; 46 import android.os.UserHandle; 47 import android.os.UserManager; 48 import android.os.storage.IStorageManager; 49 import android.os.storage.StorageManager; 50 import android.provider.Settings; 51 52 import androidx.test.InstrumentationRegistry; 53 import androidx.test.runner.AndroidJUnit4; 54 55 import com.android.internal.util.test.FakeSettingsProvider; 56 import com.android.internal.util.test.FakeSettingsProviderRule; 57 import com.android.internal.widget.LockPatternUtils; 58 import com.android.internal.widget.LockSettingsInternal; 59 import com.android.internal.widget.LockscreenCredential; 60 import com.android.server.LocalServices; 61 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager; 62 import com.android.server.pm.UserManagerInternal; 63 import com.android.server.wm.WindowManagerInternal; 64 65 import org.junit.After; 66 import org.junit.Before; 67 import org.junit.Rule; 68 import org.junit.runner.RunWith; 69 import org.mockito.invocation.InvocationOnMock; 70 import org.mockito.stubbing.Answer; 71 72 import java.io.File; 73 import java.util.ArrayList; 74 import java.util.Arrays; 75 76 @RunWith(AndroidJUnit4.class) 77 public abstract class BaseLockSettingsServiceTests { 78 protected static final int PRIMARY_USER_ID = 0; 79 protected static final int MANAGED_PROFILE_USER_ID = 12; 80 protected static final int TURNED_OFF_PROFILE_USER_ID = 17; 81 protected static final int SECONDARY_USER_ID = 20; 82 protected static final int TERTIARY_USER_ID = 21; 83 84 protected UserInfo mPrimaryUserInfo; 85 protected UserInfo mSecondaryUserInfo; 86 protected UserInfo mTertiaryUserInfo; 87 88 private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>(); 89 90 LockSettingsServiceTestable mService; 91 LockSettingsInternal mLocalService; 92 93 MockLockSettingsContext mContext; 94 LockSettingsStorageTestable mStorage; 95 96 Resources mResources; 97 FakeGateKeeperService mGateKeeperService; 98 NotificationManager mNotificationManager; 99 UserManager mUserManager; 100 FakeStorageManager mStorageManager; 101 IActivityManager mActivityManager; 102 DevicePolicyManager mDevicePolicyManager; 103 DevicePolicyManagerInternal mDevicePolicyManagerInternal; 104 MockSyntheticPasswordManager mSpManager; 105 IAuthSecret mAuthSecretService; 106 WindowManagerInternal mMockWindowManager; 107 FakeGsiService mGsiService; 108 PasswordSlotManagerTestable mPasswordSlotManager; 109 RecoverableKeyStoreManager mRecoverableKeyStoreManager; 110 UserManagerInternal mUserManagerInternal; 111 DeviceStateCache mDeviceStateCache; 112 FingerprintManager mFingerprintManager; 113 FaceManager mFaceManager; 114 PackageManager mPackageManager; 115 LockSettingsServiceTestable.MockInjector mInjector; 116 @Rule 117 public FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule(); 118 119 @Before setUp_baseServices()120 public void setUp_baseServices() throws Exception { 121 mResources = createMockResources(); 122 mGateKeeperService = new FakeGateKeeperService(); 123 mNotificationManager = mock(NotificationManager.class); 124 mUserManager = mock(UserManager.class); 125 mStorageManager = new FakeStorageManager(); 126 mActivityManager = mock(IActivityManager.class); 127 mDevicePolicyManager = mock(DevicePolicyManager.class); 128 mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class); 129 mMockWindowManager = mock(WindowManagerInternal.class); 130 mGsiService = new FakeGsiService(); 131 mPasswordSlotManager = new PasswordSlotManagerTestable(); 132 mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class); 133 mUserManagerInternal = mock(UserManagerInternal.class); 134 mDeviceStateCache = mock(DeviceStateCache.class); 135 mFingerprintManager = mock(FingerprintManager.class); 136 mFaceManager = mock(FaceManager.class); 137 mPackageManager = mock(PackageManager.class); 138 139 LocalServices.removeServiceForTest(LockSettingsInternal.class); 140 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); 141 LocalServices.removeServiceForTest(WindowManagerInternal.class); 142 LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal); 143 LocalServices.addService(WindowManagerInternal.class, mMockWindowManager); 144 145 final Context origContext = InstrumentationRegistry.getContext(); 146 mContext = new MockLockSettingsContext(origContext, mResources, 147 mSettingsRule.mockContentResolver(origContext), mUserManager, mNotificationManager, 148 mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class), 149 mock(KeyguardManager.class), mFingerprintManager, mFaceManager, mPackageManager); 150 mStorage = new LockSettingsStorageTestable(mContext, 151 new File(origContext.getFilesDir(), "locksettings")); 152 File storageDir = mStorage.mStorageDir; 153 if (storageDir.exists()) { 154 FileUtils.deleteContents(storageDir); 155 } else { 156 storageDir.mkdirs(); 157 } 158 159 mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService, 160 mUserManager, mPasswordSlotManager); 161 mAuthSecretService = mock(IAuthSecret.class); 162 mInjector = 163 new LockSettingsServiceTestable.MockInjector( 164 mContext, 165 mStorage, 166 mActivityManager, 167 setUpStorageManagerMock(), 168 mSpManager, 169 mGsiService, 170 mRecoverableKeyStoreManager, 171 mUserManagerInternal, 172 mDeviceStateCache); 173 mService = 174 new LockSettingsServiceTestable(mInjector, mGateKeeperService, mAuthSecretService); 175 mService.mHasSecureLockScreen = true; 176 mPrimaryUserInfo = 177 new UserInfo( 178 PRIMARY_USER_ID, 179 null, 180 null, 181 UserInfo.FLAG_INITIALIZED 182 | UserInfo.FLAG_ADMIN 183 | UserInfo.FLAG_PRIMARY 184 | UserInfo.FLAG_MAIN 185 | UserInfo.FLAG_FULL); 186 mSecondaryUserInfo = 187 new UserInfo( 188 SECONDARY_USER_ID, 189 null, 190 null, 191 UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL); 192 mTertiaryUserInfo = 193 new UserInfo( 194 TERTIARY_USER_ID, 195 null, 196 null, 197 UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL); 198 199 when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo); 200 when(mUserManagerInternal.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo); 201 mPrimaryUserProfiles.add(mPrimaryUserInfo); 202 installChildProfile(MANAGED_PROFILE_USER_ID); 203 installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID); 204 for (UserInfo profile : mPrimaryUserProfiles) { 205 when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles); 206 } 207 when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(mSecondaryUserInfo); 208 when(mUserManagerInternal.getUserInfo(eq(SECONDARY_USER_ID))) 209 .thenReturn(mSecondaryUserInfo); 210 when(mUserManager.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo); 211 when(mUserManagerInternal.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo); 212 213 final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles); 214 allUsers.add(mSecondaryUserInfo); 215 allUsers.add(mTertiaryUserInfo); 216 when(mUserManager.getUsers()).thenReturn(allUsers); 217 218 when(mActivityManager.unlockUser2(anyInt(), any())).thenAnswer( 219 invocation -> { 220 Object[] args = invocation.getArguments(); 221 int userId = (int) args[0]; 222 IProgressListener listener = (IProgressListener) args[1]; 223 listener.onStarted(userId, null); 224 listener.onFinished(userId, null); 225 return true; 226 }); 227 228 // Adding a fake Device Owner app which will enable escrow token support in LSS. 229 when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn( 230 new ComponentName("com.dummy.package", ".FakeDeviceOwner")); 231 when(mUserManagerInternal.isDeviceManaged()).thenReturn(true); 232 when(mDeviceStateCache.isUserOrganizationManaged(anyInt())).thenReturn(true); 233 when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true); 234 mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID); 235 mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID); 236 237 setDeviceProvisioned(true); 238 mLocalService = LocalServices.getService(LockSettingsInternal.class); 239 } 240 createMockResources()241 private Resources createMockResources() { 242 Resources res = mock(Resources.class); 243 244 // Set up some default configs, copied from core/res/res/values/config.xml 245 when(res.getBoolean(eq(com.android.internal.R.bool.config_disableLockscreenByDefault))) 246 .thenReturn(false); 247 when(res.getBoolean( 248 eq(com.android.internal.R.bool.config_enableCredentialFactoryResetProtection))) 249 .thenReturn(true); 250 when(res.getBoolean(eq(com.android.internal.R.bool.config_isMainUserPermanentAdmin))) 251 .thenReturn(true); 252 when(res.getBoolean(eq(com.android.internal.R.bool.config_strongAuthRequiredOnBoot))) 253 .thenReturn(true); 254 when(res.getBoolean(eq(com.android.internal.R.bool.config_repairModeSupported))) 255 .thenReturn(true); 256 return res; 257 } 258 setDeviceProvisioned(boolean provisioned)259 protected void setDeviceProvisioned(boolean provisioned) { 260 Settings.Global.putInt(mContext.getContentResolver(), 261 Settings.Global.DEVICE_PROVISIONED, provisioned ? 1 : 0); 262 } 263 setUserSetupComplete(boolean complete)264 protected void setUserSetupComplete(boolean complete) { 265 Settings.Secure.putIntForUser(mContext.getContentResolver(), 266 Settings.Secure.USER_SETUP_COMPLETE, complete ? 1 : 0, UserHandle.USER_SYSTEM); 267 } 268 setSecureFrpMode(boolean secure)269 protected void setSecureFrpMode(boolean secure) { 270 if (android.security.Flags.frpEnforcement()) { 271 mStorage.setTestFactoryResetProtectionState(secure); 272 } 273 Settings.Secure.putIntForUser(mContext.getContentResolver(), 274 Settings.Secure.SECURE_FRP_MODE, secure ? 1 : 0, UserHandle.USER_SYSTEM); 275 } 276 installChildProfile(int profileId)277 private UserInfo installChildProfile(int profileId) { 278 final UserInfo userInfo = new UserInfo( 279 profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE); 280 userInfo.profileGroupId = PRIMARY_USER_ID; 281 mPrimaryUserProfiles.add(userInfo); 282 when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo); 283 when(mUserManager.getProfileParent(eq(profileId))).thenReturn(mPrimaryUserInfo); 284 when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true); 285 when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true); 286 when(mUserManagerInternal.getUserInfo(eq(profileId))).thenReturn(userInfo); 287 // TODO(b/258213147): Remove 288 when(mUserManagerInternal.isUserManaged(eq(profileId))).thenReturn(true); 289 when(mDeviceStateCache.isUserOrganizationManaged(eq(profileId))) 290 .thenReturn(true); 291 return userInfo; 292 } 293 installAndTurnOffChildProfile(int profileId)294 private UserInfo installAndTurnOffChildProfile(int profileId) { 295 final UserInfo userInfo = installChildProfile(profileId); 296 userInfo.flags |= UserInfo.FLAG_QUIET_MODE; 297 when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false); 298 when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false); 299 return userInfo; 300 } 301 setUpStorageManagerMock()302 private IStorageManager setUpStorageManagerMock() throws RemoteException { 303 final IStorageManager sm = mock(IStorageManager.class); 304 305 doAnswer(invocation -> { 306 Object[] args = invocation.getArguments(); 307 mStorageManager.unlockCeStorage(/* userId= */ (int) args[0], 308 /* secret= */ (byte[]) args[1]); 309 return null; 310 }).when(sm).unlockCeStorage(anyInt(), any()); 311 312 doAnswer(invocation -> { 313 Object[] args = invocation.getArguments(); 314 mStorageManager.setCeStorageProtection(/* userId= */ (int) args[0], 315 /* secret= */ (byte[]) args[1]); 316 return null; 317 }).when(sm).setCeStorageProtection(anyInt(), any()); 318 319 return sm; 320 } 321 mockBiometricsHardwareFingerprintsAndTemplates(int userId)322 private void mockBiometricsHardwareFingerprintsAndTemplates(int userId) { 323 // Hardware must be detected and fingerprints must be enrolled 324 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true); 325 when(mFingerprintManager.isHardwareDetected()).thenReturn(true); 326 when(mFingerprintManager.hasEnrolledFingerprints(userId)).thenReturn(true); 327 doAnswer(new Answer<Void>() { 328 @Override 329 public Void answer(InvocationOnMock invocation) throws Throwable { 330 FingerprintManager.RemovalCallback callback = 331 (FingerprintManager.RemovalCallback) invocation.getArguments()[1]; 332 callback.onRemovalSucceeded(null, 0); 333 return null; 334 } 335 }).when(mFingerprintManager).removeAll(eq(userId), any()); 336 337 338 // Hardware must be detected and templates must be enrolled 339 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true); 340 when(mFaceManager.isHardwareDetected()).thenReturn(true); 341 when(mFaceManager.hasEnrolledTemplates(userId)).thenReturn(true); 342 doAnswer(new Answer<Void>() { 343 @Override 344 public Void answer(InvocationOnMock invocation) throws Throwable { 345 FaceManager.RemovalCallback callback = 346 (FaceManager.RemovalCallback) invocation.getArguments()[1]; 347 callback.onRemovalSucceeded(null, 0); 348 return null; 349 } 350 }).when(mFaceManager).removeAll(eq(userId), any()); 351 } 352 353 @After tearDown_baseServices()354 public void tearDown_baseServices() throws Exception { 355 mStorage.closeDatabase(); 356 File db = InstrumentationRegistry.getContext().getDatabasePath("locksettings.db"); 357 assertTrue(!db.exists() || db.delete()); 358 359 File storageDir = mStorage.mStorageDir; 360 assertTrue(FileUtils.deleteContents(storageDir)); 361 362 mPasswordSlotManager.cleanup(); 363 } 364 flushHandlerTasks()365 protected void flushHandlerTasks() { 366 mService.mHandler.runWithScissors(() -> { }, 0 /*now*/); // Flush runnables on handler 367 } 368 assertNotEquals(long expected, long actual)369 protected void assertNotEquals(long expected, long actual) { 370 assertTrue(expected != actual); 371 } 372 assertArrayEquals(byte[] expected, byte[] actual)373 protected static void assertArrayEquals(byte[] expected, byte[] actual) { 374 assertTrue(Arrays.equals(expected, actual)); 375 } 376 assertArrayNotEquals(byte[] expected, byte[] actual)377 protected static void assertArrayNotEquals(byte[] expected, byte[] actual) { 378 assertFalse(Arrays.equals(expected, actual)); 379 } 380 newPassword(String password)381 protected LockscreenCredential newPassword(String password) { 382 return LockscreenCredential.createPasswordOrNone(password); 383 } 384 newPin(String pin)385 protected LockscreenCredential newPin(String pin) { 386 return LockscreenCredential.createPinOrNone(pin); 387 } 388 newPattern(String pattern)389 protected LockscreenCredential newPattern(String pattern) { 390 return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern( 391 pattern.getBytes())); 392 } 393 nonePassword()394 protected LockscreenCredential nonePassword() { 395 return LockscreenCredential.createNone(); 396 } 397 398 } 399