O subsistema de entrada do Android consiste nominalmente em um pipeline de eventos que atravessa várias camadas do sistema.
Pipeline de entrada
Na camada mais baixa, o dispositivo de entrada físico produz sinais que descrevem mudanças de estado, como pressionamentos de teclas e pontos de contato de toque. O firmware do dispositivo codifica e transmite esses sinais de alguma forma, como enviando relatórios USB HID para o sistema ou produzindo interrupções em um barramento I2C.
Os sinais são então decodificados por um driver de dispositivo no kernel do Linux. O kernel Linux fornece drivers para muitos periféricos padrão, especialmente aqueles que aderem ao protocolo HID. No entanto, um OEM muitas vezes deve fornecer drivers personalizados para dispositivos incorporados que estão totalmente integrados ao sistema em um nível inferior, como telas sensíveis ao toque.
Os drivers de dispositivo de entrada são responsáveis por traduzir sinais específicos do dispositivo em um formato de evento de entrada padrão, por meio do protocolo de entrada do Linux. O protocolo de entrada do Linux define um conjunto padrão de tipos de eventos e códigos no arquivo de cabeçalho do kernel linux/input.h
. Dessa forma, os componentes fora do kernel não precisam se preocupar com detalhes como códigos de verificação física, usos de HID, mensagens I2C, pinos GPIO e assim por diante.
Em seguida, o componente Android EventHub
lê eventos de entrada do kernel abrindo o driver evdev
associado a cada dispositivo de entrada. O componente Android InputReader decodifica os eventos de entrada de acordo com a classe do dispositivo e produz um fluxo de eventos de entrada do Android. Como parte desse processo, os códigos de evento do protocolo de entrada do Linux são traduzidos em códigos de evento do Android de acordo com a configuração do dispositivo de entrada, arquivos de layout de teclado e diversas tabelas de mapeamento.
Finalmente, o InputReader
envia eventos de entrada para o InputDispatcher que os encaminha para a janela apropriada.
Pontos de controle
Existem vários estágios no pipeline de entrada que efetuam o controle sobre o comportamento do dispositivo de entrada.
Configuração de driver e firmware
Os drivers de dispositivos de entrada frequentemente configuram o comportamento do dispositivo de entrada definindo parâmetros em registros ou até mesmo carregando o próprio firmware. Este é particularmente o caso de dispositivos embarcados, como telas sensíveis ao toque, onde grande parte do processo de calibração envolve o ajuste desses parâmetros ou a correção do firmware para fornecer a precisão e a capacidade de resposta desejadas e para suprimir o ruído.
As opções de configuração do driver geralmente são especificadas como parâmetros de módulo no pacote de suporte da placa kernel (BSP) para que o mesmo driver possa suportar várias implementações de hardware diferentes.
Esta documentação tenta descrever a configuração do driver ou firmware, mas oferece orientação sobre a calibração do dispositivo em geral.
Propriedades de configuração da placa
O pacote de suporte da placa do kernel (BSP) pode exportar propriedades de configuração da placa via SysFS que são usadas pelo componente InputReader do Android, como o posicionamento de teclas virtuais em uma tela sensível ao toque.
Consulte as seções de classe de dispositivo para obter detalhes sobre como diferentes dispositivos usam as propriedades de configuração da placa.
Sobreposições de recursos
Alguns comportamentos de entrada são configurados por meio de sobreposições de recursos em config.xml
, como a operação do interruptor de tampa.
Aqui estão alguns exemplos:
config_lidKeyboardAccessibility
: especifica o efeito da chave da tampa sobre se o teclado de hardware está acessível ou oculto.config_lidNavigationAccessibility
: especifica o efeito da chave da tampa sobre se o trackpad está acessível ou oculto.config_longPressOnPowerBehavior
: especifica o que deve acontecer quando o usuário mantém pressionado o botão liga/desliga.config_lidOpenRotation
: especifica o efeito da chave da tampa na orientação da tela.
Consulte a documentação em frameworks/base/core/res/res/values/config.xml
para obter detalhes sobre cada opção de configuração.
Mapas principais
Os mapas principais são usados pelos componentes EventHub
e InputReader
do Android para configurar o mapeamento de códigos de eventos do Linux para códigos de eventos do Android para teclas, botões e eixos do joystick. O mapeamento pode depender do dispositivo ou do idioma.
Consulte as seções de classes de dispositivos para obter detalhes sobre como diferentes dispositivos usam mapas de teclas.
Arquivos de configuração do dispositivo de entrada
Os arquivos de configuração do dispositivo de entrada são usados pelos componentes Android EventHub
e InputReader
para configurar características especiais do dispositivo, como a forma como as informações de tamanho do toque são relatadas.
Consulte as seções de classes de dispositivos para obter detalhes sobre como diferentes dispositivos usam mapas de configuração de dispositivos de entrada.
Entenda os usos do HID e os códigos de eventos
Freqüentemente, há vários identificadores diferentes usados para se referir a qualquer tecla de um teclado, botão de um controlador de jogo, eixo de joystick ou outro controle. As relações entre esses identificadores nem sempre são as mesmas: eles dependem de um conjunto de tabelas de mapeamento, algumas das quais são fixas e outras que variam com base nas características do dispositivo, no driver do dispositivo, na localidade atual, na configuração do sistema, preferências do usuário e outros fatores.
- Código de verificação física
Um código de varredura físico é um identificador específico do dispositivo associado a cada tecla, botão ou outro controle. Como os códigos de verificação física geralmente variam de um dispositivo para outro, o firmware ou driver de dispositivo é responsável por mapeá-los para identificadores padrão, como usos HID ou códigos de chave do Linux.
Os códigos de digitalização são de interesse principalmente para teclados. Outros dispositivos normalmente se comunicam em baixo nível usando pinos GPIO, mensagens I2C ou outros meios. Conseqüentemente, as camadas superiores da pilha de software dependem dos drivers de dispositivo para entender o que está acontecendo.
- Uso HID
Um uso de HID é um identificador padrão usado para relatar o estado de um controle, como uma tecla do teclado, eixo do joystick, botão do mouse ou ponto de contato de toque. A maioria dos dispositivos de entrada USB e Bluetooth estão em conformidade com a especificação HID, o que permite que o sistema interaja com eles de maneira uniforme.
O Android Framework depende dos drivers HID do kernel Linux para traduzir códigos de uso HID em códigos-chave do Linux e outros identificadores. Portanto, os usos de HID são de interesse principalmente para fabricantes de periféricos.
- Código-chave do Linux
Um código-chave do Linux é um identificador padrão para uma chave ou botão. Os códigos-chave do Linux são definidos no arquivo de cabeçalho
linux/input.h
usando constantes que começam com o prefixoKEY_
ouBTN_
. Os drivers de entrada do kernel Linux são responsáveis por traduzir códigos de varredura física, usos de HID e outros sinais específicos de dispositivos em códigos-chave do Linux e fornecer informações sobre eles como parte de eventosEV_KEY
.A API do Android às vezes se refere ao código-chave do Linux associado a uma chave como seu "código de verificação". Isso é tecnicamente incorreto, mas ajuda a distinguir os códigos-chave do Linux dos códigos-chave do Android na API.
- Código do eixo relativo ou absoluto do Linux
Um código de eixo relativo ou absoluto do Linux é um identificador padrão para relatar movimentos relativos ou posições absolutas ao longo de um eixo, como os movimentos relativos de um mouse ao longo de seu eixo X ou a posição absoluta de um joystick ao longo de seu eixo X. O código do eixo Linux é definido no arquivo de cabeçalho
linux/input.h
usando constantes que começam com o prefixoREL_
ouABS_
. Os drivers de entrada do kernel Linux são responsáveis por traduzir os usos HID e outros sinais específicos do dispositivo em códigos de eixo Linux e fornecer informações sobre eles como parte dos eventosEV_REL
eEV_ABS
.- Código do switch Linux
Um código de switch Linux é um identificador padrão para relatar o estado de um switch em um dispositivo, como um switch de tampa. Os códigos de switch do Linux são definidos no arquivo de cabeçalho
linux/input.h
usando constantes que começam com o prefixoSW_
. Os drivers de entrada do kernel Linux relatam alterações de estado do switch como eventosEV_SW
.Os aplicativos Android geralmente não recebem eventos de switches, mas o sistema pode usá-los internamente para controlar várias funções específicas do dispositivo.
- Código-chave do Android
Um código-chave do Android é um identificador padrão definido na API do Android para indicar uma chave específica, como 'HOME'. Os códigos-chave do Android são definidos pela classe
android.view.KeyEvent
como constantes que começam com o prefixoKEYCODE_
.O layout da chave especifica como os códigos-chave do Linux são mapeados para os códigos-chave do Android. Diferentes layouts de teclas podem ser usados dependendo do modelo do teclado, idioma, país, layout ou funções especiais.
As combinações de códigos-chave do Android são transformadas em códigos de caracteres usando um mapa de caracteres-chave específico do dispositivo e da localidade. Por exemplo, quando as teclas identificadas como
KEYCODE_SHIFT
eKEYCODE_A
são pressionadas juntas, o sistema procura a combinação no mapa de caracteres-chave e encontra a letra maiúscula 'A', que é então inserida no widget de texto atualmente em foco.- Código do eixo Android
Um código de eixo Android é um identificador padrão definido na API Android para indicar um eixo de dispositivo específico. Os códigos de eixo do Android são definidos pela classe
android.view.MotionEvent
como constantes que começam com o prefixoAXIS_
.O layout principal especifica como os códigos de eixo do Linux são mapeados para os códigos de eixo do Android. Diferentes layouts de teclas podem ser usados dependendo do modelo do dispositivo, idioma, país, layout ou funções especiais.
- Metaestado do Android
Um metaestado do Android é um identificador padrão definido na API do Android para indicar quais teclas modificadoras são pressionadas. Os metaestados do Android são definidos pela classe
android.view.KeyEvent
como constantes que começam com o prefixoMETA_
.O metaestado atual é determinado pelo componente Android InputReader que monitora quando teclas modificadoras como
KEYCODE_SHIFT_LEFT
são pressionadas/liberadas e define/redefine o sinalizador de metaestado apropriado.A relação entre chaves modificadoras e metaestados é codificada, mas o layout das teclas pode alterar a forma como as próprias teclas modificadoras são mapeadas, o que, por sua vez, afeta os metaestados.
- Estado do botão Android
Um estado de botão do Android é um identificador padrão definido na API do Android para indicar quais botões (no mouse ou na caneta) são pressionados. Os estados dos botões do Android são definidos pela classe
android.view.MotionEvent
como constantes que começam com o prefixoBUTTON_
.O estado atual do botão é determinado pelo componente InputReader do Android, que monitora quando os botões (em um mouse ou caneta) são pressionados/soltados e define/redefine o sinalizador de estado do botão apropriado.
A relação entre botões e estados de botão é codificada.
Leitura adicional
- Códigos de eventos de entrada do Linux
- Protocolo multitoque Linux
- Drivers de entrada Linux
- Feedback forçado do Linux
- Informações HID, incluindo tabelas de uso HID