在TP的driver中,报虚拟按键的方法常见的有两种:
1.直接报键值(kernel的)
2.报一个坐标,上层通过KL的解析来判定是哪个键。
下面说下第二种:
TP的kl被存放在/sys/board_properties/virtualkeys.devicename中,pull出来后可以看看内容:
0x01:139:100:900:40:60:0x01:158:400:900:40:60
可以发现就是在驱动代码中写的范围,分别是中心点X,中心点Y,宽度和高度,其实就是一个矩形区域,以X,Y为中心点,分别延伸 w/2, h/2。
4.0上对此kl的解析是在virtualkeymap.cpp中:
- do {
- String8 token = mTokenizer->nextToken(WHITESPACE_OR_FIELD_DELIMITER);
- if (token != "0x01") {
- LOGE("%s: Unknown virtual key type, expected 0x01.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
- VirtualKeyDefinition defn;
- bool success = parseNextIntField(&defn.scanCode)
- && parseNextIntField(&defn.centerX)
- && parseNextIntField(&defn.centerY)
- && parseNextIntField(&defn.width)
- && parseNextIntField(&defn.height);
- if (!success) {
- LOGE("%s: Expected 5 colon-delimited integers in virtual key definition.",
- mTokenizer->getLocation().string());
- return BAD_VALUE;
- }
0X01是标志位,接下来的一位是scancode,再接下来就是xywh。
需要注意的是实际的范围是[x-w/2,x+w/2] ,[y-h/2,y+h/2].
2.3.5上是在inputmanager.java中getVirtualKeyDefinitions方法中解析的:
- try {
- FileInputStream fis = new FileInputStream(
- "/sys/board_properties/virtualkeys." + deviceName);
- InputStreamReader isr = new InputStreamReader(fis);
- BufferedReader br = new BufferedReader(isr, 2048);
- String str = br.readLine();
- if (str != null) {
- String[] it = str.split(":");
- if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "***** VIRTUAL KEYS: " + it);
- final int N = it.length-6;
- for (int i=0; i<=N; i+=6) {
- if (!"0x01".equals(it[i])) {
- Slog.w(TAG, "Unknown virtual key type at elem #" + i + ": " + it[i] + " for device " + deviceName);
- continue;
- }
- try {
- VirtualKeyDefinition key = new VirtualKeyDefinition();
- key.scanCode = Integer.parseInt(it[i+1]);
- key.centerX = Integer.parseInt(it[i+2]);
- key.centerY = Integer.parseInt(it[i+3]);
- key.width = Integer.parseInt(it[i+4]);
- key.height = Integer.parseInt(it[i+5]);
- if (DEBUG_VIRTUAL_KEYS) Slog.v(TAG, "Virtual key "
- + key.scanCode + ": center=" + key.centerX + "," + key.centerY + " size=" + key.width + "x"
- + key.height);
- keys.add(key);
- } catch (NumberFormatException e) {
- Slog.w(TAG, "Bad number in virtual key definition at region "
- + i + " in: " + str + " for device " + deviceName, e);
- }
- }
- }
- br.close(); } catch (FileNotFoundException e) {
- Slog.i(TAG, "No virtual keys found for device " + deviceName + ".");
- } catch (IOException e) {
- Slog.w(TAG, "Error reading virtual keys for device " + deviceName + ".", e);
- }
- return keys.toArray(new VirtualKeyDefinition[keys.size()]);
- }
实际是在inputread中使用:
TouchInputMapper::configureVirtualKeysLocked()方法中会计算出每个虚拟按键对应的矩形范围,并将scancode转换成keycode。