1 /* 2 * Copyright (C) 2018 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.wm; 18 19 import static android.os.Process.FIRST_APPLICATION_UID; 20 import static android.os.Process.NFC_UID; 21 import static android.os.Process.SYSTEM_UID; 22 import static android.os.UserHandle.USER_ALL; 23 import static android.os.UserHandle.USER_SYSTEM; 24 25 import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock; 26 27 import static org.hamcrest.Matchers.containsString; 28 import static org.junit.Assert.assertFalse; 29 import static org.junit.Assert.assertThat; 30 import static org.junit.Assert.assertTrue; 31 import static org.junit.Assert.fail; 32 33 import android.os.Binder; 34 import android.os.Handler; 35 import android.os.IBinder; 36 import android.os.UserHandle; 37 import android.platform.test.annotations.Presubmit; 38 import android.util.SparseBooleanArray; 39 40 import com.android.server.wm.LockTaskController.LockTaskToken; 41 42 import org.junit.Before; 43 import org.junit.Test; 44 45 import java.lang.reflect.Constructor; 46 47 @Presubmit 48 public class KeyguardDisableHandlerTest { 49 50 private KeyguardDisableHandler mKeyguardDisable; 51 52 private boolean mKeyguardEnabled; 53 private SparseBooleanArray mKeyguardSecure = new SparseBooleanArray(); 54 private SparseBooleanArray mDpmRequiresPassword = new SparseBooleanArray(); 55 56 @Before setUp()57 public void setUp() throws Exception { 58 mKeyguardEnabled = true; 59 60 mKeyguardDisable = new KeyguardDisableHandler(new KeyguardDisableHandler.Injector() { 61 @Override 62 public boolean dpmRequiresPassword(int userId) { 63 return mDpmRequiresPassword.get(userId); 64 } 65 66 @Override 67 public boolean isKeyguardSecure(int userId) { 68 return mKeyguardSecure.get(userId); 69 } 70 71 @Override 72 public int getProfileParentId(int userId) { 73 return userId; 74 } 75 76 @Override 77 public void enableKeyguard(boolean enabled) { 78 mKeyguardEnabled = enabled; 79 } 80 }, mock(Handler.class)) { 81 @Override 82 public void disableKeyguard(IBinder token, String tag, int callingUid, int userId) { 83 super.disableKeyguard(token, tag, callingUid, userId); 84 // In the actual code, the update is posted to the handler thread. Eagerly update 85 // here to simplify the test. 86 updateKeyguardEnabled(userId); 87 } 88 89 @Override 90 public void reenableKeyguard(IBinder token, int callingUid, int userId) { 91 super.reenableKeyguard(token, callingUid, userId); 92 // In the actual code, the update is posted to the handler thread. Eagerly update 93 // here to simplify the test. 94 updateKeyguardEnabled(userId); 95 } 96 }; 97 } 98 99 @Test starts_enabled()100 public void starts_enabled() { 101 assertTrue(mKeyguardEnabled); 102 mKeyguardDisable.updateKeyguardEnabled(USER_ALL); 103 assertTrue(mKeyguardEnabled); 104 } 105 106 @Test disable_fromApp_disables()107 public void disable_fromApp_disables() { 108 mKeyguardDisable.disableKeyguard(new Binder(), "Tag", FIRST_APPLICATION_UID, USER_SYSTEM); 109 assertFalse(mKeyguardEnabled); 110 } 111 112 @Test disable_fromApp_secondaryUser_disables()113 public void disable_fromApp_secondaryUser_disables() { 114 mKeyguardDisable.setCurrentUser(1); 115 mKeyguardDisable.disableKeyguard(new Binder(), "Tag", 116 UserHandle.getUid(1, FIRST_APPLICATION_UID), 1); 117 assertFalse(mKeyguardEnabled); 118 } 119 120 @Test disable_fromSystem_LockTask_disables()121 public void disable_fromSystem_LockTask_disables() { 122 mKeyguardDisable.disableKeyguard(createLockTaskToken(), "Tag", SYSTEM_UID, USER_SYSTEM); 123 assertFalse(mKeyguardEnabled); 124 } 125 126 @Test disable_fromSystem_genericToken_fails()127 public void disable_fromSystem_genericToken_fails() { 128 try { 129 mKeyguardDisable.disableKeyguard(new Binder(), "Tag", SYSTEM_UID, USER_SYSTEM); 130 fail("Expected exception not thrown"); 131 } catch (UnsupportedOperationException e) { 132 assertThat(e.getMessage(), containsString("Only apps can use the KeyguardLock API")); 133 } 134 assertTrue(mKeyguardEnabled); 135 } 136 137 @Test disable_fromNonApp_genericToken_fails()138 public void disable_fromNonApp_genericToken_fails() { 139 try { 140 mKeyguardDisable.disableKeyguard(new Binder(), "Tag", NFC_UID, USER_SYSTEM); 141 fail("Expected exception not thrown"); 142 } catch (UnsupportedOperationException e) { 143 assertThat(e.getMessage(), containsString("Only apps can use the KeyguardLock API")); 144 } 145 assertTrue(mKeyguardEnabled); 146 } 147 148 @Test disable_fromApp_secure_staysEnabled()149 public void disable_fromApp_secure_staysEnabled() { 150 configureIsSecure(true, USER_SYSTEM); 151 mKeyguardDisable.disableKeyguard(new Binder(), "Tag", FIRST_APPLICATION_UID, USER_SYSTEM); 152 assertTrue(mKeyguardEnabled); 153 } 154 155 @Test disable_fromApp_dpmRequiresPassword_staysEnabled()156 public void disable_fromApp_dpmRequiresPassword_staysEnabled() { 157 configureDpmRequiresPassword(true, USER_SYSTEM); 158 mKeyguardDisable.disableKeyguard(new Binder(), "Tag", FIRST_APPLICATION_UID, USER_SYSTEM); 159 assertTrue(mKeyguardEnabled); 160 } 161 162 @Test disable_fromSystem_LockTask_secure_disables()163 public void disable_fromSystem_LockTask_secure_disables() { 164 configureIsSecure(true, USER_SYSTEM); 165 mKeyguardDisable.disableKeyguard(createLockTaskToken(), "Tag", SYSTEM_UID, USER_SYSTEM); 166 assertFalse(mKeyguardEnabled); 167 } 168 169 @Test disable_fromSystem_LockTask_requiresDpm_staysEnabled()170 public void disable_fromSystem_LockTask_requiresDpm_staysEnabled() { 171 configureDpmRequiresPassword(true, USER_SYSTEM); 172 mKeyguardDisable.disableKeyguard(createLockTaskToken(), "Tag", SYSTEM_UID, USER_SYSTEM); 173 assertTrue(mKeyguardEnabled); 174 } 175 176 @Test disable_fromApp_thenSecure_reenables()177 public void disable_fromApp_thenSecure_reenables() { 178 mKeyguardDisable.disableKeyguard(new Binder(), "Tag", FIRST_APPLICATION_UID, USER_SYSTEM); 179 configureIsSecure(true, USER_SYSTEM); 180 assertTrue(mKeyguardEnabled); 181 } 182 183 @Test disable_fromSystem_LockTask_thenRequiresDpm_reenables()184 public void disable_fromSystem_LockTask_thenRequiresDpm_reenables() { 185 mKeyguardDisable.disableKeyguard(createLockTaskToken(), "Tag", SYSTEM_UID, USER_SYSTEM); 186 configureDpmRequiresPassword(true, USER_SYSTEM); 187 assertTrue(mKeyguardEnabled); 188 } 189 190 @Test user_switch_to_enabledUser_applies_enabled()191 public void user_switch_to_enabledUser_applies_enabled() { 192 mKeyguardDisable.disableKeyguard(createLockTaskToken(), "Tag", SYSTEM_UID, USER_SYSTEM); 193 assertFalse("test setup failed", mKeyguardEnabled); 194 mKeyguardDisable.setCurrentUser(1); 195 assertTrue(mKeyguardEnabled); 196 } 197 198 @Test user_switch_to_disabledUser_applies_disabled()199 public void user_switch_to_disabledUser_applies_disabled() { 200 mKeyguardDisable.disableKeyguard(createLockTaskToken(), "Tag", 201 SYSTEM_UID, 1); 202 assertTrue("test setup failed", mKeyguardEnabled); 203 mKeyguardDisable.setCurrentUser(1); 204 assertFalse(mKeyguardEnabled); 205 } 206 configureIsSecure(boolean secure, int userId)207 private void configureIsSecure(boolean secure, int userId) { 208 mKeyguardSecure.put(userId, secure); 209 mKeyguardDisable.updateKeyguardEnabled(userId); 210 } 211 configureDpmRequiresPassword(boolean requiresPassword, int userId)212 private void configureDpmRequiresPassword(boolean requiresPassword, int userId) { 213 mDpmRequiresPassword.put(userId, requiresPassword); 214 mKeyguardDisable.updateKeyguardEnabled(userId); 215 } 216 createLockTaskToken()217 private LockTaskToken createLockTaskToken() { 218 try { 219 final Constructor<LockTaskToken> constructor = 220 LockTaskToken.class.getDeclaredConstructor(); 221 constructor.setAccessible(true); 222 return constructor.newInstance(); 223 } catch (Exception e) { 224 throw new RuntimeException(e); 225 } 226 } 227 } 228