Android 輸入子系統名義上由一個遍歷系統多個層的事件管道組成。
輸入管道
在最底層,實體輸入裝置產生描述狀態變化的訊號,例如按鍵和觸控接觸點。裝置韌體以某種方式編碼和傳輸這些訊號,例如透過向系統發送 USB HID 報告或在 I2C 總線上產生中斷。
然後這些訊號由 Linux 核心中的裝置驅動程式進行解碼。 Linux 核心為許多標準週邊裝置提供驅動程序,特別是那些遵守 HID 協議的周邊。然而,OEM 通常必須為在低階緊密整合到系統中的嵌入式裝置(例如觸控螢幕)提供自訂驅動程式。
輸入裝置驅動程式負責透過 Linux 輸入協定將裝置特定訊號轉換為標準輸入事件格式。 Linux 輸入協定在linux/input.h
核心頭檔中定義了一組標準的事件類型和程式碼。這樣,核心以外的元件就不需要關心實體掃描碼、HID使用、I2C訊息、GPIO引腳等細節。
接下來,Android EventHub
元件透過開啟與每個輸入裝置關聯的evdev
驅動程式從核心讀取輸入事件。然後,Android InputReader 元件會根據裝置類別對輸入事件進行解碼,並產生 Android 輸入事件流。作為此過程的一部分,根據輸入裝置配置、鍵盤佈局檔案和各種映射表,將 Linux 輸入協定事件代碼轉換為 Android 事件代碼。
最後, InputReader
將輸入事件傳送到InputDispatcher,後者將它們轉送到適當的視窗。
控制點
輸入管道中有幾個階段可以實現對輸入設備行為的控制。
驅動程式和韌體配置
輸入裝置驅動程式經常透過設定暫存器中的參數甚至上傳韌體本身來配置輸入裝置的行為。對於觸控螢幕等嵌入式設備尤其如此,其中校準過程的很大一部分涉及調整這些參數或修復韌體以提供所需的精度和響應能力並抑制雜訊。
驅動程式配置選項通常在核心板支援包 (BSP) 中指定為模組參數,以便相同驅動程式可以支援多種不同的硬體實作。
本文檔確實嘗試描述驅動程式或韌體配置,但它確實提供了有關設備校準的一般指導。
板配置屬性
核心板支援包 (BSP) 可以透過 Android InputReader 元件使用的 SysFS 匯出板配置屬性,例如觸控螢幕上虛擬按鍵的放置。
有關不同設備如何使用板配置屬性的詳細信息,請參閱設備類別部分。
資源疊加
一些輸入行為是透過config.xml
中的資源覆蓋來配置的,例如蓋子開關的操作。
這裡有一些例子:
config_lidKeyboardAccessibility
:指定蓋子開關對硬體鍵盤是否可存取或隱藏的影響。config_lidNavigationAccessibility
:指定蓋子開關對觸控板可存取還是隱藏的影響。config_longPressOnPowerBehavior
:指定使用者按住電源按鈕時應發生的情況。config_lidOpenRotation
:指定蓋子開關對螢幕方向的影響。
有關每個配置選項的詳細信息,請參閱frameworks/base/core/res/res/values/config.xml
中的文件。
按鍵圖
Android EventHub
和InputReader
元件使用按鍵映射來配置按鍵、操縱桿按鈕和操縱桿軸從 Linux 事件代碼到 Android 事件代碼的映射。此映射可能依賴裝置或語言。
有關不同設備如何使用鍵映射的詳細信息,請參閱設備類部分。
輸入設備設定檔
Android EventHub
和InputReader
元件使用輸入裝置設定檔來配置特殊裝置特性,例如如何報告觸控尺寸資訊。
有關不同設備如何使用輸入設備配置映射的詳細信息,請參閱設備類部分。
了解 HID 用法和事件代碼
通常有幾個不同的標識符用於指鍵盤上的任何給定鍵、遊戲控制器上的按鈕、操縱桿軸或其他控制項。這些標識符之間的關係並不總是相同的:它們依賴一組映射表,其中一些是固定的,一些根據設備的特性、設備驅動程式、當前區域設定、系統配置、用戶偏好和其他因素。
- 實體掃碼
實體掃描碼是與每個按鍵、按鈕或其他控制項相關聯的裝置特定識別碼。由於實體掃描代碼通常因裝置而異,因此韌體或裝置驅動程式負責將它們對應到標準標識符,例如 HID 用法或 Linux 金鑰代碼。
掃描碼主要是鍵盤感興趣的。其他設備通常使用 GPIO 引腳、I2C 訊息或其他方式進行低階通訊。因此,軟體堆疊的上層依賴裝置驅動程式來了解正在發生的情況。
- HID 使用
HID 用法是一種標準標識符,用於報告鍵盤按鍵、操縱桿軸、滑鼠按鈕或觸控接觸點等控制項的狀態。大多數 USB 和藍牙輸入裝置都符合 HID 規範,這使得系統能夠以統一的方式與其連接。
Android 框架依賴 Linux 核心 HID 驅動程式將 HID 使用程式碼轉換為 Linux 金鑰程式碼和其他識別碼。因此,週邊設備製造商主要對 HID 用途感興趣。
- Linux 關鍵程式碼
Linux 鍵碼是鍵或按鈕的標準識別碼。 Linux 鍵碼是在
linux/input.h
頭檔中使用以前綴KEY_
或BTN_
開頭的常數定義的。 Linux 核心輸入驅動程式負責將實體掃描程式碼、HID 使用和其他裝置特定訊號轉換為 Linux 按鍵程式碼,並作為EV_KEY
事件的一部分傳遞有關它們的資訊。Android API 有時會將與某個按鍵關聯的 Linux 鍵碼稱為「掃描碼」。這在技術上是不正確的,但它有助於區分 API 中的 Linux 金鑰程式碼和 Android 金鑰程式碼。
- Linux 相對或絕對軸程式碼
Linux 相對或絕對軸代碼是用於報告沿軸的相對運動或絕對位置的標準標識符,例如滑鼠沿其 X 軸的相對運動或操縱桿沿其 X 軸的絕對位置。 Linux 軸代碼是在
linux/input.h
頭檔中使用以前綴REL_
或ABS_
開頭的常數定義的。 Linux 核心輸入驅動程式負責將 HID 用法和其他裝置特定訊號轉換為 Linux 軸程式碼,並作為EV_REL
和EV_ABS
事件的一部分傳遞有關它們的資訊。- Linux 切換程式碼
Linux 開關代碼是用於報告裝置上開關(例如蓋子開關)狀態的標準識別碼。 Linux 開關代碼是在
linux/input.h
頭檔中使用以前綴SW_
開頭的常數定義的。 Linux 核心輸入驅動程式將開關狀態變更報告為EV_SW
事件。Android 應用程式通常不會接收來自開關的事件,但係統可能會在內部使用它們來控制各種裝置特定的功能。
- 安卓關鍵程式碼
Android 鍵碼是 Android API 中定義的標準標識符,用於指示特定鍵(例如「HOME」)。 Android 鍵碼由
android.view.KeyEvent
類別定義為以前綴KEYCODE_
開頭的常數。鍵佈局指定 Linux 鍵程式碼如何對應到 Android 鍵程式碼。根據鍵盤型號、語言、國家、佈局或特殊功能,可以使用不同的按鍵佈局。
使用裝置和區域特定的按鍵字元對應表將 Android 按鍵代碼的組合轉換為字元代碼。例如,當同時按下標識為
KEYCODE_SHIFT
和KEYCODE_A
的按鍵時,系統會在按鍵字元映射表中尋找該組合併找到大寫字母“A”,然後將其插入到目前聚焦的文字小部件中。- Android 軸代碼
Android 軸代碼是 Android API 中定義的標準標識符,用於指示特定裝置軸。 Android 軸程式碼由
android.view.MotionEvent
類別定義為以前綴AXIS_
開頭的常數。鍵佈局指定 Linux 軸代碼如何對應到 Android 軸代碼。根據設備型號、語言、國家/地區、佈局或特殊功能,可以使用不同的按鍵佈局。
- Android 元狀態
Android 元狀態是 Android API 中定義的標準標識符,用於指示按下了哪些修飾鍵。 Android 元狀態由
android.view.KeyEvent
類別定義為以前綴META_
開頭的常數。當前元狀態由 Android InputReader 元件決定,該元件監視何時按下/釋放修改鍵(例如
KEYCODE_SHIFT_LEFT
並設定/重設對應的元狀態標誌。修飾鍵和元狀態之間的關係是硬編碼的,但鍵佈局可以改變修飾鍵本身的映射方式,從而影響元狀態。
- Android 按鈕狀態
Android 按鈕狀態是 Android API 中定義的標準標識符,用於指示按下了哪些按鈕(滑鼠或手寫筆上的按鈕)。 Android 按鈕狀態由
android.view.MotionEvent
類別定義為以前綴BUTTON_
開頭的常數。當前按鈕狀態由 Android InputReader 元件決定,該元件監視何時按下/釋放按鈕(滑鼠或手寫筆上的按鈕)並設定/重設對應的按鈕狀態標誌。
按鈕和按鈕狀態之間的關係是硬編碼的。