• 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] /* 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