1 /*
2  * Copyright (C) 2023 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.USER_REPAIR_MODE;
20 import static com.android.internal.widget.LockPatternUtils.VERIFY_FLAG_WRITE_REPAIR_MODE_PW;
21 
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertSame;
24 
25 import android.app.PropertyInvalidatedCache;
26 import android.platform.test.annotations.Presubmit;
27 import android.provider.Settings;
28 
29 import androidx.test.filters.SmallTest;
30 import androidx.test.runner.AndroidJUnit4;
31 
32 import com.android.internal.widget.LockPatternUtils;
33 import com.android.internal.widget.VerifyCredentialResponse;
34 import com.android.server.locksettings.LockSettingsStorage.PersistentData;
35 
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 
40 @SmallTest
41 @Presubmit
42 @RunWith(AndroidJUnit4.class)
43 public class LockscreenRepairModeTest extends BaseLockSettingsServiceTests {
44 
45     @Before
setUp()46     public void setUp() throws Exception {
47         PropertyInvalidatedCache.disableForTestMode();
48         mService.initializeSyntheticPassword(PRIMARY_USER_ID);
49     }
50 
51     @Test
verifyPin_writeRepairModePW()52     public void verifyPin_writeRepairModePW() {
53         mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
54         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
55 
56         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
57                 mService.verifyCredential(
58                         newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
59                         .getResponseCode());
60         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
61                 mService.getCredentialType(USER_REPAIR_MODE));
62     }
63 
64     @Test
verifyPattern_writeRepairModePW()65     public void verifyPattern_writeRepairModePW() {
66         mService.setLockCredential(newPattern("4321"), nonePassword(), PRIMARY_USER_ID);
67         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
68 
69         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
70                 mService.verifyCredential(
71                         newPattern("4321"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
72                         .getResponseCode());
73         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
74                 mService.getCredentialType(USER_REPAIR_MODE));
75     }
76 
77     @Test
verifyPassword_writeRepairModePW()78     public void verifyPassword_writeRepairModePW() {
79         mService.setLockCredential(newPassword("4321"), nonePassword(), PRIMARY_USER_ID);
80         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
81 
82         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
83                 mService.verifyCredential(
84                         newPassword("4321"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
85                         .getResponseCode());
86         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
87                 mService.getCredentialType(USER_REPAIR_MODE));
88     }
89 
90     @Test
verifyCredential_writeRepairModePW_repairModeActive()91     public void verifyCredential_writeRepairModePW_repairModeActive() {
92         mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
93         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
94 
95         setRepairModeActive(true);
96         assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
97                 mService.verifyCredential(
98                                 newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
99                         .getResponseCode());
100         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
101     }
102 
103     @Test
deleteRepairModePersistentData()104     public void deleteRepairModePersistentData() {
105         mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
106         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
107         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
108                 mService.verifyCredential(
109                                 newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
110                         .getResponseCode());
111         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
112                 mService.getCredentialType(USER_REPAIR_MODE));
113 
114         mService.deleteRepairModePersistentDataIfNeeded();
115         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
116     }
117 
118     @Test
verifyPin_userRepairMode()119     public void verifyPin_userRepairMode() {
120         mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
121         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
122         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
123                 mService.verifyCredential(
124                         newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
125                         .getResponseCode());
126         setRepairModeActive(true);
127 
128         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
129                 mService.getCredentialType(USER_REPAIR_MODE));
130         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
131                 mService.verifyCredential(newPin("1234"), USER_REPAIR_MODE, 0 /* flags */)
132                         .getResponseCode());
133     }
134 
135     @Test
verifyPattern_userRepairMode()136     public void verifyPattern_userRepairMode() {
137         mService.setLockCredential(newPattern("4321"), nonePassword(), PRIMARY_USER_ID);
138         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
139         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
140                 mService.verifyCredential(
141                         newPattern("4321"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
142                         .getResponseCode());
143         setRepairModeActive(true);
144 
145         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
146                 mService.getCredentialType(USER_REPAIR_MODE));
147         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
148                 mService.verifyCredential(newPattern("4321"), USER_REPAIR_MODE, 0 /* flags */)
149                         .getResponseCode());
150     }
151 
152     @Test
verifyPassword_userRepairMode()153     public void verifyPassword_userRepairMode() {
154         mService.setLockCredential(newPassword("4321"), nonePassword(), PRIMARY_USER_ID);
155         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
156         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
157                 mService.verifyCredential(
158                         newPassword("4321"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
159                         .getResponseCode());
160         setRepairModeActive(true);
161 
162         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
163                 mService.getCredentialType(USER_REPAIR_MODE));
164         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
165                 mService.verifyCredential(newPassword("4321"), USER_REPAIR_MODE, 0 /* flags */)
166                         .getResponseCode());
167     }
168 
169     @Test
verifyCredential_userRepairMode_repairModeIsNotActive()170     public void verifyCredential_userRepairMode_repairModeIsNotActive() {
171         mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
172         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
173         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
174                 mService.verifyCredential(
175                                 newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
176                         .getResponseCode());
177 
178         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
179                 mService.getCredentialType(USER_REPAIR_MODE));
180         assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
181                 mService.verifyCredential(newPin("1234"), USER_REPAIR_MODE, 0 /* flags */)
182                         .getResponseCode());
183     }
184 
185     @Test
verifyCredential_userRepairMode_wrongPin()186     public void verifyCredential_userRepairMode_wrongPin() {
187         mService.setLockCredential(newPin("1234"), nonePassword(), PRIMARY_USER_ID);
188         assertSame(PersistentData.NONE, mStorage.readRepairModePersistentData());
189         assertEquals(VerifyCredentialResponse.RESPONSE_OK,
190                 mService.verifyCredential(
191                                 newPin("1234"), PRIMARY_USER_ID, VERIFY_FLAG_WRITE_REPAIR_MODE_PW)
192                         .getResponseCode());
193         setRepairModeActive(true);
194 
195         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PIN,
196                 mService.getCredentialType(USER_REPAIR_MODE));
197         assertEquals(VerifyCredentialResponse.RESPONSE_ERROR,
198                 mService.verifyCredential(newPin("5678"), USER_REPAIR_MODE, 0 /* flags */)
199                         .getResponseCode());
200     }
201 
setRepairModeActive(boolean active)202     private void setRepairModeActive(boolean active) {
203         Settings.Global.putInt(mContext.getContentResolver(),
204                 Settings.Global.REPAIR_MODE_ACTIVE, active ? 1 : 0);
205     }
206 }
207