觸控設備

Android 支持各種觸摸屏和触摸板,包括基於觸控筆的數字化平板電腦。

觸摸屏是與顯示器相關聯的觸摸設備,使得用戶具有直接操縱屏幕上的項目的印象。

觸摸板是與數字化儀平板電腦等顯示器不相關的觸摸設備。觸摸板通常用於指向或絕對間接定位或基於手勢的用戶界面控制。

觸摸設備可能具有功能類似於鼠標按鈕的按鈕。

有時可以使用各種不同的工具(例如手指或觸控筆)來操作觸摸設備,具體取決於底層觸摸傳感器技術。

觸摸設備有時用於實現虛擬鍵。例如,在某些 Android 設備上,觸摸屏傳感器區域延伸到顯示屏邊緣之外,並作為觸敏鍵盤的一部分提供雙重用途。

由於觸控設備種類繁多,Android 依賴大量的配置屬性來描述每個設備的特性和期望的行為。

觸控設備分類

如果同時滿足以下兩個條件,則輸入設備被歸類為多點觸控設備:

  • 輸入設備報告ABS_MT_POSITION_XABS_MT_POSITION_Y絕對軸的存在。

  • 輸入設備沒有任何遊戲手柄按鈕。這種情況解決了某些遊戲手柄的歧義,這些手柄報告的軸代碼與 MT 軸的代碼重疊。

如果同時滿足以下兩個條件,則輸入設備被歸類為單點觸控設備:

  • 輸入設備不屬於多點觸控設備。輸入設備要么被歸類為單點觸控設備,要么被歸類為多點觸控設備,絕不是兩者兼而有之。

  • 輸入設備報告ABS_XABS_Y絕對軸的存在,以及BTN_TOUCH鍵碼的存在。

一旦輸入設備被分類為觸摸設備,通過嘗試加載設備的虛擬鍵映射文件來確定虛擬鍵的存在。如果虛擬按鍵映射可用,則設備的按鍵佈局文件也會被加載。

有關虛擬鍵映射文件的位置和格式,請參閱以下部分。

接下來,系統為觸摸設備加載輸入設備配置文件。

所有內置的觸摸設備都應該有輸入設備配置文件。如果不存在輸入設備配置文件,系統將選擇適用於典型通用觸摸外圍設備(例如外部 USB 或藍牙 HID 觸摸屏或觸摸板)的默認配置。這些默認值不是為內置觸摸屏設計的,很可能會導致不正確的行為。

加載輸入設備配置後,系統會將輸入設備分類為觸摸屏觸摸板指針設備。

  • 觸摸屏設備用於直接操作屏幕上的對象。由於用戶直接觸摸屏幕,系統不需要任何額外的提示來指示正在操作的對象。

  • 觸摸板設備用於向應用程序提供有關在給定傳感器區域上的觸摸的絕對定位信息。它可能對數字化平板電腦有用。

  • 指針設備用於使用光標間接操縱屏幕上的對象。手指被解釋為多點觸控指針手勢。其他工具,例如觸控筆,使用絕對位置進行解釋。

    有關詳細信息,請參閱間接多點觸控指針手勢

以下規則用於將輸入設備分類為觸摸屏觸摸板指針設備。

  • 如果設置了touch.deviceType屬性,則設備類型將按照指示設置。

  • 如果輸入設備報告存在INPUT_PROP_DIRECT輸入屬性(通過EVIOCGPROP ioctl),則設備類型將設置為touch screen 。此條件假定直接輸入觸摸設備連接到也連接的顯示器。

  • 如果輸入設備報告存在INPUT_PROP_POINTER輸入屬性(通過EVIOCGPROP ioctl),則設備類型將設置為指針

  • 如果輸入設備報告存在REL_XREL_Y相對軸,則設備類型將設置為touch pad 。此條件解決了包含鼠標和触摸板的輸入設備的歧義。在這種情況下,觸摸板將不會用於控制指針,因為鼠標已經控制了它。

  • 否則,設備類型將設置為指針。此默認設置確保未被指定任何其他特殊用途的觸摸板將用於控制指針。

鈕扣

按鈕是可選控件,應用程序可以使用它們來執行附加功能。觸摸設備上的按鈕的行為類似於鼠標按鈕,主要用於指針式觸摸設備或觸控筆。

支持以下按鈕:

  • BTN_LEFT :映射到MotionEvent.BUTTON_PRIMARY

  • BTN_RIGHT :映射到MotionEvent.BUTTON_SECONDARY

  • BTN_MIDDLE :映射到MotionEvent.BUTTON_MIDDLE

  • BTN_BACKBTN_SIDE :映射到MotionEvent.BUTTON_BACK 。按下此按鈕還會將按鍵與鍵碼KeyEvent.KEYCODE_BACK合成。

  • BTN_FORWARDBTN_EXTRA :映射到MotionEvent.BUTTON_FORWARD 。按下此按鈕還會將按鍵與鍵碼KeyEvent.KEYCODE_FORWARD合成。

  • BTN_STYLUS :映射到MotionEvent.BUTTON_SECONDARY

  • BTN_STYLUS2 :映射到MotionEvent.BUTTON_TERTIARY

工具和工具類型

工具是用於與觸摸設備交互的手指、觸控筆或其他設備。一些觸控設備可以區分不同類型的工具。

