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] /* secret */); 225 return null; 226 } 227 }).when(sm).addUserKeyAuth(anyInt(), anyInt(), any()); 228 229 doAnswer(new Answer<Void>() { 230 @Override 231 public Void answer(InvocationOnMock invocation) throws Throwable { 232 Object[] args = invocation.getArguments(); 233 mStorageManager.clearUserKeyAuth((int) args[0] /* userId */, 234 (int) args[1] /* serialNumber */, 235 (byte[]) args[2] /* secret */); 236 return null; 237 } 238 }).when(sm).clearUserKeyAuth(anyInt(), anyInt(), any()); 239 240 doAnswer( 241 new Answer<Void>() { 242 @Override 243 public Void answer(InvocationOnMock invocation) throws Throwable { 244 Object[] args = invocation.getArguments(); 245 mStorageManager.fixateNewestUserKeyAuth((int) args[0] /* userId */); 246 return null; 247 } 248 }).when(sm).fixateNewestUserKeyAuth(anyInt()); 249 return sm; 250 } 251 mockBiometricsHardwareFingerprintsAndTemplates(int userId)252 private void mockBiometricsHardwareFingerprintsAndTemplates(int userId) { 253 // Hardware must be detected and fingerprints must be enrolled 254 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true); 255 when(mFingerprintManager.isHardwareDetected()).thenReturn(true); 256 when(mFingerprintManager.hasEnrolledFingerprints(userId)).thenReturn(true); 257 doAnswer(new Answer<Void>() { 258 @Override 259 public Void answer(InvocationOnMock invocation) throws Throwable { 260 FingerprintManager.RemovalCallback callback = 261 (FingerprintManager.RemovalCallback) invocation.getArguments()[1]; 262 callback.onRemovalSucceeded(null, 0); 263 return null; 264 } 265 }).when(mFingerprintManager).removeAll(eq(userId), any()); 266 267 268 // Hardware must be detected and templates must be enrolled 269 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true); 270 when(mFaceManager.isHardwareDetected()).thenReturn(true); 271 when(mFaceManager.hasEnrolledTemplates(userId)).thenReturn(true); 272 doAnswer(new Answer<Void>() { 273 @Override 274 public Void answer(InvocationOnMock invocation) throws Throwable { 275 FaceManager.RemovalCallback callback = 276 (FaceManager.RemovalCallback) invocation.getArguments()[1]; 277 callback.onRemovalSucceeded(null, 0); 278 return null; 279 } 280 }).when(mFaceManager).removeAll(eq(userId), any()); 281 } 282 283 @After tearDown_baseServices()284 public void tearDown_baseServices() throws Exception { 285 mStorage.closeDatabase(); 286 File db = InstrumentationRegistry.getContext().getDatabasePath("locksettings.db"); 287 assertTrue(!db.exists() || db.delete()); 288 289 File storageDir = mStorage.mStorageDir; 290 assertTrue(FileUtils.deleteContents(storageDir)); 291 292 mPasswordSlotManager.cleanup(); 293 } 294 flushHandlerTasks()295 protected void flushHandlerTasks() { 296 mService.mHandler.runWithScissors(() -> { }, 0 /*now*/); // Flush runnables on handler 297 } 298 assertNotEquals(long expected, long actual)299 protected void assertNotEquals(long expected, long actual) { 300 assertTrue(expected != actual); 301 } 302 assertArrayEquals(byte[] expected, byte[] actual)303 protected static void assertArrayEquals(byte[] expected, byte[] actual) { 304 assertTrue(Arrays.equals(expected, actual)); 305 } 306 assertArrayNotEquals(byte[] expected, byte[] actual)307 protected static void assertArrayNotEquals(byte[] expected, byte[] actual) { 308 assertFalse(Arrays.equals(expected, actual)); 309 } 310 newPassword(String password)311 protected LockscreenCredential newPassword(String password) { 312 return LockscreenCredential.createPasswordOrNone(password); 313 } 314 newPin(String pin)315 protected LockscreenCredential newPin(String pin) { 316 return LockscreenCredential.createPinOrNone(pin); 317 } 318 newPattern(String pattern)319 protected LockscreenCredential newPattern(String pattern) { 320 return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern( 321 pattern.getBytes())); 322 } 323 nonePassword()324 protected LockscreenCredential nonePassword() { 325 return LockscreenCredential.createNone(); 326 } 327 328 } 329