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