在 Android 的其他地方,如MotionEvent API,工具通常被稱為指針

支持以下工具類型:

  • BTN_TOOL_FINGERMT_TOOL_FINGER :映射到MotionEvent.TOOL_TYPE_FINGER

  • BTN_TOOL_PENMT_TOOL_PEN :映射到MotionEvent.TOOL_TYPE_STYLUS

  • BTN_TOOL_RUBBER :映射到MotionEvent.TOOL_TYPE_ERASER

  • BTN_TOOL_BRUSH :映射到MotionEvent.TOOL_TYPE_STYLUS

  • BTN_TOOL_PENCIL :映射到MotionEvent.TOOL_TYPE_STYLUS

  • BTN_TOOL_AIRBRUSH :映射到MotionEvent.TOOL_TYPE_STYLUS

  • BTN_TOOL_MOUSE :映射到MotionEvent.TOOL_TYPE_MOUSE

  • BTN_TOOL_LENS :映射到MotionEvent.TOOL_TYPE_MOUSE

  • BTN_TOOL_DOUBLETAPBTN_TOOL_TRIPLETAPBTN_TOOL_QUADTAP :映射到MotionEvent.TOOL_TYPE_FINGER

懸停與觸摸工具

工具可以與觸摸設備接觸,也可以在範圍內並懸停在其上方。並非所有觸摸設備都能夠感知懸停在觸摸設備上方的工具的存在。那些這樣做的,例如基於射頻的手寫筆數字化儀,通常可以檢測工具何時在數字化儀的有限範圍內。

InputReader組件負責區分觸摸工具和懸停工具。同樣,觸摸工具和懸停工具以不同方式報告給應用程序。

使用MotionEvent.ACTION_DOWNMotionEvent.ACTION_MOVEMotionEvent.ACTION_DOWNMotionEvent.ACTION_POINTER_DOWNMotionEvent.ACTION_POINTER_UP將觸摸工具作為觸摸事件報告給應用程序。

懸停工具使用MotionEvent.ACTION_HOVER_ENTERMotionEvent.ACTION_HOVER_MOVEMotionEvent.ACTION_HOVER_EXIT作為通用運動事件報告給應用程序。

