Appareils tactiles

Android prend en charge une variété d'écrans tactiles et de pavés tactiles, y compris les tablettes numériques à stylet.

Les écrans tactiles sont des dispositifs tactiles qui sont associés à un affichage de sorte que l'utilisateur a l'impression de manipuler directement des éléments à l'écran.

Les pavés tactiles sont des appareils tactiles qui ne sont pas associés à un écran tel qu'une tablette numérique. Les pavés tactiles sont généralement utilisés pour le pointage ou pour le positionnement indirect absolu ou le contrôle gestuel d'une interface utilisateur.

Les appareils tactiles peuvent avoir des boutons dont les fonctions sont similaires aux boutons de la souris.

Les appareils tactiles peuvent parfois être manipulés à l'aide d'une variété d'outils différents tels que les doigts ou un stylet en fonction de la technologie de capteur tactile sous-jacente.

Les appareils tactiles sont parfois utilisés pour implémenter des clés virtuelles. Par exemple, sur certains appareils Android, la zone du capteur de l'écran tactile s'étend au-delà du bord de l'écran et remplit une double fonction dans le cadre d'un clavier tactile.

En raison de la grande variété d'appareils tactiles, Android s'appuie sur un grand nombre de propriétés de configuration pour décrire les caractéristiques et le comportement souhaité de chaque appareil.

Classification des appareils tactiles

Un périphérique d'entrée est classé comme périphérique multipoint si les deux conditions suivantes sont remplies :

  • Le dispositif d'entrée signale la présence des axes absolus ABS_MT_POSITION_X et ABS_MT_POSITION_Y .

  • Le périphérique d'entrée n'a pas de boutons de manette de jeu. Cette condition résout une ambiguïté avec certaines manettes de jeu qui signalent des axes avec des codes qui chevauchent ceux des axes MT.

Un périphérique d'entrée est classé comme périphérique à simple contact si les deux conditions suivantes sont remplies :

  • Le périphérique d'entrée n'est pas classé comme un périphérique multi-touch. Un périphérique d'entrée est soit classé comme périphérique à simple contact, soit comme périphérique multi-touch, jamais les deux.

  • Le dispositif d'entrée signale la présence des axes absolus ABS_X et ABS_Y , et la présence du code clé BTN_TOUCH .

Une fois qu'un dispositif d'entrée a été classé comme dispositif tactile, la présence de touches virtuelles est déterminée en tentant de charger le fichier de carte de touches virtuelles pour le dispositif. Si une carte de touches virtuelle est disponible, le fichier de disposition des touches de l'appareil est également chargé.

Reportez-vous à la section ci-dessous concernant l'emplacement et le format des fichiers de cartes de touches virtuelles.

Ensuite, le système charge le fichier de configuration du périphérique d'entrée pour le périphérique tactile.

Tous les périphériques tactiles intégrés doivent avoir des fichiers de configuration de périphérique d'entrée. Si aucun fichier de configuration de périphérique d'entrée n'est présent, le système choisira une configuration par défaut appropriée pour les périphériques tactiles à usage général typiques tels que les écrans tactiles externes USB ou Bluetooth HID ou les pavés tactiles. Ces valeurs par défaut ne sont pas conçues pour les écrans tactiles intégrés et entraîneront très probablement un comportement incorrect.

Une fois la configuration du périphérique d'entrée chargée, le système classera le périphérique d'entrée en tant qu'écran tactile , pavé tactile ou périphérique de pointage.

  • Un dispositif à écran tactile est utilisé pour la manipulation directe d'objets sur l'écran. Puisque l'utilisateur touche directement l'écran, le système n'a pas besoin d'affordations supplémentaires pour indiquer les objets manipulés.

  • Un dispositif à pavé tactile est utilisé pour fournir des informations de positionnement absolu à une application concernant les touches sur une zone de capteur donnée. Cela peut être utile pour les tablettes numériques.

  • Un dispositif de pointage est utilisé pour la manipulation indirecte d'objets sur l'écran à l'aide d'un curseur . Les doigts sont interprétés comme des gestes de pointeur multi-touch. D'autres outils, tels que les stylets, sont interprétés à l'aide de positions absolues.

    Voir Gestes indirects du pointeur multipoint pour plus d'informations.

