• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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