blob: 237091de2640b0fa9313533fcb57327e40f9fe57 [file] [log] [blame]
Adrian Roose5424992014-11-07 21:47:17 +01001/*
2 * Copyright (C) 2014 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
Andrew Scull507d11c2017-05-03 17:19:01 +010017package com.android.server.locksettings;
Adrian Roose5424992014-11-07 21:47:17 +010018
Rubin Xu1de89b32016-11-30 20:03:13 +000019import static org.mockito.Matchers.eq;
20import static org.mockito.Mockito.mock;
21import static org.mockito.Mockito.when;
22
Rubin Xu0cbc19e2016-12-09 14:00:21 +000023import android.app.NotificationManager;
Rubin Xu8b30ec32017-03-05 00:47:09 +000024import android.app.admin.DevicePolicyManager;
Rubin Xu16c823e2017-06-27 14:44:58 +010025import android.app.trust.TrustManager;
Adrian Roose5424992014-11-07 21:47:17 +010026import android.content.pm.UserInfo;
27import android.database.sqlite.SQLiteDatabase;
28import android.os.FileUtils;
29import android.os.UserManager;
Rubin Xuaa32d152017-04-27 17:01:05 +010030import android.os.storage.StorageManager;
Adrian Roose5424992014-11-07 21:47:17 +010031import android.test.AndroidTestCase;
Adrian Roosb2375942018-01-19 22:31:28 +010032import android.util.Log;
33import android.util.Log.TerribleFailure;
34import android.util.Log.TerribleFailureHandler;
Adrian Roose5424992014-11-07 21:47:17 +010035
Rubin Xu1de89b32016-11-30 20:03:13 +000036import com.android.internal.widget.LockPatternUtils;
Adrian Roosb2375942018-01-19 22:31:28 +010037import com.android.server.PersistentDataBlockManagerInternal;
Andrew Scull507d11c2017-05-03 17:19:01 +010038import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
Adrian Roos7374d3a2017-03-31 14:14:53 -070039import com.android.server.locksettings.LockSettingsStorage.PersistentData;
40
Adrian Roose5424992014-11-07 21:47:17 +010041import java.io.File;
42import java.util.ArrayList;
43import java.util.Arrays;
44import java.util.List;
45import java.util.concurrent.CountDownLatch;
46
Rubin Xu1de89b32016-11-30 20:03:13 +000047/**
Andrew Scull507d11c2017-05-03 17:19:01 +010048 * runtest frameworks-services -c com.android.server.locksettings.LockSettingsStorageTests
Rubin Xu1de89b32016-11-30 20:03:13 +000049 */
Adrian Roose5424992014-11-07 21:47:17 +010050public class LockSettingsStorageTests extends AndroidTestCase {
Adrian Roos7374d3a2017-03-31 14:14:53 -070051 private static final int SOME_USER_ID = 1034;
Rubin Xu1de89b32016-11-30 20:03:13 +000052 private final byte[] PASSWORD_0 = "thepassword0".getBytes();
53 private final byte[] PASSWORD_1 = "password1".getBytes();
54 private final byte[] PATTERN_0 = "123654".getBytes();
55 private final byte[] PATTERN_1 = "147852369".getBytes();
56
Adrian Roos7374d3a2017-03-31 14:14:53 -070057 public static final byte[] PAYLOAD = new byte[] {1, 2, -1, -2, 33};
58
Adrian Roosb2375942018-01-19 22:31:28 +010059 LockSettingsStorageTestable mStorage;
Adrian Roose5424992014-11-07 21:47:17 +010060 File mStorageDir;
61
62 private File mDb;
63
64 @Override
65 protected void setUp() throws Exception {
66 super.setUp();
67 mStorageDir = new File(getContext().getFilesDir(), "locksettings");
68 mDb = getContext().getDatabasePath("locksettings.db");
69
70 assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
71 assertTrue(FileUtils.deleteContents(mStorageDir));
72 assertTrue(!mDb.exists() || mDb.delete());
73
Rubin Xu1de89b32016-11-30 20:03:13 +000074 final UserManager mockUserManager = mock(UserManager.class);
75 // User 2 is a profile of user 1.
76 when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
77 // User 3 is a profile of user 0.
78 when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
Adrian Roose5424992014-11-07 21:47:17 +010079
Rubin Xu0cbc19e2016-12-09 14:00:21 +000080 MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
Rubin Xuaa32d152017-04-27 17:01:05 +010081 mock(NotificationManager.class), mock(DevicePolicyManager.class),
Rubin Xu16c823e2017-06-27 14:44:58 +010082 mock(StorageManager.class), mock(TrustManager.class));
Rubin Xu0cbc19e2016-12-09 14:00:21 +000083 mStorage = new LockSettingsStorageTestable(context,
84 new File(getContext().getFilesDir(), "locksettings"));
85 mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
86 @Override
87 public void initialize(SQLiteDatabase db) {
88 mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
89 }
90 });
Adrian Roose5424992014-11-07 21:47:17 +010091 }
92
93 @Override
94 protected void tearDown() throws Exception {
95 super.tearDown();
96 mStorage.closeDatabase();
97 }
98
99 public void testKeyValue_InitializeWorked() {
100 assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
101 mStorage.clearCache();
102 assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
103 }
104
105 public void testKeyValue_WriteThenRead() {
106 mStorage.writeKeyValue("key", "value", 0);
107 assertEquals("value", mStorage.readKeyValue("key", "default", 0));
108 mStorage.clearCache();
109 assertEquals("value", mStorage.readKeyValue("key", "default", 0));
110 }
111
112 public void testKeyValue_DefaultValue() {
113 assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
114 assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
115 }
116
117 public void testKeyValue_Concurrency() {
118 final Object monitor = new Object();
119 List<Thread> threads = new ArrayList<>();
120 for (int i = 0; i < 100; i++) {
121 final int threadId = i;
122 threads.add(new Thread() {
123 @Override
124 public void run() {
125 synchronized (monitor) {
126 try {
127 monitor.wait();
128 } catch (InterruptedException e) {
129 return;
130 }
131 mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
132 mStorage.readKeyValue("key", "default", 0);
133 mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
134 mStorage.readKeyValue("key", "default", 0);
135 mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
136 mStorage.readKeyValue("key", "default", 0);
137 mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
138 mStorage.readKeyValue("key", "default", 0);
139 mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
140 mStorage.readKeyValue("key", "default", 0);
141 }
142 }
143 });
144 threads.get(i).start();
145 }
146 mStorage.writeKeyValue("key", "initalValue", 0);
147 synchronized (monitor) {
148 monitor.notifyAll();
149 }
150 for (int i = 0; i < threads.size(); i++) {
151 try {
152 threads.get(i).join();
153 } catch (InterruptedException e) {
154 }
155 }
156 assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
157 mStorage.clearCache();
158 assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
159 }
160
161 public void testKeyValue_CacheStarvedWriter() {
162 final CountDownLatch latch = new CountDownLatch(1);
163 List<Thread> threads = new ArrayList<>();
164 for (int i = 0; i < 100; i++) {
165 final int threadId = i;
166 threads.add(new Thread() {
167 @Override
168 public void run() {
169 try {
170 latch.await();
171 } catch (InterruptedException e) {
172 return;
173 }
174 if (threadId == 50) {
175 mStorage.writeKeyValue("starvedWriterKey", "value", 0);
176 } else {
177 mStorage.readKeyValue("starvedWriterKey", "default", 0);
178 }
179 }
180 });
181 threads.get(i).start();
182 }
183 latch.countDown();
184 for (int i = 0; i < threads.size(); i++) {
185 try {
186 threads.get(i).join();
187 } catch (InterruptedException e) {
188 }
189 }
190 String cached = mStorage.readKeyValue("key", "default", 0);
191 mStorage.clearCache();
192 String storage = mStorage.readKeyValue("key", "default", 0);
193 assertEquals("Cached value didn't match stored value", storage, cached);
194 }
195
196 public void testRemoveUser() {
197 mStorage.writeKeyValue("key", "value", 0);
Rubin Xu1de89b32016-11-30 20:03:13 +0000198 writePasswordBytes(PASSWORD_0, 0);
199 writePatternBytes(PATTERN_0, 0);
Adrian Roose5424992014-11-07 21:47:17 +0100200
201 mStorage.writeKeyValue("key", "value", 1);
Rubin Xu1de89b32016-11-30 20:03:13 +0000202 writePasswordBytes(PASSWORD_1, 1);
203 writePatternBytes(PATTERN_1, 1);
Adrian Roose5424992014-11-07 21:47:17 +0100204
205 mStorage.removeUser(0);
206
207 assertEquals("value", mStorage.readKeyValue("key", "default", 1));
208 assertEquals("default", mStorage.readKeyValue("key", "default", 0));
Rubin Xu1de89b32016-11-30 20:03:13 +0000209 assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
210 assertPatternBytes(PATTERN_1, 1);
Adrian Roose5424992014-11-07 21:47:17 +0100211 }
212
Rubin Xu1de89b32016-11-30 20:03:13 +0000213 public void testCredential_Default() {
214 assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
Adrian Roose5424992014-11-07 21:47:17 +0100215 }
216
217 public void testPassword_Write() {
Rubin Xu1de89b32016-11-30 20:03:13 +0000218 writePasswordBytes(PASSWORD_0, 0);
Adrian Roose5424992014-11-07 21:47:17 +0100219
Rubin Xu1de89b32016-11-30 20:03:13 +0000220 assertPasswordBytes(PASSWORD_0, 0);
Adrian Roose5424992014-11-07 21:47:17 +0100221 mStorage.clearCache();
Rubin Xu1de89b32016-11-30 20:03:13 +0000222 assertPasswordBytes(PASSWORD_0, 0);
Adrian Roose5424992014-11-07 21:47:17 +0100223 }
224
225 public void testPassword_WriteProfileWritesParent() {
Rubin Xu1de89b32016-11-30 20:03:13 +0000226 writePasswordBytes(PASSWORD_0, 1);
227 writePasswordBytes(PASSWORD_1, 2);
Adrian Roose5424992014-11-07 21:47:17 +0100228
Rubin Xu1de89b32016-11-30 20:03:13 +0000229 assertPasswordBytes(PASSWORD_0, 1);
230 assertPasswordBytes(PASSWORD_1, 2);
Adrian Roose5424992014-11-07 21:47:17 +0100231 mStorage.clearCache();
Rubin Xu1de89b32016-11-30 20:03:13 +0000232 assertPasswordBytes(PASSWORD_0, 1);
233 assertPasswordBytes(PASSWORD_1, 2);
Adrian Roose5424992014-11-07 21:47:17 +0100234 }
235
Ricky Waia46b40f2016-03-31 16:48:29 +0100236 public void testLockType_WriteProfileWritesParent() {
Rubin Xu1de89b32016-11-30 20:03:13 +0000237 writePasswordBytes(PASSWORD_0, 10);
238 writePatternBytes(PATTERN_0, 20);
Ricky Waia46b40f2016-03-31 16:48:29 +0100239
Rubin Xu1de89b32016-11-30 20:03:13 +0000240 assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
241 mStorage.readCredentialHash(10).type);
242 assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
243 mStorage.readCredentialHash(20).type);
Ricky Waia46b40f2016-03-31 16:48:29 +0100244 mStorage.clearCache();
Rubin Xu1de89b32016-11-30 20:03:13 +0000245 assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
246 mStorage.readCredentialHash(10).type);
247 assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
248 mStorage.readCredentialHash(20).type);
249 }
250
251 public void testPassword_WriteParentWritesProfile() {
252 writePasswordBytes(PASSWORD_0, 2);
253 writePasswordBytes(PASSWORD_1, 1);
254
255 assertPasswordBytes(PASSWORD_1, 1);
256 assertPasswordBytes(PASSWORD_0, 2);
257 mStorage.clearCache();
258 assertPasswordBytes(PASSWORD_1, 1);
259 assertPasswordBytes(PASSWORD_0, 2);
Ricky Waia46b40f2016-03-31 16:48:29 +0100260 }
261
262 public void testProfileLock_ReadWriteChildProfileLock() {
263 assertFalse(mStorage.hasChildProfileLock(20));
Rubin Xu1de89b32016-11-30 20:03:13 +0000264 mStorage.writeChildProfileLock(20, PASSWORD_0);
265 assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
Ricky Waia46b40f2016-03-31 16:48:29 +0100266 assertTrue(mStorage.hasChildProfileLock(20));
267 mStorage.clearCache();
Rubin Xu1de89b32016-11-30 20:03:13 +0000268 assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
Ricky Waia46b40f2016-03-31 16:48:29 +0100269 assertTrue(mStorage.hasChildProfileLock(20));
270 }
271
Adrian Roose5424992014-11-07 21:47:17 +0100272 public void testPattern_Write() {
Rubin Xu1de89b32016-11-30 20:03:13 +0000273 writePatternBytes(PATTERN_0, 0);
Adrian Roose5424992014-11-07 21:47:17 +0100274
Rubin Xu1de89b32016-11-30 20:03:13 +0000275 assertPatternBytes(PATTERN_0, 0);
Adrian Roose5424992014-11-07 21:47:17 +0100276 mStorage.clearCache();
Rubin Xu1de89b32016-11-30 20:03:13 +0000277 assertPatternBytes(PATTERN_0, 0);
Adrian Roose5424992014-11-07 21:47:17 +0100278 }
279
280 public void testPattern_WriteProfileWritesParent() {
Rubin Xu1de89b32016-11-30 20:03:13 +0000281 writePatternBytes(PATTERN_0, 1);
282 writePatternBytes(PATTERN_1, 2);
Adrian Roose5424992014-11-07 21:47:17 +0100283
Rubin Xu1de89b32016-11-30 20:03:13 +0000284 assertPatternBytes(PATTERN_0, 1);
285 assertPatternBytes(PATTERN_1, 2);
Adrian Roose5424992014-11-07 21:47:17 +0100286 mStorage.clearCache();
Rubin Xu1de89b32016-11-30 20:03:13 +0000287 assertPatternBytes(PATTERN_0, 1);
288 assertPatternBytes(PATTERN_1, 2);
Adrian Roose5424992014-11-07 21:47:17 +0100289 }
290
291 public void testPattern_WriteParentWritesProfile() {
Rubin Xu1de89b32016-11-30 20:03:13 +0000292 writePatternBytes(PATTERN_1, 2);
293 writePatternBytes(PATTERN_0, 1);
Adrian Roose5424992014-11-07 21:47:17 +0100294
Rubin Xu1de89b32016-11-30 20:03:13 +0000295 assertPatternBytes(PATTERN_0, 1);
296 assertPatternBytes(PATTERN_1, 2);
Adrian Roose5424992014-11-07 21:47:17 +0100297 mStorage.clearCache();
Rubin Xu1de89b32016-11-30 20:03:13 +0000298 assertPatternBytes(PATTERN_0, 1);
299 assertPatternBytes(PATTERN_1, 2);
Adrian Roose5424992014-11-07 21:47:17 +0100300 }
301
302 public void testPrefetch() {
303 mStorage.writeKeyValue("key", "toBeFetched", 0);
Rubin Xu1de89b32016-11-30 20:03:13 +0000304 writePatternBytes(PATTERN_0, 0);
Adrian Roose5424992014-11-07 21:47:17 +0100305
306 mStorage.clearCache();
307 mStorage.prefetchUser(0);
308
309 assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
Rubin Xu1de89b32016-11-30 20:03:13 +0000310 assertPatternBytes(PATTERN_0, 0);
Adrian Roose5424992014-11-07 21:47:17 +0100311 }
312
313 public void testFileLocation_Owner() {
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000314 LockSettingsStorage storage = new LockSettingsStorage(getContext());
Adrian Roose5424992014-11-07 21:47:17 +0100315
Rubin Xu1de89b32016-11-30 20:03:13 +0000316 assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
317 assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
318 assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
319 assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
Adrian Roose5424992014-11-07 21:47:17 +0100320 }
321
322 public void testFileLocation_SecondaryUser() {
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000323 LockSettingsStorage storage = new LockSettingsStorage(getContext());
Adrian Roose5424992014-11-07 21:47:17 +0100324
Rubin Xu1de89b32016-11-30 20:03:13 +0000325 assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
326 assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
Adrian Roose5424992014-11-07 21:47:17 +0100327 }
328
329 public void testFileLocation_ProfileToSecondary() {
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000330 LockSettingsStorage storage = new LockSettingsStorage(getContext());
Adrian Roose5424992014-11-07 21:47:17 +0100331
Rubin Xu1de89b32016-11-30 20:03:13 +0000332 assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
333 assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
Adrian Roose5424992014-11-07 21:47:17 +0100334 }
335
336 public void testFileLocation_ProfileToOwner() {
Rubin Xu0cbc19e2016-12-09 14:00:21 +0000337 LockSettingsStorage storage = new LockSettingsStorage(getContext());
Adrian Roose5424992014-11-07 21:47:17 +0100338
Rubin Xu1de89b32016-11-30 20:03:13 +0000339 assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
340 assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
Adrian Roose5424992014-11-07 21:47:17 +0100341 }
342
Rubin Xu3bf722a2016-12-15 16:07:38 +0000343 public void testSyntheticPasswordState() {
344 final byte[] data = {1,2,3,4};
345 mStorage.writeSyntheticPasswordState(10, 1234L, "state", data);
346 assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
347 assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
348
Rubin Xuaa32d152017-04-27 17:01:05 +0100349 mStorage.deleteSyntheticPasswordState(10, 1234L, "state");
Rubin Xu3bf722a2016-12-15 16:07:38 +0000350 assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
351 }
352
Adrian Roosb2375942018-01-19 22:31:28 +0100353 public void testPersistentDataBlock_unavailable() {
354 mStorage.mPersistentDataBlock = null;
355
356 assertSame(PersistentData.NONE, mStorage.readPersistentDataBlock());
357 }
358
359 public void testPersistentDataBlock_empty() {
360 mStorage.mPersistentDataBlock = mock(PersistentDataBlockManagerInternal.class);
361
362 assertSame(PersistentData.NONE, mStorage.readPersistentDataBlock());
363 }
364
365 public void testPersistentDataBlock_withData() {
366 mStorage.mPersistentDataBlock = mock(PersistentDataBlockManagerInternal.class);
367 when(mStorage.mPersistentDataBlock.getFrpCredentialHandle())
368 .thenReturn(PersistentData.toBytes(PersistentData.TYPE_SP_WEAVER, SOME_USER_ID,
369 DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, PAYLOAD));
370
371 PersistentData data = mStorage.readPersistentDataBlock();
372
373 assertEquals(PersistentData.TYPE_SP_WEAVER, data.type);
374 assertEquals(SOME_USER_ID, data.userId);
375 assertEquals(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, data.qualityForUi);
376 assertArrayEquals(PAYLOAD, data.payload);
377 }
378
379 public void testPersistentDataBlock_exception() {
380 mStorage.mPersistentDataBlock = mock(PersistentDataBlockManagerInternal.class);
381 when(mStorage.mPersistentDataBlock.getFrpCredentialHandle())
382 .thenThrow(new IllegalStateException("oops"));
383 assertSame(PersistentData.NONE, mStorage.readPersistentDataBlock());
384 }
385
Adrian Roos7374d3a2017-03-31 14:14:53 -0700386 public void testPersistentData_serializeUnserialize() {
Andrew Scull971f2942017-07-12 15:09:45 +0100387 byte[] serialized = PersistentData.toBytes(PersistentData.TYPE_SP, SOME_USER_ID,
Adrian Roos7374d3a2017-03-31 14:14:53 -0700388 DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, PAYLOAD);
389 PersistentData deserialized = PersistentData.fromBytes(serialized);
390
Andrew Scull971f2942017-07-12 15:09:45 +0100391 assertEquals(PersistentData.TYPE_SP, deserialized.type);
Adrian Roos7374d3a2017-03-31 14:14:53 -0700392 assertEquals(DevicePolicyManager.PASSWORD_QUALITY_COMPLEX, deserialized.qualityForUi);
393 assertArrayEquals(PAYLOAD, deserialized.payload);
394 }
395
396 public void testPersistentData_unserializeNull() {
397 PersistentData deserialized = PersistentData.fromBytes(null);
398 assertSame(PersistentData.NONE, deserialized);
399 }
400
401 public void testPersistentData_unserializeEmptyArray() {
402 PersistentData deserialized = PersistentData.fromBytes(new byte[0]);
403 assertSame(PersistentData.NONE, deserialized);
404 }
405
Adrian Roosb2375942018-01-19 22:31:28 +0100406 public void testPersistentData_unserializeInvalid() {
407 assertNotNull(suppressAndReturnWtf(() -> {
408 PersistentData deserialized = PersistentData.fromBytes(new byte[]{5});
409 assertSame(PersistentData.NONE, deserialized);
410 }));
411 }
412
Adrian Roos7374d3a2017-03-31 14:14:53 -0700413 public void testPersistentData_unserialize_version1() {
414 // This test ensures that we can read serialized VERSION_1 PersistentData even if we change
415 // the wire format in the future.
416 byte[] serializedVersion1 = new byte[] {
417 1, /* PersistentData.VERSION_1 */
Andrew Scull971f2942017-07-12 15:09:45 +0100418 1, /* PersistentData.TYPE_SP */
Adrian Roos7374d3a2017-03-31 14:14:53 -0700419 0x00, 0x00, 0x04, 0x0A, /* SOME_USER_ID */
420 0x00, 0x03, 0x00, 0x00, /* PASSWORD_NUMERIC_COMPLEX */
421 1, 2, -1, -2, 33, /* PAYLOAD */
422 };
423 PersistentData deserialized = PersistentData.fromBytes(serializedVersion1);
424 assertEquals(PersistentData.TYPE_SP, deserialized.type);
425 assertEquals(SOME_USER_ID, deserialized.userId);
426 assertEquals(DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX,
427 deserialized.qualityForUi);
428 assertArrayEquals(PAYLOAD, deserialized.payload);
429
430 // Make sure the constants we use on the wire do not change.
431 assertEquals(0, PersistentData.TYPE_NONE);
Andrew Scull971f2942017-07-12 15:09:45 +0100432 assertEquals(1, PersistentData.TYPE_SP);
433 assertEquals(2, PersistentData.TYPE_SP_WEAVER);
Adrian Roos7374d3a2017-03-31 14:14:53 -0700434 }
435
436 public void testCredentialHash_serializeUnserialize() {
437 byte[] serialized = CredentialHash.create(
438 PAYLOAD, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD).toBytes();
439 CredentialHash deserialized = CredentialHash.fromBytes(serialized);
440
441 assertEquals(CredentialHash.VERSION_GATEKEEPER, deserialized.version);
442 assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, deserialized.type);
443 assertArrayEquals(PAYLOAD, deserialized.hash);
444 assertFalse(deserialized.isBaseZeroPattern);
445 }
446
447 public void testCredentialHash_unserialize_versionGatekeeper() {
448 // This test ensures that we can read serialized VERSION_GATEKEEPER CredentialHashes
449 // even if we change the wire format in the future.
450 byte[] serialized = new byte[] {
451 1, /* VERSION_GATEKEEPER */
452 2, /* CREDENTIAL_TYPE_PASSWORD */
453 0, 0, 0, 5, /* hash length */
454 1, 2, -1, -2, 33, /* hash */
455 };
456 CredentialHash deserialized = CredentialHash.fromBytes(serialized);
457
458 assertEquals(CredentialHash.VERSION_GATEKEEPER, deserialized.version);
459 assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, deserialized.type);
460 assertArrayEquals(PAYLOAD, deserialized.hash);
461 assertFalse(deserialized.isBaseZeroPattern);
462
463 // Make sure the constants we use on the wire do not change.
464 assertEquals(-1, LockPatternUtils.CREDENTIAL_TYPE_NONE);
465 assertEquals(1, LockPatternUtils.CREDENTIAL_TYPE_PATTERN);
466 assertEquals(2, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD);
467 }
468
Adrian Roose5424992014-11-07 21:47:17 +0100469 private static void assertArrayEquals(byte[] expected, byte[] actual) {
470 if (!Arrays.equals(expected, actual)) {
471 fail("expected:<" + Arrays.toString(expected) +
472 "> but was:<" + Arrays.toString(actual) + ">");
473 }
474 }
Rubin Xu1de89b32016-11-30 20:03:13 +0000475
476 private void writePasswordBytes(byte[] password, int userId) {
477 mStorage.writeCredentialHash(CredentialHash.create(
478 password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
479 }
480
481 private void writePatternBytes(byte[] pattern, int userId) {
482 mStorage.writeCredentialHash(CredentialHash.create(
483 pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
484 }
485
486 private void assertPasswordBytes(byte[] password, int userId) {
487 CredentialHash cred = mStorage.readCredentialHash(userId);
488 assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
489 assertArrayEquals(password, cred.hash);
490 }
491
492 private void assertPatternBytes(byte[] pattern, int userId) {
493 CredentialHash cred = mStorage.readCredentialHash(userId);
494 assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
495 assertArrayEquals(pattern, cred.hash);
496 }
Adrian Roosb2375942018-01-19 22:31:28 +0100497
498 /**
499 * Suppresses reporting of the WTF to system_server, so we don't pollute the dropbox with
500 * intentionally caused WTFs.
501 */
502 private TerribleFailure suppressAndReturnWtf(Runnable r) {
503 TerribleFailure[] captured = new TerribleFailure[1];
504 TerribleFailureHandler prevWtfHandler = Log.setWtfHandler((t, w, s) -> captured[0] = w);
505 try {
506 r.run();
507 } finally {
508 Log.setWtfHandler(prevWtfHandler);
509 }
510 return captured[0];
511 }
Adrian Roose5424992014-11-07 21:47:17 +0100512}