Les règles suivantes sont utilisées pour classer le périphérique d'entrée en tant qu'écran tactile , pavé tactile ou périphérique de pointage.

  • Si la propriété touch.deviceType est définie, le type de périphérique sera défini comme indiqué.

  • Si le périphérique d'entrée signale la présence de la propriété d'entrée INPUT_PROP_DIRECT (via l'ioctl EVIOCGPROP ), alors le type de périphérique sera défini sur écran tactile . Cette condition suppose que les périphériques tactiles à saisie directe sont connectés à un écran également connecté.

  • Si le périphérique d'entrée signale la présence de la propriété d'entrée INPUT_PROP_POINTER (via l'ioctl EVIOCGPROP ), alors le type de périphérique sera défini sur pointeur .

  • Si le dispositif d'entrée signale la présence des axes relatifs REL_X ou REL_Y , alors le type de dispositif sera réglé sur pavé tactile . Cette condition résout une ambiguïté pour les périphériques d'entrée qui se composent à la fois d'une souris et d'un pavé tactile. Dans ce cas, le pavé tactile ne sera pas utilisé pour contrôler le pointeur car la souris le contrôle déjà.

  • Sinon, le type de périphérique sera défini sur pointeur . Cette valeur par défaut garantit que les pavés tactiles qui n'ont pas été désignés à d'autres fins spéciales serviront à contrôler le pointeur.

Boutons

Les boutons sont des commandes facultatives qui peuvent être utilisées par les applications pour exécuter des fonctions supplémentaires. Les boutons des appareils tactiles se comportent de la même manière que les boutons de la souris et sont principalement utilisés avec des appareils tactiles de type pointeur ou avec un stylet.

Les boutons suivants sont pris en charge :

  • BTN_LEFT : mappé à MotionEvent.BUTTON_PRIMARY .

  • BTN_RIGHT : mappé à MotionEvent.BUTTON_SECONDARY .

  • BTN_MIDDLE : mappé à MotionEvent.BUTTON_MIDDLE .

  • BTN_BACK et BTN_SIDE : mappés à MotionEvent.BUTTON_BACK . L'appui sur ce bouton synthétise également un appui sur une touche avec le code de touche KeyEvent.KEYCODE_BACK .

  • BTN_FORWARD et BTN_EXTRA : mappés à MotionEvent.BUTTON_FORWARD . L'appui sur ce bouton synthétise également une pression de touche avec le code de touche KeyEvent.KEYCODE_FORWARD .

  • BTN_STYLUS : mappé à MotionEvent.BUTTON_SECONDARY .

  • BTN_STYLUS2 : mappé à MotionEvent.BUTTON_TERTIARY .

Outils et types d'outils

Un outil est un doigt, un stylet ou un autre appareil utilisé pour interagir avec l'appareil tactile. Certains appareils tactiles peuvent distinguer différents types d'outils.

Ailleurs dans Android, comme dans l'API MotionEvent , un outil est souvent appelé un pointeur .

Les types d'outils suivants sont pris en charge :

  • BTN_TOOL_FINGER et MT_TOOL_FINGER : mappés à MotionEvent.TOOL_TYPE_FINGER .

  • BTN_TOOL_PEN et MT_TOOL_PEN : mappés à MotionEvent.TOOL_TYPE_STYLUS .

  • BTN_TOOL_RUBBER : mappé à MotionEvent.TOOL_TYPE_ERASER .

  • BTN_TOOL_BRUSH : mappé à MotionEvent.TOOL_TYPE_STYLUS .

  • BTN_TOOL_PENCIL : mappé à MotionEvent.TOOL_TYPE_STYLUS .

  • BTN_TOOL_AIRBRUSH : mappé à MotionEvent.TOOL_TYPE_STYLUS .

  • BTN_TOOL_MOUSE : mappé à MotionEvent.TOOL_TYPE_MOUSE .

  • BTN_TOOL_LENS : mappé à MotionEvent.TOOL_TYPE_MOUSE .

  • BTN_TOOL_DOUBLETAP , BTN_TOOL_TRIPLETAP et BTN_TOOL_QUADTAP : mappés à MotionEvent.TOOL_TYPE_FINGER .

Outils de survol ou de toucher

Les outils peuvent être soit en contact avec l'appareil tactile, soit à portée et planant au-dessus de celui-ci. Tous les appareils tactiles ne sont pas capables de détecter la présence d'un outil planant au-dessus de l'appareil tactile. Ceux qui le font, tels que les numériseurs à stylet basés sur RF, peuvent souvent détecter lorsque l'outil se trouve dans une plage limitée du numériseur.

Le composant InputReader prend soin de distinguer les outils en contact des outils en survol. De même, les outils tactiles et les outils flottants sont signalés aux applications de différentes manières.

Les outils tactiles sont signalés aux applications en tant qu'événements tactiles à l'aide MotionEvent.ACTION_DOWN , MotionEvent.ACTION_MOVE , MotionEvent.ACTION_DOWN , MotionEvent.ACTION_POINTER_DOWN et MotionEvent.ACTION_POINTER_UP .

Les outils en survol sont signalés aux applications en tant qu'événements de mouvement génériques à l'aide MotionEvent.ACTION_HOVER_ENTER , MotionEvent.ACTION_HOVER_MOVE et MotionEvent.ACTION_HOVER_EXIT .

Configuration requise pour le pilote de périphérique tactile

  1. Les pilotes d'appareils tactiles ne doivent enregistrer que les axes et les codes de touches pour les axes et les boutons qu'ils prennent réellement en charge. L'enregistrement d'axes ou de codes clés excessifs peut perturber l'algorithme de classification de l'appareil ou amener le système à détecter de manière incorrecte les capacités de l'appareil.

    Par exemple, si l'appareil signale le code de touche BTN_TOUCH , le système supposera que BTN_TOUCH sera toujours utilisé pour indiquer si l'outil touche réellement l'écran. Par conséquent, BTN_TOUCH ne doit pas être utilisé pour indiquer que l'outil est simplement dans la plage et en vol stationnaire.

  2. Les appareils à simple contact utilisent les événements d'entrée Linux suivants :

    • ABS_X : (OBLIGATOIRE) Indique la coordonnée X de l'outil.

    • ABS_Y : (OBLIGATOIRE) Indique la coordonnée Y de l'outil.

    • ABS_PRESSURE : (facultatif) Indique la pression physique appliquée à la pointe de l'outil ou la force du signal du contact tactile.

    • ABS_TOOL_WIDTH : (optionnel) Indique la section transversale ou la largeur du contact tactile ou de l'outil lui-même.

    • ABS_DISTANCE : (optionnel) Indique la distance de l'outil à la surface de l'appareil tactile.

    • ABS_TILT_X : (facultatif) Indique l'inclinaison de l'outil à partir de la surface de l'appareil tactile le long de l'axe X.

    • ABS_TILT_Y : (facultatif) Indique l'inclinaison de l'outil à partir de la surface de l'appareil tactile le long de l'axe Y.

    • BTN_TOUCH : (OBLIGATOIRE) Indique si l'outil touche l'appareil.

    • BTN_LEFT , BTN_RIGHT , BTN_MIDDLE , BTN_BACK , BTN_SIDE , BTN_FORWARD , BTN_EXTRA , BTN_STYLUS , BTN_STYLUS2 : (optionnel) Indique l'état des boutons .

    • BTN_TOOL_FINGER , BTN_TOOL_PEN , BTN_TOOL_RUBBER , BTN_TOOL_BRUSH , BTN_TOOL_PENCIL , BTN_TOOL_AIRBRUSH , BTN_TOOL_MOUSE , BTN_TOOL_LENS , BTN_TOOL_DOUBLETAP , BTN_TOOL_TRIPLETAP , BTN_TOOL_QUADTAP : (facultatif) Indique le type d'outil .

  3. Les appareils multi-touch utilisent les événements d'entrée Linux suivants :

    • ABS_MT_POSITION_X : (OBLIGATOIRE) Indique la coordonnée X de l'outil.

    • ABS_MT_POSITION_Y : (OBLIGATOIRE) Indique la coordonnée Y de l'outil.

    • ABS_MT_PRESSURE : (optionnel) Indique la pression physique appliquée à la pointe de l'outil ou la force du signal du contact tactile.

    • ABS_MT_TOUCH_MAJOR : (optionnel) Indique la section transversale du contact tactile, ou la longueur de la dimension la plus longue du contact tactile.

    • ABS_MT_TOUCH_MINOR : (optionnel) Indique la longueur de la dimension la plus courte du contact tactile. Cet axe ne doit pas être utilisé si ABS_MT_TOUCH_MAJOR signale une mesure de surface.

    • ABS_MT_WIDTH_MAJOR : (optionnel) Indique la surface de la section transversale de l'outil lui-même, ou la longueur de la dimension la plus longue de l'outil lui-même. Cet axe ne doit pas être utilisé si les dimensions de l'outil lui-même sont inconnues.

    • ABS_MT_WIDTH_MINOR : (optionnel) Indique la longueur de la dimension la plus courte de l'outil lui-même. Cet axe ne doit pas être utilisé si ABS_MT_WIDTH_MAJOR signale une mesure de surface ou si les dimensions de l'outil lui-même sont inconnues.

    • ABS_MT_ORIENTATION : (facultatif) Indique l'orientation de l'outil.

    • ABS_MT_DISTANCE : (optionnel) Indique la distance de l'outil à la surface de l'appareil tactile.

    • ABS_MT_TOOL_TYPE : (optionnel) Indique le type d'outil comme MT_TOOL_FINGER ou MT_TOOL_PEN .

    • ABS_MT_TRACKING_ID : (facultatif) Indique l'identifiant de suivi de l'outil. L'identifiant de suivi est un nombre entier non négatif arbitraire utilisé pour identifier et suivre chaque outil indépendamment lorsque plusieurs outils sont actifs. Par exemple, lorsque plusieurs doigts touchent l'appareil, chaque doigt doit se voir attribuer un identifiant de suivi distinct qui est utilisé tant que le doigt reste en contact. Les identifiants de suivi peuvent être réutilisés lorsque leurs outils associés sont hors de portée.

    • ABS_MT_SLOT : (optionnel) Indique l'identifiant de l'emplacement de l'outil, lors de l'utilisation du protocole Linux multi-touch 'B'. Reportez-vous à la documentation du protocole multi-touch Linux pour plus de détails.

    • BTN_TOUCH : (OBLIGATOIRE) Indique si l'outil touche l'appareil.

    • BTN_LEFT , BTN_RIGHT , BTN_MIDDLE , BTN_BACK , BTN_SIDE , BTN_FORWARD , BTN_EXTRA , BTN_STYLUS , BTN_STYLUS2 : (optionnel) Indique l'état des boutons .

    • BTN_TOOL_FINGER , BTN_TOOL_PEN , BTN_TOOL_RUBBER , BTN_TOOL_BRUSH , BTN_TOOL_PENCIL , BTN_TOOL_AIRBRUSH , BTN_TOOL_MOUSE , BTN_TOOL_LENS , BTN_TOOL_DOUBLETAP , BTN_TOOL_TRIPLETAP , BTN_TOOL_QUADTAP : (facultatif) Indique le type d'outil .

  4. Si des axes pour les protocoles monotouche et multitouche sont définis, seuls les axes multitouches seront utilisés et les axes monotouches seront ignorés.

  5. Les valeurs minimale et maximale des ABS_X , ABS_Y , ABS_MT_POSITION_X et ABS_MT_POSITION_Y définissent les limites de la zone active de l'appareil en unités de surface spécifiques à l'appareil. Dans le cas d'un écran tactile, la zone active décrit la partie du dispositif tactile qui recouvre réellement l'affichage.

    Pour un écran tactile, le système interpole automatiquement les positions tactiles rapportées en unités de surface pour obtenir les positions tactiles en pixels d'affichage selon le calcul suivant :

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

    Un écran tactile peut signaler des contacts en dehors de la zone active signalée.

    Les touchers initiés en dehors de la zone active ne sont pas délivrés aux applications mais peuvent être utilisés pour les touches virtuelles.

    Les touches initiées à l'intérieur de la zone active, ou qui entrent et sortent de la zone d'affichage sont transmises aux applications. Par conséquent, si un toucher commence dans les limites d'une application puis se déplace en dehors de la zone active, l'application peut recevoir des événements tactiles avec des coordonnées d'affichage qui sont négatives ou au-delà des limites de l'affichage. C'est un comportement attendu.

    Un appareil tactile ne doit jamais limiter les coordonnées tactiles aux limites de la zone active. Si un toucher sort de la zone active, il doit être signalé comme étant en dehors de la zone active, ou il ne doit pas être signalé du tout.

    Par exemple, si le doigt de l'utilisateur touche près du coin supérieur gauche de l'écran tactile, il peut signaler une coordonnée de (minX, minY). Si le doigt continue à se déplacer plus loin en dehors de la zone active, l'écran tactile doit soit commencer à rapporter les coordonnées avec des composants inférieurs à minX et minY, comme (minX - 2, minY - 3), soit arrêter complètement de rapporter le toucher. En d'autres termes, l'écran tactile ne doit pas signaler (minX, minY) lorsque le doigt de l'utilisateur touche vraiment en dehors de la zone active.

    Le serrage des coordonnées tactiles sur le bord de l'écran crée une limite dure artificielle autour du bord de l'écran qui empêche le système de suivre en douceur les mouvements qui entrent ou sortent des limites de la zone d'affichage.

  6. Les valeurs signalées par ABS_PRESSURE ou ABS_MT_PRESSURE , si elles sont signalées, doivent être non nulles lorsque l'outil touche l'appareil et nulles sinon pour indiquer que l'outil est en vol stationnaire.

    La communication des informations sur la pression est facultative mais fortement recommandée. Les applications peuvent utiliser les informations de pression pour implémenter un dessin sensible à la pression et d'autres effets.

  7. Les valeurs rapportées par ABS_TOOL_WIDTH , ABS_MT_TOUCH_MAJOR , ABS_MT_TOUCH_MINOR , ABS_MT_WIDTH_MAJOR ou ABS_MT_WIDTH_MINOR doivent être non nulles lorsque l'outil touche l'appareil et nulles sinon, mais ce n'est pas obligatoire. Par exemple, le dispositif tactile peut être capable de mesurer la taille des contacts tactiles au doigt mais pas les contacts tactiles du stylet.

    Les informations sur la taille des rapports sont facultatives mais fortement recommandées. Les applications peuvent utiliser les informations de pression pour implémenter un dessin sensible à la taille et d'autres effets.

  8. Les valeurs signalées par ABS_DISTANCE ou ABS_MT_DISTANCE doivent approcher de zéro lorsque l'outil touche l'appareil. La distance peut rester non nulle même lorsque l'outil est en contact direct. Les valeurs exactes rapportées dépendent de la manière dont le matériel mesure la distance.

    La transmission des informations de distance est facultative mais recommandée pour les dispositifs à stylet.

  9. Les valeurs rapportées par ABS_TILT_X et ABS_TILT_Y doivent être nulles lorsque l'outil est perpendiculaire à l'appareil. Une inclinaison non nulle est considérée comme une indication que l'outil est maintenu incliné.

    Les angles d'inclinaison le long des axes X et Y sont supposés être spécifiés en degrés à partir de la perpendiculaire. Le point central (parfaitement perpendiculaire) est donné par (max + min) / 2 pour chaque axe. Les valeurs inférieures au point central représentent une inclinaison vers le haut ou vers la gauche, les valeurs supérieures au point central représentent une inclinaison vers le bas ou vers la droite.

    L' InputReader convertit les composantes d'inclinaison X et Y en un angle d'inclinaison perpendiculaire allant de 0 à PI / 2 radians et un angle d'orientation planaire allant de -PI à PI radians. Cette représentation aboutit à une description de l'orientation compatible avec ce qui est utilisé pour décrire les touchers des doigts.

    Le signalement des informations d'inclinaison est facultatif mais recommandé pour les dispositifs à stylet.

  10. Si le type d'outil est rapporté par ABS_MT_TOOL_TYPE , il remplacera toute information de type d'outil rapportée par BTN_TOOL_* . Si aucune information sur le type d'outil n'est disponible, le type d'outil par défaut est MotionEvent.TOOL_TYPE_FINGER .

  11. Un outil est déterminé comme étant actif en fonction des conditions suivantes :

    • Lors de l'utilisation du protocole à simple contact, l'outil est actif si BTN_TOUCH ou BTN_TOOL_* vaut 1.

      Cette condition implique que le InputReader doit avoir au moins quelques informations sur la nature de l'outil, soit s'il touche, soit au moins son type d'outil. Si aucune information n'est disponible, l'outil est considéré comme inactif (hors plage).

    • Lors de l'utilisation du protocole multi-touch « A », l'outil est actif chaque fois qu'il apparaît dans le rapport de synchronisation le plus récent. Lorsque l'outil cesse d'apparaître dans les rapports de synchronisation, il cesse d'exister.

    • Lors de l'utilisation du protocole multi-touch 'B', l'outil est actif tant qu'il a un emplacement actif. Lorsque l'emplacement est effacé, l'outil cesse d'exister.

  12. Un outil est déterminé comme étant en vol stationnaire en fonction des conditions suivantes :

    • Si l'outil est BTN_TOOL_MOUSE ou BTN_TOOL_LENS , alors l'outil ne survole pas, même si l'une des conditions suivantes est vraie.

    • Si l'outil est actif et que le conducteur signale des informations de pression et que la pression signalée est nulle, l'outil est en vol stationnaire.

    • Si l'outil est actif et que le pilote prend en charge le code de clé BTN_TOUCH et que BTN_TOUCH a une valeur de zéro, alors l'outil est en vol stationnaire.

  13. L' InputReader prend en charge les protocoles multi-touch 'A' et 'B'. Les nouveaux pilotes doivent utiliser le protocole "B", mais l'un ou l'autre fonctionnera.

  14. À partir d'Android Ice Cream Sandwich 4.0, les pilotes d'écran tactile peuvent devoir être modifiés pour se conformer à la spécification du protocole d'entrée Linux.

    Les modifications suivantes peuvent être nécessaires :

    • Lorsqu'un outil devient inactif (le doigt monte), il doit cesser d'apparaître dans les rapports de synchronisation multi-touch suivants. Lorsque tous les outils deviennent inactifs (tous les doigts remontent), le pilote doit envoyer un paquet de rapport de synchronisation vide, tel que SYN_MT_REPORT suivi de SYN_REPORT .

      Les versions précédentes d'Android s'attendaient à ce que les événements "up" soient signalés en envoyant une valeur de pression de 0. L'ancien comportement était incompatible avec la spécification du protocole d'entrée Linux et n'est plus pris en charge.

    • Les informations sur la pression physique ou l'intensité du signal doivent être signalées à l'aide ABS_MT_PRESSURE .

      Les versions précédentes d'Android récupéraient les informations de pression de ABS_MT_TOUCH_MAJOR . L'ancien comportement était incompatible avec la spécification du protocole d'entrée Linux et n'est plus pris en charge.

    • Les informations sur la taille tactile doivent être signalées à l'aide ABS_MT_TOUCH_MAJOR .

      Les versions précédentes d'Android récupéraient les informations de taille de ABS_MT_TOOL_MAJOR . L'ancien comportement était incompatible avec la spécification du protocole d'entrée Linux et n'est plus pris en charge.

    Les pilotes d'appareils tactiles n'ont plus besoin de personnalisations spécifiques à Android. En s'appuyant sur le protocole d'entrée Linux standard, Android peut prendre en charge une plus grande variété de périphériques tactiles, tels que les écrans tactiles multi-touch HID externes, à l'aide de pilotes non modifiés.

Fonctionnement de l'appareil tactile

Ce qui suit est un bref résumé du fonctionnement de l'appareil tactile sur Android.

  1. L' EventHub lit les événements bruts du pilote evdev .

  2. L' InputReader consomme les événements bruts et met à jour l'état interne de la position et d'autres caractéristiques de chaque outil. Il suit également les états des boutons.

  3. Si les boutons BACK ou FORWARD ont été enfoncés ou relâchés, l' InputReader informe l' InputDispatcher de l'événement clé.

  4. L' InputReader détermine si une pression sur une touche virtuelle s'est produite. Si c'est le cas, il informe le InputDispatcher de l'événement clé.

  5. L' InputReader détermine si le toucher a été initié dans les limites de l'affichage. Si c'est le cas, il informe le InputDispatcher de l'événement tactile.

  6. S'il n'y a pas d'outils en contact mais qu'il y a au moins un outil en survol, l' InputReader informe le InputDispatcher de l'événement de survol.

  7. Si le type d'appareil tactile est pointer , InputReader effectue la détection du mouvement du pointeur, déplace le pointeur et les repères en conséquence et informe InputDispatcher de l'événement de pointeur.

  8. Le InputDispatcher utilise le WindowManagerPolicy pour déterminer si les événements doivent être distribués et s'ils doivent réveiller l'appareil. Ensuite, InputDispatcher transmet les événements aux applications appropriées.

Configuration de l'appareil tactile

Le comportement de l'appareil tactile est déterminé par les axes, les boutons, les propriétés d'entrée, la configuration de l'appareil d'entrée, la carte des touches virtuelles et la disposition des touches de l'appareil.

Reportez-vous aux sections suivantes pour plus de détails sur les fichiers qui participent à la configuration du clavier :

Propriétés

Le système s'appuie sur de nombreuses propriétés de configuration de périphérique d'entrée pour configurer et calibrer le comportement du périphérique tactile.

L'une des raisons en est que les pilotes de périphérique pour les périphériques tactiles signalent souvent les caractéristiques des touches à l'aide d'unités spécifiques au périphérique.

Par exemple, de nombreux appareils tactiles mesurent la zone de contact tactile à l'aide d'une échelle interne spécifique à l'appareil, telle que le nombre total de nœuds de capteur qui ont été déclenchés par le toucher. Cette valeur de taille brute n'aurait pas de sens pour les applications car elles auraient besoin de connaître la taille physique et d'autres caractéristiques des nœuds de capteur de l'appareil tactile.

Le système utilise des paramètres d'étalonnage codés dans les fichiers de configuration du dispositif d'entrée pour décoder, transformer et normaliser les valeurs rapportées par le dispositif tactile en une représentation standard plus simple que les applications peuvent comprendre.

Conventions documentaires

À des fins de documentation, nous utiliserons les conventions suivantes pour décrire les valeurs utilisées par le système lors du processus d'étalonnage.

Valeurs d'axe brutes

Les expressions suivantes indiquent les valeurs brutes signalées par le pilote de périphérique tactile en tant EV_ABS .

raw.x
La valeur de l'axe ABS_X ou ABS_MT_POSITION_X .
raw.y
La valeur de l'axe ABS_Y ou ABS_MT_POSITION_Y .
raw.pressure
La valeur de l'axe ABS_PRESSURE ou ABS_MT_PRESSURE , ou 0 si non disponible.
raw.touchMajor
La valeur de l'axe ABS_MT_TOUCH_MAJOR , ou 0 si non disponible.
raw.touchMinor
La valeur de l'axe ABS_MT_TOUCH_MINOR , ou raw.touchMajor si non disponible.
raw.toolMajor
La valeur de l'axe ABS_TOOL_WIDTH ou ABS_MT_WIDTH_MAJOR , ou 0 si non disponible.
raw.toolMinor
La valeur de l'axe ABS_MT_WIDTH_MINOR , ou raw.toolMajor si non disponible.
raw.orientation
La valeur de l'axe ABS_MT_ORIENTATION , ou 0 si non disponible.
raw.distance
La valeur de l'axe ABS_DISTANCE ou ABS_MT_DISTANCE , ou 0 si non disponible.
raw.tiltX
La valeur de l'axe ABS_TILT_X , ou 0 si non disponible.
raw.tiltY
La valeur de l'axe ABS_TILT_Y , ou 0 si non disponible.

Plages d'axe brut

Les expressions suivantes indiquent les limites des valeurs brutes. Ils sont obtenus en appelant EVIOCGABS ioctl pour chaque axe.

raw.*.min
La valeur minimale inclusive de l'axe brut.
raw.*.max
La valeur maximale inclusive de l'axe brut.
raw.*.range
Équivalent à raw.*.max - raw.*.min .
raw.*.fuzz
La précision de l'axe brut. par exemple. fuzz = 1 implique que les valeurs sont précises à +/- 1 unité.
raw.width
La largeur inclusive de la zone tactile, équivalente à raw.x.range + 1 .
raw.height
La hauteur inclusive de la zone tactile, équivalente à raw.y.range + 1 .

Plages de sortie

Les expressions suivantes indiquent les caractéristiques du système de coordonnées de sortie. Le système utilise une interpolation linéaire pour traduire les informations de position tactile des unités de surface utilisées par le dispositif tactile en unités de sortie qui seront signalées aux applications telles que les pixels d'affichage.

output.width
La largeur de sortie. Pour les écrans tactiles (associés à un afficheur), il s'agit de la largeur d'affichage en pixels. Pour les tablettes tactiles (non associées à un écran), la largeur de sortie est égale raw.width , indiquant qu'aucune interpolation ne sera effectuée.
output.height
La hauteur de sortie. Pour les écrans tactiles (associés à un afficheur), il s'agit de la hauteur d'affichage en pixels. Pour les tablettes tactiles (non associées à un écran), la hauteur de sortie est égale raw.height , indiquant qu'aucune interpolation ne sera effectuée.
output.diag
La longueur diagonale du système de coordonnées en sortie, équivalente à sqrt(output.width ^2 + output.height ^2) .

Configuration de base

Le mappeur d'entrée tactile utilise de nombreuses propriétés de configuration dans le fichier de configuration du périphérique d'entrée pour spécifier les valeurs d'étalonnage. Le tableau suivant décrit certaines propriétés de configuration à usage général. Toutes les autres propriétés sont décrites dans les sections suivantes avec les champs qu'elles sont utilisées pour calibrer.

touch.deviceType

Définition : touch.deviceType = touchScreen | touchPad | pointer | default

Spécifie le type d'appareil tactile.

  • Si la valeur est touchScreen , l'appareil tactile est un écran tactile associé à un affichage.

  • Si la valeur est touchPad , l'appareil tactile est un pavé tactile non associé à un écran.

  • Si la valeur est pointer , l'appareil tactile est un pavé tactile non associé à un écran et ses mouvements sont utilisés pour les gestes indirects du pointeur multi-touch .

  • Si la valeur est default , le système détecte automatiquement le type d'appareil en fonction de l'algorithme de classification.

Reportez-vous à la section Classification pour plus de détails sur la manière dont le type d'appareil influence le comportement de l'appareil tactile.

Avant Honeycomb, tous les appareils tactiles étaient supposés être des écrans tactiles.

touch.orientationAware

Définition : touch.orientationAware = 0 | 1

Spécifie si l'appareil tactile doit réagir aux changements d'orientation de l'affichage.

  • Si la valeur est 1 , les positions tactiles signalées par l'appareil tactile sont pivotées chaque fois que l'orientation de l'affichage change.

  • Si la valeur est 0 , les positions tactiles signalées par l'appareil tactile sont insensibles aux changements d'orientation de l'affichage.

La valeur par défaut est 1 si l'appareil est un écran tactile, 0 sinon.

Le système fait la distinction entre les écrans tactiles et les affichages internes et externes. Un écran tactile interne sensible à l'orientation pivote en fonction de l'orientation de l'affichage interne. Un écran tactile externe conscient de l'orientation est tourné sur la base de l'orientation de l'affichage externe.

La reconnaissance de l'orientation est utilisée pour prendre en charge la rotation des écrans tactiles sur des appareils tels que le Nexus One. Par exemple, lorsque l'appareil est tourné dans le sens des aiguilles d'une montre de 90 degrés par rapport à son orientation naturelle, les positions absolues des touches sont remappées de sorte qu'une touche dans le coin supérieur gauche du système de coordonnées absolu de l'écran tactile est signalée comme une touche dans le coin supérieur gauche. coin du système de coordonnées pivoté de l'affichage. Ceci est fait pour que les touchers soient signalés avec le même système de coordonnées que les applications utilisent pour dessiner leurs éléments visuels.

Avant Honeycomb, tous les appareils tactiles étaient supposés être conscients de l'orientation.

touch.gestureMode

Définition : touch.gestureMode = pointer | spots | default

Spécifie le mode de présentation des gestes du pointeur. Cette propriété de configuration n'est pertinente que lorsque l'appareil tactile est de type pointer .

  • Si la valeur est pointer , les gestes du pavé tactile sont présentés au moyen d'un curseur semblable à un pointeur de souris.

  • Si la valeur est spots , les gestes du pavé tactile sont présentés par une ancre qui représente le centroïde du geste et un ensemble de points circulaires qui représentent la position des doigts individuels.

La valeur par défaut est pointer lorsque la propriété d'entrée INPUT_PROP_SEMI_MT est définie, ou spots dans le cas contraire.

Champs X et Y

Les champs X et Y fournissent des informations de position pour le centre de la zone de contact.

Calcul

Le calcul est simple : les informations de position du pilote tactile sont interpolées linéairement dans le système de coordonnées de sortie.

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 , Champs de Size

Les champs TouchMajor et TouchMinor décrivent les dimensions approximatives de la zone de contact en unités de sortie (pixels).

Les champs ToolMajor et ToolMinor décrivent les dimensions approximatives de l' outil lui-même en unités de sortie (pixels).

Le champ Size décrit la taille normalisée du toucher par rapport au plus grand toucher possible que l'appareil tactile peut détecter. La plus petite taille normalisée possible est de 0,0 (pas de contact ou non mesurable) et la plus grande taille normalisée possible est de 1,0 (la zone du capteur est saturée).

Lorsque la longueur et la largeur approximatives peuvent être mesurées, le champ TouchMajor spécifie la dimension la plus longue et le champ TouchMinor spécifie la dimension la plus courte de la zone de contact. Lorsque seul le diamètre approximatif de la zone de contact peut être mesuré, les champs TouchMajor et TouchMinor seront égaux.

De même, le champ ToolMajor spécifie la dimension la plus longue et le champ ToolMinor spécifie la dimension la plus courte de la section transversale de l'outil.

Si la taille tactile n'est pas disponible mais que la taille de l'outil est disponible, la taille de l'outil sera réglée égale à la taille tactile. Inversement, si la taille de l'outil n'est pas disponible mais que la taille tactile est disponible, la taille tactile sera alors égale à la taille de l'outil.

Les appareils tactiles mesurent ou signalent la taille tactile et la taille de l'outil de différentes manières. L'implémentation actuelle prend en charge trois types de mesures différents : diamètre, aire et boîte englobante géométrique en unités de surface.

touch.size.calibration

Définition : touch.size.calibration = none | geometric | diameter | area | default

Spécifie le type de mesure utilisé par le pilote tactile pour signaler la taille tactile et la taille de l'outil.

  • Si la valeur est none , la taille est définie sur zéro.

  • Si la valeur est geometric , la taille est supposée être spécifiée dans les mêmes unités de surface que la position, elle est donc mise à l'échelle de la même manière.

  • Si la valeur est diameter , la taille est supposée être proportionnelle au diamètre (largeur) de la touche ou de l'outil.

  • Si la valeur est area , la taille est supposée être proportionnelle à la zone du toucher ou de l'outil.

  • Si la valeur est default , le système utilise le calibrage geometric si l'axe raw.touchMajor ou raw.toolMajor est disponible, sinon il utilise le calibrage none .

touch.size.scale

Définition : touch.size.scale = <un nombre à virgule flottante non négatif>

Spécifie un facteur d'échelle constant utilisé dans l'étalonnage.

La valeur par défaut est 1.0 .

touch.size.bias

Définition : touch.size.bias = <un nombre à virgule flottante non négatif>

Spécifie une valeur de biais constante utilisée dans l'étalonnage.

La valeur par défaut est 0.0 .

touch.size.isSummed

Définition : touch.size.isSummed = 0 | 1

Spécifie si la taille est rapportée comme la somme des tailles de tous les contacts actifs, ou est rapportée individuellement pour chaque contact.

  • Si la valeur est 1 , la taille rapportée sera divisée par le nombre de contacts avant utilisation.

  • Si la valeur est 0 , la taille rapportée sera utilisée telle quelle.

La valeur par défaut est 0 .

Certains appareils tactiles, en particulier les appareils "Semi-MT", ne peuvent pas distinguer les dimensions individuelles de plusieurs contacts, ils signalent donc une mesure de taille qui représente leur surface ou largeur totale. Cette propriété ne doit être définie sur 1 que pour de tels appareils. En cas de doute, réglez cette valeur sur 0 .

Calcul

Le calcul des TouchMajor , TouchMinor , ToolMajor , ToolMinor et Size dépend des paramètres de calibrage spécifiés.

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

Champ de Pressure

Le champ Pressure décrit la pression physique approximative appliquée à l'appareil tactile sous la forme d'une valeur normalisée comprise entre 0,0 (pas de contact) et 1,0 (pleine force).

Une pression nulle indique que l'outil est en vol stationnaire.

touch.pressure.calibration

Définition : touch.pressure.calibration = none | physical | amplitude | default

Spécifie le type de mesure utilisé par le pilote tactile pour signaler la pression.

  • Si la valeur est none , la pression est inconnue, elle est donc définie sur 1,0 lors du toucher et sur 0,0 lors du survol.

  • Si la valeur est physical , l'axe de pression est supposé mesurer l'intensité physique réelle de la pression appliquée au pavé tactile.

  • 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.

Palm rejection

As of Android 13, the system can automatically reject inputs from palms when the built-in framework is enabled. In-house, custom-built solutions are still supported, though they might need to be modified to return the TOOL_TYPE_PALM flag when a palm is detected. The built-in framework also works in conjunction with custom solutions.

The actual model looks at the first 90 ms of gesture data, at the current pointer, and at the surrounding pointers, then considers how far away from the edge of the display the touches are. It then determines, on a per-pointer basis, which of the pointers are palms. It also takes into account the size of each contact, as reported by TouchMajor and TouchMinor . The Android framework then removes the pointers that are marked as palms from the touch stream.

If a pointer was already sent to the apps, then the system either:

  • (If there are other active pointers) Cancels the pointer with ACTION_POINTER_UP and FLAG_CANCELED set.
  • (If this is the only pointer) Cancels the pointer with ACTION_CANCEL .

A public API, MotionEvent.FLAG_CANCELED , indicates that the current event shouldn't trigger user action. This flag is set for both ACTION_CANCEL and ACTION_POINTER_UP .

If the palm pointer wasn't sent to apps, then the system simply drops the pointer.

Enable palm rejection

  1. In your touch driver, use the input_abs_set_res macro to set the resolutions for the following fields (units are pixels per mm ):
    • ABS_MT_POSITION_X
    • ABS_MT_POSITION_Y
    • ABS_MT_TOUCH_MAJOR
    • ABS_MT_TOUCH_MINOR

    Support for ABS_MT_TOUCH_MINOR is optional. However, if your device does support it, make sure the resolution is set correctly.

  2. To confirm the fields are set correctly, run:
        $ adb shell getevent -li
    
  3. To enable the feature during runtime, run:
        $ adb shell device_config put input_native_boot palm_rejection_enabled 1
    
  4. Restart the system_server process.
         $ adb shell stop && adb shell start
        
  5. Confirm that adb shell dumpsys input shows that there are palm rejectors inside UnwantedInteractionBlocker . If it doesn't, check the input-related logs to find clues on what might be misconfigured.

    See the following example for reference:

    UnwantedInteractionBlocker:
      mEnablePalmRejection: true
      isPalmRejectionEnabled (flag value): true
      mPalmRejectors:
        deviceId = 3:
          mDeviceInfo:
            max_x = 
            max_y = 
            x_res = 11.00
            y_res = 11.00
            major_radius_res = 1.00
            minor_radius_res = 1.00
            minor_radius_supported = true
            touch_major_res = 1
            touch_minor_res = 1
          mSlotState:
            mSlotsByPointerId:
    
            mPointerIdsBySlot:
    
          mSuppressedPointerIds: {}
    
  6. To permanently enable the feature, add the corresponding sysprop command in your init**rc file:

    setprop persist.device_config.input_native_boot.palm_rejection_enabled 1
    

Further Reading

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