blob: 537287d18cca55440f4380a4770ddfa2dd0ab11f [file] [log] [blame]
Rubin Xu0cbc19e2016-12-09 14:00:21 +00001/*
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
Andrew Scull507d11c2017-05-03 17:19:01 +010017package com.android.server.locksettings;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000018
19import static org.mockito.Matchers.any;
Rubin Xu7b7424b2017-03-31 18:03:20 +010020import static org.mockito.Matchers.anyBoolean;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000021import static org.mockito.Matchers.anyInt;
22import static org.mockito.Matchers.eq;
Rubin Xub31be1b2017-06-16 17:08:21 +010023import static org.mockito.Mockito.doAnswer;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000024import static org.mockito.Mockito.mock;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000025import static org.mockito.Mockito.when;
26
27import android.app.IActivityManager;
Andrew Scullf49794b2018-04-13 12:01:25 +010028import android.app.KeyguardManager;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000029import android.app.NotificationManager;
Rubin Xu8b30ec32017-03-05 00:47:09 +000030import android.app.admin.DevicePolicyManager;
Andrew Scull1416bd02018-01-05 18:33:58 +000031import android.app.admin.DevicePolicyManagerInternal;
Rubin Xu0f1e56d2019-08-23 13:34:25 +010032import android.app.admin.DeviceStateCache;
Rubin Xu16c823e2017-06-27 14:44:58 +010033import android.app.trust.TrustManager;
Rubin Xu8b30ec32017-03-05 00:47:09 +000034import android.content.ComponentName;
Alex Johnston6183cf92019-10-03 15:59:03 +010035import android.content.pm.PackageManager;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000036import android.content.pm.UserInfo;
Andrew Sculle6527c12018-01-05 18:33:58 +000037import android.hardware.authsecret.V1_0.IAuthSecret;
Rubin Xuf526a692019-10-14 11:42:41 +010038import android.hardware.face.Face;
Alex Johnston6183cf92019-10-03 15:59:03 +010039import android.hardware.face.FaceManager;
Rubin Xuf526a692019-10-14 11:42:41 +010040import android.hardware.fingerprint.Fingerprint;
Alex Johnston6183cf92019-10-03 15:59:03 +010041import android.hardware.fingerprint.FingerprintManager;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000042import android.os.FileUtils;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000043import android.os.IProgressListener;
Rubin Xub31be1b2017-06-16 17:08:21 +010044import android.os.RemoteException;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000045import android.os.UserManager;
Rubin Xu0f1e56d2019-08-23 13:34:25 +010046import android.os.UserManagerInternal;
Rubin Xub31be1b2017-06-16 17:08:21 +010047import android.os.storage.IStorageManager;
Lenka Trochtova66c492a2018-12-06 11:29:21 +010048import android.os.storage.StorageManager;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000049import android.security.KeyStore;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000050import android.test.AndroidTestCase;
51
Rubin Xu16c823e2017-06-27 14:44:58 +010052import com.android.internal.widget.ILockSettings;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000053import com.android.internal.widget.LockPatternUtils;
Rubin Xufcd49f92017-08-24 18:21:52 +010054import com.android.internal.widget.LockSettingsInternal;
Andrew Scull1416bd02018-01-05 18:33:58 +000055import com.android.server.LocalServices;
Annie Meng086ddc82019-03-29 17:43:35 +000056import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
Lenka Trochtova66c492a2018-12-06 11:29:21 +010057import com.android.server.wm.WindowManagerInternal;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000058
59import org.mockito.invocation.InvocationOnMock;
60import org.mockito.stubbing.Answer;
61
62import java.io.File;
Andrew Scull8e87af52017-03-03 15:38:48 +000063import java.util.ArrayList;
Charles Hedec05402017-04-21 13:45:34 +010064import java.util.Arrays;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000065
66
Pavel Grafov57f1b662019-03-27 14:55:38 +000067public abstract class BaseLockSettingsServiceTests extends AndroidTestCase {
Rubin Xu0cbc19e2016-12-09 14:00:21 +000068 protected static final int PRIMARY_USER_ID = 0;
69 protected static final int MANAGED_PROFILE_USER_ID = 12;
Andrew Scull8e87af52017-03-03 15:38:48 +000070 protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000071 protected static final int SECONDARY_USER_ID = 20;
72
73 private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
74 UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
Rubin Xu0cbc19e2016-12-09 14:00:21 +000075 private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
76 UserInfo.FLAG_INITIALIZED);
77
Andrew Scull8e87af52017-03-03 15:38:48 +000078 private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
79
Rubin Xu0cbc19e2016-12-09 14:00:21 +000080 LockSettingsService mService;
Rubin Xufcd49f92017-08-24 18:21:52 +010081 LockSettingsInternal mLocalService;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000082
83 MockLockSettingsContext mContext;
84 LockSettingsStorageTestable mStorage;
85
86 LockPatternUtils mLockPatternUtils;
Rubin Xu16c823e2017-06-27 14:44:58 +010087 FakeGateKeeperService mGateKeeperService;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000088 NotificationManager mNotificationManager;
89 UserManager mUserManager;
Rubin Xub31be1b2017-06-16 17:08:21 +010090 FakeStorageManager mStorageManager;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000091 IActivityManager mActivityManager;
Rubin Xu8b30ec32017-03-05 00:47:09 +000092 DevicePolicyManager mDevicePolicyManager;
Andrew Scull1416bd02018-01-05 18:33:58 +000093 DevicePolicyManagerInternal mDevicePolicyManagerInternal;
Rubin Xu0cbc19e2016-12-09 14:00:21 +000094 KeyStore mKeyStore;
Rubin Xu7b7424b2017-03-31 18:03:20 +010095 MockSyntheticPasswordManager mSpManager;
Andrew Sculle6527c12018-01-05 18:33:58 +000096 IAuthSecret mAuthSecretService;
Lenka Trochtova66c492a2018-12-06 11:29:21 +010097 WindowManagerInternal mMockWindowManager;
David Anderson6ebc25b2019-02-12 16:25:56 -080098 FakeGsiService mGsiService;
David Anderson28dea682019-02-20 13:37:51 -080099 PasswordSlotManagerTestable mPasswordSlotManager;
Annie Meng086ddc82019-03-29 17:43:35 +0000100 RecoverableKeyStoreManager mRecoverableKeyStoreManager;
Rubin Xu0f1e56d2019-08-23 13:34:25 +0100101 UserManagerInternal mUserManagerInternal;
102 DeviceStateCache mDeviceStateCache;
Alex Johnston6183cf92019-10-03 15:59:03 +0100103 FingerprintManager mFingerprintManager;
104 FaceManager mFaceManager;
105 PackageManager mPackageManager;
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100106 protected boolean mHasSecureLockScreen;
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000107
108 @Override
109 protected void setUp() throws Exception {
110 super.setUp();
111
Rubin Xu16c823e2017-06-27 14:44:58 +0100112 mGateKeeperService = new FakeGateKeeperService();
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000113 mNotificationManager = mock(NotificationManager.class);
114 mUserManager = mock(UserManager.class);
Rubin Xub31be1b2017-06-16 17:08:21 +0100115 mStorageManager = new FakeStorageManager();
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000116 mActivityManager = mock(IActivityManager.class);
Rubin Xu8b30ec32017-03-05 00:47:09 +0000117 mDevicePolicyManager = mock(DevicePolicyManager.class);
Andrew Scull1416bd02018-01-05 18:33:58 +0000118 mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class);
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100119 mMockWindowManager = mock(WindowManagerInternal.class);
David Anderson6ebc25b2019-02-12 16:25:56 -0800120 mGsiService = new FakeGsiService();
David Anderson28dea682019-02-20 13:37:51 -0800121 mPasswordSlotManager = new PasswordSlotManagerTestable();
Annie Meng086ddc82019-03-29 17:43:35 +0000122 mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class);
Rubin Xu0f1e56d2019-08-23 13:34:25 +0100123 mUserManagerInternal = mock(UserManagerInternal.class);
124 mDeviceStateCache = mock(DeviceStateCache.class);
Alex Johnston6183cf92019-10-03 15:59:03 +0100125 mFingerprintManager = mock(FingerprintManager.class);
126 mFaceManager = mock(FaceManager.class);
127 mPackageManager = mock(PackageManager.class);
Andrew Scull1416bd02018-01-05 18:33:58 +0000128
Rubin Xufcd49f92017-08-24 18:21:52 +0100129 LocalServices.removeServiceForTest(LockSettingsInternal.class);
Andrew Scull1416bd02018-01-05 18:33:58 +0000130 LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100131 LocalServices.removeServiceForTest(WindowManagerInternal.class);
Andrew Scull1416bd02018-01-05 18:33:58 +0000132 LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal);
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100133 LocalServices.addService(WindowManagerInternal.class, mMockWindowManager);
Rubin Xu7b7424b2017-03-31 18:03:20 +0100134
Rubin Xu8b30ec32017-03-05 00:47:09 +0000135 mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
Andrew Scullf49794b2018-04-13 12:01:25 +0100136 mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class),
Alex Johnston6183cf92019-10-03 15:59:03 +0100137 mock(KeyguardManager.class), mFingerprintManager, mFaceManager, mPackageManager);
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000138 mStorage = new LockSettingsStorageTestable(mContext,
139 new File(getContext().getFilesDir(), "locksettings"));
140 File storageDir = mStorage.mStorageDir;
141 if (storageDir.exists()) {
142 FileUtils.deleteContents(storageDir);
143 } else {
144 storageDir.mkdirs();
145 }
146
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100147 mHasSecureLockScreen = true;
Rubin Xu16c823e2017-06-27 14:44:58 +0100148 mLockPatternUtils = new LockPatternUtils(mContext) {
149 @Override
150 public ILockSettings getLockSettings() {
151 return mService;
152 }
Lenka Trochtova66c492a2018-12-06 11:29:21 +0100153
154 @Override
155 public boolean hasSecureLockScreen() {
156 return mHasSecureLockScreen;
157 }
Rubin Xu16c823e2017-06-27 14:44:58 +0100158 };
Adrian Roos2adc2632017-09-05 17:01:42 +0200159 mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService,
David Anderson28dea682019-02-20 13:37:51 -0800160 mUserManager, mPasswordSlotManager);
Andrew Sculle6527c12018-01-05 18:33:58 +0000161 mAuthSecretService = mock(IAuthSecret.class);
Rubin Xub31be1b2017-06-16 17:08:21 +0100162 mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils, mStorage,
163 mGateKeeperService, mKeyStore, setUpStorageManagerMock(), mActivityManager,
Rubin Xu0f1e56d2019-08-23 13:34:25 +0100164 mSpManager, mAuthSecretService, mGsiService, mRecoverableKeyStoreManager,
165 mUserManagerInternal, mDeviceStateCache);
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000166 when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
Andrew Scull8e87af52017-03-03 15:38:48 +0000167 mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
168 installChildProfile(MANAGED_PROFILE_USER_ID);
Charles Hedec05402017-04-21 13:45:34 +0100169 installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
Annie Meng086ddc82019-03-29 17:43:35 +0000170 for (UserInfo profile : mPrimaryUserProfiles) {
171 when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles);
172 }
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000173 when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
174
Andrew Sculle6527c12018-01-05 18:33:58 +0000175 final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
176 allUsers.add(SECONDARY_USER_INFO);
177 when(mUserManager.getUsers(anyBoolean())).thenReturn(allUsers);
178
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000179 when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
180 new Answer<Boolean>() {
181 @Override
182 public Boolean answer(InvocationOnMock invocation) throws Throwable {
183 Object[] args = invocation.getArguments();
184 mStorageManager.unlockUser((int)args[0], (byte[])args[2],
185 (IProgressListener) args[3]);
186 return true;
187 }
188 });
189
Rubin Xu8b30ec32017-03-05 00:47:09 +0000190 // Adding a fake Device Owner app which will enable escrow token support in LSS.
191 when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
192 new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
Rubin Xu0f1e56d2019-08-23 13:34:25 +0100193 when(mUserManagerInternal.isDeviceManaged()).thenReturn(true);
194 when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true);
Alex Johnston6183cf92019-10-03 15:59:03 +0100195 mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID);
196 mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID);
Rubin Xu0f1e56d2019-08-23 13:34:25 +0100197
Rubin Xufcd49f92017-08-24 18:21:52 +0100198 mLocalService = LocalServices.getService(LockSettingsInternal.class);
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000199 }
200
Andrew Scull8e87af52017-03-03 15:38:48 +0000201 private UserInfo installChildProfile(int profileId) {
202 final UserInfo userInfo = new UserInfo(
203 profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
Annie Meng086ddc82019-03-29 17:43:35 +0000204 userInfo.profileGroupId = PRIMARY_USER_ID;
Andrew Scull8e87af52017-03-03 15:38:48 +0000205 mPrimaryUserProfiles.add(userInfo);
206 when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
207 when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
Charles Hedec05402017-04-21 13:45:34 +0100208 when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
209 when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
Rubin Xu0f1e56d2019-08-23 13:34:25 +0100210 when(mUserManagerInternal.isUserManaged(eq(profileId))).thenReturn(true);
Andrew Scull8e87af52017-03-03 15:38:48 +0000211 return userInfo;
212 }
213
Charles Hedec05402017-04-21 13:45:34 +0100214 private UserInfo installAndTurnOffChildProfile(int profileId) {
Andrew Scull8e87af52017-03-03 15:38:48 +0000215 final UserInfo userInfo = installChildProfile(profileId);
216 userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
Charles Hedec05402017-04-21 13:45:34 +0100217 when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
218 when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
Andrew Scull8e87af52017-03-03 15:38:48 +0000219 return userInfo;
220 }
221
Rubin Xub31be1b2017-06-16 17:08:21 +0100222 private IStorageManager setUpStorageManagerMock() throws RemoteException {
223 final IStorageManager sm = mock(IStorageManager.class);
224
225 doAnswer(new Answer<Void>() {
226 @Override
227 public Void answer(InvocationOnMock invocation) throws Throwable {
228 Object[] args = invocation.getArguments();
229 mStorageManager.addUserKeyAuth((int) args[0] /* userId */,
230 (int) args[1] /* serialNumber */,
231 (byte[]) args[2] /* token */,
232 (byte[]) args[3] /* secret */);
233 return null;
234 }
235 }).when(sm).addUserKeyAuth(anyInt(), anyInt(), any(), any());
236
237 doAnswer(
238 new Answer<Void>() {
239 @Override
240 public Void answer(InvocationOnMock invocation) throws Throwable {
241 Object[] args = invocation.getArguments();
242 mStorageManager.fixateNewestUserKeyAuth((int) args[0] /* userId */);
243 return null;
244 }
245 }).when(sm).fixateNewestUserKeyAuth(anyInt());
246 return sm;
247 }
248
Alex Johnston6183cf92019-10-03 15:59:03 +0100249 private void mockBiometricsHardwareFingerprintsAndTemplates(int userId) {
250 // Hardware must be detected and fingerprints must be enrolled
251 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
252 when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
253 when(mFingerprintManager.hasEnrolledFingerprints(userId)).thenReturn(true);
Rubin Xuf526a692019-10-14 11:42:41 +0100254 doAnswer(new Answer<Void>() {
255 @Override
256 public Void answer(InvocationOnMock invocation) throws Throwable {
257 Fingerprint fp = (Fingerprint) invocation.getArguments()[0];
258 FingerprintManager.RemovalCallback callback =
259 (FingerprintManager.RemovalCallback) invocation.getArguments()[2];
260 callback.onRemovalSucceeded(fp, 0);
261 return null;
262 }
263 }).when(mFingerprintManager).remove(any(), eq(userId), any());
264
Alex Johnston6183cf92019-10-03 15:59:03 +0100265
266 // Hardware must be detected and templates must be enrolled
267 when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
268 when(mFaceManager.isHardwareDetected()).thenReturn(true);
269 when(mFaceManager.hasEnrolledTemplates(userId)).thenReturn(true);
Rubin Xuf526a692019-10-14 11:42:41 +0100270 doAnswer(new Answer<Void>() {
271 @Override
272 public Void answer(InvocationOnMock invocation) throws Throwable {
273 Face face = (Face) invocation.getArguments()[0];
274 FaceManager.RemovalCallback callback =
275 (FaceManager.RemovalCallback) invocation.getArguments()[2];
276 callback.onRemovalSucceeded(face, 0);
277 return null;
278 }
279 }).when(mFaceManager).remove(any(), eq(userId), any());
Alex Johnston6183cf92019-10-03 15:59:03 +0100280 }
281
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000282 @Override
283 protected void tearDown() throws Exception {
284 super.tearDown();
285 mStorage.closeDatabase();
286 File db = getContext().getDatabasePath("locksettings.db");
287 assertTrue(!db.exists() || db.delete());
288
289 File storageDir = mStorage.mStorageDir;
290 assertTrue(FileUtils.deleteContents(storageDir));
David Anderson28dea682019-02-20 13:37:51 -0800291
292 mPasswordSlotManager.cleanup();
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000293 }
Rubin Xu3bf722a2016-12-15 16:07:38 +0000294
Rubin Xu340e5ba2019-05-14 16:10:03 +0100295 protected void flushHandlerTasks() {
296 mService.mHandler.runWithScissors(() -> { }, 0 /*now*/); // Flush runnables on handler
297 }
298
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000299 protected void assertNotEquals(long expected, long actual) {
300 assertTrue(expected != actual);
301 }
302
Rubin Xu3bf722a2016-12-15 16:07:38 +0000303 protected static void assertArrayEquals(byte[] expected, byte[] actual) {
304 assertTrue(Arrays.equals(expected, actual));
305 }
306
Andrew Scull7f4ff4c2018-01-05 18:33:58 +0000307 protected static void assertArrayNotEquals(byte[] expected, byte[] actual) {
Rubin Xu3bf722a2016-12-15 16:07:38 +0000308 assertFalse(Arrays.equals(expected, actual));
309 }
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000310}