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.StorageManager;
41 import android.os.storage.IStorageManager;
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 
50 import org.mockito.invocation.InvocationOnMock;
51 import org.mockito.stubbing.Answer;
52 
53 import java.io.File;
54 import java.util.ArrayList;
55 import java.util.Arrays;
56 
57 
58 public class BaseLockSettingsServiceTests extends AndroidTestCase {
59     protected static final int PRIMARY_USER_ID = 0;
60     protected static final int MANAGED_PROFILE_USER_ID = 12;
61     protected static final int TURNED_OFF_PROFILE_USER_ID = 17;
62     protected static final int SECONDARY_USER_ID = 20;
63 
64     private static final UserInfo PRIMARY_USER_INFO = new UserInfo(PRIMARY_USER_ID, null, null,
65             UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY);
66     private static final UserInfo SECONDARY_USER_INFO = new UserInfo(SECONDARY_USER_ID, null, null,
67             UserInfo.FLAG_INITIALIZED);
68 
69     private ArrayList<UserInfo> mPrimaryUserProfiles = new ArrayList<>();
70 
71     LockSettingsService mService;
72     LockSettingsInternal mLocalService;
73 
74     MockLockSettingsContext mContext;
75     LockSettingsStorageTestable mStorage;
76 
77     LockPatternUtils mLockPatternUtils;
78     FakeGateKeeperService mGateKeeperService;
79     NotificationManager mNotificationManager;
80     UserManager mUserManager;
81     FakeStorageManager mStorageManager;
82     IActivityManager mActivityManager;
83     DevicePolicyManager mDevicePolicyManager;
84     DevicePolicyManagerInternal mDevicePolicyManagerInternal;
85     KeyStore mKeyStore;
86     MockSyntheticPasswordManager mSpManager;
87     IAuthSecret mAuthSecretService;
88 
89     @Override
setUp()90     protected void setUp() throws Exception {
91         super.setUp();
92 
93         mGateKeeperService = new FakeGateKeeperService();
94         mNotificationManager = mock(NotificationManager.class);
95         mUserManager = mock(UserManager.class);
96         mStorageManager = new FakeStorageManager();
97         mActivityManager = mock(IActivityManager.class);
98         mDevicePolicyManager = mock(DevicePolicyManager.class);
99         mDevicePolicyManagerInternal = mock(DevicePolicyManagerInternal.class);
100 
101         LocalServices.removeServiceForTest(LockSettingsInternal.class);
102         LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
103         LocalServices.addService(DevicePolicyManagerInternal.class, mDevicePolicyManagerInternal);
104 
105         mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
106                 mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class),
107                 mock(KeyguardManager.class));
108         mStorage = new LockSettingsStorageTestable(mContext,
109                 new File(getContext().getFilesDir(), "locksettings"));
110         File storageDir = mStorage.mStorageDir;
111         if (storageDir.exists()) {
112             FileUtils.deleteContents(storageDir);
113         } else {
114             storageDir.mkdirs();
115         }
116 
117         mLockPatternUtils = new LockPatternUtils(mContext) {
118             @Override
119             public ILockSettings getLockSettings() {
120                 return mService;
121             }
122         };
123         mSpManager = new MockSyntheticPasswordManager(mContext, mStorage, mGateKeeperService,
124                 mUserManager);
125         mAuthSecretService = mock(IAuthSecret.class);
126         mService = new LockSettingsServiceTestable(mContext, mLockPatternUtils, mStorage,
127                 mGateKeeperService, mKeyStore, setUpStorageManagerMock(), mActivityManager,
128                 mSpManager, mAuthSecretService);
129         when(mUserManager.getUserInfo(eq(PRIMARY_USER_ID))).thenReturn(PRIMARY_USER_INFO);
130         mPrimaryUserProfiles.add(PRIMARY_USER_INFO);
131         installChildProfile(MANAGED_PROFILE_USER_ID);
132         installAndTurnOffChildProfile(TURNED_OFF_PROFILE_USER_ID);
133         when(mUserManager.getProfiles(eq(PRIMARY_USER_ID))).thenReturn(mPrimaryUserProfiles);
134         when(mUserManager.getUserInfo(eq(SECONDARY_USER_ID))).thenReturn(SECONDARY_USER_INFO);
135 
136         final ArrayList<UserInfo> allUsers = new ArrayList<>(mPrimaryUserProfiles);
137         allUsers.add(SECONDARY_USER_INFO);
138         when(mUserManager.getUsers(anyBoolean())).thenReturn(allUsers);
139 
140         when(mActivityManager.unlockUser(anyInt(), any(), any(), any())).thenAnswer(
141                 new Answer<Boolean>() {
142             @Override
143             public Boolean answer(InvocationOnMock invocation) throws Throwable {
144                 Object[] args = invocation.getArguments();
145                 mStorageManager.unlockUser((int)args[0], (byte[])args[2],
146                         (IProgressListener) args[3]);
147                 return true;
148             }
149         });
150 
151         // Adding a fake Device Owner app which will enable escrow token support in LSS.
152         when(mDevicePolicyManager.getDeviceOwnerComponentOnAnyUser()).thenReturn(
153                 new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
154         mLocalService = LocalServices.getService(LockSettingsInternal.class);
155     }
156 
installChildProfile(int profileId)157     private UserInfo installChildProfile(int profileId) {
158         final UserInfo userInfo = new UserInfo(
159             profileId, null, null, UserInfo.FLAG_INITIALIZED | UserInfo.FLAG_MANAGED_PROFILE);
160         mPrimaryUserProfiles.add(userInfo);
161         when(mUserManager.getUserInfo(eq(profileId))).thenReturn(userInfo);
162         when(mUserManager.getProfileParent(eq(profileId))).thenReturn(PRIMARY_USER_INFO);
163         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(true);
164         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(true);
165         return userInfo;
166     }
167 
installAndTurnOffChildProfile(int profileId)168     private UserInfo installAndTurnOffChildProfile(int profileId) {
169         final UserInfo userInfo = installChildProfile(profileId);
170         userInfo.flags |= UserInfo.FLAG_QUIET_MODE;
171         when(mUserManager.isUserRunning(eq(profileId))).thenReturn(false);
172         when(mUserManager.isUserUnlocked(eq(profileId))).thenReturn(false);
173         return userInfo;
174     }
175 
setUpStorageManagerMock()176     private IStorageManager setUpStorageManagerMock() throws RemoteException {
177         final IStorageManager sm = mock(IStorageManager.class);
178 
179         doAnswer(new Answer<Void>() {
180             @Override
181             public Void answer(InvocationOnMock invocation) throws Throwable {
182                 Object[] args = invocation.getArguments();
183                 mStorageManager.addUserKeyAuth((int) args[0] /* userId */,
184                         (int) args[1] /* serialNumber */,
185                         (byte[]) args[2] /* token */,
186                         (byte[]) args[3] /* secret */);
187                 return null;
188             }
189         }).when(sm).addUserKeyAuth(anyInt(), anyInt(), any(), any());
190 
191         doAnswer(
192                 new Answer<Void>() {
193             @Override
194             public Void answer(InvocationOnMock invocation) throws Throwable {
195                 Object[] args = invocation.getArguments();
196                 mStorageManager.fixateNewestUserKeyAuth((int) args[0] /* userId */);
197                 return null;
198             }
199         }).when(sm).fixateNewestUserKeyAuth(anyInt());
200         return sm;
201     }
202 
203     @Override
tearDown()204     protected void tearDown() throws Exception {
205         super.tearDown();
206         mStorage.closeDatabase();
207         File db = getContext().getDatabasePath("locksettings.db");
208         assertTrue(!db.exists() || db.delete());
209 
210         File storageDir = mStorage.mStorageDir;
211         assertTrue(FileUtils.deleteContents(storageDir));
212     }
213 
assertNotEquals(long expected, long actual)214     protected void assertNotEquals(long expected, long actual) {
215         assertTrue(expected != actual);
216     }
217 
assertArrayEquals(byte[] expected, byte[] actual)218     protected static void assertArrayEquals(byte[] expected, byte[] actual) {
219         assertTrue(Arrays.equals(expected, actual));
220     }
221 
assertArrayNotEquals(byte[] expected, byte[] actual)222     protected static void assertArrayNotEquals(byte[] expected, byte[] actual) {
223         assertFalse(Arrays.equals(expected, actual));
224     }
225 }
226