• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.server.locksettings;
18 
19 import static org.mockito.Matchers.any;
20 import static org.mockito.Matchers.anyBoolean;
21 import static org.mockito.Matchers.anyInt;
22 import static org.mockito.Matchers.eq;
23 import static org.mockito.Mockito.doAnswer;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.when;
26 
27 import android.app.IActivityManager;
28 import android.app.KeyguardManager;
29 import android.app.NotificationManager;
30 import android.app.admin.DevicePolicyManager;
31 import android.app.admin.DevicePolicyManagerInternal;
32 import android.app.trust.TrustManager;
33 import android.content.ComponentName;
34 import android.content.pm.UserInfo;
35 import android.hardware.authsecret.V1_0.IAuthSecret;
36 import android.os.FileUtils;
37 import android.os.IProgressListener;
38 import android.os.RemoteException;
39 import android.os.UserManager;
40 import android.os.storage.IStorageManager;
41 import android.os.storage.StorageManager;
42 import android.security.KeyStore;
43 import android.test.AndroidTestCase;
44 
45 import com.android.internal.widget.ILockSettings;
46 import com.android.internal.widget.LockPatternUtils;
47 import com.android.internal.widget.LockSettingsInternal;
48 import com.android.server.LocalServices;
49 import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
50 import com.android.server.wm.WindowManagerInternal;
51 
52 import org.mockito.invocation.InvocationOnMock;
53 import org.mockito.stubbing.Answer;
54 
55 import java.io.File;
56 import java.util.ArrayList;
57 import java.util.Arrays;
58 
59 
60 public abstract class BaseLockSettingsServiceTests extends AndroidTestCase {
61     protected static final int PRIMARY_USER_ID = 0;
62     protected static final int MANAGED_PROFILE_USER_ID = 12;
63     protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
64     protected static final int SECONDARY_USER_ID = 20;
65 
66     private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
67             UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
68     private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
69             UserInfo.FLAG_INITIALIZED);
70 
71     private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
72 
73     LockSettingsService mService;
74     LockSettingsInternal mLocalService;
75 
76     MockLockSettingsContext mContext;
77     LockSettingsStorageTestable mStorage;
78 
79     LockPatternUtils mLockPatternUtils;
80     FakeGateKeeperService mGateKeeperService;
81     NotificationManager mNotificationManager;
82     UserManager mUserManager;
83     FakeStorageManager mStorageManager;
84     IActivityManager mActivityManager;
85     DevicePolicyManager mDevicePolicyManager;
86     DevicePolicyManagerInternal mDevicePolicyManagerInternal;
87     KeyStore mKeyStore;
88     MockSyntheticPasswordManager mSpManager;
89     IAuthSecret mAuthSecretService;
90     WindowManagerInternal mMockWindowManager;
91     FakeGsiService mGsiService;
92     PasswordSlotManagerTestable mPasswordSlotManager;
93     RecoverableKeyStoreManager mRecoverableKeyStoreManager;
94     protected boolean mHasSecureLockScreen;
95 
96     @Override
setUp()97     protected void setUp() throws Exception {
98         super.setUp();
99 
100         mGateKeeperService = new FakeGateKeeperService();
101         mNotificationManager = mock(NotificationManager.class);
102         mUserManager = mock(UserManager.class);
103         mStorageManager = new FakeStorageManager();
104         mActivityManager = mock(IActivityManager.class);
105         mDevicePolicyManager = mock(DevicePolicyManager.class);
106         mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class);
107         mMockWindowManager = mock(WindowManagerInternal.class);
108         mGsiService = new FakeGsiService();
109         mPasswordSlotManager = new PasswordSlotManagerTestable();
110         mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class);
111 
112         LocalServices.removeServiceForTest(LockSettingsInternal.class);
113         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
114         LocalServices.removeServiceForTest(WindowManagerInternal.class);
115         LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal);
116         LocalServices.addService(WindowManagerInternal.class, mMockWindowManager);
117 
118         mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
119                 mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class),
120                 mock(KeyguardManager.class));
121         mStorage = new LockSettingsStorageTestable(mContext,
122                 new File(getContext().getFilesDir(), "locksettings"));
123         File storageDir = mStorage.mStorageDir;
124         if (storageDir.exists()) {
125             FileUtils.deleteContents(storageDir);
126         } else {
127             storageDir.mkdirs();
128         }
129 
130         mHasSecureLockScreen = true;
131         mLockPatternUtils = new LockPatternUtils(mContext) {
132             @Override
133             public ILockSettings getLockSettings() {
134                 return mService;
135             }
136 
137             @Override
138             public boolean hasSecureLockScreen() {
139                 return mHasSecureLockScreen;
140             }
141         };
142         mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService,
143                 mUserManager, mPasswordSlotManager);
144         mAuthSecretService = mock(IAuthSecret.class);
145         mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils, mStorage,
146                 mGateKeeperService, mKeyStore, setUpStorageManagerMock(), mActivityManager,
147                 mSpManager, mAuthSecretService, mGsiService, mRecoverableKeyStoreManager);
148         when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
149         mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
150         installChildProfile(MANAGED_PROFILE_USER_ID);
151         installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
152         for (UserInfo profile : mPrimaryUserProfiles) {
153             when(mUserManager.getProfiles(eq(profile.id))).thenReturn(mPrimaryUserProfiles);
154         }
155         when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
156 
157         final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
158         allUsers.add(SECONDARY_USER_INFO);
159         when(mUserManager.getUsers(anyBoolean())).thenReturn(allUsers);
160 
161         when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
162                 new Answer<Boolean>() {
163             @Override
164             public Boolean answer(InvocationOnMock invocation) throws Throwable {
165                 Object[] args = invocation.getArguments();
166                 mStorageManager.unlockUser((int)args[0], (byte[])args[2],
167                         (IProgressListener) args[3]);
168                 return true;
169             }
170         });
171 
172         // Adding a fake Device Owner app which will enable escrow token support in LSS.
173         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
174                 new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
175         mLocalService = LocalServices.getService(LockSettingsInternal.class);
176     }
177 
installChildProfile(int profileId)178     private UserInfo installChildProfile(int profileId) {
179         final UserInfo userInfo = new UserInfo(
180             profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
181         userInfo.profileGroupId = PRIMARY_USER_ID;
182         mPrimaryUserProfiles.add(userInfo);
183         when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
184         when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
185         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
186         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
187         return userInfo;
188     }
189 
installAndTurnOffChildProfile(int profileId)190     private UserInfo installAndTurnOffChildProfile(int profileId) {
191         final UserInfo userInfo = installChildProfile(profileId);
192         userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
193         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
194         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
195         return userInfo;
196     }
197 
setUpStorageManagerMock()198     private IStorageManager setUpStorageManagerMock() throws RemoteException {
199         final IStorageManager sm = mock(IStorageManager.class);
200 
201         doAnswer(new Answer<Void>() {
202             @Override
203             public Void answer(InvocationOnMock invocation) throws Throwable {
204                 Object[] args = invocation.getArguments();
205                 mStorageManager.addUserKeyAuth((int) args[0] /* userId */,
206                         (int) args[1] /* serialNumber */,
207                         (byte[]) args[2] /* token */,
208                         (byte[]) args[3] /* secret */);
209                 return null;
210             }
211         }).when(sm).addUserKeyAuth(anyInt(), anyInt(), any(), any());
212 
213         doAnswer(
214                 new Answer<Void>() {
215             @Override
216             public Void answer(InvocationOnMock invocation) throws Throwable {
217                 Object[] args = invocation.getArguments();
218                 mStorageManager.fixateNewestUserKeyAuth((int) args[0] /* userId */);
219                 return null;
220             }
221         }).when(sm).fixateNewestUserKeyAuth(anyInt());
222         return sm;
223     }
224 
225     @Override
tearDown()226     protected void tearDown() throws Exception {
227         super.tearDown();
228         mStorage.closeDatabase();
229         File db = getContext().getDatabasePath("locksettings.db");
230         assertTrue(!db.exists() || db.delete());
231 
232         File storageDir = mStorage.mStorageDir;
233         assertTrue(FileUtils.deleteContents(storageDir));
234 
235         mPasswordSlotManager.cleanup();
236     }
237 
flushHandlerTasks()238     protected void flushHandlerTasks() {
239         mService.mHandler.runWithScissors(() -> { }, 0 /*now*/); // Flush runnables on handler
240     }
241 
assertNotEquals(long expected, long actual)242     protected void assertNotEquals(long expected, long actual) {
243         assertTrue(expected != actual);
244     }
245 
assertArrayEquals(byte[] expected, byte[] actual)246     protected static void assertArrayEquals(byte[] expected, byte[] actual) {
247         assertTrue(Arrays.equals(expected, actual));
248     }
249 
assertArrayNotEquals(byte[] expected, byte[] actual)250     protected static void assertArrayNotEquals(byte[] expected, byte[] actual) {
251         assertFalse(Arrays.equals(expected, actual));
252     }
253 }
254