【轉】ADROID 2.1 架構解析 7 鍵盤

原文出處: http://blog.csdn.net/skdev/archive/2010/03/08/5355542.aspx

 

 

7 鍵盤
系統在KeyInputQueue服務裏創建了一個線程,在這個線程裏不斷讀取輸入事件,然後對這個事件進行處理。

7.1 按鍵輸入隊列服務
按鍵輸入事件有多種方式,如:鍵盤敲擊、觸摸屏觸擊、鼠標點擊及多點觸摸,主要是按下和放開的事件。

7.1.1 輸入事件的數據結構
文件:frameworks/base/core/java/android/view/RawInputEvent.java

7.1.2 輸入事件服務
文件:frameworks/base/services/java/com/android/server/KeyInputQueue.java

7.1.2.1 獲取事件

調用readEvent,將輸入事件讀取到ev類,即RawInputEvent的變量裏,readEvent對應jni的android_server_KeyInputQueue_readEvent

7.1.2.2 處理鍵盤事件

處理鍵盤事件,並將該事件加入事件隊列。

7.2硬件調用
文件:frameworks/base/services/jni/com_android_server_KeyInputQueue.cpp

將從eventhub讀到的變量存到android/view/RawInputEvent類對應的變量裏。

7.3 EventHub庫
文件:frameworks/base/libs/ui/EventHub.cpp

7.3.1 讀取輸入設備狀態

openPlatformInput() 打開/dev/input/ 目錄下的所有輸入設備文件。

打開設備後,不斷輪循所有設備,直到讀取有POLLIN事件產生的設備的狀態。

7.3.2 導入鍵盤配置文件

由以上代碼可知,會優先加載/system/usr/keylayout/輸入設備名稱.kl

如: /sys/class/input/input1/name = keypad,則會加載/system/usr/keylayout/keypad.kl,如果該文件不存在,則加載默認文件/system/usr/keylayout/qwerty.kl,該文件的原型在:sdk/emulator/keymaps/qwerty.kl ,eclair以前的版本都是放在development/ emulator/keymaps/qwerty.kl

7.3.3 按鍵映射
如7.3.2所示代碼,先加載配置文件:

如7.3.1所示代碼,再將讀取到的按鍵碼進行轉換:

err = mDevices[i]->layoutMap->map(iev.code, outKeycode, outFlags);

文件:frameworks/base/libs/ui/KeyLayoutMap.cpp

由以上代碼可知,是以如下方式對配置文件進行解析的:

BEGIN: 如果第一個關鍵字是key,則轉入SCANCODE,否則退出。

SCANCODE: 將第二個關鍵字轉爲數字,即掃描碼scancode,轉向KEYCODE。

KEYCODE: 將第三個關鍵字與KEYCODES列表配對,找出關鍵碼keycode,轉向FLAG。

FLAG:如果第四個關鍵字是key,則保存剛掃描的鍵碼,然後轉向SCANCODE,否則將該關鍵字與FLAGS列表配對,找出flags值,然後轉向BEGIN。

 

注:KEYCODES列表和FLAGS列表的定義在:

frameworks/base/include/ui/KeycodeLabels.h

  

Map的功能是根據scancode,找到對應的keycode.

 

qwerty.kl 的部分配置:

7.4 字符映射
7.4.1 加載字符配置表
文件:frameworks/base/core/java/android/view/KeyCharacterMap.java

ctor_native 原型如下:

文件:frameworks/base/core/jni/android_text_KeyCharacterMap.cpp

KeyCharacterMap::load原型如下:

文件:frameworks/base/libs/ui/KeyCharacterMap.cpp

以上所提及代碼要實現的功能是:先查看hw.keyboards.%u.devname的屬性,若存在則打開/system/usr/keychars/%s.kcm.bin文件,否則打開默認文件:/system/usr/keychars/qwerty.kcm.bin

 

文件:frameworks/base/libs/ui/EventHub.cpp

參考<<7.3.2 導入鍵盤配置文件>>裏的:

在代碼裏設置了KeyCharacterMap::load 中hw.keyboards.%u.devname所需要的值,即設備名稱,如: /sys/class/input/input1/name = keypad,則會加載/system/usr/keychars/keypad.kcm.bin

 

例:

/sys/class/input/input1/name = keypad

則要打開的文件路徑是:

/system/usr/keylayout/keypad.kl

/system/usr/keychars/keypad.kcm.bin

若以上文件不存在,則使用默認文件:

/system/usr/keylayout/qwerty.kl

/system/usr/keychars/qwerty.kcm.bin

7.4.2字符映射
文件:frameworks/base/core/java/android/view/KeyCharacterMap.java

getMatch_native 原型如下:

文件:frameworks/base/core/jni/android_text_KeyCharacterMap.cpp

getMatch的原型如下:

文件:frameworks/base/libs/ui/KeyCharacterMap.cpp

 qwerty.kcm的部分配置:

找到keyCode對應的所有字符,然後再根據modifiers選擇對應的字符

7.5 流程總結
當有按鍵響應時,內核傳給ANDROID的是scancode,ANDROID將scancode經配置表(如qwerty.kl)找到keycode標識符,然後由內部表KEYCODES列表找到keycode的數字值,再由keycode的數字值經字符配置表(如qwerty.kcm)找到對應的字符值。

 

本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/skdev/archive/2010/03/08/5355542.aspx

發佈了10 篇原創文章 · 獲贊 3 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章