• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * 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 com.android.cts.input
18 
19 import android.app.Instrumentation
20 import android.view.InputDevice.SOURCE_KEYBOARD
21 
createKeyboardRegisterCommandnull22 private fun createKeyboardRegisterCommand(
23     keys: List<String>,
24     productId: Int
25 ): UinputRegisterCommand {
26     val configurationItems = listOf(
27         ConfigurationItem("UI_SET_EVBIT", listOf("EV_KEY")),
28         ConfigurationItem("UI_SET_KEYBIT", keys)
29     )
30 
31     return UinputRegisterCommand(
32         id = 1,
33         name = "Test Keyboard (USB)",
34         vid = 0x18d1,
35         pid = productId,
36         bus = "usb",
37         port = "usb:1",
38         configuration = configurationItems,
39         absInfo = emptyMap(),
40     )
41 }
42 
43 /**
44  * A Keyboard that only has a few common keys (lots of keys are missing, for simplicity).
45  */
46 class UinputKeyboard(
47     instrumentation: Instrumentation,
48     keys: List<String> = listOf(
49         "KEY_Q", "KEY_W", "KEY_E", "KEY_A", "KEY_B", "KEY_C", "KEY_BACKSPACE", "KEY_ESC",
50         "KEY_LEFTALT", "KEY_LEFTMETA", "KEY_LEFT", "KEY_LEFTSHIFT", "KEY_CAPSLOCK",
51     ),
52     productId: Int = 0xabcd,
53 ) : UinputDevice(
54     instrumentation,
55     SOURCE_KEYBOARD,
56     createKeyboardRegisterCommand(keys, productId),
57     null // display
58 ) {
59 
60   companion object {
61     const val EV_KEY = 1
62     const val KEY_DOWN = 1
63     const val KEY_UP = 0
64     const val EV_SYN = 0
65     const val SYN_REPORT = 0
66   }
67 
68   // store the keys that are currently down
69   private val keysDown = mutableSetOf<Int>()
70 
injectEventsnull71   private fun injectEvents(events: IntArray) {
72       injectEvents(events.joinToString(prefix = "[", postfix = "]", separator = ","))
73   }
74 
injectKeyDownnull75   fun injectKeyDown(scanCode: Int) {
76       if (!keysDown.add(scanCode)) {
77         throw IllegalArgumentException("Key $scanCode is already down")
78       }
79       injectEvents(intArrayOf(EV_KEY, scanCode, KEY_DOWN, EV_SYN, SYN_REPORT, 0))
80   }
81 
injectKeyUpnull82   fun injectKeyUp(scanCode: Int) {
83       if (!keysDown.remove(scanCode)) {
84         throw IllegalArgumentException("Key $scanCode is not down")
85       }
86       injectEvents(intArrayOf(EV_KEY, scanCode, KEY_UP, EV_SYN, SYN_REPORT, 0))
87   }
88 }
89