觸控設備驅動程序要求

  1. 觸摸設備驅動程序應該只為它們實際支持的軸和按鈕註冊軸和鍵代碼。註冊多餘的軸或鍵碼可能會混淆設備分類算法或導致系統錯誤地檢測設備的功能。

    例如,如果設備報告了BTN_TOUCH鍵碼,系統將假定BTN_TOUCH將始終用於指示工具是否實際觸摸屏幕。因此,不應使用BTN_TOUCH來指示工具僅在範圍內並懸停。

  2. 單點觸控設備使用以下 Linux 輸入事件:

    • ABS_X :(必需)報告工具的 X 坐標。

    • ABS_Y :(必需)報告工具的 Y 坐標。

    • ABS_PRESSURE :(可選)報告施加到工具尖端的物理壓力或觸摸接觸的信號強度。

    • ABS_TOOL_WIDTH :(可選)報告觸摸觸點或工具本身的橫截面積或寬度。

    • ABS_DISTANCE :(可選)報告工具與觸摸設備表面的距離。

    • ABS_TILT_X :(可選)報告工具從觸摸設備表面沿 X 軸的傾斜度。

    • ABS_TILT_Y :(可選)報告工具從觸摸設備表面沿 Y 軸的傾斜度。

    • BTN_TOUCH :(必需)指示工具是否正在觸摸設備。

    • BTN_LEFTBTN_RIGHTBTN_MIDDLEBTN_BACKBTN_SIDEBTN_FORWARDBTN_EXTRABTN_STYLUSBTN_STYLUS2 :(可選)報告按鈕狀態。

    • BTN_TOOL_FINGERBTN_TOOL_PENBTN_TOOL_RUBBERBTN_TOOL_BRUSHBTN_TOOL_PENCILBTN_TOOL_AIRBRUSHBTN_TOOL_MOUSEBTN_TOOL_LENSBTN_TOOL_DOUBLETAPBTN_TOOL_TRIPLETAPBTN_TOOL_QUADTAP :(可選)報告工具類型

  3. 多點觸控設備使用以下 Linux 輸入事件:

    • ABS_MT_POSITION_X :(必需)報告工具的 X 坐標。

    • ABS_MT_POSITION_Y :(必需)報告工具的 Y 坐標。

    • ABS_MT_PRESSURE :(可選)報告施加到工具尖端的物理壓力或觸摸接觸的信號強度。

    • ABS_MT_TOUCH_MAJOR :(可選)報告觸摸接觸的橫截面積,或觸摸接觸的較長尺寸的長度。

    • ABS_MT_TOUCH_MINOR :(可選)報告觸摸接觸的較短尺寸的長度。如果ABS_MT_TOUCH_MAJOR報告面積測量,則不應使用此軸。

    • ABS_MT_WIDTH_MAJOR :(可選)報告工具本身的橫截面積,或工具本身較長尺寸的長度。如果工具本身的尺寸未知,則不應使用該軸。

    • ABS_MT_WIDTH_MINOR :(可選)報告工具本身的較短尺寸的長度。如果ABS_MT_WIDTH_MAJOR正在報告面積測量或工具本身的尺寸未知,則不應使用此軸。

    • ABS_MT_ORIENTATION :(可選)報告工具的方向。

    • ABS_MT_DISTANCE :(可選)報告工具與觸摸設備表面的距離。

    • ABS_MT_TOOL_TYPE :(可選)工具類型報告為MT_TOOL_FINGERMT_TOOL_PEN

    • ABS_MT_TRACKING_ID :(可選)報告工具的跟踪 ID。跟踪 id 是一個任意非負整數,用於在多個工具處於活動狀態時獨立地識別和跟踪每個工具。例如,當多個手指觸摸設備時,應該為每個手指分配一個不同的跟踪 id,只要手指保持接觸,就會使用該跟踪 id。當相關工具超出範圍時,可以重複使用跟踪 ID。

    • ABS_MT_SLOT :(可選)在使用 Linux 多點觸控協議“B”時報告工具的插槽 ID。有關詳細信息,請參閱 Linux 多點觸控協議文檔。

    • BTN_TOUCH :(必需)指示工具是否正在觸摸設備。

    • BTN_LEFTBTN_RIGHTBTN_MIDDLEBTN_BACKBTN_SIDEBTN_FORWARDBTN_EXTRABTN_STYLUSBTN_STYLUS2 :(可選)報告按鈕狀態。

    • BTN_TOOL_FINGERBTN_TOOL_PENBTN_TOOL_RUBBERBTN_TOOL_BRUSHBTN_TOOL_PENCILBTN_TOOL_AIRBRUSHBTN_TOOL_MOUSEBTN_TOOL_LENSBTN_TOOL_DOUBLETAPBTN_TOOL_TRIPLETAPBTN_TOOL_QUADTAP :(可選)報告工具類型

  4. 如果同時定義了單點觸控和多點觸控協議的軸,則僅使用多點觸控軸,而忽略單點觸控軸。

  5. ABS_XABS_YABS_MT_POSITION_XABS_MT_POSITION_Y軸的最小值和最大值以特定於設備的表面單位定義了設備活動區域的邊界。在觸摸屏的情況下,活動區域描述了觸摸設備實際覆蓋顯示器的部分。

    對於觸摸屏,系統會自動將上報的觸摸位置以表面為單位進行插值,得到以顯示像素為單位的觸摸位置,計算公式如下:

    displayX = (x - minX) * displayWidth / (maxX - minX + 1)
    displayY = (y - minY) * displayHeight / (maxY - minY + 1)
    

    觸摸屏可以報告報告的活動區域之外的觸摸。

    在活動區域之外發起的觸摸不會傳遞給應用程序,但可以用於虛擬鍵。

    在活動區域內發起的觸摸,或者進入和退出顯示區域的觸摸被傳遞給應用程序。因此,如果觸摸在應用程序的邊界內開始,然後移出活動區域,則應用程序可能會接收到顯示坐標為負數或超出顯示邊界的觸摸事件。這是預期的行為。

    觸摸設備不應該將觸摸坐標限制在活動區域的範圍內。如果觸摸退出活動區域,則應將其報告為在活動區域之外,或者根本不應該報告。

    例如,如果用戶的手指在觸摸屏的左上角附近進行觸摸,則它可能會報告 (minX, minY) 的坐標。如果手指繼續移動到活動區域之外,觸摸屏應該開始報告具有小於 minX 和 minY 的分量的坐標,例如 (minX - 2, minY - 3),或者應該完全停止報告觸摸。換句話說,當用戶的手指真正觸摸到活動區域之外時,觸摸屏應該報告 (minX, minY)。

    將觸摸坐標固定到顯示邊緣會在屏幕邊緣周圍創建人造硬邊界,從而防止系統平滑跟踪進入或退出顯示區域邊界的運動。

  6. ABS_PRESSUREABS_MT_PRESSURE報告的值,如果它們被報告的話,當工具接觸設備時必須非零,否則為零表示工具正在懸停。

    報告壓力信息是可選的,但強烈建議。應用程序可以使用壓力信息來實現壓敏繪圖和其他效果。

  7. ABS_TOOL_WIDTHABS_MT_TOUCH_MAJORABS_MT_TOUCH_MINORABS_MT_WIDTH_MAJORABS_MT_WIDTH_MINOR報告的值在工具接觸設備時應為非零,否則為零,但這不是必需的。例如,觸摸設備可能能夠測量手指觸摸觸點的大小,但不能測量觸控筆觸摸觸點的大小。

    報告大小信息是可選的,但強烈建議。應用程序可以使用壓力信息來實現尺寸敏感的繪圖和其他效果。

  8. 當工具接觸設備時, ABS_DISTANCEABS_MT_DISTANCE報告的值應接近零。即使工具直接接觸,該距離也可能保持非零。報告的確切值取決於硬件測量距離的方式。

    報告距離信息是可選的,但建議用於觸控筆設備。

  9. 當工具垂直於設備時, ABS_TILT_XABS_TILT_Y報告的值應為零。非零傾斜被視為工具被保持在傾斜的指示。

    假設沿 X 軸和 Y 軸的傾斜角以與垂直線的度數為單位。每個軸的中心點(完全垂直)由(max + min) / 2給出。小於中心點的值表示向上或向左傾斜,大於中心點的值表示向下或向右傾斜。

    InputReader將 X 和 Y 傾斜分量轉換為範圍從 0 到PI / 2弧度的垂直傾斜角和範圍從-PIPI弧度的平面方向角。這種表示導致對方向的描述與用於描述手指觸摸的內容兼容。

    報告傾斜信息是可選的,但建議用於觸控筆設備。

  10. 如果工具類型由ABS_MT_TOOL_TYPE報告,它將取代任何由BTN_TOOL_*報告的工具類型信息。如果根本沒有可用的工具類型信息,則工具類型默認為MotionEvent.TOOL_TYPE_FINGER

  11. 根據以下條件確定工具處於活動狀態:

    • 使用單點觸控協議時,如果BTN_TOUCHBTN_TOOL_*為 1,則該工具處於活動狀態。

      這種情況意味著InputReader需要至少有一些關於工具性質的信息,無論是觸摸還是工具類型。如果沒有可用信息,則假定該工具處於非活動狀態(超出範圍)。

    • 使用多點觸控協議“A”時,只要該工具出現在最近的同步報告中,它就會處於活動狀態。當該工具停止出現在同步報告中時,它就不再存在。

    • 使用多點觸控協議“B”時,只要工具有一個活動插槽,它就處於活動狀態。當它清除插槽時,該工具將不復存在。

  12. 根據以下條件確定工具處於懸停狀態:

    • 如果工具是BTN_TOOL_MOUSEBTN_TOOL_LENS ,則即使滿足以下任一條件,工具也不會懸停。

    • 如果工具處於活動狀態並且驅動程序報告壓力信息,並且報告的壓力為零,則工具處於懸停狀態。

    • 如果該工具處於活動狀態且驅動程序支持BTN_TOUCH鍵碼且BTN_TOUCH的值為零,則該工具處於懸停狀態。

  13. InputReader支持多點觸控協議“A”和“B”。新驅動程序應使用“B”協議,但兩者都可以。

  14. 從 Android Ice Cream Sandwich 4.0 開始,可能需要更改觸摸屏驅動程序以符合 Linux 輸入協議規範。

    可能需要進行以下更改:

    • 當工具變為非活動狀態(手指“向上”)時,它應該停止出現在後續的多點觸控同步報告中。當所有工具都變為非活動狀態(所有手指都“向上”)時,驅動程序應發送一個空的同步報告數據包,例如SYN_MT_REPORT後跟SYN_REPORT

      早期版本的 Android 期望通過發送壓力值 0 來報告“向上”事件。舊的行為與 Linux 輸入協議規範不兼容,不再受支持。

    • 應使用ABS_MT_PRESSURE報告物理壓力或信號強度信息。

      以前版本的 Android 從ABS_MT_TOUCH_MAJOR檢索壓力信息。舊行為與 Linux 輸入協議規範不兼容,不再受支持。

    • 應使用ABS_MT_TOUCH_MAJOR報告觸摸大小信息。

      以前版本的 Android 從ABS_MT_TOOL_MAJOR檢索大小信息。舊行為與 Linux 輸入協議規範不兼容,不再受支持。

    觸控設備驅動程序不再需要特定於 Android 的自定義。依靠標準的 Linux 輸入協議,Android 可以使用未經修改的驅動程序支持更廣泛的觸摸外圍設備,例如外部 HID 多點觸控觸摸屏。

