LockSettingsStorageTests.java revision 1de89b3bec2f296763f3ecde9a36ecbca2110f3d
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
23e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.content.Context;
24e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.content.ContextWrapper;
25e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.content.pm.UserInfo;
26e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.database.sqlite.SQLiteDatabase;
27e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.os.FileUtils;
28e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.os.UserManager;
29e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport android.test.AndroidTestCase;
30e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
311de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xuimport com.android.internal.widget.LockPatternUtils;
321de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xuimport com.android.server.LockSettingsStorage.CredentialHash;
33e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.io.File;
34e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.util.ArrayList;
35e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.util.Arrays;
36e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.util.List;
37e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roosimport java.util.concurrent.CountDownLatch;
38e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
391de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu/**
401de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu * runtest frameworks-services -c com.android.server.LockSettingsStorageTests
411de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu */
42e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roospublic class LockSettingsStorageTests extends AndroidTestCase {
431de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private final byte[] PASSWORD_0 = "thepassword0".getBytes();
441de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private final byte[] PASSWORD_1 = "password1".getBytes();
451de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private final byte[] PATTERN_0 = "123654".getBytes();
461de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private final byte[] PATTERN_1 = "147852369".getBytes();
471de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
48e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    LockSettingsStorage mStorage;
49e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    File mStorageDir;
50e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
51e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    private File mDb;
52e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
53e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    @Override
54e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    protected void setUp() throws Exception {
55e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        super.setUp();
56e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorageDir = new File(getContext().getFilesDir(), "locksettings");
57e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mDb = getContext().getDatabasePath("locksettings.db");
58e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
59e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertTrue(mStorageDir.exists() || mStorageDir.mkdirs());
60e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertTrue(FileUtils.deleteContents(mStorageDir));
61e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertTrue(!mDb.exists() || mDb.delete());
62e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
63e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        final Context ctx = getContext();
641de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        final UserManager mockUserManager = mock(UserManager.class);
651de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        // User 2 is a profile of user 1.
661de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        when(mockUserManager.getProfileParent(eq(2))).thenReturn(new UserInfo(1, "name", 0));
671de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        // User 3 is a profile of user 0.
681de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        when(mockUserManager.getProfileParent(eq(3))).thenReturn(new UserInfo(0, "name", 0));
69e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        setContext(new ContextWrapper(ctx) {
70e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            @Override
71e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            public Object getSystemService(String name) {
72e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                if (USER_SERVICE.equals(name)) {
731de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                    return mockUserManager;
74e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                }
75e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                return super.getSystemService(name);
76e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            }
77e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        });
78e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
79e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage = new LockSettingsStorage(getContext(), new LockSettingsStorage.Callback() {
80e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            @Override
81e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            public void initialize(SQLiteDatabase db) {
82e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                mStorage.writeKeyValue(db, "initializedKey", "initialValue", 0);
83e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            }
84e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }) {
85e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            @Override
86e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            String getLockPatternFilename(int userId) {
87e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                return new File(mStorageDir,
88e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        super.getLockPatternFilename(userId).replace('/', '-')).getAbsolutePath();
89e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            }
90e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
91e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            @Override
92e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            String getLockPasswordFilename(int userId) {
93e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                return new File(mStorageDir,
94e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        super.getLockPasswordFilename(userId).replace('/', '-')).getAbsolutePath();
95e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            }
96a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai
97a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai            @Override
98a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai            String getChildProfileLockFile(int userId) {
99a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai                return new File(mStorageDir,
100a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai                        super.getChildProfileLockFile(userId).replace('/', '-')).getAbsolutePath();
101a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai            }
102e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        };
103e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
104e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
105e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    @Override
106e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    protected void tearDown() throws Exception {
107e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        super.tearDown();
108e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.closeDatabase();
109e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
110e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
111e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_InitializeWorked() {
112e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
113e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
114e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("initialValue", mStorage.readKeyValue("initializedKey", "default", 0));
115e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
116e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
117e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_WriteThenRead() {
118e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "value", 0);
119e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
120e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
121e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("value", mStorage.readKeyValue("key", "default", 0));
122e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
123e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
124e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_DefaultValue() {
125e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("default", mStorage.readKeyValue("unititialized key", "default", 0));
126e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("default2", mStorage.readKeyValue("unititialized key", "default2", 0));
127e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
128e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
129e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_Concurrency() {
130e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        final Object monitor = new Object();
131e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        List<Thread> threads = new ArrayList<>();
132e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        for (int i = 0; i < 100; i++) {
133e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            final int threadId = i;
134e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            threads.add(new Thread() {
135e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                @Override
136e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                public void run() {
137e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    synchronized (monitor) {
138e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        try {
139e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                            monitor.wait();
140e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        } catch (InterruptedException e) {
141e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                            return;
142e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        }
143e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "1 from thread " + threadId, 0);
144e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
145e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "2 from thread " + threadId, 0);
146e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
147e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "3 from thread " + threadId, 0);
148e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
149e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "4 from thread " + threadId, 0);
150e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
151e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("key", "5 from thread " + threadId, 0);
152e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("key", "default", 0);
153e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    }
154e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                }
155e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            });
156e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            threads.get(i).start();
157e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
158e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "initalValue", 0);
159e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        synchronized (monitor) {
160e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            monitor.notifyAll();
161e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
162e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        for (int i = 0; i < threads.size(); i++) {
163e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            try {
164e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                threads.get(i).join();
165e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            } catch (InterruptedException e) {
166e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            }
167e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
168e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
169e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
170e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals('5', mStorage.readKeyValue("key", "default", 0).charAt(0));
171e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
172e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
173e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testKeyValue_CacheStarvedWriter() {
174e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        final CountDownLatch latch = new CountDownLatch(1);
175e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        List<Thread> threads = new ArrayList<>();
176e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        for (int i = 0; i < 100; i++) {
177e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            final int threadId = i;
178e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            threads.add(new Thread() {
179e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                @Override
180e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                public void run() {
181e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    try {
182e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        latch.await();
183e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    } catch (InterruptedException e) {
184e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        return;
185e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    }
186e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    if (threadId == 50) {
187e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.writeKeyValue("starvedWriterKey", "value", 0);
188e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    } else {
189e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                        mStorage.readKeyValue("starvedWriterKey", "default", 0);
190e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    }
191e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                }
192e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            });
193e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            threads.get(i).start();
194e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
195e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        latch.countDown();
196e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        for (int i = 0; i < threads.size(); i++) {
197e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            try {
198e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                threads.get(i).join();
199e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            } catch (InterruptedException e) {
200e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            }
201e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
202e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        String cached = mStorage.readKeyValue("key", "default", 0);
203e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
204e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        String storage = mStorage.readKeyValue("key", "default", 0);
205e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("Cached value didn't match stored value", storage, cached);
206e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
207e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
208e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testRemoveUser() {
209e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "value", 0);
2101de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 0);
2111de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 0);
212e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
213e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "value", 1);
2141de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_1, 1);
2151de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_1, 1);
216e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
217e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.removeUser(0);
218e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
219e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("value", mStorage.readKeyValue("key", "default", 1));
220e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("default", mStorage.readKeyValue("key", "default", 0));
2211de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_NONE, mStorage.readCredentialHash(0).type);
2221de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 1);
223e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
224e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2251de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    public void testCredential_Default() {
2261de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(mStorage.readCredentialHash(0).type, LockPatternUtils.CREDENTIAL_TYPE_NONE);
227e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
228e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
229e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPassword_Write() {
2301de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 0);
231e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2321de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 0);
233e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2341de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 0);
235e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
236e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
237e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPassword_WriteProfileWritesParent() {
2381de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 1);
2391de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_1, 2);
240e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2411de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 1);
2421de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_1, 2);
243e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2441de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 1);
2451de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_1, 2);
246e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
247e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
248a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai    public void testLockType_WriteProfileWritesParent() {
2491de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 10);
2501de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 20);
251a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai
2521de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
2531de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                mStorage.readCredentialHash(10).type);
2541de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
2551de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                mStorage.readCredentialHash(20).type);
256a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai        mStorage.clearCache();
2571de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD,
2581de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                mStorage.readCredentialHash(10).type);
2591de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN,
2601de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                mStorage.readCredentialHash(20).type);
261a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai    }
262a46b40fd5c3603b59c4a0d5d5fa4b0547fc26affRicky Wai
263e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPassword_WriteParentWritesProfile() {
2641de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_0, 2);
2651de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePasswordBytes(PASSWORD_1, 1);
266e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2671de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_1, 1);
2681de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 2);
269e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2701de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_1, 1);
2711de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPasswordBytes(PASSWORD_0, 2);
272e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
273e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2741de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    public void testProfileLock_ReadWriteChildProfileLock() {
2751de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertFalse(mStorage.hasChildProfileLock(20));
2761de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        mStorage.writeChildProfileLock(20, PASSWORD_0);
2771de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
2781de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertTrue(mStorage.hasChildProfileLock(20));
2791de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        mStorage.clearCache();
2801de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertArrayEquals(PASSWORD_0, mStorage.readChildProfileLock(20));
2811de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertTrue(mStorage.hasChildProfileLock(20));
282e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
283e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
284e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPattern_Write() {
2851de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 0);
286e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2871de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 0);
288e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2891de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 0);
290e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
291e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
292e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPattern_WriteProfileWritesParent() {
2931de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 1);
2941de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_1, 2);
295e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
2961de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 1);
2971de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 2);
298e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
2991de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 1);
3001de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 2);
301e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
302e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
303e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPattern_WriteParentWritesProfile() {
3041de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_1, 2);
3051de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 1);
306e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3071de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 1);
3081de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 2);
309e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
3101de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 1);
3111de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_1, 2);
312e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
313e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
314e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testPrefetch() {
315e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.writeKeyValue("key", "toBeFetched", 0);
3161de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        writePatternBytes(PATTERN_0, 0);
317e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
318e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.clearCache();
319e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        mStorage.prefetchUser(0);
320e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
321e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        assertEquals("toBeFetched", mStorage.readKeyValue("key", "default", 0));
3221de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertPatternBytes(PATTERN_0, 0);
323e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
324e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
325e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testFileLocation_Owner() {
326e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        LockSettingsStorage storage = new LockSettingsStorage(getContext(), null);
327e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3281de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/gesture.key", storage.getLegacyLockPatternFilename(0));
3291de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/password.key", storage.getLegacyLockPasswordFilename(0));
3301de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/gatekeeper.pattern.key", storage.getLockPatternFilename(0));
3311de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/gatekeeper.password.key", storage.getLockPasswordFilename(0));
332e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
333e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
334e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testFileLocation_SecondaryUser() {
335e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        LockSettingsStorage storage = new LockSettingsStorage(getContext(), null);
336e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3371de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/1/gatekeeper.pattern.key", storage.getLockPatternFilename(1));
3381de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/1/gatekeeper.password.key", storage.getLockPasswordFilename(1));
339e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
340e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
341e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testFileLocation_ProfileToSecondary() {
342e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        LockSettingsStorage storage = new LockSettingsStorage(getContext(), null);
343e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3441de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/2/gatekeeper.pattern.key", storage.getLockPatternFilename(2));
3451de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/2/gatekeeper.password.key", storage.getLockPasswordFilename(2));
346e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
347e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
348e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    public void testFileLocation_ProfileToOwner() {
349e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        LockSettingsStorage storage = new LockSettingsStorage(getContext(), null);
350e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
3511de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/3/gatekeeper.pattern.key", storage.getLockPatternFilename(3));
3521de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals("/data/system/users/3/gatekeeper.password.key", storage.getLockPasswordFilename(3));
353e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
354e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos
355e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    private static void assertArrayEquals(byte[] expected, byte[] actual) {
356e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        if (!Arrays.equals(expected, actual)) {
357e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos            fail("expected:<" + Arrays.toString(expected) +
358e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos                    "> but was:<" + Arrays.toString(actual) + ">");
359e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos        }
360e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos    }
3611de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
3621de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private void writePasswordBytes(byte[] password, int userId) {
3631de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        mStorage.writeCredentialHash(CredentialHash.create(
3641de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                password, LockPatternUtils.CREDENTIAL_TYPE_PASSWORD), userId);
3651de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    }
3661de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
3671de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private void writePatternBytes(byte[] pattern, int userId) {
3681de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        mStorage.writeCredentialHash(CredentialHash.create(
3691de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu                pattern, LockPatternUtils.CREDENTIAL_TYPE_PATTERN), userId);
3701de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    }
3711de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
3721de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private void assertPasswordBytes(byte[] password, int userId) {
3731de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        CredentialHash cred = mStorage.readCredentialHash(userId);
3741de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PASSWORD, cred.type);
3751de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertArrayEquals(password, cred.hash);
3761de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    }
3771de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu
3781de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    private void assertPatternBytes(byte[] pattern, int userId) {
3791de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        CredentialHash cred = mStorage.readCredentialHash(userId);
3801de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertEquals(LockPatternUtils.CREDENTIAL_TYPE_PATTERN, cred.type);
3811de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu        assertArrayEquals(pattern, cred.hash);
3821de89b3bec2f296763f3ecde9a36ecbca2110f3dRubin Xu    }
383e542499a304f067372d85722e11a74b4e56b0bd7Adrian Roos}
384