• 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.Context;
37 import android.content.pm.PackageManager;
38 import android.content.pm.UserInfo;
39 import android.content.res.Resources;
40 import android.hardware.authsecret.IAuthSecret;
41 import android.hardware.face.FaceManager;
42 import android.hardware.fingerprint.FingerprintManager;
43 import android.os.FileUtils;
44 import android.os.IProgressListener;
45 import android.os.RemoteException;
46 import android.os.UserHandle;
47 import android.os.UserManager;
48 import android.os.storage.IStorageManager;
49 import android.os.storage.StorageManager;
50 import android.provider.Settings;
51 
52 import androidx.test.InstrumentationRegistry;
53 import androidx.test.runner.AndroidJUnit4;
54 
55 import com.android.internal.util.test.FakeSettingsProvider;
56 import com.android.internal.util.test.FakeSettingsProviderRule;
57 import com.android.internal.widget.LockPatternUtils;
58 import com.android.internal.widget.LockSettingsInternal;
59 import com.android.internal.widget.LockscreenCredential;
60 import com.android.server.LocalServices;
61 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
62 import com.android.server.pm.UserManagerInternal;
63 import com.android.server.wm.WindowManagerInternal;
64 
65 import org.junit.After;
66 import org.junit.Before;
67 import org.junit.Rule;
68 import org.junit.runner.RunWith;
69 import org.mockito.invocation.InvocationOnMock;
70 import org.mockito.stubbing.Answer;
71 
72 import java.io.File;
73 import java.util.ArrayList;
74 import java.util.Arrays;
75 
76 @RunWith(AndroidJUnit4.class)
77 public abstract class BaseLockSettingsServiceTests {
78     protected static final int PRIMARY_USER_ID = 0;
79     protected static final int MANAGED_PROFILE_USER_ID = 12;
80     protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
81     protected static final int SECONDARY_USER_ID = 20;
82     protected static final int TERTIARY_USER_ID = 21;
83 
84     protected UserInfo mPrimaryUserInfo;
85     protected UserInfo mSecondaryUserInfo;
86     protected UserInfo mTertiaryUserInfo;
87 
88     private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
89 
90     LockSettingsServiceTestable mService;
91     LockSettingsInternal mLocalService;
92 
93     MockLockSettingsContext mContext;
94     LockSettingsStorageTestable mStorage;
95     LockSettingsStrongAuth mStrongAuth;
96 
97     Resources mResources;
98     FakeGateKeeperService mGateKeeperService;
99     NotificationManager mNotificationManager;
100     UserManager mUserManager;
101     FakeStorageManager mStorageManager;
102     IActivityManager mActivityManager;
103     DevicePolicyManager mDevicePolicyManager;
104     DevicePolicyManagerInternal mDevicePolicyManagerInternal;
105     MockSyntheticPasswordManager mSpManager;
106     IAuthSecret mAuthSecretService;
107     WindowManagerInternal mMockWindowManager;
108     FakeGsiService mGsiService;
109     PasswordSlotManagerTestable mPasswordSlotManager;
110     RecoverableKeyStoreManager mRecoverableKeyStoreManager;
111     UserManagerInternal mUserManagerInternal;
112     DeviceStateCache mDeviceStateCache;
113     FingerprintManager mFingerprintManager;
114     FaceManager mFaceManager;
115     PackageManager mPackageManager;
116     LockSettingsServiceTestable.MockInjector mInjector;
117     @Rule
118     public FakeSettingsProviderRule mSettingsRule = FakeSettingsProvider.rule();
119 
120     @Before
setUp_baseServices()121     public void setUp_baseServices() throws Exception {
122         mResources = createMockResources();
123         mGateKeeperService = new FakeGateKeeperService();
124         mNotificationManager = mock(NotificationManager.class);
125         mUserManager = mock(UserManager.class);
126         mStorageManager = new FakeStorageManager();
127         mActivityManager = mock(IActivityManager.class);
128         mDevicePolicyManager = mock(DevicePolicyManager.class);
129         mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class);
130         mMockWindowManager = mock(WindowManagerInternal.class);
131         mGsiService = new FakeGsiService();
132         mPasswordSlotManager = new PasswordSlotManagerTestable();
133         mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class);
134         mUserManagerInternal = mock(UserManagerInternal.class);
135         mDeviceStateCache = mock(DeviceStateCache.class);
136         mFingerprintManager = mock(FingerprintManager.class);
137         mFaceManager = mock(FaceManager.class);
138         mPackageManager = mock(PackageManager.class);
139         mStrongAuth = mock(LockSettingsStrongAuth.class);
140 
141         LocalServices.removeServiceForTest(LockSettingsInternal.class);
142         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
143         LocalServices.removeServiceForTest(WindowManagerInternal.class);
144         LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal);
145         LocalServices.addService(WindowManagerInternal.class, mMockWindowManager);
146 
147         final Context origContext = InstrumentationRegistry.getContext();
148         mContext = new MockLockSettingsContext(origContext, mResources,
149                 mSettingsRule.mockContentResolver(origContext), mUserManager, mNotificationManager,
150                 mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class),
151                 mock(KeyguardManager.class), mFingerprintManager, mFaceManager, mPackageManager);
152         mStorage = new LockSettingsStorageTestable(mContext,
153                 new File(origContext.getFilesDir(), "locksettings"));
154         File storageDir = mStorage.mStorageDir;
155         if (storageDir.exists()) {
156             FileUtils.deleteContents(storageDir);
157         } else {
158             storageDir.mkdirs();
159         }
160 
161         mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService,
162                 mUserManager, mPasswordSlotManager);
163         mAuthSecretService = mock(IAuthSecret.class);
164         mInjector =
165                 new LockSettingsServiceTestable.MockInjector(
166                         mContext,
167                         mStorage, mStrongAuth,
168                         mActivityManager,
169                         setUpStorageManagerMock(),
170                         mSpManager,
171                         mGsiService,
172                         mRecoverableKeyStoreManager,
173                         mUserManagerInternal,
174                         mDeviceStateCache);
175         mService =
176                 new LockSettingsServiceTestable(mInjector, mGateKeeperService, mAuthSecretService);
177         mService.mHasSecureLockScreen = true;
178         mPrimaryUserInfo =
179                 new UserInfo(
180                         PRIMARY_USER_ID,
181                         null,
182                         null,
183                         UserInfo.FLAG_INITIALIZED
184                                 | UserInfo.FLAG_ADMIN
185                                 | UserInfo.FLAG_PRIMARY
186                                 | UserInfo.FLAG_MAIN
187                                 | UserInfo.FLAG_FULL);
188         mSecondaryUserInfo =
189                 new UserInfo(
190                         SECONDARY_USER_ID,
191                         null,
192                         null,
193                         UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL);
194         mTertiaryUserInfo =
195                 new UserInfo(
196                         TERTIARY_USER_ID,
197                         null,
198                         null,
199                         UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_FULL);
200 
201         when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo);
202         when(mUserManagerInternal.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserInfo);
203         mPrimaryUserProfiles.add(mPrimaryUserInfo);
204         installChildProfile(MANAGED_PROFILE_USER_ID);
205         installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
206         for (UserInfo profile : mPrimaryUserProfiles) {
207             when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles);
208         }
209         when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(mSecondaryUserInfo);
210         when(mUserManagerInternal.getUserInfo(eq(SECONDARY_USER_ID)))
211                 .thenReturn(mSecondaryUserInfo);
212         when(mUserManager.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo);
213         when(mUserManagerInternal.getUserInfo(eq(TERTIARY_USER_ID))).thenReturn(mTertiaryUserInfo);
214 
215         final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
216         allUsers.add(mSecondaryUserInfo);
217         allUsers.add(mTertiaryUserInfo);
218         when(mUserManager.getUsers()).thenReturn(allUsers);
219 
220         when(mActivityManager.unlockUser2(anyInt(), any())).thenAnswer(
221             invocation -> {
222                 Object[] args = invocation.getArguments();
223                 int userId = (int) args[0];
224                 IProgressListener listener = (IProgressListener) args[1];
225                 listener.onStarted(userId, null);
226                 listener.onFinished(userId, null);
227                 return true;
228             });
229 
230         // Adding a fake Device Owner app which will enable escrow token support in LSS.
231         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
232                 new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
233         when(mUserManagerInternal.isDeviceManaged()).thenReturn(true);
234         when(mDeviceStateCache.isUserOrganizationManaged(anyInt())).thenReturn(true);
235         when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true);
236         mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID);
237         mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID);
238 
239         setDeviceProvisioned(true);
240         mLocalService = LocalServices.getService(LockSettingsInternal.class);
241     }
242 
createMockResources()243     private Resources createMockResources() {
244         Resources res = mock(Resources.class);
245 
246         // Set up some default configs, copied from core/res/res/values/config.xml
247         when(res.getBoolean(eq(com.android.internal.R.bool.config_disableLockscreenByDefault)))
248                 .thenReturn(false);
249         when(res.getBoolean(
250                 eq(com.android.internal.R.bool.config_enableCredentialFactoryResetProtection)))
251                 .thenReturn(true);
252         when(res.getBoolean(eq(com.android.internal.R.bool.config_isMainUserPermanentAdmin)))
253                 .thenReturn(true);
254         when(res.getBoolean(eq(com.android.internal.R.bool.config_strongAuthRequiredOnBoot)))
255                 .thenReturn(true);
256         when(res.getBoolean(eq(com.android.internal.R.bool.config_repairModeSupported)))
257                 .thenReturn(true);
258         return res;
259     }
260 
setDeviceProvisioned(boolean provisioned)261     protected void setDeviceProvisioned(boolean provisioned) {
262         Settings.Global.putInt(mContext.getContentResolver(),
263                 Settings.Global.DEVICE_PROVISIONED, provisioned ? 1 : 0);
264     }
265 
setUserSetupComplete(boolean complete)266     protected void setUserSetupComplete(boolean complete) {
267         Settings.Secure.putIntForUser(mContext.getContentResolver(),
268                 Settings.Secure.USER_SETUP_COMPLETE, complete ? 1 : 0, UserHandle.USER_SYSTEM);
269     }
270 
setSecureFrpMode(boolean secure)271     protected void setSecureFrpMode(boolean secure) {
272         if (android.security.Flags.frpEnforcement()) {
273             mStorage.setTestFactoryResetProtectionState(secure);
274         }
275         Settings.Secure.putIntForUser(mContext.getContentResolver(),
276                 Settings.Secure.SECURE_FRP_MODE, secure ? 1 : 0, UserHandle.USER_SYSTEM);
277     }
278 
installChildProfile(int profileId)279     private UserInfo installChildProfile(int profileId) {
280         final UserInfo userInfo = new UserInfo(
281             profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
282         userInfo.profileGroupId = PRIMARY_USER_ID;
283         mPrimaryUserProfiles.add(userInfo);
284         when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
285         when(mUserManager.getProfileParent(eq(profileId))).thenReturn(mPrimaryUserInfo);
286         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
287         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
288         when(mUserManagerInternal.getUserInfo(eq(profileId))).thenReturn(userInfo);
289         // TODO(b/258213147): Remove
290         when(mUserManagerInternal.isUserManaged(eq(profileId))).thenReturn(true);
291         when(mDeviceStateCache.isUserOrganizationManaged(eq(profileId)))
292                 .thenReturn(true);
293         return userInfo;
294     }
295 
installAndTurnOffChildProfile(int profileId)296     private UserInfo installAndTurnOffChildProfile(int profileId) {
297         final UserInfo userInfo = installChildProfile(profileId);
298         userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
299         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
300         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
301         return userInfo;
302     }
303 
setUpStorageManagerMock()304     private IStorageManager setUpStorageManagerMock() throws RemoteException {
305         final IStorageManager sm = mock(IStorageManager.class);
306 
307         doAnswer(invocation -> {
308             Object[] args = invocation.getArguments();
309             mStorageManager.unlockCeStorage(/* userId= */ (int) args[0],
310                     /* secret= */ (byte[]) args[1]);
311             return null;
312         }).when(sm).unlockCeStorage(anyInt(), any());
313 
314         doAnswer(invocation -> {
315             Object[] args = invocation.getArguments();
316             mStorageManager.setCeStorageProtection(/* userId= */ (int) args[0],
317                     /* secret= */ (byte[]) args[1]);
318             return null;
319         }).when(sm).setCeStorageProtection(anyInt(), any());
320 
321         return sm;
322     }
323 
mockBiometricsHardwareFingerprintsAndTemplates(int userId)324     private void mockBiometricsHardwareFingerprintsAndTemplates(int userId) {
325         // Hardware must be detected and fingerprints must be enrolled
326         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
327         when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
328         when(mFingerprintManager.hasEnrolledFingerprints(userId)).thenReturn(true);
329         doAnswer(new Answer<Void>() {
330             @Override
331             public Void answer(InvocationOnMock invocation) throws Throwable {
332                 FingerprintManager.RemovalCallback callback =
333                         (FingerprintManager.RemovalCallback) invocation.getArguments()[1];
334                 callback.onRemovalSucceeded(null, 0);
335                 return null;
336             }
337         }).when(mFingerprintManager).removeAll(eq(userId), any());
338 
339 
340         // Hardware must be detected and templates must be enrolled
341         when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
342         when(mFaceManager.isHardwareDetected()).thenReturn(true);
343         when(mFaceManager.hasEnrolledTemplates(userId)).thenReturn(true);
344         doAnswer(new Answer<Void>() {
345             @Override
346             public Void answer(InvocationOnMock invocation) throws Throwable {
347                 FaceManager.RemovalCallback callback =
348                         (FaceManager.RemovalCallback) invocation.getArguments()[1];
349                 callback.onRemovalSucceeded(null, 0);
350                 return null;
351             }
352         }).when(mFaceManager).removeAll(eq(userId), any());
353     }
354 
355     @After
tearDown_baseServices()356     public void tearDown_baseServices() throws Exception {
357         if (mStorage != null) {
358             mStorage.closeDatabase();
359         }
360         File db = InstrumentationRegistry.getContext().getDatabasePath("locksettings.db");
361         assertTrue(!db.exists() || db.delete());
362 
363         if (mStorage != null) {
364             File storageDir = mStorage.mStorageDir;
365             assertTrue(FileUtils.deleteContents(storageDir));
366         }
367 
368         if (mPasswordSlotManager != null) {
369             mPasswordSlotManager.cleanup();
370         }
371     }
372 
flushHandlerTasks()373     protected void flushHandlerTasks() {
374         mService.mHandler.runWithScissors(() -> { }, 0 /*now*/); // Flush runnables on handler
375     }
376 
assertNotEquals(long expected, long actual)377     protected void assertNotEquals(long expected, long actual) {
378         assertTrue(expected != actual);
379     }
380 
assertArrayEquals(byte[] expected, byte[] actual)381     protected static void assertArrayEquals(byte[] expected, byte[] actual) {
382         assertTrue(Arrays.equals(expected, actual));
383     }
384 
assertArrayNotEquals(byte[] expected, byte[] actual)385     protected static void assertArrayNotEquals(byte[] expected, byte[] actual) {
386         assertFalse(Arrays.equals(expected, actual));
387     }
388 
newPassword(String password)389     protected LockscreenCredential newPassword(String password) {
390         return LockscreenCredential.createPasswordOrNone(password);
391     }
392 
newPin(String pin)393     protected LockscreenCredential newPin(String pin) {
394         return LockscreenCredential.createPinOrNone(pin);
395     }
396 
newPattern(String pattern)397     protected LockscreenCredential newPattern(String pattern) {
398         return LockscreenCredential.createPattern(LockPatternUtils.byteArrayToPattern(
399                 pattern.getBytes()));
400     }
401 
nonePassword()402     protected LockscreenCredential nonePassword() {
403         return LockscreenCredential.createNone();
404     }
405 
406 }
407