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 com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE;
20 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD;
21 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PATTERN;
22 import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PIN;
23 
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertFalse;
26 import static org.junit.Assert.assertNotNull;
27 import static org.junit.Assert.assertNull;
28 import static org.junit.Assert.assertTrue;
29 import static org.junit.Assert.fail;
30 import static org.mockito.ArgumentMatchers.any;
31 import static org.mockito.ArgumentMatchers.anyInt;
32 import static org.mockito.ArgumentMatchers.eq;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.reset;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37 
38 import android.app.PropertyInvalidatedCache;
39 import android.os.RemoteException;
40 import android.platform.test.annotations.Presubmit;
41 import android.service.gatekeeper.GateKeeperResponse;
42 import android.text.TextUtils;
43 
44 import androidx.test.filters.SmallTest;
45 import androidx.test.runner.AndroidJUnit4;
46 
47 import com.android.internal.widget.LockPatternUtils;
48 import com.android.internal.widget.LockscreenCredential;
49 import com.android.internal.widget.VerifyCredentialResponse;
50 
51 import org.junit.Before;
52 import org.junit.Test;
53 import org.junit.runner.RunWith;
54 
55 /**
56  * atest FrameworksServicesTests:LockSettingsServiceTests
57  */
58 @SmallTest
59 @Presubmit
60 @RunWith(AndroidJUnit4.class)
61 public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
62 
63     @Before
setUp()64     public void setUp() {
65         PropertyInvalidatedCache.disableForTestMode();
66         mService.initializeSyntheticPassword(PRIMARY_USER_ID);
67         mService.initializeSyntheticPassword(MANAGED_PROFILE_USER_ID);
68     }
69 
70     @Test
testSetPasswordPrimaryUser()71     public void testSetPasswordPrimaryUser() throws RemoteException {
72         setAndVerifyCredential(PRIMARY_USER_ID, newPassword("password"));
73     }
74 
75     @Test
testSetPasswordFailsWithoutLockScreen()76     public void testSetPasswordFailsWithoutLockScreen() throws RemoteException {
77         testSetCredentialFailsWithoutLockScreen(PRIMARY_USER_ID, newPassword("password"));
78     }
79 
80     @Test
testSetPatternPrimaryUser()81     public void testSetPatternPrimaryUser() throws RemoteException {
82         setAndVerifyCredential(PRIMARY_USER_ID, newPattern("123456789"));
83     }
84 
85     @Test
testSetPatternFailsWithoutLockScreen()86     public void testSetPatternFailsWithoutLockScreen() throws RemoteException {
87         testSetCredentialFailsWithoutLockScreen(PRIMARY_USER_ID, newPattern("123456789"));
88     }
89 
90     @Test
testChangePasswordPrimaryUser()91     public void testChangePasswordPrimaryUser() throws RemoteException {
92         testChangeCredential(PRIMARY_USER_ID, newPattern("78963214"), newPassword("asdfghjk"));
93     }
94 
95     @Test
testChangePatternPrimaryUser()96     public void testChangePatternPrimaryUser() throws RemoteException {
97         testChangeCredential(PRIMARY_USER_ID, newPassword("!£$%^&*(())"), newPattern("1596321"));
98     }
99 
100     @Test
testChangePasswordFailPrimaryUser()101     public void testChangePasswordFailPrimaryUser() throws RemoteException {
102         setCredential(PRIMARY_USER_ID, newPassword("password"));
103         assertFalse(mService.setLockCredential(newPassword("newpwd"), newPassword("badpwd"),
104                     PRIMARY_USER_ID));
105         assertVerifyCredential(PRIMARY_USER_ID, newPassword("password"));
106     }
107 
108     @Test
testClearPasswordPrimaryUser()109     public void testClearPasswordPrimaryUser() throws RemoteException {
110         setCredential(PRIMARY_USER_ID, newPassword("password"));
111         clearCredential(PRIMARY_USER_ID, newPassword("password"));
112     }
113 
114     @Test
testManagedProfileUnifiedChallenge()115     public void testManagedProfileUnifiedChallenge() throws RemoteException {
116         mService.initializeSyntheticPassword(TURNED_OFF_PROFILE_USER_ID);
117 
118         final LockscreenCredential firstUnifiedPassword = newPassword("pwd-1");
119         final LockscreenCredential secondUnifiedPassword = newPassword("pwd-2");
120         setCredential(PRIMARY_USER_ID, firstUnifiedPassword);
121         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
122         final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
123         final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
124         final long turnedOffProfileSid =
125                 mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID);
126         assertTrue(primarySid != 0);
127         assertTrue(profileSid != 0);
128         assertTrue(profileSid != primarySid);
129         assertTrue(turnedOffProfileSid != 0);
130         assertTrue(turnedOffProfileSid != primarySid);
131         assertTrue(turnedOffProfileSid != profileSid);
132 
133         // clear auth token and wait for verify challenge from primary user to re-generate it.
134         mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
135         mGateKeeperService.clearAuthToken(TURNED_OFF_PROFILE_USER_ID);
136         // verify credential
137         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
138                 firstUnifiedPassword, PRIMARY_USER_ID, 0 /* flags */)
139                 .getResponseCode());
140 
141         // Verify that we have a new auth token for the profile
142         assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
143         assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
144 
145         // Verify that profile which aren't running (e.g. turn off work) don't get unlocked
146         assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
147 
148         // Change primary password and verify that profile SID remains
149         setCredential(PRIMARY_USER_ID, secondUnifiedPassword, firstUnifiedPassword);
150         assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
151         assertNull(mGateKeeperService.getAuthToken(TURNED_OFF_PROFILE_USER_ID));
152 
153         // Clear unified challenge
154         clearCredential(PRIMARY_USER_ID, secondUnifiedPassword);
155         assertEquals(0, mGateKeeperService.getSecureUserId(PRIMARY_USER_ID));
156         assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
157         assertEquals(0, mGateKeeperService.getSecureUserId(TURNED_OFF_PROFILE_USER_ID));
158     }
159 
160     @Test
testManagedProfileSeparateChallenge()161     public void testManagedProfileSeparateChallenge() throws RemoteException {
162         final LockscreenCredential primaryPassword = newPassword("primary");
163         final LockscreenCredential profilePassword = newPassword("profile");
164         setCredential(PRIMARY_USER_ID, primaryPassword);
165         setCredential(MANAGED_PROFILE_USER_ID, profilePassword);
166 
167         final long primarySid = mGateKeeperService.getSecureUserId(PRIMARY_USER_ID);
168         final long profileSid = mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID);
169         assertTrue(primarySid != 0);
170         assertTrue(profileSid != 0);
171         assertTrue(profileSid != primarySid);
172 
173         // clear auth token and make sure verify challenge from primary user does not regenerate it.
174         mGateKeeperService.clearAuthToken(MANAGED_PROFILE_USER_ID);
175         // verify primary credential
176         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
177                 primaryPassword, PRIMARY_USER_ID, 0 /* flags */)
178                 .getResponseCode());
179         assertNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
180 
181         // verify profile credential
182         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
183                 profilePassword, MANAGED_PROFILE_USER_ID, 0 /* flags */)
184                 .getResponseCode());
185         assertNotNull(mGateKeeperService.getAuthToken(MANAGED_PROFILE_USER_ID));
186         assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
187 
188         setCredential(PRIMARY_USER_ID, newPassword("pwd"), primaryPassword);
189         assertEquals(VerifyCredentialResponse.RESPONSE_OK, mService.verifyCredential(
190                 profilePassword, MANAGED_PROFILE_USER_ID, 0 /* flags */)
191                 .getResponseCode());
192         assertEquals(profileSid, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
193     }
194 
195     @Test
testManagedProfileChallengeUnification_parentUserNoPassword()196     public void testManagedProfileChallengeUnification_parentUserNoPassword() throws Exception {
197         // Start with a profile with unified challenge, parent user has not password
198         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
199         assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
200         assertEquals(CREDENTIAL_TYPE_NONE, mService.getCredentialType(MANAGED_PROFILE_USER_ID));
201 
202         // Set a separate challenge on the profile
203         setCredential(MANAGED_PROFILE_USER_ID, newPassword("12345678"));
204         assertNotEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
205         assertEquals(CREDENTIAL_TYPE_PASSWORD, mService.getCredentialType(MANAGED_PROFILE_USER_ID));
206 
207         // Now unify again, profile should become passwordless again
208         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false,
209                 newPassword("12345678"));
210         assertEquals(0, mGateKeeperService.getSecureUserId(MANAGED_PROFILE_USER_ID));
211         assertEquals(CREDENTIAL_TYPE_NONE, mService.getCredentialType(MANAGED_PROFILE_USER_ID));
212     }
213 
214     @Test
testSetLockCredential_forPrimaryUser_sendsCredentials()215     public void testSetLockCredential_forPrimaryUser_sendsCredentials() throws Exception {
216         setCredential(PRIMARY_USER_ID, newPassword("password"));
217         verify(mRecoverableKeyStoreManager)
218                 .lockScreenSecretChanged(CREDENTIAL_TYPE_PASSWORD, "password".getBytes(),
219                         PRIMARY_USER_ID);
220     }
221 
222     @Test
testSetLockCredential_forProfileWithSeparateChallenge_sendsCredentials()223     public void testSetLockCredential_forProfileWithSeparateChallenge_sendsCredentials()
224             throws Exception {
225         setCredential(MANAGED_PROFILE_USER_ID, newPattern("12345"));
226         verify(mRecoverableKeyStoreManager)
227                 .lockScreenSecretChanged(CREDENTIAL_TYPE_PATTERN, "12345".getBytes(),
228                         MANAGED_PROFILE_USER_ID);
229     }
230 
231     @Test
testSetLockCredential_forProfileWithSeparateChallenge_updatesCredentials()232     public void testSetLockCredential_forProfileWithSeparateChallenge_updatesCredentials()
233             throws Exception {
234         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, true, null);
235         setCredential(MANAGED_PROFILE_USER_ID, newPattern("12345"));
236         setCredential(MANAGED_PROFILE_USER_ID, newPassword("newPassword"), newPattern("12345"));
237         verify(mRecoverableKeyStoreManager)
238                 .lockScreenSecretChanged(CREDENTIAL_TYPE_PASSWORD, "newPassword".getBytes(),
239                         MANAGED_PROFILE_USER_ID);
240     }
241 
242     @Test
testSetLockCredential_forProfileWithUnifiedChallenge_doesNotSendRandomCredential()243     public void testSetLockCredential_forProfileWithUnifiedChallenge_doesNotSendRandomCredential()
244             throws Exception {
245         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
246         setCredential(PRIMARY_USER_ID, newPattern("12345"));
247         verify(mRecoverableKeyStoreManager, never())
248                 .lockScreenSecretChanged(
249                         eq(CREDENTIAL_TYPE_PASSWORD), any(), eq(MANAGED_PROFILE_USER_ID));
250     }
251 
252     @Test
253     public void
testSetLockCredential_forPrimaryUserWithUnifiedChallengeProfile_updatesBothCredentials()254             testSetLockCredential_forPrimaryUserWithUnifiedChallengeProfile_updatesBothCredentials()
255                     throws Exception {
256         final LockscreenCredential oldCredential = newPassword("oldPassword");
257         final LockscreenCredential newCredential = newPassword("newPassword");
258         setCredential(PRIMARY_USER_ID, oldCredential);
259         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
260         setCredential(PRIMARY_USER_ID, newCredential, oldCredential);
261 
262         verify(mRecoverableKeyStoreManager)
263                 .lockScreenSecretChanged(CREDENTIAL_TYPE_PASSWORD, newCredential.getCredential(),
264                         PRIMARY_USER_ID);
265         verify(mRecoverableKeyStoreManager)
266                 .lockScreenSecretChanged(CREDENTIAL_TYPE_PASSWORD, newCredential.getCredential(),
267                         MANAGED_PROFILE_USER_ID);
268     }
269 
270     @Test
271     public void
testSetLockCredential_forPrimaryUserWithUnifiedChallengeProfile_removesBothCredentials()272             testSetLockCredential_forPrimaryUserWithUnifiedChallengeProfile_removesBothCredentials()
273                     throws Exception {
274         setCredential(PRIMARY_USER_ID, newPassword("oldPassword"));
275         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
276         clearCredential(PRIMARY_USER_ID, newPassword("oldPassword"));
277 
278         verify(mRecoverableKeyStoreManager)
279                 .lockScreenSecretChanged(CREDENTIAL_TYPE_NONE, null, PRIMARY_USER_ID);
280         verify(mRecoverableKeyStoreManager)
281                 .lockScreenSecretChanged(CREDENTIAL_TYPE_NONE, null, MANAGED_PROFILE_USER_ID);
282     }
283 
284     @Test
testClearLockCredential_removesBiometrics()285     public void testClearLockCredential_removesBiometrics() throws RemoteException {
286         setCredential(PRIMARY_USER_ID, newPattern("123654"));
287         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
288         clearCredential(PRIMARY_USER_ID, newPattern("123654"));
289 
290         // Verify fingerprint is removed
291         verify(mFingerprintManager).removeAll(eq(PRIMARY_USER_ID), any());
292         verify(mFaceManager).removeAll(eq(PRIMARY_USER_ID), any());
293 
294         verify(mFingerprintManager).removeAll(eq(MANAGED_PROFILE_USER_ID), any());
295         verify(mFaceManager).removeAll(eq(MANAGED_PROFILE_USER_ID), any());
296     }
297 
298     @Test
testSetLockCredential_forUnifiedToSeparateChallengeProfile_sendsNewCredentials()299     public void testSetLockCredential_forUnifiedToSeparateChallengeProfile_sendsNewCredentials()
300             throws Exception {
301         final LockscreenCredential parentPassword = newPassword("parentPassword");
302         final LockscreenCredential profilePassword = newPassword("profilePassword");
303         setCredential(PRIMARY_USER_ID, parentPassword);
304         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
305         setCredential(MANAGED_PROFILE_USER_ID, profilePassword);
306         verify(mRecoverableKeyStoreManager)
307                 .lockScreenSecretChanged(CREDENTIAL_TYPE_PASSWORD, profilePassword.getCredential(),
308                         MANAGED_PROFILE_USER_ID);
309     }
310 
311     @Test
312     public void
testSetLockCredential_forSeparateToUnifiedChallengeProfile_doesNotSendRandomCredential()313             testSetLockCredential_forSeparateToUnifiedChallengeProfile_doesNotSendRandomCredential()
314                     throws Exception {
315         final LockscreenCredential parentPassword = newPassword("parentPassword");
316         final LockscreenCredential profilePassword = newPattern("12345");
317         mService.setSeparateProfileChallengeEnabled(
318                 MANAGED_PROFILE_USER_ID, true, profilePassword);
319         setCredential(PRIMARY_USER_ID, parentPassword);
320         setAndVerifyCredential(MANAGED_PROFILE_USER_ID, profilePassword);
321 
322         mService.setSeparateProfileChallengeEnabled(
323                 MANAGED_PROFILE_USER_ID, false, profilePassword);
324 
325         // Called once for setting the initial separate profile credentials and not again during
326         // unification.
327         verify(mRecoverableKeyStoreManager)
328                 .lockScreenSecretChanged(anyInt(), any(), eq(MANAGED_PROFILE_USER_ID));
329     }
330 
331     @Test
testVerifyCredential_forPrimaryUser_sendsCredentials()332     public void testVerifyCredential_forPrimaryUser_sendsCredentials() throws Exception {
333         final LockscreenCredential password = newPassword("password");
334         setCredential(PRIMARY_USER_ID, password);
335         reset(mRecoverableKeyStoreManager);
336 
337         mService.verifyCredential(password, PRIMARY_USER_ID, 0 /* flags */);
338 
339         verify(mRecoverableKeyStoreManager)
340                 .lockScreenSecretAvailable(
341                         CREDENTIAL_TYPE_PASSWORD, password.getCredential(), PRIMARY_USER_ID);
342     }
343 
344     @Test
testVerifyCredential_forProfileWithSeparateChallenge_sendsCredentials()345     public void testVerifyCredential_forProfileWithSeparateChallenge_sendsCredentials()
346             throws Exception {
347         final LockscreenCredential pattern = newPattern("12345");
348         setCredential(MANAGED_PROFILE_USER_ID, pattern);
349         reset(mRecoverableKeyStoreManager);
350 
351         mService.verifyCredential(pattern, MANAGED_PROFILE_USER_ID, 0 /* flags */);
352 
353         verify(mRecoverableKeyStoreManager)
354                 .lockScreenSecretAvailable(
355                         CREDENTIAL_TYPE_PATTERN, pattern.getCredential(), MANAGED_PROFILE_USER_ID);
356     }
357 
358     @Test
verifyCredential_forPrimaryUserWithUnifiedChallengeProfile_sendsCredentialsForBoth()359     public void verifyCredential_forPrimaryUserWithUnifiedChallengeProfile_sendsCredentialsForBoth()
360                     throws Exception {
361         final LockscreenCredential pattern = newPattern("12345");
362         setCredential(PRIMARY_USER_ID, pattern);
363         mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
364         reset(mRecoverableKeyStoreManager);
365 
366         mService.verifyCredential(pattern, PRIMARY_USER_ID, 0 /* flags */);
367 
368         // Parent sends its credentials for both the parent and profile.
369         verify(mRecoverableKeyStoreManager)
370                 .lockScreenSecretAvailable(
371                         CREDENTIAL_TYPE_PATTERN, pattern.getCredential(), PRIMARY_USER_ID);
372         verify(mRecoverableKeyStoreManager)
373                 .lockScreenSecretAvailable(
374                         CREDENTIAL_TYPE_PATTERN, pattern.getCredential(), MANAGED_PROFILE_USER_ID);
375         // Profile doesn't send its own random credentials.
376         verify(mRecoverableKeyStoreManager, never())
377                 .lockScreenSecretAvailable(
378                         eq(CREDENTIAL_TYPE_PASSWORD), any(), eq(MANAGED_PROFILE_USER_ID));
379     }
380 
381     @Test
testSetCredentialNotPossibleInSecureFrpModeDuringSuw()382     public void testSetCredentialNotPossibleInSecureFrpModeDuringSuw() {
383         setUserSetupComplete(false);
384         setSecureFrpMode(true);
385         try {
386             mService.setLockCredential(newPassword("1234"), nonePassword(), PRIMARY_USER_ID);
387             fail("Password shouldn't be changeable before FRP unlock");
388         } catch (SecurityException e) { }
389     }
390 
391     @Test
testSetCredentialPossibleInSecureFrpModeAfterSuw()392     public void testSetCredentialPossibleInSecureFrpModeAfterSuw() throws RemoteException {
393         setUserSetupComplete(true);
394         setSecureFrpMode(true);
395         setCredential(PRIMARY_USER_ID, newPassword("1234"));
396     }
397 
398     @Test
testPasswordHistoryDisabledByDefault()399     public void testPasswordHistoryDisabledByDefault() throws Exception {
400         final int userId = PRIMARY_USER_ID;
401         checkPasswordHistoryLength(userId, 0);
402         setCredential(userId, newPassword("1234"));
403         checkPasswordHistoryLength(userId, 0);
404     }
405 
406     @Test
testPasswordHistoryLengthHonored()407     public void testPasswordHistoryLengthHonored() throws Exception {
408         final int userId = PRIMARY_USER_ID;
409         when(mDevicePolicyManager.getPasswordHistoryLength(any(), eq(userId))).thenReturn(3);
410         checkPasswordHistoryLength(userId, 0);
411 
412         setCredential(userId, newPassword("pass1"));
413         checkPasswordHistoryLength(userId, 1);
414 
415         setCredential(userId, newPassword("pass2"), newPassword("pass1"));
416         checkPasswordHistoryLength(userId, 2);
417 
418         setCredential(userId, newPassword("pass3"), newPassword("pass2"));
419         checkPasswordHistoryLength(userId, 3);
420 
421         // maximum length should have been reached
422         setCredential(userId, newPassword("pass4"), newPassword("pass3"));
423         checkPasswordHistoryLength(userId, 3);
424     }
425 
426     @Test(expected=NullPointerException.class)
testSetBooleanRejectsNullKey()427     public void testSetBooleanRejectsNullKey() {
428         mService.setBoolean(null, false, 0);
429     }
430 
431     @Test(expected=NullPointerException.class)
testSetLongRejectsNullKey()432     public void testSetLongRejectsNullKey() {
433         mService.setLong(null, 0, 0);
434     }
435 
436     @Test(expected=NullPointerException.class)
testSetStringRejectsNullKey()437     public void testSetStringRejectsNullKey() {
438         mService.setString(null, "value", 0);
439     }
440 
checkPasswordHistoryLength(int userId, int expectedLen)441     private void checkPasswordHistoryLength(int userId, int expectedLen) {
442         String history = mService.getString(LockPatternUtils.PASSWORD_HISTORY_KEY, "", userId);
443         String[] hashes = TextUtils.split(history, LockPatternUtils.PASSWORD_HISTORY_DELIMITER);
444         assertEquals(expectedLen, hashes.length);
445     }
446 
testSetCredentialFailsWithoutLockScreen( int userId, LockscreenCredential credential)447     private void testSetCredentialFailsWithoutLockScreen(
448             int userId, LockscreenCredential credential) throws RemoteException {
449         mService.mHasSecureLockScreen = false;
450         try {
451             mService.setLockCredential(credential, nonePassword(), userId);
452             fail("An exception should have been thrown.");
453         } catch (UnsupportedOperationException e) {
454             // Success - the exception was expected.
455         }
456 
457         assertEquals(CREDENTIAL_TYPE_NONE, mService.getCredentialType(userId));
458     }
459 
testChangeCredential(int userId, LockscreenCredential newCredential, LockscreenCredential oldCredential)460     private void testChangeCredential(int userId, LockscreenCredential newCredential,
461             LockscreenCredential oldCredential) throws RemoteException {
462         setCredential(userId, oldCredential);
463         setCredential(userId, newCredential, oldCredential);
464         assertVerifyCredential(userId, newCredential);
465     }
466 
assertVerifyCredential(int userId, LockscreenCredential credential)467     private void assertVerifyCredential(int userId, LockscreenCredential credential)
468             throws RemoteException{
469         VerifyCredentialResponse response = mService.verifyCredential(credential, userId,
470                 0 /* flags */);
471 
472         assertEquals(GateKeeperResponse.RESPONSE_OK, response.getResponseCode());
473         if (credential.isPassword()) {
474             assertEquals(CREDENTIAL_TYPE_PASSWORD, mService.getCredentialType(userId));
475         } else if (credential.isPin()) {
476             assertEquals(CREDENTIAL_TYPE_PIN, mService.getCredentialType(userId));
477         } else if (credential.isPattern()) {
478             assertEquals(CREDENTIAL_TYPE_PATTERN, mService.getCredentialType(userId));
479         } else {
480             assertEquals(CREDENTIAL_TYPE_NONE, mService.getCredentialType(userId));
481         }
482         // check for bad credential
483         final LockscreenCredential badCredential;
484         if (!credential.isNone()) {
485             badCredential = credential.duplicate();
486             badCredential.getCredential()[0] ^= 1;
487         } else {
488             badCredential = LockscreenCredential.createPin("0");
489         }
490         assertEquals(GateKeeperResponse.RESPONSE_ERROR, mService.verifyCredential(
491                 badCredential, userId, 0 /* flags */).getResponseCode());
492     }
493 
setAndVerifyCredential(int userId, LockscreenCredential newCredential)494     private void setAndVerifyCredential(int userId, LockscreenCredential newCredential)
495             throws RemoteException {
496         setCredential(userId, newCredential);
497         assertVerifyCredential(userId, newCredential);
498     }
499 
setCredential(int userId, LockscreenCredential newCredential)500     private void setCredential(int userId, LockscreenCredential newCredential)
501             throws RemoteException {
502         setCredential(userId, newCredential, nonePassword());
503     }
504 
clearCredential(int userId, LockscreenCredential oldCredential)505     private void clearCredential(int userId, LockscreenCredential oldCredential)
506             throws RemoteException {
507         setCredential(userId, nonePassword(), oldCredential);
508     }
509 
setCredential(int userId, LockscreenCredential newCredential, LockscreenCredential oldCredential)510     private void setCredential(int userId, LockscreenCredential newCredential,
511             LockscreenCredential oldCredential) throws RemoteException {
512         assertTrue(mService.setLockCredential(newCredential, oldCredential, userId));
513         assertEquals(newCredential.getType(), mService.getCredentialType(userId));
514         if (newCredential.isNone()) {
515             assertEquals(0, mGateKeeperService.getSecureUserId(userId));
516         } else {
517             assertNotEquals(0, mGateKeeperService.getSecureUserId(userId));
518         }
519     }
520 }
521