Input子系统_v1

参考学习链接:
http://blog.csdn.net/tkwxty/article/details/43338921
keycode 对应的是frameworks/native/include/android/keycodes.h 中的键值
http://blog.csdn.net/yuanzihui/article/details/52871652

输入子系统:
首先要先设置具备的key类型,

一.首先要先设置具备的key类型

__set_bit(KEY_CAM_SHELTER_NEAR, kpd_input_dev->keybit);
__set_bit(KEY_CAM_SHELTER_FAR, kpd_input_dev->keybit);

二.上报key

input_report_key(kpd_input_dev, KEY_CAM_SHELTER_NEAR, 1);
input_sync(kpd_input_dev);
input_report_key(kpd_input_dev, KEY_CAM_SHELTER_NEAR, 0);
input_sync(kpd_input_dev);
每个键值上保需要上报按下和抬起。
1.Include/linux/input.h(mtk--/Inlcude/linux/uapi/linux/input.h)
   该文件中的按键定义在linux kernel层定义使用
2.device/xxx/xxx.kl
   该文件中的按键值和input.h中的按键值一直,其中xxx.kl(keycodelayout)完成linux到Android层的映射,(input.h和xxx.kl文件中的名字不需要一致,但是按键码必须一致)
3.frameworks/native/include/android/keycodes.h 
  在这个文件中,定义android对应的键码和键值进行定义,定义形式要与第四点对应转换成的形式对应,要不然出错,因为在没有定义之前使用该键值。
4.frameworks/native/include/input/InputEventLabels.h

  #define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key }  

  这个宏会对kl传过来的相应的key的名字进行处理 ->
  生产一个数组元素 { 字符串key, AKEYCODE_($key) } 
  ##把两个符号连起来 eg: #defined test(x,y)   x##y     equal  xy
  #a指把a当成符号,就是把#后面的看成字符串
  
  #define DEFINE_KEYCODE(key) { #key, AKEYCODE_##key }
  #define DEFINE_AXIS(axis) { #axis, AMOTION_EVENT_AXIS_##axis }
  #define DEFINE_LED(led) { #led, ALED_##led }
  #define DEFINE_FLAG(flag) { #flag, POLICY_FLAG_##flag }
5.frameworks/base/core/res/res/values/attrs.xml
在布局文件中定义对应的枚举类型的KEY,要与第5点上的keyEvent里的文件对应,应保持变量名和值一直
6.frameworks/base/core/java/android/view/KeyEvent.java
  此文件是一个KeyEvent类,前期所有准备都是在为了给这个类
7.frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java
   在这个类里面对按键进行捕获和进行功能实现
调试经验:
问题:某些按键值,在上层获取到为0 :eg: STAR(*) POUND(#)
1.在底层用getevent /dev/input/event1查看的时候,在底层上报的值是对的,而且在frameworks/native/include/input/InputEventLabels.h 文件里看到对应的配置也是有的。

2.最后确定是在kl文件出了问题,.kl文件中少对该按键的描述,可以通过下面的步骤一步一步查看。

    2.1 首先先在底层看下映射文件用的是哪一个:
          adb shell; dumpsys input |grep kl;
          会列出一个列表:
                KeyLayoutFile: /system/usr/keylayout/Generic.kl
                KeyLayoutFile: /system/usr/keylayout/mtk-kpd.kl
                KeyLayoutFile: /system/usr/keylayout/Generic.kl
                KeyLayoutFile: /system/usr/keylayout/Generic.kl
                KeyLayoutFile: /system/usr/keylayout/ACCDET.kl
            查看是否调试平台自己的kl文件在不在列表中,如果不在的话,那就证明,底层kl在和InputEventLabels.h文件里面定义的数组
            static const InputEventLabel KEYCODES[] = {}中的映射有错误,导致不再使用平台自带的kl文件,而使用了安卓自自带的映射文件Generic.kl,所以在添加该InputEventLabels.h文
            件的这个数组时一定要注意,只能多,不能少。即:kl文件中有的,该数组里面也一定要有。
    
    2.2 下面我们可以用这个命令来查看是那个键有问题导致kl文件映射失败:
        adb wait-for-device;adb shell logcat "Expected keyword, got"
        这个命令会打印出导致失败的按键。
        源码在:frameworks/native/libs/input/KeyLayoutMap.cpp
                status_t KeyLayoutMap::Parser::parse() {
                       mTokenizer->skipDelimiters(WHITESPACE);
                      if (!mTokenizer->isEol() && mTokenizer->peekChar() != '#') {
                        ALOGE("%s: Expected end of line or trailing comment, got '%s'.",
                        mTokenizer->getLocation().string(),
                        mTokenizer->peekRemainderOfLine().string());
                        return BAD_VALUE;
                        }
        这个文件里面还有三个调试宏控制,如下:

       // Enables debug output for the parser.
       #define DEBUG_PARSER 0

       // Enables debug output for parser performance.
       #define DEBUG_PARSER_PERFORMANCE 0

       // Enables debug output for mapping.
       #define DEBUG_MAPPING 0
       
       打开三个调试宏之后可以用,
       adb shell logcat |grep "EventHub" 来获取按键按下时,上层的对应键值码keycode
    
input 输入子系统驱动编写
编写符合输入子系统框架的设备驱动程序主要有以下四个步骤:

1.分配一个input_dev结构体,调用input_allocate_device()或者devm_input_allocate_device(struct input_dev*)实现;

2.设置input设备支持的事件类型,其支持的事件类型如下表;

3.将输入设备注册到输入子系统中,调用input_register_device(struct input_dev*)函数实现;

4.硬件相关的代码:注册中断处理函数,比如键盘设备需要编写按键的抬起、放下,触摸屏设备需要编写按下、抬起、绝对移动,鼠标设备需要编写单击、抬起、相对移动,并且需要在必要的时候提交硬件数据(键值/坐标/状态等等),即上报输入事件。

猜你喜欢

转载自blog.csdn.net/qq_16919359/article/details/90038067
v1