觸控設備操作

下面簡單總結一下Android上的觸控設備操作。

  1. EventHubevdev驅動程序讀取原始事件。

  2. InputReader使用原始事件並更新有關每個工具的位置和其他特徵的內部狀態。它還跟踪按鈕狀態。

  3. 如果按下或釋放 BACK 或 FORWARD 按鈕,則InputReader會通知InputDispatcher有關鍵事件。

  4. InputReader確定是否發生了虛擬按鍵按下。如果是這樣,它會通知InputDispatcher關鍵事件。

  5. InputReader確定觸摸是否在顯示範圍內啟動。如果是這樣,它會通知InputDispatcher觸摸事件。

  6. 如果沒有觸摸工具但至少有一個懸停工具,則InputReader通知InputDispatcher懸停事件。

  7. 如果觸摸設備類型是指針,則InputReader執行指針手勢檢測,相應地移動指針和點,並通知InputDispatcher指針事件。

  8. InputDispatcher使用WindowManagerPolicy來確定是否應該分派事件以及它們是否應該喚醒設備。然後, InputDispatcher將事件傳遞給適當的應用程序。

觸控設備配置

觸摸設備行為由設備的軸、按鈕、輸入屬性、輸入設備配置、虛擬鍵映射和鍵佈局決定。

有關參與鍵盤配置的文件的更多詳細信息,請參閱以下部分:

特性

系統依賴於許多輸入設備配置屬性來配置和校準觸摸設備行為。

原因之一是觸摸設備的設備驅動程序經常使用設備特定的單元報告觸摸的特性。

例如,許多觸摸設備使用內部設備特定的尺度來測量觸摸接觸面積,例如由觸摸觸發的傳感器節點的總數。這個原始尺寸值對應用程序沒有意義,因為它們需要了解觸摸設備傳感器節點的物理尺寸和其他特性。

該系統使用輸入設備配置文件中編碼的校準參數,將觸摸設備報告的值解碼、轉換和規範化為應用程序可以理解的更簡單的標準表示。

文檔約定

出於文檔目的,我們將使用以下約定來描述系統在校準過程中使用的值。

