OSDN Git Service

[automerger skipped] Import translations. DO NOT MERGE skipped: f6e12d6972 skipped...
[android-x86/frameworks-base.git] / services / tests / servicestests / src / com / android / server / LockSettingsStorageTests.java
1 /*
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
17 package com.android.server;
18
19 import static org.mockito.Matchers.eq;
20 import static org.mockito.Mockito.mock;
21 import static org.mockito.Mockito.when;
22
23 import android.app.NotificationManager;
24 import android.app.admin.DevicePolicyManager;
25 import android.content.Context;
26 import android.content.ContextWrapper;
27 import android.content.pm.UserInfo;
28 import android.database.sqlite.SQLiteDatabase;
29 import android.os.FileUtils;
30 import android.os.UserManager;
31 import android.os.storage.StorageManager;
32 import android.test.AndroidTestCase;
33
34 import com.android.internal.widget.LockPatternUtils;
35 import com.android.server.LockSettingsStorage.CredentialHash;
36 import java.io.File;
37 import java.util.ArrayList;
38 import java.util.Arrays;
39 import java.util.List;
40 import java.util.concurrent.CountDownLatch;
41
42 /**
43  * runtest frameworks-services -c com.android.server.LockSettingsStorageTests
44  */
45 public class LockSettingsStorageTests extends AndroidTestCase {
46     private final byte[] PASSWORD_0 = "thepassword0".getBytes();
47     private final byte[] PASSWORD_1 = "password1".getBytes();
48     private final byte[] PATTERN_0 = "123654".getBytes();
49     private final byte[] PATTERN_1 = "147852369".getBytes();
50
51     LockSettingsStorage mStorage;
52     File mStorageDir;
53
54     private File mDb;
55
56     @Override
57     protected void setUp() throws Exception {
58         super.setUp();
59         mStorageDir = new File(getContext().getFilesDir(), "locksettings");
60         mDb = getContext().getDatabasePath("locksettings.db");
61
62         assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
63         assertTrue(FileUtils.deleteContents(mStorageDir));
64         assertTrue(!mDb.exists() || mDb.delete());
65
66         final UserManager mockUserManager = mock(UserManager.class);
67         // User 2 is a profile of user 1.
68         when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
69         // User 3 is a profile of user 0.
70         when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
71
72         MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
73                 mock(NotificationManager.class), mock(DevicePolicyManager.class),
74                 mock(StorageManager.class));
75         mStorage = new LockSettingsStorageTestable(context,
76                 new File(getContext().getFilesDir(), "locksettings"));
77         mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
78                     @Override
79                     public void initialize(SQLiteDatabase db) {
80                         mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
81                     }
82                 });
83     }
84
85     @Override
86     protected void tearDown() throws Exception {
87         super.tearDown();
88         mStorage.closeDatabase();
89     }
90
91     public void testKeyValue_InitializeWorked() {
92         assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
93         mStorage.clearCache();
94         assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
95     }
96
97     public void testKeyValue_WriteThenRead() {
98         mStorage.writeKeyValue("key", "value", 0);
99         assertEquals("value", mStorage.readKeyValue("key", "default", 0));
100         mStorage.clearCache();
101         assertEquals("value", mStorage.readKeyValue("key", "default", 0));
102     }
103
104     public void testKeyValue_DefaultValue() {
105         assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
106         assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
107     }
108
109     public void testKeyValue_Concurrency() {
110         final Object monitor = new Object();
111         List<Thread> threads = new ArrayList<>();
112         for (int i = 0; i < 100; i++) {
113             final int threadId = i;
114             threads.add(new Thread() {
115                 @Override
116                 public void run() {
117                     synchronized (monitor) {
118                         try {
119                             monitor.wait();
120                         } catch (InterruptedException e) {
121                             return;
122                         }
123                         mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
124                         mStorage.readKeyValue("key", "default", 0);
125                         mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
126                         mStorage.readKeyValue("key", "default", 0);
127                         mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
128                         mStorage.readKeyValue("key", "default", 0);
129                         mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
130                         mStorage.readKeyValue("key", "default", 0);
131                         mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
132                         mStorage.readKeyValue("key", "default", 0);
133                     }
134                 }
135             });
136             threads.get(i).start();
137         }
138         mStorage.writeKeyValue("key", "initalValue", 0);
139         synchronized (monitor) {
140             monitor.notifyAll();
141         }
142         for (int i = 0; i < threads.size(); i++) {
143             try {
144                 threads.get(i).join();
145             } catch (InterruptedException e) {
146             }
147         }
148         assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
149         mStorage.clearCache();
150         assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
151     }
152
153     public void testKeyValue_CacheStarvedWriter() {
154         final CountDownLatch latch = new CountDownLatch(1);
155         List<Thread> threads = new ArrayList<>();
156         for (int i = 0; i < 100; i++) {
157             final int threadId = i;
158             threads.add(new Thread() {
159                 @Override
160                 public void run() {
161                     try {
162                         latch.await();
163                     } catch (InterruptedException e) {
164                         return;
165                     }
166                     if (threadId == 50) {
167                         mStorage.writeKeyValue("starvedWriterKey", "value", 0);
168                     } else {
169                         mStorage.readKeyValue("starvedWriterKey", "default", 0);
170                     }
171                 }
172             });
173             threads.get(i).start();
174         }
175         latch.countDown();
176         for (int i = 0; i < threads.size(); i++) {
177             try {
178                 threads.get(i).join();
179             } catch (InterruptedException e) {
180             }
181         }
182         String cached = mStorage.readKeyValue("key", "default", 0);
183         mStorage.clearCache();
184         String storage = mStorage.readKeyValue("key", "default", 0);
185         assertEquals("Cached value didn't match stored value", storage, cached);
186     }
187
188     public void testRemoveUser() {
189         mStorage.writeKeyValue("key", "value", 0);
190         writePasswordBytes(PASSWORD_0, 0);
191         writePatternBytes(PATTERN_0, 0);
192
193         mStorage.writeKeyValue("key", "value", 1);
194         writePasswordBytes(PASSWORD_1, 1);
195         writePatternBytes(PATTERN_1, 1);
196
197         mStorage.removeUser(0);
198
199         assertEquals("value", mStorage.readKeyValue("key", "default", 1));
200         assertEquals("default", mStorage.readKeyValue("key", "default", 0));
201         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
202         assertPatternBytes(PATTERN_1, 1);
203     }
204
205     public void testCredential_Default() {
206         assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
207     }
208
209     public void testPassword_Write() {
210         writePasswordBytes(PASSWORD_0, 0);
211
212         assertPasswordBytes(PASSWORD_0, 0);
213         mStorage.clearCache();
214         assertPasswordBytes(PASSWORD_0, 0);
215     }
216
217     public void testPassword_WriteProfileWritesParent() {
218         writePasswordBytes(PASSWORD_0, 1);
219         writePasswordBytes(PASSWORD_1, 2);
220
221         assertPasswordBytes(PASSWORD_0, 1);
222         assertPasswordBytes(PASSWORD_1, 2);
223         mStorage.clearCache();
224         assertPasswordBytes(PASSWORD_0, 1);
225         assertPasswordBytes(PASSWORD_1, 2);
226     }
227
228     public void testLockType_WriteProfileWritesParent() {
229         writePasswordBytes(PASSWORD_0, 10);
230         writePatternBytes(PATTERN_0, 20);
231
232         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
233                 mStorage.readCredentialHash(10).type);
234         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
235                 mStorage.readCredentialHash(20).type);
236         mStorage.clearCache();
237         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
238                 mStorage.readCredentialHash(10).type);
239         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
240                 mStorage.readCredentialHash(20).type);
241     }
242
243     public void testPassword_WriteParentWritesProfile() {
244         writePasswordBytes(PASSWORD_0, 2);
245         writePasswordBytes(PASSWORD_1, 1);
246
247         assertPasswordBytes(PASSWORD_1, 1);
248         assertPasswordBytes(PASSWORD_0, 2);
249         mStorage.clearCache();
250         assertPasswordBytes(PASSWORD_1, 1);
251         assertPasswordBytes(PASSWORD_0, 2);
252     }
253
254     public void testProfileLock_ReadWriteChildProfileLock() {
255         assertFalse(mStorage.hasChildProfileLock(20));
256         mStorage.writeChildProfileLock(20, PASSWORD_0);
257         assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
258         assertTrue(mStorage.hasChildProfileLock(20));
259         mStorage.clearCache();
260         assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
261         assertTrue(mStorage.hasChildProfileLock(20));
262     }
263
264     public void testPattern_Write() {
265         writePatternBytes(PATTERN_0, 0);
266
267         assertPatternBytes(PATTERN_0, 0);
268         mStorage.clearCache();
269         assertPatternBytes(PATTERN_0, 0);
270     }
271
272     public void testPattern_WriteProfileWritesParent() {
273         writePatternBytes(PATTERN_0, 1);
274         writePatternBytes(PATTERN_1, 2);
275
276         assertPatternBytes(PATTERN_0, 1);
277         assertPatternBytes(PATTERN_1, 2);
278         mStorage.clearCache();
279         assertPatternBytes(PATTERN_0, 1);
280         assertPatternBytes(PATTERN_1, 2);
281     }
282
283     public void testPattern_WriteParentWritesProfile() {
284         writePatternBytes(PATTERN_1, 2);
285         writePatternBytes(PATTERN_0, 1);
286
287         assertPatternBytes(PATTERN_0, 1);
288         assertPatternBytes(PATTERN_1, 2);
289         mStorage.clearCache();
290         assertPatternBytes(PATTERN_0, 1);
291         assertPatternBytes(PATTERN_1, 2);
292     }
293
294     public void testPrefetch() {
295         mStorage.writeKeyValue("key", "toBeFetched", 0);
296         writePatternBytes(PATTERN_0, 0);
297
298         mStorage.clearCache();
299         mStorage.prefetchUser(0);
300
301         assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
302         assertPatternBytes(PATTERN_0, 0);
303     }
304
305     public void testFileLocation_Owner() {
306         LockSettingsStorage storage = new LockSettingsStorage(getContext());
307
308         assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
309         assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
310         assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
311         assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
312     }
313
314     public void testFileLocation_SecondaryUser() {
315         LockSettingsStorage storage = new LockSettingsStorage(getContext());
316
317         assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
318         assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
319     }
320
321     public void testFileLocation_ProfileToSecondary() {
322         LockSettingsStorage storage = new LockSettingsStorage(getContext());
323
324         assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
325         assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
326     }
327
328     public void testFileLocation_ProfileToOwner() {
329         LockSettingsStorage storage = new LockSettingsStorage(getContext());
330
331         assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
332         assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
333     }
334
335     public void testSyntheticPasswordState() {
336         final byte[] data = {1,2,3,4};
337         mStorage.writeSyntheticPasswordState(10, 1234L, "state", data);
338         assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
339         assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
340
341         mStorage.deleteSyntheticPasswordState(10, 1234L, "state");
342         assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
343     }
344
345     private static void assertArrayEquals(byte[] expected, byte[] actual) {
346         if (!Arrays.equals(expected, actual)) {
347             fail("expected:<" + Arrays.toString(expected) +
348                     "> but was:<" + Arrays.toString(actual) + ">");
349         }
350     }
351
352     private void writePasswordBytes(byte[] password, int userId) {
353         mStorage.writeCredentialHash(CredentialHash.create(
354                 password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
355     }
356
357     private void writePatternBytes(byte[] pattern, int userId) {
358         mStorage.writeCredentialHash(CredentialHash.create(
359                 pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
360     }
361
362     private void assertPasswordBytes(byte[] password, int userId) {
363         CredentialHash cred = mStorage.readCredentialHash(userId);
364         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
365         assertArrayEquals(password, cred.hash);
366     }
367
368     private void assertPatternBytes(byte[] pattern, int userId) {
369         CredentialHash cred = mStorage.readCredentialHash(userId);
370         assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
371         assertArrayEquals(pattern, cred.hash);
372     }
373 }