1e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos/*
2e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos * Copyright (C) 2014 The Android Open Source Project
3e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos *
4e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos * Licensed under the Apache License, Version 2.0 (the "License");
5e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos * you may not use this file except in compliance with the License.
6e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos * You may obtain a copy of the License at
7e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos *
8e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos *      http://www.apache.org/licenses/LICENSE-2.0
9e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos *
10e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos * Unless required by applicable law or agreed to in writing, software
11e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos * distributed under the License is distributed on an "AS IS" BASIS,
12e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos * See the License for the specific language governing permissions and
14e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos * limitations under the License
15e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos */
16e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
17e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roospackage com.android.server;
18e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
191de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xuimport static org.mockito.Matchers.eq;
201de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xuimport static org.mockito.Mockito.mock;
211de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xuimport static org.mockito.Mockito.when;
221de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
230cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xuimport android.app.NotificationManager;
248b30ec3f49d4c8037bc6aa03ed6dd91aff3968adRubin Xuimport android.app.admin.DevicePolicyManager;
25e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.content.Context;
26e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.content.ContextWrapper;
27e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.content.pm.UserInfo;
28e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.database.sqlite.SQLiteDatabase;
29e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.os.FileUtils;
30e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.os.UserManager;
31ee67b61bb08ab09be413f181f948f6359f4c256dRubin Xuimport android.os.storage.StorageManager;
32e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.test.AndroidTestCase;
33e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
341de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xuimport com.android.internal.widget.LockPatternUtils;
351de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xuimport com.android.server.LockSettingsStorage.CredentialHash;
36e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.io.File;
37e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.util.ArrayList;
38e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.util.Arrays;
39e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.util.List;
40e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.util.concurrent.CountDownLatch;
41e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
421de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu/**
431de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * runtest frameworks-services -c com.android.server.LockSettingsStorageTests
441de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu */
45e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roospublic class LockSettingsStorageTests extends AndroidTestCase {
461de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private final byte[] PASSWORD_0 = "thepassword0".getBytes();
471de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private final byte[] PASSWORD_1 = "password1".getBytes();
481de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private final byte[] PATTERN_0 = "123654".getBytes();
491de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private final byte[] PATTERN_1 = "147852369".getBytes();
501de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
51e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    LockSettingsStorage mStorage;
52e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    File mStorageDir;
53e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
54e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    private File mDb;
55e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
56e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    @Override
57e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    protected void setUp() throws Exception {
58e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        super.setUp();
59e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorageDir = new File(getContext().getFilesDir(), "locksettings");
60e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mDb = getContext().getDatabasePath("locksettings.db");
61e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
62e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
63e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertTrue(FileUtils.deleteContents(mStorageDir));
64e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertTrue(!mDb.exists() || mDb.delete());
65e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
661de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        final UserManager mockUserManager = mock(UserManager.class);
671de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        // User 2 is a profile of user 1.
681de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
691de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        // User 3 is a profile of user 0.
701de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
71e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
720cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu        MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
73ee67b61bb08ab09be413f181f948f6359f4c256dRubin Xu                mock(NotificationManager.class), mock(DevicePolicyManager.class),
74ee67b61bb08ab09be413f181f948f6359f4c256dRubin Xu                mock(StorageManager.class));
750cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu        mStorage = new LockSettingsStorageTestable(context,
760cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu                new File(getContext().getFilesDir(), "locksettings"));
770cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu        mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
780cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu                    @Override
790cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu                    public void initialize(SQLiteDatabase db) {
800cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu                        mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
810cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu                    }
820cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu                });
83e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
84e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
85e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    @Override
86e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    protected void tearDown() throws Exception {
87e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        super.tearDown();
88e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.closeDatabase();
89e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
90e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
91e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_InitializeWorked() {
92e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
93e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
94e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
95e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
96e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
97e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_WriteThenRead() {
98e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "value", 0);
99e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
100e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
101e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
102e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
103e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
104e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_DefaultValue() {
105e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
106e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
107e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
108e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
109e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_Concurrency() {
110e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        final Object monitor = new Object();
111e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        List<Thread> threads = new ArrayList<>();
112e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        for (int i = 0; i < 100; i++) {
113e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            final int threadId = i;
114e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            threads.add(new Thread() {
115e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                @Override
116e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                public void run() {
117e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    synchronized (monitor) {
118e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        try {
119e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                            monitor.wait();
120e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        } catch (InterruptedException e) {
121e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                            return;
122e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        }
123e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
124e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
125e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
126e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
127e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
128e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
129e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
130e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
131e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
132e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
133e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    }
134e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                }
135e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            });
136e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            threads.get(i).start();
137e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
138e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "initalValue", 0);
139e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        synchronized (monitor) {
140e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            monitor.notifyAll();
141e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
142e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        for (int i = 0; i < threads.size(); i++) {
143e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            try {
144e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                threads.get(i).join();
145e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            } catch (InterruptedException e) {
146e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            }
147e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
148e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
149e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
150e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
151e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
152e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
153e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_CacheStarvedWriter() {
154e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        final CountDownLatch latch = new CountDownLatch(1);
155e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        List<Thread> threads = new ArrayList<>();
156e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        for (int i = 0; i < 100; i++) {
157e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            final int threadId = i;
158e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            threads.add(new Thread() {
159e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                @Override
160e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                public void run() {
161e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    try {
162e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        latch.await();
163e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    } catch (InterruptedException e) {
164e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        return;
165e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    }
166e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    if (threadId == 50) {
167e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("starvedWriterKey", "value", 0);
168e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    } else {
169e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("starvedWriterKey", "default", 0);
170e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    }
171e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                }
172e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            });
173e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            threads.get(i).start();
174e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
175e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        latch.countDown();
176e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        for (int i = 0; i < threads.size(); i++) {
177e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            try {
178e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                threads.get(i).join();
179e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            } catch (InterruptedException e) {
180e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            }
181e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
182e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        String cached = mStorage.readKeyValue("key", "default", 0);
183e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
184e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        String storage = mStorage.readKeyValue("key", "default", 0);
185e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("Cached value didn't match stored value", storage, cached);
186e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
187e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
188e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testRemoveUser() {
189e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "value", 0);
1901de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 0);
1911de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 0);
192e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
193e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "value", 1);
1941de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_1, 1);
1951de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_1, 1);
196e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
197e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.removeUser(0);
198e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
199e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("value", mStorage.readKeyValue("key", "default", 1));
200e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("default", mStorage.readKeyValue("key", "default", 0));
2011de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
2021de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 1);
203e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
204e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2051de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    public void testCredential_Default() {
2061de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
207e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
208e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
209e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPassword_Write() {
2101de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 0);
211e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2121de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 0);
213e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2141de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 0);
215e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
216e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
217e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPassword_WriteProfileWritesParent() {
2181de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 1);
2191de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_1, 2);
220e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2211de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 1);
2221de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_1, 2);
223e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2241de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 1);
2251de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_1, 2);
226e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
227e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
228a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai    public void testLockType_WriteProfileWritesParent() {
2291de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 10);
2301de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 20);
231a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai
2321de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
2331de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                mStorage.readCredentialHash(10).type);
2341de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
2351de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                mStorage.readCredentialHash(20).type);
236a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai        mStorage.clearCache();
2371de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
2381de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                mStorage.readCredentialHash(10).type);
2391de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
2401de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                mStorage.readCredentialHash(20).type);
241a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai    }
242a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai
243e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPassword_WriteParentWritesProfile() {
2441de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 2);
2451de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_1, 1);
246e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2471de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_1, 1);
2481de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 2);
249e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2501de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_1, 1);
2511de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 2);
252e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
253e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2541de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    public void testProfileLock_ReadWriteChildProfileLock() {
2551de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertFalse(mStorage.hasChildProfileLock(20));
2561de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        mStorage.writeChildProfileLock(20, PASSWORD_0);
2571de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
2581de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertTrue(mStorage.hasChildProfileLock(20));
2591de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        mStorage.clearCache();
2601de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
2611de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertTrue(mStorage.hasChildProfileLock(20));
262e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
263e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
264e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPattern_Write() {
2651de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 0);
266e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2671de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 0);
268e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2691de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 0);
270e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
271e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
272e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPattern_WriteProfileWritesParent() {
2731de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 1);
2741de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_1, 2);
275e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2761de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 1);
2771de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 2);
278e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2791de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 1);
2801de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 2);
281e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
282e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
283e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPattern_WriteParentWritesProfile() {
2841de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_1, 2);
2851de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 1);
286e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2871de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 1);
2881de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 2);
289e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2901de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 1);
2911de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 2);
292e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
293e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
294e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPrefetch() {
295e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "toBeFetched", 0);
2961de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 0);
297e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
298e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
299e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.prefetchUser(0);
300e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
301e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
3021de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 0);
303e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
304e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
305e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testFileLocation_Owner() {
3060cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu        LockSettingsStorage storage = new LockSettingsStorage(getContext());
307e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3081de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
3091de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
3101de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
3111de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
312e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
313e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
314e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testFileLocation_SecondaryUser() {
3150cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu        LockSettingsStorage storage = new LockSettingsStorage(getContext());
316e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3171de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
3181de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
319e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
320e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
321e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testFileLocation_ProfileToSecondary() {
3220cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu        LockSettingsStorage storage = new LockSettingsStorage(getContext());
323e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3241de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
3251de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
326e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
327e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
328e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testFileLocation_ProfileToOwner() {
3290cbc19e4a66f7db51596b57ca91afc6f5b27f3b4Rubin Xu        LockSettingsStorage storage = new LockSettingsStorage(getContext());
330e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3311de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
3321de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
333e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
334e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3353bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu    public void testSyntheticPasswordState() {
3363bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu        final byte[] data = {1,2,3,4};
3373bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu        mStorage.writeSyntheticPasswordState(10, 1234L, "state", data);
3383bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu        assertArrayEquals(data, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
3393bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu        assertEquals(null, mStorage.readSyntheticPasswordState(0, 1234L, "state"));
3403bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu
341ee67b61bb08ab09be413f181f948f6359f4c256dRubin Xu        mStorage.deleteSyntheticPasswordState(10, 1234L, "state");
3423bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu        assertEquals(null, mStorage.readSyntheticPasswordState(10, 1234L, "state"));
3433bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu    }
3443bf722a8d54ca7192dfe07ee7b73eac7d25ccac5Rubin Xu
345e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    private static void assertArrayEquals(byte[] expected, byte[] actual) {
346e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        if (!Arrays.equals(expected, actual)) {
347e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            fail("expected:<" + Arrays.toString(expected) +
348e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    "> but was:<" + Arrays.toString(actual) + ">");
349e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
350e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
3511de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
3521de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private void writePasswordBytes(byte[] password, int userId) {
3531de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        mStorage.writeCredentialHash(CredentialHash.create(
3541de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
3551de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    }
3561de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
3571de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private void writePatternBytes(byte[] pattern, int userId) {
3581de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        mStorage.writeCredentialHash(CredentialHash.create(
3591de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
3601de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    }
3611de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
3621de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private void assertPasswordBytes(byte[] password, int userId) {
3631de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        CredentialHash cred = mStorage.readCredentialHash(userId);
3641de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
3651de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertArrayEquals(password, cred.hash);
3661de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    }
3671de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
3681de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private void assertPatternBytes(byte[] pattern, int userId) {
3691de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        CredentialHash cred = mStorage.readCredentialHash(userId);
3701de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
3711de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertArrayEquals(pattern, cred.hash);
3721de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    }
373e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos}
374