原始軸值

以下表達式將觸摸設備驅動程序報告為EV_ABS事件的原始值表示。

raw.x
ABS_XABS_MT_POSITION_X軸的值。
raw.y
ABS_YABS_MT_POSITION_Y軸的值。
raw.pressure
ABS_PRESSUREABS_MT_PRESSURE軸的值,如果不可用,則為 0。
raw.touchMajor
ABS_MT_TOUCH_MAJOR軸的值,如果不可用,則為 0。
raw.touchMinor
ABS_MT_TOUCH_MINOR軸的值,如果不可用, raw.touchMajor
raw.toolMajor
ABS_TOOL_WIDTHABS_MT_WIDTH_MAJOR軸的值,如果不可用,則為 0。
raw.toolMinor
ABS_MT_WIDTH_MINOR軸的值,如果不可用, raw.toolMajor
raw.orientation
ABS_MT_ORIENTATION軸的值,如果不可用,則為 0。
raw.distance
ABS_DISTANCEABS_MT_DISTANCE軸的值,如果不可用,則為 0。
raw.tiltX
ABS_TILT_X軸的值,如果不可用,則為 0。
raw.tiltY
ABS_TILT_Y軸的值,如果不可用,則為 0。

原始軸範圍

以下表達式表示原始值的界限。它們是通過為每個軸調用EVIOCGABS ioctl 獲得的。

raw.*.min
原始軸的包含最小值。
raw.*.max
原始軸的包含最大值。
raw.*.range
相當於raw.*.max - raw.*.min
raw.*.fuzz
原始軸的精度。例如。 fuzz = 1 表示值精確到 +/- 1 個單位。
raw.width
觸摸區域的包含寬度,相當於raw.x.range + 1
raw.height
觸摸區域的包含高度,相當於raw.y.range + 1

輸出範圍

以下表達式表示輸出坐標系的特徵。該系統使用線性插值將觸摸位置信息從觸摸設備使用的表面單元轉換為輸出單元,這些輸出單元將報告給顯示像素等應用程序。

output.width
輸出寬度。對於觸摸屏(與顯示器相關聯),這是以像素為單位的顯示寬度。對於觸摸板(不與顯示器關聯),輸出寬度等於raw.width ,表示不會執行插值。
output.height
輸出高度。對於觸摸屏(與顯示器相關聯),這是以像素為單位的顯示器高度。對於觸摸板(不與顯示器關聯),輸出高度等於raw.height ,表示不會執行插值。
output.diag
輸出坐標系的對角線長度,相當於sqrt(output.width ^2 + output.height ^2)

基本配置

觸摸輸入映射器使用輸入設備配置文件中的許多配置屬性來指定校準值。下表描述了一些通用配置屬性。所有其他屬性以及它們用於校準的字段都在以下部分中進行了描述。

touch.deviceType

定義: touch.deviceType = touchScreen | touchPad | pointer | default

指定觸摸設備類型。

  • 如果值為touchScreen ,則觸摸設備是與顯示器關聯的觸摸屏。

  • 如果值為touchPad ,則觸摸設備是與顯示器無關的觸摸板。

  • 如果值為pointer ,則觸摸設備是與顯示器無關的觸摸板,其動作用於間接多點觸摸指針手勢

  • 如果值為default ,系統會根據分類算法自動檢測設備類型。

有關設備類型如何影響觸摸設備行為的更多詳細信息,請參閱分類部分。

在 Honeycomb 之前,所有的觸摸設備都被假定為觸摸屏。

touch.orientationAware

定義: touch.orientationAware = 0 | 1

指定觸摸設備是否應對顯示方向更改做出反應。

  • 如果值為1 ,則每當顯示方向改變時,觸摸設備報告的觸摸位置都會旋轉。

  • 如果值為0 ,則觸摸設備報告的觸摸位置不受顯示方向變化的影響。

如果設備是觸摸屏,則默認值為1 ,否則為0

該系統區分內部和外部觸摸屏和顯示器。方向感知內部觸摸屏根據內部顯示器的方向旋轉。基於外部顯示器的方向旋轉感知方向的外部觸摸屏。

方向感知用於支持 Nexus One 等設備上的觸摸屏旋轉。例如,當設備從其自然方向順時針旋轉 90 度時,觸摸的絕對位置被重新映射,使得觸摸屏絕對坐標系左上角的觸摸被報告為左上角的觸摸顯示器旋轉坐標系的一角。這樣做是為了使用與應用程序繪製其視覺元素相同的坐標係來報告觸摸。

在 Honeycomb 之前,所有的觸摸設備都被認為是方向感知的。

touch.gestureMode

定義: touch.gestureMode = pointer | spots | default

指定指針手勢的演示模式。此配置屬性僅在觸摸設備類型為pointer時才相關。

  • 如果值為pointer ,則觸摸板手勢通過類似於鼠標指針的光標呈現。

  • 如果值為spots ,則觸摸板手勢由代表手勢質心的錨點和代表各個手指位置的一組圓形點呈現。

當設置INPUT_PROP_SEMI_MT輸入屬性時,默認值為pointer ,否則為spots

XY字段

X 和 Y 字段提供接觸區域中心的位置信息。

計算

計算很簡單:來自觸摸驅動程序的位置信息被線性插值到輸出坐標系。

