Android按键事件——上层与驱动的映射

http://blog.csdn.net/zengdaquan007/article/details/8686431


首先查看android对上层按键事件的定义,在头文件<KeycodeLabels.h>中:

  1. static const KeycodeLabel KEYCODES[] = {  
  2.     { "SOFT_LEFT", 1 },  
  3.     { "SOFT_RIGHT", 2 },  
  4.     { "HOME", 3 },  
  5.     { "BACK", 4 },  
  6.     { "CALL", 5 },  
  7.     { "ENDCALL", 6 },  
  8.     { "0", 7 },  
  9.     { "1", 8 },  
  10.     { "2", 9 },  
  11.     { "3", 10 },  
  12.     { "4", 11 },  
  13.     { "5", 12 },  
  14.     { "6", 13 },  
  15.     { "7", 14 },  
  16.     { "8", 15 },  
  17.     { "9", 16 },  
  18.     { "STAR", 17 },  
  19.     { "POUND", 18 },  
  20.     { "DPAD_UP", 19 },  
  21.     { "DPAD_DOWN", 20 },  
  22.     { "DPAD_LEFT", 21 },  
  23.     { "DPAD_RIGHT", 22 },  
  24.     { "DPAD_CENTER", 23 },  
  25.     { "VOLUME_UP", 24 },  
  26.     { "VOLUME_DOWN", 25 },  
  27.     { "POWER", 26 },  
  28.     { "CAMERA", 27 },  
  29.     { "CLEAR", 28 },  
  30.     { "A", 29 },  
  31.     { "B", 30 },  
  32.     { "C", 31 },  
  33.     { "D", 32 },  
  34.     { "E", 33 },  
  35.     { "F", 34 },  
  36.     { "G", 35 },  
  37.     { "H", 36 },  
  38.     { "I", 37 },  
  39.     { "J", 38 },  
  40.     { "K", 39 },  
  41.     { "L", 40 },  
  42.     { "M", 41 },  
  43.     { "N", 42 },  
  44.     { "O", 43 },  
  45.     { "P", 44 },  
  46.     { "Q", 45 },  
  47.     { "R", 46 },  
  48.     { "S", 47 },  
  49.     { "T", 48 },  
  50.     ...  
  51.     { "BUTTON_14", 201 },  
  52.     { "BUTTON_15", 202 },  
  53.     { "BUTTON_16", 203 },  
  54.     { "LANGUAGE_SWITCH", 204 },  
  55.     { "MANNER_MODE", 205 },  
  56.     { "3D_MODE", 206 },  
  57.     { "CONTACTS", 207 },  
  58.     { "CALENDAR", 208 },  
  59.     { "MUSIC", 209 },  
  60.     { "CALCULATOR", 210 },  
  61.     { "ZENKAKU_HANKAKU", 211 },  
  62.     { "EISU", 212 },  
  63.     { "MUHENKAN", 213 },  
  64.     { "HENKAN", 214 },  
  65.     { "KATAKANA_HIRAGANA", 215 },  
  66.     { "YEN", 216 },  
  67.     { "RO", 217 },  
  68.     { "KANA", 218 },  
  69.     { "ASSIST", 219 },  
  70.   
  71.     // NOTE: If you add a new keycode here you must also add it to several other files.  
  72.     //       Refer to frameworks/base/core/java/android/view/KeyEvent.java for the full list.  
  73.   
  74.     { NULL, 0 }  
  75. };  
  76.   
  77. </span>  
左边是事件的名称,根据字面意思非常容易了解其作用;右边是对应的事件号,比如我们在终端敲入"input keyevent 4"命令,就可以产生BACK的效果。上层按键事件的定义个人建议不要修改,如果增加了一个新的按键事件的定义,也要到KeyEvent.java里面作相应的修改。

    按键的底层驱动事件是驱动开发人员自行定义的,这里我们只关心它上报的事件和对应的按键号。假如设备现在有6个按键,其对应的按键事件为:

按键                       事件

key 1                     0x01

key 2                     0x02

key 3                     0x03

key 4                     0x04

key 5                     0x05

key 6                     0x06

   

    目前的情况是,android上层已经有按键事件的定义了,底层驱动也有按键事件上报。但是缺少了中间的对接层,也就是说哪个按键对应哪种事件还不清楚。所以,需要为它们加入一个布局文件。按键的布局文件存放在frameworks/base/data/keyboards目录下,以.kl为后缀的文件都是键盘的布局文件,ls一下:

  1. android-4.2_r1/frameworks/base/data/keyboards$ ls  
  2. Android.mk  
  3. Generic.kcm       
  4. qwerty2.kcm  qwerty.kl               
  5. Vendor_046d_Product_c294.kl   
  6. Vendor_054c_Product_0268.kl      
  7. Virtual.kcm  
  8. AVRCP.kl     
  9. Generic.kl          
  10. keyboards.mk    
  11. qwerty.idc      
  12. Vendor_045e_Product_028e.kl   
  13. Vendor_046d_Product_c299.kl   
  14. Vendor_05ac_Product_0239.kl  
  15. common.mk  
  16. qwerty2.idc     
  17. qwerty.kcm      
  18. Vendor_046d_Product_c216.kl  
  19. Vendor_046d_Product_c532.kl   
  20. Vendor_22b8_Product_093d.kl  
  21. </span>  

    具体读取哪个布局文件是根据驱动的名字来确定的,如果找不到与驱动名字相同的文件,就会读取默认文件Generic.kl。现在我们假设键盘在驱动层的名字为“my_keypad”,所以需要创建一个名为“my_keypad,kl”的布局文件。文件的内容是什么呢,不急。目前还有一点不明确,上面提到的6个按键的作用我们还没有定义。假设定义如下:

