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 import android.security.KeyStore; 52 53 import androidx.test.InstrumentationRegistry; 54 import androidx.test.runner.AndroidJUnit4; 55 56 import com.android.internal.util.test.FakeSettingsProvider; 57 import com.android.internal.util.test.FakeSettingsProviderRule; 58 import com.android.internal.widget.LockPatternUtils; 59 import com.android.internal.widget.LockSettingsInternal; 60 import com.android.internal.widget.LockscreenCredential; 61 import com.android.server.LocalServices; 62 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager; 63 import com.android.server.pm.UserManagerInternal; 64 import com.android.server.wm.WindowManagerInternal; 65 66 import org.junit.After; 67 import org.junit.Before; 68 import org.junit.Rule; 69 import org.junit.runner.RunWith; 70 import org.mockito.invocation.InvocationOnMock; 71 import org.mockito.stubbing.Answer; 72 73 import java.io.File; 74 import java.util.ArrayList; 75 import java.util.Arrays; 76 77 @RunWith(AndroidJUnit4.class) 78 public abstract class BaseLockSettingsServiceTests { 79 protected static final int PRIMARY_USER_ID = 0; 80 protected static final int MANAGED_PROFILE_USER_ID = 12; 81 protected static final int TURNED_OFF_PROFILE_USER_ID = 17; 82 protected static final int SECONDARY_USER_ID = 20; 83 protected static final int TERTIARY_USER_ID = 21; 84 85 protected UserInfo mPrimaryUserInfo; 86 protected UserInfo mSecondaryUserInfo; 87 protected UserInfo mTertiaryUserInfo; 88 89 private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>(); 90 91 LockSettingsServiceTestable mService; 92 LockSettingsInternal mLocalService; 93 94 MockLockSettingsContext mContext; 95 LockSettingsStorageTestable mStorage; 96 97 Resources mResources; 98 FakeGateKeeperService mGateKeeperService; 99 NotificationManager mNotificationManager; 100 UserManager mUserManager; 101 FakeStorageManager mStorageManager; 102 IActivityManager mActivityManager; 103 DevicePolicyManager mDevicePolicyManager; 104 DevicePolicyManagerInternal mDevicePolicyManagerInternal; 105 KeyStore mKeyStore; 106 MockSyntheticPasswordManager mSpManager; 107 IAuthSecret mAuthSecretService; 108 WindowManagerInternal mMockWindowManager; 109 FakeGsiService mGsiService; 110 PasswordSlotManagerTestable mPasswordSlotManager; 111 RecoverableKeyStoreManager mRecoverableKeyStoreManager; 112 UserManagerInternal mUserManagerInternal; 113 DeviceStateCache mDeviceStateCache; 114 FingerprintManager mFingerprintManager; 115 FaceManager mFaceManager; 116 PackageManager mPackageManager; 117 LockSettingsServiceTestable.MockInjector mInjector; 118 @Rule 119 public FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule(); 120 121 @Before setUp_baseServices()122 public void setUp_baseServices() throws Exception { 123 mResources = createMockResources(); 124 mGateKeeperService = new FakeGateKeeperService(); 125 mNotificationManager = mock(NotificationManager.class); 126 mUserManager = mock(UserManager.class); 127 mStorageManager = new FakeStorageManager(); 128 mActivityManager = mock(IActivityManager.class); 129 mDevicePolicyManager = mock(DevicePolicyManager.class); 130 mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class); 131 mMockWindowManager = mock(WindowManagerInternal.class); 132 mGsiService = new FakeGsiService(); 133 mPasswordSlotManager = new PasswordSlotManagerTestable(); 134 mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class); 135 mUserManagerInternal = mock(UserManagerInternal.class); 136 mDeviceStateCache = mock(DeviceStateCache.class); 137 mFingerprintManager = mock(FingerprintManager.class); 138 mFaceManager = mock(FaceManager.class); 139 mPackageManager = mock(PackageManager.class); 140 141 LocalServices.removeServiceForTest(LockSettingsInternal.class); 142 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); 143 LocalServices.removeServiceForTest(WindowManagerInternal.class); 144 LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal); 145 LocalServices.addService(WindowManagerInternal.class, mMockWindowManager); 146 147 final Context origContext = InstrumentationRegistry.getContext(); 148 mContext = new MockLockSettingsContext(origContext, mResources, 149 mSettingsRule.mockContentResolver(origContext), mUserManager, mNotificationManager, 150 mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class), 151 mock(KeyguardManager.class), mFingerprintManager, mFaceManager, mPackageManager); 152 mStorage = new LockSettingsStorageTestable(mContext, 153 new File(origContext.getFilesDir(), "locksettings")); 154 File storageDir = mStorage.mStorageDir; 155 if (storageDir.exists()) { 156 FileUtils.deleteContents(storageDir); 157 } else { 158 storageDir.mkdirs(); 159 } 160 161 mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService, 162 mUserManager, mPasswordSlotManager); 163 mAuthSecretService = mock(IAuthSecret.class); 164 mInjector = 165 new LockSettingsServiceTestable.MockInjector( 166 mContext, 167 mStorage, 168 mKeyStore, 169 mActivityManager, 170 setUpStorageManagerMock(), 171 mSpManager, 172 mGsiService, 173 mRecoverableKeyStoreManager, 174 mUserManagerInternal, 175 mDeviceStateCache); 176 mService = 177 new LockSettingsServiceTestable(mInjector, mGateKeeperService, mAuthSecretService); 178 mService.mHasSecureLockScreen = true; 179 mPrimaryUserInfo = 180 new UserInfo( 181 PRIMARY_USER_ID, 182 null, 183 null, 184 UserInfo.FLAG_INITIALIZED 185 | UserInfo.FLAG_ADMIN 186 | UserInfo.FLAG_PRIMARY 187 | UserInfo.FLAG_MAIN 188 | UserInfo.FLAG_FULL); 189 mSecondaryUserInfo = 190 new UserInfo( 191 SECONDARY_USER_ID, 192 null, 193 null, 194 UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL); 195 mTertiaryUserInfo = 196 new UserInfo( 197 TERTIARY_USER_ID, 198 null, 199 null, 200 UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL); 201 202 when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo); 203 when(mUserManagerInternal.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo); 204 mPrimaryUserProfiles.add(mPrimaryUserInfo); 205 installChildProfile(MANAGED_PROFILE_USER_ID); 206 installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID); 207 for (UserInfo profile : mPrimaryUserProfiles) { 208 when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles); 209 } 210 when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(mSecondaryUserInfo); 211 when(mUserManagerInternal.getUserInfo(eq(SECONDARY_USER_ID))) 212 .thenReturn(mSecondaryUserInfo); 213 when(mUserManager.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo); 214 when(mUserManagerInternal.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo); 215 216 final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles); 217 allUsers.add(mSecondaryUserInfo); 218 allUsers.add(mTertiaryUserInfo); 219 when(mUserManager.getUsers()).thenReturn(allUsers); 220 221 when(mActivityManager.unlockUser2(anyInt(), any())).thenAnswer( 222 invocation -> { 223 Object[] args = invocation.getArguments(); 224 int userId = (int) args[0]; 225 IProgressListener listener = (IProgressListener) args[1]; 226 listener.onStarted(userId, null); 227 listener.onFinished(userId, null); 228 return true; 229 }); 230 231 // Adding a fake Device Owner app which will enable escrow token support in LSS. 232 when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn( 233 new ComponentName("com.dummy.package", ".FakeDeviceOwner")); 234 when(mUserManagerInternal.isDeviceManaged()).thenReturn(true); 235 when(mDeviceStateCache.isUserOrganizationManaged(anyInt())).thenReturn(true); 236 when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true); 237 mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID); 238 mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID); 239 240 setDeviceProvisioned(true); 241 mLocalService = LocalServices.getService(LockSettingsInternal.class); 242 } 243 createMockResources()244 private Resources createMockResources() { 245 Resources res = mock(Resources.class); 246 247 // Set up some default configs, copied from core/res/res/values/config.xml 248 when(res.getBoolean(eq(com.android.internal.R.bool.config_disableLockscreenByDefault))) 249 .thenReturn(false); 250 when(res.getBoolean( 251 eq(com.android.internal.R.bool.config_enableCredentialFactoryResetProtection))) 252 .thenReturn(true); 253 when(res.getBoolean(eq(com.android.internal.R.bool.config_isMainUserPermanentAdmin))) 254 .thenReturn(true); 255 when(res.getBoolean(eq(com.android.internal.R.bool.config_strongAuthRequiredOnBoot))) 256 .thenReturn(true); 257 when(res.getBoolean(eq(com.android.internal.R.bool.config_repairModeSupported))) 258 .thenReturn(true); 259 return res; 260 } 261 setDeviceProvisioned(boolean provisioned)262 protected void setDeviceProvisioned(boolean provisioned) { 263 Settings.Global.putInt(mContext.getContentResolver(), 264 Settings.Global.DEVICE_PROVISIONED, provisioned ? 1 : 0); 265 } 266 setUserSetupComplete(boolean complete)267 protected void setUserSetupComplete(boolean complete) { 268 Settings.Secure.putIntForUser(mContext.getContentResolver(), 269 Settings.Secure.USER_SETUP_COMPLETE, complete ? 1 : 0, UserHandle.USER_SYSTEM); 270 } 271 setSecureFrpMode(boolean secure)272 protected void setSecureFrpMode(boolean secure) { 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.unlockUserKey(/* userId= */ (int) args[0], 308 /* secret= */ (byte[]) args[2]); 309 return null; 310 }).when(sm).unlockUserKey(anyInt(), anyInt(), any()); 311 312 doAnswer(invocation -> { 313 Object[] args = invocation.getArguments(); 314 mStorageManager.setUserKeyProtection(/* userId= */ (int) args[0], 315 /* secret= */ (byte[]) args[1]); 316 return null; 317 }).when(sm).setUserKeyProtection(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