1 /* <lambda>null2 * Copyright 2024 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 android.hardware.input 18 19 import android.content.Context 20 import android.content.ContextWrapper 21 import android.platform.test.annotations.Presubmit 22 import android.platform.test.flag.junit.SetFlagsRule 23 import android.view.KeyEvent 24 import androidx.test.core.app.ApplicationProvider 25 import com.android.test.input.MockInputManagerRule 26 import kotlin.test.assertEquals 27 import kotlin.test.assertNotNull 28 import kotlin.test.assertNull 29 import kotlin.test.fail 30 import org.junit.Assert.assertThrows 31 import org.junit.Before 32 import org.junit.Rule 33 import org.junit.Test 34 import org.junit.runner.RunWith 35 import org.mockito.Mockito 36 import org.mockito.Mockito.doAnswer 37 import org.mockito.Mockito.`when` 38 import org.mockito.junit.MockitoJUnitRunner 39 40 /** 41 * Tests for [InputManager.KeyGestureEventHandler]. 42 * 43 * Build/Install/Run: atest InputTests:KeyGestureEventHandlerTest 44 */ 45 @Presubmit 46 @RunWith(MockitoJUnitRunner::class) 47 class KeyGestureEventHandlerTest { 48 49 companion object { 50 const val DEVICE_ID = 1 51 val HOME_GESTURE_EVENT = 52 KeyGestureEvent.Builder() 53 .setDeviceId(DEVICE_ID) 54 .setKeycodes(intArrayOf(KeyEvent.KEYCODE_H)) 55 .setModifierState(KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON) 56 .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_HOME) 57 .build() 58 val BACK_GESTURE_EVENT = 59 KeyGestureEvent.Builder() 60 .setDeviceId(DEVICE_ID) 61 .setKeycodes(intArrayOf(KeyEvent.KEYCODE_DEL)) 62 .setModifierState(KeyEvent.META_META_ON or KeyEvent.META_META_LEFT_ON) 63 .setKeyGestureType(KeyGestureEvent.KEY_GESTURE_TYPE_BACK) 64 .build() 65 } 66 67 @get:Rule val rule = SetFlagsRule() 68 @get:Rule val inputManagerRule = MockInputManagerRule() 69 70 private var registeredListener: IKeyGestureHandler? = null 71 private lateinit var context: Context 72 private lateinit var inputManager: InputManager 73 74 @Before 75 fun setUp() { 76 context = Mockito.spy(ContextWrapper(ApplicationProvider.getApplicationContext())) 77 inputManager = InputManager(context) 78 `when`(context.getSystemService(Mockito.eq(Context.INPUT_SERVICE))).thenReturn(inputManager) 79 80 // Handle key gesture handler registration. 81 doAnswer { 82 val listener = it.getArgument(1) as IKeyGestureHandler 83 if ( 84 registeredListener != null && 85 registeredListener!!.asBinder() != listener.asBinder() 86 ) { 87 // There can only be one registered key gesture handler per process. 88 fail("Trying to register a new listener when one already exists") 89 } 90 registeredListener = listener 91 null 92 } 93 .`when`(inputManagerRule.mock) 94 .registerKeyGestureHandler(Mockito.any(), Mockito.any()) 95 96 // Handle key gesture handler being unregistered. 97 doAnswer { 98 val listener = it.getArgument(0) as IKeyGestureHandler 99 if ( 100 registeredListener == null || 101 registeredListener!!.asBinder() != listener.asBinder() 102 ) { 103 fail("Trying to unregister a listener that is not registered") 104 } 105 registeredListener = null 106 null 107 } 108 .`when`(inputManagerRule.mock) 109 .unregisterKeyGestureHandler(Mockito.any()) 110 } 111 112 private fun handleKeyGestureEvent(event: KeyGestureEvent) { 113 val eventToSend = AidlKeyGestureEvent() 114 eventToSend.deviceId = event.deviceId 115 eventToSend.keycodes = event.keycodes 116 eventToSend.modifierState = event.modifierState 117 eventToSend.gestureType = event.keyGestureType 118 eventToSend.action = event.action 119 eventToSend.displayId = event.displayId 120 eventToSend.flags = event.flags 121 registeredListener!!.handleKeyGesture(eventToSend, null) 122 } 123 124 @Test 125 fun testHandlerHasCorrectGestureNotified() { 126 var callbackCount = 0 127 128 // Add a key gesture event listener 129 inputManager.registerKeyGestureEventHandler( 130 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_HOME) 131 ) { event, _ -> 132 assertEquals(HOME_GESTURE_EVENT, event) 133 callbackCount++ 134 } 135 136 // Request handling for key gesture event will notify the handler. 137 handleKeyGestureEvent(HOME_GESTURE_EVENT) 138 assertEquals(1, callbackCount) 139 } 140 141 @Test 142 fun testAddingHandlersRegistersInternalCallbackHandler() { 143 // Set up two callbacks. 144 val callback1 = InputManager.KeyGestureEventHandler { _, _ -> } 145 val callback2 = InputManager.KeyGestureEventHandler { _, _ -> } 146 147 assertNull(registeredListener) 148 149 // Adding the handler should register the callback with InputManagerService. 150 inputManager.registerKeyGestureEventHandler( 151 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_HOME), 152 callback1, 153 ) 154 assertNotNull(registeredListener) 155 156 // Adding another handler should not register new internal listener. 157 val currListener = registeredListener 158 inputManager.registerKeyGestureEventHandler( 159 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_BACK), 160 callback2, 161 ) 162 assertEquals(currListener, registeredListener) 163 } 164 165 @Test 166 fun testRemovingHandlersUnregistersInternalCallbackHandler() { 167 // Set up two callbacks. 168 val callback1 = InputManager.KeyGestureEventHandler { _, _ -> } 169 val callback2 = InputManager.KeyGestureEventHandler { _, _ -> } 170 171 inputManager.registerKeyGestureEventHandler( 172 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_HOME), 173 callback1, 174 ) 175 inputManager.registerKeyGestureEventHandler( 176 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_BACK), 177 callback2, 178 ) 179 180 // Only removing all handlers should remove the internal callback 181 inputManager.unregisterKeyGestureEventHandler(callback1) 182 assertNotNull(registeredListener) 183 inputManager.unregisterKeyGestureEventHandler(callback2) 184 assertNull(registeredListener) 185 } 186 187 @Test 188 fun testMultipleHandlers() { 189 // Set up two callbacks. 190 var callbackCount1 = 0 191 var callbackCount2 = 0 192 // Handler 1 captures all home gestures 193 val callback1 = 194 InputManager.KeyGestureEventHandler { event, _ -> 195 callbackCount1++ 196 assertEquals(KeyGestureEvent.KEY_GESTURE_TYPE_HOME, event.keyGestureType) 197 } 198 // Handler 2 captures all back gestures 199 val callback2 = 200 InputManager.KeyGestureEventHandler { event, _ -> 201 callbackCount2++ 202 assertEquals(KeyGestureEvent.KEY_GESTURE_TYPE_BACK, event.keyGestureType) 203 } 204 205 // Add both key gesture event handlers 206 inputManager.registerKeyGestureEventHandler( 207 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_HOME), 208 callback1, 209 ) 210 inputManager.registerKeyGestureEventHandler( 211 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_BACK), 212 callback2, 213 ) 214 215 // Request handling for home key gesture event, should notify only callback1 216 handleKeyGestureEvent(HOME_GESTURE_EVENT) 217 assertEquals(1, callbackCount1) 218 assertEquals(0, callbackCount2) 219 220 // Request handling for back key gesture event, should notify only callback2 221 handleKeyGestureEvent(BACK_GESTURE_EVENT) 222 assertEquals(1, callbackCount1) 223 assertEquals(1, callbackCount2) 224 225 inputManager.unregisterKeyGestureEventHandler(callback1) 226 227 // Request handling for home key gesture event, should not trigger callback2 228 handleKeyGestureEvent(HOME_GESTURE_EVENT) 229 assertEquals(1, callbackCount1) 230 assertEquals(1, callbackCount2) 231 } 232 233 @Test 234 fun testUnableToRegisterSameHandlerTwice() { 235 val handler = InputManager.KeyGestureEventHandler { _, _ -> } 236 237 inputManager.registerKeyGestureEventHandler( 238 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_HOME), 239 handler, 240 ) 241 242 assertThrows(IllegalArgumentException::class.java) { 243 inputManager.registerKeyGestureEventHandler( 244 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_BACK), 245 handler, 246 ) 247 } 248 } 249 250 @Test 251 fun testUnableToRegisterSameGestureTwice() { 252 val handler1 = InputManager.KeyGestureEventHandler { _, _ -> } 253 val handler2 = InputManager.KeyGestureEventHandler { _, _ -> } 254 255 inputManager.registerKeyGestureEventHandler( 256 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_HOME), 257 handler1, 258 ) 259 260 assertThrows(IllegalArgumentException::class.java) { 261 inputManager.registerKeyGestureEventHandler( 262 listOf(KeyGestureEvent.KEY_GESTURE_TYPE_HOME), 263 handler2, 264 ) 265 } 266 } 267 } 268