按键                        作用

key 1                      确定

key 2                      返回

key 3                      菜单

key 4                      主解面

key 5                      左移

key 6                      右移

对应的布局文件“my_keypad,kl”的内容就应该为:

  1. <span style="font-size:14px;">key 0x1   ENTER  
  2. key 0x2   BACK  
  3. key 0x3   MENU  
  4. key 0x4   HOME  
  5. key 0x5   DPAD_LEFT  
  6. key 0x6   DPAD_RIGHT</span>  

把布局文件编译进系统,在当前目录的common.mk中,在keylayouts变量的末尾加入: my_keypad.kl\

到这里,android键盘的底层驱动事件跟上层定义的按键事件就对应起来了。


************************************************************************************************************

我的实际工作经验,增加audio jack 的button的映射关系
1. @device/somc/yukon/AndroidBoard.mk中添加
    include $(CLEAR_VARS)    
    LOCAL_MODULE := msm8226-tapan-snd-card_Button_Jack.kl
    LOCAL_MODULE_TAGS := optional
    LOCAL_MODULE_CLASS := ETC    
    LOCAL_SRC_FILES := $(LOCAL_MODULE)    
    LOCAL_MODULE_PATH := $(TARGET_OUT_KEYLAYOUT)    
    include $(BUILD_PREBUILT)
    则会在手机 system/usr/keylayout 目录下增加文件 msm8226-tapan-snd-card_Button_Jack.kl
2. @device/somc/yukon/platform.mk中增加
    PRODUCT_PACKAGES += \    
        msm8226-tapan-snd-card_Button_Jack.kl
3. @device/somc/yukon目录下增加文件msm8226-tapan-snd-card_Button_Jack.kl
4. 特别注意 msm8226-tapan-snd-card_Button_Jack.kl的文件名不是随意写的。
    status_t KeyMap::load@frameworks/base/libs/androidfw/keyboard.cpp
    {
        if (deviceConfiguration) {
            String8 keyLayoutName;
            if (deviceConfiguration->tryGetProperty(String8("keyboard.layout"),
                ....
        }
        // Try searching by device identifier.
        if (probeKeyMap(deviceIdenfifier, String8::empty())) {
        return OK;
        }

        // Fall back on the Generic key map.
        // TODO Apply some additional heuristics here to figure out what kind of
        //      generic key map to use (US English, etc.) for typical external keyboards.
        if (probeKeyMap(deviceIdenfifier, String8("Generic"))) {
        return OK;
        }

        // Try the Virtual key map as a last resort.
        if (probeKeyMap(deviceIdenfifier, String8("Virtual"))) {
        return OK;
        }
    }
     #getevent -i
    add device 2: /dev/input/event7
      bus:      0000
      vendor    0000
      product   0000
      version   0000
      name:     "msm8226-tapan-snd-card Button Jack"
      location: "ALSA"
      id:       ""
      version:  1.0.1
      events:
        KEY (0001): 00e2  0101  0102  0103  0104  0105  0106  0107
      input props:
        <none>
    读取*.kl的名字组合顺序为
    a. 首先查看 props中是否有keyboard.layout的参数,如果有则读取该名字的kl文件
    b. 如果 该设备的vendor,product和version都不全为0,则通过它们的组合成 kl的文件名
        Vendor_%04x_Product_%04x_Version_%04x.kl
        Vendor_%04x_Product_%04x.kl
        最终形成文件路径system/usr/keylayout/Vendor_xxxx_Product_xxxx.kl或system/usr/keylayout/Vendor_xxxx_Product_xxxx_Version_xxxx.kl
    c. 如果vendor,product,version都为0,则通过该设备的name: "msm8226-tapan-snd-card Button Jack"来组合kl文件名
        appendInputDeviceConfigurationFileRelativePath中会把其中的空格转换成'_'
        最终形成文件路径system/usr/keylayout/msm8226-tapan-snd-card_Button_Jack.kl
5.还可以直接用 snd_jack_set_key 映射
    ret = snd_jack_set_key(button_jack.jack,SND_JACK_BTN_0,KEY_MEDIA);

*********************************************************************************************************


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值