xScale = output.width / raw.width
yScale = output.height / raw.height

If not orientation aware or screen rotation is 0 degrees:
output.x = (raw.x - raw.x.min) * xScale
output.y = (raw.y - raw.y.min) * yScale
Else If rotation is 90 degrees:
    output.x = (raw.y - raw.y.min) * yScale
    output.y = (raw.x.max - raw.x) * xScale
Else If rotation is 180 degrees:
    output.x = (raw.x.max - raw.x) * xScale
    output.y = (raw.y.max - raw.y) * yScale
Else If rotation is 270 degrees:
    output.x = (raw.y.max - raw.y) * yScale
    output.y = (raw.x - raw.x.min) * xScale
End If

TouchMajor , TouchMinor , ToolMajor , ToolMinor , Size字段

TouchMajorTouchMinor字段以輸出單位(像素)描述接觸區域的大致尺寸。

ToolMajorToolMinor字段以輸出單位(像素)描述工具本身的大致尺寸。

Size字段描述了相對於觸摸設備可以感知的最大可能觸摸的標準化觸摸尺寸。最小可能的歸一化尺寸為 0.0(無接觸,或無法測量),最大可能的歸一化尺寸為 1.0(傳感器區域已飽和)。

當大致長度和寬度都可以測量時, TouchMajor字段指定接觸區域的較長尺寸, TouchMinor字段指定接觸區域的較短尺寸。當只能測量接觸區域的大致直徑時, TouchMajorTouchMinor字段將相等。

同樣, ToolMajor字段指定較長的尺寸, ToolMinor字段指定工具橫截面積的較短尺寸。

如果觸摸尺寸不可用但工具尺寸可用,則工具尺寸將設置為等於觸摸尺寸。相反,如果工具尺寸不可用但觸摸尺寸可用,則觸摸尺寸將設置為等於工具尺寸。

觸摸設備以各種方式測量或報告觸摸大小和工具大小。當前實現支持三種不同類型的測量:直徑、面積和以表面為單位的幾何邊界框。

touch.size.calibration

定義: touch.size.calibration = none | geometric | diameter | area | default

指定觸摸驅動程序用於報告觸摸大小和工具大小的測量類型。

  • 如果值為none ,則大小設置為零。

  • 如果值為geometric ,則假定大小以與位置相同的表面單位指定,因此以相同的方式縮放。

  • 如果值為diameter ,則假定大小與觸摸或工具的直徑(寬度)成比例。

  • 如果值為area ,則假定大小與觸摸或工具的面積成比例。

  • 如果值為default ,則係統在raw.touchMajorraw.toolMajor軸可用時使用geometric校準,否則使用none校準。

touch.size.scale

定義: touch.size.scale = <一個非負浮點數>

指定校準中使用的恆定比例因子。

默認值為1.0

touch.size.bias

定義: touch.size.bias = <一個非負浮點數>

指定校準中使用的恆定偏差值。

默認值為0.0

touch.size.isSummed

定義: touch.size.isSummed = 0 | 1

指定大小是報告為所有活動聯繫人大小的總和,還是針對每個聯繫人單獨報告。

  • 如果值為1 ,則報告的大小將除以使用前的聯繫人數量。

  • 如果值為0 ,則報告的大小將按原樣使用。

默認值為0

一些觸摸設備,尤其是“Semi-MT”設備無法區分多個觸點的各個尺寸,因此它們報告的尺寸測量值表示它們的總面積或寬度。對於此類設備,該屬性只能設置為1 。如果有疑問,請將此值設置為0

計算

TouchMajorTouchMinorToolMajorToolMinorSize字段的計算取決於指定的校準參數。

If raw.touchMajor and raw.toolMajor are available:
    touchMajor = raw.touchMajor
    touchMinor = raw.touchMinor
    toolMajor = raw.toolMajor
    toolMinor = raw.toolMinor
Else If raw.touchMajor is available:
    toolMajor = touchMajor = raw.touchMajor
    toolMinor = touchMinor = raw.touchMinor
Else If raw.toolMajor is available:
    touchMajor = toolMajor = raw.toolMajor
    touchMinor = toolMinor = raw.toolMinor
Else
    touchMajor = toolMajor = 0
    touchMinor = toolMinor = 0
    size = 0
End If

size = avg(touchMajor, touchMinor)

If touch.size.isSummed == 1:
    touchMajor = touchMajor / numberOfActiveContacts
    touchMinor = touchMinor / numberOfActiveContacts
    toolMajor = toolMajor / numberOfActiveContacts
    toolMinor = toolMinor / numberOfActiveContacts
    size = size / numberOfActiveContacts
End If

If touch.size.calibration == "none":
    touchMajor = toolMajor = 0
    touchMinor = toolMinor = 0
    size = 0
Else If touch.size.calibration == "geometric":
    outputScale = average(output.width / raw.width, output.height / raw.height)
    touchMajor = touchMajor * outputScale
    touchMinor = touchMinor * outputScale
    toolMajor = toolMajor * outputScale
    toolMinor = toolMinor * outputScale
Else If touch.size.calibration == "area":
    touchMajor = sqrt(touchMajor)
    touchMinor = touchMajor
    toolMajor = sqrt(toolMajor)
    toolMinor = toolMajor
Else If touch.size.calibration == "diameter":
    touchMinor = touchMajor
    toolMinor = toolMajor
