輸入

Android 輸入 HAL 圖標

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 EventHubInputReader組件使用鍵映射來配置從 Linux 事件代碼到鍵、操縱桿按鈕和操縱桿軸的 Android 事件代碼的映射。映射可能依賴於設備或語言。

有關不同設備如何使用鍵映射的詳細信息,請參閱設備類部分。

輸入設備配置文件

Android EventHubInputReader組件使用輸入設備配置文件來配置特殊設備特性,例如如何報告觸摸大小信息。

有關不同設備如何使用輸入設備配置映射的詳細信息,請參閱設備類部分。

了解 HID 用法和事件代碼

通常有幾個不同的標識符用於指代鍵盤上的任何給定鍵、遊戲控制器上的按鈕、操縱桿軸或其他控件。這些標識符之間的關係並不總是相同的:它們依賴於一組映射表,其中一些是固定的,一些根據設備的特性、設備驅動程序、當前區域設置、系統配置而變化,用戶偏好和其他因素。

實物掃碼

物理掃描碼是與每個鍵、按鈕或其他控件相關聯的特定於設備的標識符。由於物理掃描碼通常因設備而異,因此固件或設備驅動程序負責將它們映射到標準標識符,例如 HID Usages 或 Linux 鍵碼。

掃描碼主要對鍵盤感興趣。其他設備通常使用 GPIO 引腳、I2C 消息或其他方式進行低級別通信。因此,軟件堆棧的上層依賴於設備驅動程序來理解正在發生的事情。

隱藏使用

HID 用法是一種標準標識符,用於報告控件的狀態,例如鍵盤鍵、操縱桿軸、鼠標按鈕或觸摸接觸點。大多數 USB 和藍牙輸入設備都符合 HID 規範,這使得系統能夠以統一的方式與它們進行接口。

Android Framework 依靠 Linux 內核 HID 驅動程序將 HID 使用代碼轉換為 Linux 鍵碼和其他標識符。因此,HID 的使用主要是外圍設備製造商感興趣的。

關鍵代碼

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_RELEV_ABS事件的一部分提供。

Linux 開關代碼

Linux 開關代碼是用於報告設備上開關狀態的標準標識符,例如蓋子開關。 Linux 開關代碼使用以前綴SW_開頭的常量在linux/input.h頭文件中定義。 Linux 內核輸入驅動程序將開關狀態更改報告為EV_SW事件。

Android 應用程序通常不接收來自開關的事件,但係統可能會在內部使用它們來控制各種設備特定的功能。

安卓鍵碼

Android 鍵碼是 Android API 中定義的標準標識符,用於指示特定鍵,例如“HOME”。 Android 鍵碼由android.view.KeyEvent類定義為以前綴KEYCODE_開頭的常量。

鍵佈局指定 Linux 鍵碼如何映射到 Android 鍵碼。根據鍵盤型號、語言、國家/地區、佈局或特殊功能,可能會使用不同的按鍵佈局。

使用特定於設備和區域設置的鍵字符映射將 Android 鍵碼的組合轉換為字符代碼。例如,當同時按下標識為KEYCODE_SHIFTKEYCODE_A的鍵時,系統會在鍵字符映射中查找組合併找到大寫字母“A”,然後將其插入到當前獲得焦點的文本小部件中。

安卓軸碼

Android 軸代碼是 Android API 中定義的標準標識符,用於指示特定的設備軸。 Android 軸代碼由android.view.MotionEvent類定義為以前綴AXIS_開頭的常量。

鍵佈局指定 Linux 軸代碼如何映射到 Android 軸代碼。根據設備型號、語言、國家、佈局或特殊功能,可能會使用不同的按鍵佈局。

安卓元狀態

Android 元狀態是 Android API 中定義的標準標識符,用於指示按下了哪些修改鍵。 Android 元狀態由android.view.KeyEvent類定義為以前綴META_開頭的常量。

當前元狀態由 Android InputReader 組件確定,該組件監視何時按下/釋放KEYCODE_SHIFT_LEFT等修改鍵,並設置/重置適當的元狀態標誌。

修改鍵和元狀態之間的關係是硬編碼的,但鍵佈局可以改變修改鍵本身的映射方式,進而影響元狀態。

安卓按鈕狀態

Android 按鈕狀態是在 Android API 中定義的標準標識符,用於指示按下了哪些按鈕(在鼠標或手寫筆上)。 Android 按鈕狀態由android.view.MotionEvent類定義為以前綴BUTTON_開頭的常量。

當前按鈕狀態由 Android InputReader 組件確定,該組件監視何時按下/釋放按鈕(在鼠標或手寫筆上)並設置/重置適當的按鈕狀態標誌。

按鈕和按鈕狀態之間的關係是硬編碼的。

進一步閱讀

  1. Linux 輸入事件代碼
  2. Linux多點觸控協議
  3. Linux 輸入驅動程序
  4. Linux力反饋
  5. HID 信息,包括 HID 使用表