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.pm.PackageManager; 37 import android.content.pm.UserInfo; 38 import android.hardware.authsecret.V1_0.IAuthSecret; 39 import android.hardware.face.FaceManager; 40 import android.hardware.fingerprint.FingerprintManager; 41 import android.os.FileUtils; 42 import android.os.IProgressListener; 43 import android.os.RemoteException; 44 import android.os.UserManager; 45 import android.os.storage.IStorageManager; 46 import android.os.storage.StorageManager; 47 import android.security.KeyStore; 48 49 import androidx.test.InstrumentationRegistry; 50 import androidx.test.runner.AndroidJUnit4; 51 52 import com.android.internal.widget.LockPatternUtils; 53 import com.android.internal.widget.LockSettingsInternal; 54 import com.android.internal.widget.LockscreenCredential; 55 import com.android.server.LocalServices; 56 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager; 57 import com.android.server.pm.UserManagerInternal; 58 import com.android.server.wm.WindowManagerInternal; 59 60 import org.junit.After; 61 import org.junit.Before; 62 import org.junit.runner.RunWith; 63 import org.mockito.invocation.InvocationOnMock; 64 import org.mockito.stubbing.Answer; 65 66 import java.io.File; 67 import java.util.ArrayList; 68 import java.util.Arrays; 69 70 @RunWith(AndroidJUnit4.class) 71 public abstract class BaseLockSettingsServiceTests { 72 protected static final int PRIMARY_USER_ID = 0; 73 protected static final int MANAGED_PROFILE_USER_ID = 12; 74 protected static final int TURNED_OFF_PROFILE_USER_ID = 17; 75 protected static final int SECONDARY_USER_ID = 20; 76 77 private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null, 78 UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY); 79 private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null, 80 UserInfo.FLAG_INITIALIZED); 81 82 private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>(); 83 84 LockSettingsService mService; 85 LockSettingsInternal mLocalService; 86 87 MockLockSettingsContext mContext; 88 LockSettingsStorageTestable mStorage; 89 90 FakeGateKeeperService mGateKeeperService; 91 NotificationManager mNotificationManager; 92 UserManager mUserManager; 93 FakeStorageManager mStorageManager; 94 IActivityManager mActivityManager; 95 DevicePolicyManager mDevicePolicyManager; 96 DevicePolicyManagerInternal mDevicePolicyManagerInternal; 97 KeyStore mKeyStore; 98 MockSyntheticPasswordManager mSpManager; 99 IAuthSecret mAuthSecretService; 100 WindowManagerInternal mMockWindowManager; 101 FakeGsiService mGsiService; 102 PasswordSlotManagerTestable mPasswordSlotManager; 103 RecoverableKeyStoreManager mRecoverableKeyStoreManager; 104 UserManagerInternal mUserManagerInternal; 105 DeviceStateCache mDeviceStateCache; 106 FingerprintManager mFingerprintManager; 107 FaceManager mFaceManager; 108 PackageManager mPackageManager; 109 FakeSettings mSettings; 110 111 @Before setUp_baseServices()112 public void setUp_baseServices() throws Exception { 113 mGateKeeperService = new FakeGateKeeperService(); 114 mNotificationManager = mock(NotificationManager.class); 115 mUserManager = mock(UserManager.class); 116 mStorageManager = new FakeStorageManager(); 117 mActivityManager = mock(IActivityManager.class); 118 mDevicePolicyManager = mock(DevicePolicyManager.class); 119 mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class); 120 mMockWindowManager = mock(WindowManagerInternal.class); 121 mGsiService = new FakeGsiService(); 122 mPasswordSlotManager = new PasswordSlotManagerTestable(); 123 mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class); 124 mUserManagerInternal = mock(UserManagerInternal.class); 125 mDeviceStateCache = mock(DeviceStateCache.class); 126 mFingerprintManager = mock(FingerprintManager.class); 127 mFaceManager = mock(FaceManager.class); 128 mPackageManager = mock(PackageManager.class); 129 mSettings = new FakeSettings(); 130 131 LocalServices.removeServiceForTest(LockSettingsInternal.class); 132 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); 133 LocalServices.removeServiceForTest(WindowManagerInternal.class); 134 LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal); 135 LocalServices.addService(WindowManagerInternal.class, mMockWindowManager); 136 137 mContext = new MockLockSettingsContext(InstrumentationRegistry.getContext(), mUserManager, 138 mNotificationManager, mDevicePolicyManager, mock(StorageManager.class), 139 mock(TrustManager.class), mock(KeyguardManager.class), mFingerprintManager, 140 mFaceManager, mPackageManager); 141 mStorage = new LockSettingsStorageTestable(mContext, 142 new File(InstrumentationRegistry.getContext().getFilesDir(), "locksettings")); 143 File storageDir = mStorage.mStorageDir; 144 if (storageDir.exists()) { 145 FileUtils.deleteContents(storageDir); 146 } else { 147 storageDir.mkdirs(); 148 } 149 150 mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService, 151 mUserManager, mPasswordSlotManager); 152 mAuthSecretService = mock(IAuthSecret.class); 153 mService = new LockSettingsServiceTestable(mContext, mStorage, 154 mGateKeeperService, mKeyStore, setUpStorageManagerMock(), mActivityManager, 155 mSpManager, mAuthSecretService, mGsiService, mRecoverableKeyStoreManager, 156 mUserManagerInternal, mDeviceStateCache, mSettings); 157 mService.mHasSecureLockScreen = true; 158 when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO); 159 mPrimaryUserProfiles.add(PRIMARY_USER_INFO); 160 installChildProfile(MANAGED_PROFILE_USER_ID); 161 installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID); 162 for (UserInfo profile : mPrimaryUserProfiles) { 163 when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles); 164 } 165 when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO); 166 167 final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles); 168 allUsers.add(SECONDARY_USER_INFO); 169 when(mUserManager.getUsers()).thenReturn(allUsers); 170 171 when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer( 172 new Answer<Boolean>() { 173 @Override 174 public Boolean answer(InvocationOnMock invocation) throws Throwable { 175 Object[] args = invocation.getArguments(); 176 mStorageManager.unlockUser((int)args[0], (byte[])args[2], 177 (IProgressListener) args[3]); 178 return true; 179 } 180 }); 181 182 // Adding a fake Device Owner app which will enable escrow token support in LSS. 183 when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn( 184 new ComponentName("com.dummy.package", ".FakeDeviceOwner")); 185 when(mUserManagerInternal.isDeviceManaged()).thenReturn(true); 186 when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true); 187 mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID); 188 mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID); 189 190 mSettings.setDeviceProvisioned(true); 191 mLocalService = LocalServices.getService(LockSettingsInternal.class); 192 } 193 installChildProfile(int profileId)194 private UserInfo installChildProfile(int profileId) { 195 final UserInfo userInfo = new UserInfo( 196 profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE); 197 userInfo.profileGroupId = PRIMARY_USER_ID; 198 mPrimaryUserProfiles.add(userInfo); 199 when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo); 200 when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO); 201 when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true); 202 when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true); 203 when(mUserManagerInternal.isUserManaged(eq(profileId))).thenReturn(true); 204 return userInfo; 205 } 206 installAndTurnOffChildProfile(int profileId)207 private UserInfo installAndTurnOffChildProfile(int profileId) { 208 final UserInfo userInfo = installChildProfile(profileId); 209 userInfo.flags |= UserInfo.FLAG_QUIET_MODE; 210 when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false); 211 when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false); 212 return userInfo; 213 } 214 setUpStorageManagerMock()215 private IStorageManager setUpStorageManagerMock() throws RemoteException { 216 final IStorageManager sm = mock(IStorageManager.class); 217 218 doAnswer(new Answer<Void>() { 219 @Override 220 public Void answer(InvocationOnMock invocation) throws Throwable { 221 Object[] args = invocation.getArguments(); 222 mStorageManager.addUserKeyAuth((int) args[0] /* userId */, 223 (int) args[1] /* serialNumber */, 224 (byte[]) args[2] /* token */, 225 (byte[]) args[3] /* secret */); 226 return null; 227 } 228 }).when(sm).addUserKeyAuth(anyInt(), anyInt(), any(), any()); 229 230 doAnswer(new Answer<Void>() { 231 @Override 232 public Void answer(InvocationOnMock invocation) throws Throwable { 233 Object[] args = invocation.getArguments(); 234 mStorageManager.clearUserKeyAuth((int) args[0] /* userId */, 235 (int) args[1] /* serialNumber */, 236 (byte[]) args[2] /* token */, 237 (byte[]) args[3] /* secret */); 238 return null; 239 } 240 }).when(sm).clearUserKeyAuth(anyInt(), anyInt(), any(), any()); 241 242 doAnswer( 243 new Answer<Void>() { 244 @Override 245 public Void answer(InvocationOnMock invocation) throws Throwable { 246 Object[] args = invocation.getArguments(); 247 mStorageManager.fixateNewestUserKeyAuth((int) args[0] /* userId */); 248 return null; 249 } 250 }).when(sm).fixateNewestUserKeyAuth(anyInt()); 251 return sm; 252 } 253 mockBiometricsHardwareFingerprintsAndTemplates(int userId)254 private void mockBiometricsHardwareFingerprintsAndTemplates(int userId) { 255 // Hardware must be detected and fingerprints must be enrolled 256 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true); 257 when(mFingerprintManager.isHardwareDetected()).thenReturn(true); 258 when(mFingerprintManager.hasEnrolledFingerprints(userId)).thenReturn(true); 259 doAnswer(new Answer<Void>() { 260 @Override 261 public Void answer(InvocationOnMock invocation) throws Throwable { 262 FingerprintManager.RemovalCallback callback = 263 (FingerprintManager.RemovalCallback) invocation.getArguments()[1]; 264 callback.onRemovalSucceeded(null, 0); 265 return null; 266 } 267 }).when(mFingerprintManager).removeAll(eq(userId), any()); 268 269 270 // Hardware must be detected and templates must be enrolled 271 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true); 272 when(mFaceManager.isHardwareDetected()).thenReturn(true); 273 when(mFaceManager.hasEnrolledTemplates(userId)).thenReturn(true); 274 doAnswer(new Answer<Void>() { 275 @Override 276 public Void answer(InvocationOnMock invocation) throws Throwable { 277 FaceManager.RemovalCallback callback = 278 (FaceManager.RemovalCallback) invocation.getArguments()[1]; 279 callback.onRemovalSucceeded(null, 0); 280 return null; 281 } 282 }).when(mFaceManager).removeAll(eq(userId), any()); 283 } 284 285 @After tearDown_baseServices()286 public void tearDown_baseServices() throws Exception { 287 mStorage.closeDatabase(); 288 File db = InstrumentationRegistry.getContext().getDatabasePath("locksettings.db"); 289 assertTrue(!db.exists() || db.delete()); 290 291 File storageDir = mStorage.mStorageDir; 292 assertTrue(FileUtils.deleteContents(storageDir)); 293 294 mPasswordSlotManager.cleanup(); 295 } 296 flushHandlerTasks()297 protected void flushHandlerTasks() { 298 mService.mHandler.runWithScissors(() -> { }, 0 /*now*/); // Flush runnables on handler 299 } 300 assertNotEquals(long expected, long actual)301 protected void assertNotEquals(long expected, long actual) { 302 assertTrue(expected != actual); 303 } 304 assertArrayEquals(byte[] expected, byte[] actual)305 protected static void assertArrayEquals(byte[] expected, byte[] actual) { 306 assertTrue(Arrays.equals(expected, actual)); 307 } 308 assertArrayNotEquals(byte[] expected, byte[] actual)309 protected static void assertArrayNotEquals(byte[] expected, byte[] actual) { 310 assertFalse(Arrays.equals(expected, actual)); 311 } 312 newPassword(String password)313 protected LockscreenCredential newPassword(String password) { 314 return LockscreenCredential.createPasswordOrNone(password); 315 } 316 newPin(String pin)317 protected LockscreenCredential newPin(String pin) { 318 return LockscreenCredential.createPinOrNone(pin); 319 } 320 newPattern(String pattern)321 protected LockscreenCredential newPattern(String pattern) { 322 return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern( 323 pattern.getBytes())); 324 } 325 nonePassword()326 protected LockscreenCredential nonePassword() { 327 return LockscreenCredential.createNone(); 328 } 329 330 } 331