End If

If touchMajor != 0:
    output.touchMajor = touchMajor * touch.size.scale + touch.size.bias
Else
    output.touchMajor = 0
End If

If touchMinor != 0:
    output.touchMinor = touchMinor * touch.size.scale + touch.size.bias
Else
    output.touchMinor = 0
End If

If toolMajor != 0:
    output.toolMajor = toolMajor * touch.size.scale + touch.size.bias
Else
    output.toolMajor = 0
End If

If toolMinor != 0:
    output.toolMinor = toolMinor * touch.size.scale + touch.size.bias
Else
    output.toolMinor = 0
End If

output.size = size

Pressure

Pressure字段將施加到觸摸設備的近似物理壓力描述為介於 0.0(無觸摸)和 1.0(全力)之間的標準化值。

零壓力表示工具正在懸停。

touch.pressure.calibration

定義: touch.pressure.calibration = none | physical | amplitude | default

指定觸摸驅動程序用於報告壓力的測量類型。

  • 如果值為none ,則壓力未知,因此在觸摸時設置為 1.0,在懸停時設置為 0.0。

  • 如果值為physical ,則假定壓力軸測量施加到觸摸板的實際壓力物理強度。

  • If the value is amplitude , the pressure axis is assumed to measure the signal amplitude, which is related to the size of the contact and the pressure applied.

  • If the value is default , the system uses the physical calibration if the pressure axis available, otherwise uses none .

touch.pressure.scale

Definition: touch.pressure.scale = <a non-negative floating point number>

Specifies a constant scale factor used in the calibration.

The default value is 1.0 / raw.pressure.max .

Calculation

The calculation of the Pressure field depends on the specified calibration parameters.

If touch.pressure.calibration == "physical" or "amplitude":
    output.pressure = raw.pressure * touch.pressure.scale
Else
    If hovering:
        output.pressure = 0
    Else
        output.pressure = 1
    End If
End If

Orientation and Tilt Fields

The Orientation field describes the orientation of the touch and tool as an angular measurement. An orientation of 0 indicates that the major axis is oriented vertically, -PI/2 indicates that the major axis is oriented to the left, PI/2 indicates that the major axis is oriented to the right. When a stylus tool is present, the orientation range may be described in a full circle range from -PI or PI .

The Tilt field describes the inclination of the tool as an angular measurement. A tilt of 0 indicates that the tool is perpendicular to the surface. A tilt of PI/2 indicates that the tool is flat on the surface.

touch.orientation.calibration

Definition: touch.orientation.calibration = none | interpolated | vector | default

Specifies the kind of measurement used by the touch driver to report the orientation.

  • If the value is none , the orientation is unknown so it is set to 0.

  • If the value is interpolated , the orientation is linearly interpolated such that a raw value of raw.orientation.min maps to -PI/2 and a raw value of raw.orientation.max maps to PI/2 . The center value of (raw.orientation.min + raw.orientation.max) / 2 maps to 0 .

  • If the value is vector , the orientation is interpreted as a packed vector consisiting of two signed 4-bit fields. This representation is used on Atmel Object Based Protocol parts. When decoded, the vector yields an orientation angle and confidence magnitude. The confidence magnitude is used to scale the size information, unless it is geometric.

  • If the value is default , the system uses the interpolated calibration if the orientation axis available, otherwise uses none .

Calculation

The calculation of the Orientation and Tilt fields depends on the specified calibration parameters and available input.

If touch.tiltX and touch.tiltY are available:
    tiltXCenter = average(raw.tiltX.min, raw.tiltX.max)
    tiltYCenter = average(raw.tiltY.min, raw.tiltY.max)
    tiltXAngle = (raw.tiltX - tiltXCenter) * PI / 180
    tiltYAngle = (raw.tiltY - tiltYCenter) * PI / 180
    output.orientation = atan2(-sin(tiltXAngle), sinf(tiltYAngle))
    output.tilt = acos(cos(tiltXAngle) * cos(tiltYAngle))
Else If touch.orientation.calibration == "interpolated":
    center = average(raw.orientation.min, raw.orientation.max)
    output.orientation = PI / (raw.orientation.max - raw.orientation.min)
    output.tilt = 0
Else If touch.orientation.calibration == "vector":
    c1 = (raw.orientation & 0xF0) >> 4
    c2 = raw.orientation & 0x0F

    If c1 != 0 or c2 != 0:
        If c1 >= 8 Then c1 = c1 - 16
        If c2 >= 8 Then c2 = c2 - 16
        angle = atan2(c1, c2) / 2
        confidence = sqrt(c1*c1 + c2*c2)

        output.orientation = angle

        If touch.size.calibration == "diameter" or "area":
            scale = 1.0 + confidence / 16
            output.touchMajor *= scale
            output.touchMinor /= scale
            output.toolMajor *= scale
            output.toolMinor /= scale
        End If
    Else
        output.orientation = 0
    End If
    output.tilt = 0
Else
    output.orientation = 0
    output.tilt = 0
End If

If orientation aware:
    If screen rotation is 90 degrees:
        output.orientation = output.orientation - PI / 2
    Else If screen rotation is 270 degrees:
        output.orientation = output.orientation + PI / 2
    End If
End If

Distance Field

