
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) 可能會透過 SysFS 匯出板載設定屬性,這些屬性會由 Android InputReader 元件使用,例如在觸控螢幕上放置虛擬鍵。
如要進一步瞭解不同裝置如何使用電路板設定屬性,請參閱裝置類別相關章節。
資源重疊
部分輸入行為會透過 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 用途和事件代碼
通常會使用多個不同的 ID 來參照鍵盤上的任一特定按鍵、遊戲控制器上的按鈕、搖桿軸或其他控制項。這些 ID 之間的關係不一定相同:它們取決於一組對應表,其中有些是固定的,有些則會因裝置特性、裝置驅動程式、目前語言代碼、系統設定、使用者偏好設定和其他因素而異。
- 實體掃描代碼
-
實體掃描碼是裝置專屬的 ID,與每個按鍵、按鈕或其他控制項相關聯。由於實體掃描碼通常因裝置而異,因此韌體或裝置驅動程式會負責將這些碼對應至標準 ID,例如 HID 用途或 Linux 鍵碼。
掃描碼主要用於鍵盤。其他裝置通常會使用 GPIO 針腳、I2C 訊息或其他方式進行低層通訊。因此,軟體堆疊的上層會依賴裝置驅動程式來解讀發生的情況。
- HID 用途
-
HID 用途是用來回報控制項狀態的標準 ID,例如鍵盤按鍵、搖桿軸、滑鼠按鈕或觸控接觸點。大多數 USB 和藍牙輸入裝置都符合 HID 規格,因此系統可以以統一的方式與這些裝置互動。
Android 架構會依賴 Linux 核心 HID 驅動程式,將 HID 使用代碼轉譯為 Linux 鍵碼和其他 ID。因此,周邊製造商主要會對 HID 用途感興趣。
- Linux 鍵碼
-
Linux 鍵碼是鍵或按鈕的標準 ID。Linux 鍵碼是在
linux/input.h
標頭檔案中定義,使用開頭為KEY_
或BTN_
的常數。Linux 核心輸入驅動程式負責將實體掃描代碼、HID 用法和其他裝置專屬信號轉譯為 Linux 鍵碼,並將相關資訊提供為EV_KEY
事件的一部分。Android API 有時會將與金鑰相關聯的 Linux 金鑰程式碼稱為「掃描碼」。這在技術上並不正確,但有助於在 API 中區分 Linux 鍵碼和 Android 鍵碼。
- Linux 相對或絕對軸代碼
-
Linux 相對或絕對軸代碼是用於回報沿著軸的相對移動或絕對位置的標準 ID,例如滑鼠沿著 X 軸的相對移動,或搖桿沿著 X 軸的絕對位置。Linux 軸程式碼是在
linux/input.h
標頭檔案中定義,使用開頭為REL_
或ABS_
的常數。Linux 核心輸入驅動程式負責將 HID 用法和其他裝置專屬信號轉譯為 Linux 軸代碼,並在EV_REL
和EV_ABS
事件中提供相關資訊。 - Linux 切換程式碼
-
Linux 切換程式碼是用於回報裝置上切換器狀態的標準 ID,例如蓋子切換器。Linux 切換代碼是在
linux/input.h
標頭檔案中定義,使用開頭為SW_
的常數。Linux 核心輸入驅動程式會將切換狀態變更回報為EV_SW
事件。Android 應用程式通常不會接收來自切換鈕的事件,但系統可能會在內部使用這些事件,控制各種裝置專屬功能。
- Android 金鑰碼
-
Android 鍵碼是 Android API 中定義的標準 ID,用於表示特定鍵,例如「HOME」。Android 鍵碼是由
android.view.KeyEvent
類別定義為以KEYCODE_
前置字串開頭的常數。按鍵版面配置會指定 Linux 按鍵程式碼如何對應至 Android 按鍵程式碼。鍵盤型號、語言、國家/地區、版面配置或特殊功能可能會使用不同的按鍵配置。
使用裝置和語言代碼專屬的按鍵字元對應表,將 Android 按鍵程式碼組合轉換為字元程式碼。舉例來說,當同時按下
KEYCODE_SHIFT
和KEYCODE_A
鍵時,系統會在鍵字元對應表中查詢組合,並找出大寫字母「A」,然後插入目前聚焦的文字小工具中。 - Android 軸向程式碼
-
Android 軸代碼是 Android API 中定義的標準 ID,用於指示特定裝置軸。Android 軸代碼由
android.view.MotionEvent
類別定義為以AXIS_
前置字串開頭的常數。按鍵版面配置會指定 Linux 軸向程式碼如何對應至 Android 軸向程式碼。視裝置型號、語言、國家/地區、版面配置或特殊功能而定,可能會使用不同的按鍵版面配置。
- Android 元狀態
-
Android 中繼狀態是 Android API 中定義的標準 ID,用於指出按下哪些修飾鍵。Android 元狀態由
android.view.KeyEvent
類別定義為開頭為META_
的常數。目前的中繼狀態是由 Android InputReader 元件決定,該元件會監控
KEYCODE_SHIFT_LEFT
等修飾符鍵的按下 / 釋放時間,並設定 / 重設適當的中繼狀態標記。修飾鍵與中繼狀態之間的關係是硬式編碼,但按鍵配置可變更修飾鍵本身的對應方式,進而影響中繼狀態。
- Android 按鈕狀態
-
Android 按鈕狀態是 Android API 中定義的標準 ID,用於指出按下哪些按鈕 (滑鼠或觸控筆)。Android 按鈕狀態是由
android.view.MotionEvent
類別定義為開頭為BUTTON_
的常數。目前的按鈕狀態是由 Android InputReader 元件決定,該元件會監控按鈕 (在滑鼠或觸控筆上) 的按下 / 放開時間,並設定 / 重設適當的按鈕狀態標記。
按鈕和按鈕狀態之間的關係已硬式編碼。