The Distance field describes the distance between the tool and the touch device surface. A value of 0.0 indicates direct contact and larger values indicate increasing distance from the surface.

touch.distance.calibration

Definition: touch.distance.calibration = none | scaled | default

Specifies the kind of measurement used by the touch driver to report the distance.

  • If the value is none , the distance is unknown so it is set to 0.

  • If the value is scaled , the reported distance is multiplied by a constant scale factor.

  • If the value is default , the system uses the scaled calibration if the distance axis available, otherwise uses none .

touch.distance.scale

Definition: touch.distance.scale = <a non-negative floating point number>

Specifies a constant scale factor used in the calibration.

The default value is 1.0 .

Calculation

The calculation of the Distance field depends on the specified calibration parameters.

If touch.distance.calibration == "scaled":
    output.distance = raw.distance * touch.distance.scale
Else
    output.distance = 0
End If

Example

# Input device configuration file for a touch screen that supports pressure,
# size and orientation.  The pressure and size scale factors were obtained
# by measuring the characteristics of the device itself and deriving
# useful approximations based on the resolution of the touch sensor and the
# display.
#
# Note that these parameters are specific to a particular device model.
# Different parameters will need to be used for other devices.

# Basic Parameters
touch.deviceType = touchScreen
touch.orientationAware = 1

# Size
# Based on empirical measurements, we estimate the size of the contact
# using size = sqrt(area) * 28 + 0.
touch.size.calibration = area
touch.size.scale = 28
touch.size.bias = 0
touch.size.isSummed = 0

# Pressure
# Driver reports signal strength as pressure.
#
# A normal index finger touch typically registers about 80 signal strength
# units although we don't expect these values to be accurate.
touch.pressure.calibration = amplitude
touch.pressure.scale = 0.0125

# Orientation
touch.orientation.calibration = vector

Compatibility Notes

The configuration properties for touch devices changed significantly in Android Ice Cream Sandwich 4.0. All input device configuration files for touch devices must be updated to use the new configuration properties.

Older touch device drivers may also need to be updated.

Virtual Key Map Files

Touch devices are often used to implement virtual keys.

There are several ways of doing this, depending on the capabilities of the touch controller. Some touch controllers can be directly configured to implement soft keys by setting firmware registers. Other times it is desirable to perform the mapping from touch coordinates to key codes in software.

When virtual keys are implemented in software, the kernel must export a virtual key map file called virtualkeys.<devicename> as a board property. For example, if the touch screen device drivers reports its name as "touchyfeely" then the virtual key map file must have the path /sys/board_properties/virtualkeys.touchyfeely .

A virtual key map file describes the coordinates and Linux key codes of virtual keys on the touch screen.

In addition to the virtual key map file, there must be a corresponding key layout file and key character map file to map the Linux key codes to Android key codes and to specify the type of the keyboard device (usually SPECIAL_FUNCTION ).

Syntax

A virtual key map file is a plain text file consisting of a sequence of virtual key layout descriptions either separated by newlines or by colons.

Comment lines begin with '#' and continue to the end of the line.

Each virtual key is described by 6 colon-delimited components:

  • 0x01 : A version code. Must always be 0x01 .
  • <Linux key code>: The Linux key code of the virtual key.
  • <centerX>: The X pixel coordinate of the center of the virtual key.
  • <centerY>: The Y pixel coordinate of the center of the virtual key.
  • <width>: The width of the virtual key in pixels.
  • <height>: The height of the virtual key in pixels.

All coordinates and sizes are specified in terms of the display coordinate system.

Here is a virtual key map file all written on one line.

# All on one line
0x01:158:55:835:90:55:0x01:139:172:835:125:55:0x01:102:298:835:115:55:0x01:217:412:835:95:55

The same virtual key map file can also be written on multiple lines.

# One key per line
0x01:158:55:835:90:55
0x01:139:172:835:125:55
0x01:102:298:835:115:55
0x01:217:412:835:95:55

In the above example, the touch screen has a resolution of 480x800. Accordingly, all of the virtual keys have a <centerY> coordinate of 835, which is a little bit below the visible area of the touch screen.

The first key has a Linux scan code of 158 ( KEY_BACK ), centerX of 55 , centerY of 835 , width of 90 and height of 55 .

Example

Virtual key map file: /sys/board_properties/virtualkeys.touchyfeely .

0x01:158:55:835:90:55
0x01:139:172:835:125:55
0x01:102:298:835:115:55
0x01:217:412:835:95:55

Key layout file: /system/usr/keylayout/touchyfeely.kl .

key 158 BACK
key 139 MENU
key 172 HOME
key 217 SEARCH

Key character map file: /system/usr/keychars/touchyfeely.kcm .

type SPECIAL_FUNCTION

Indirect Multi-touch Pointer Gestures

In pointer mode, the system interprets the following gestures:

  1. Single finger tap: click.

  2. Single finger motion: move the pointer.

  3. Single finger motion plus button presses: drag the pointer.

  4. Two finger motion both fingers moving in the same direction: drag the area under the pointer in that direction. The pointer itself does not move.

  5. Two finger motion both fingers moving towards each other or apart in different directions: pan/scale/rotate the area surrounding the pointer. The pointer itself does not move.

  6. Multiple finger motion: freeform gesture.

Further Reading

  1. Linux multi-touch protocol
  2. ENAC list of available multitouch devices on Linux