Esta página descreve como processar entradas por seletor giratório na VHAL, configurar seu build para incluir o serviço de seletor giratório e como personalizar essa experiência em todos os apps. Para apps OEM pré-instalados, como um inicializador fornecido pelo OEM, consulte Biblioteca Car UI (car-ui-library).
VHAL
Um controle giratório é compatível com as seguintes ações:
- Deslocar para cima, para baixo, para a esquerda e para a direita.
- Gire no sentido horário e anti-horário.
- Pressione o botão Central.
- Pressione o botão Voltar .
- Pressione o botão home.
- Pressione outros botões, como "Telefone" e "Mídia".
Consulte hardware/interfaces/automotive/vehicle/2.0/types.hal
para ver a documentação sobre
as propriedades do sistema e o int32Values
correspondente.
A VHAL precisa lidar com estas ações:
Piano
Quando o usuário empurra o controle giratório para a direita, a VHAL deve usar o
HW_KEY_INPUT
com o seguinte int32Values
para enviar uma
para o Android:
ACTION_DOWN
KEYCODE_SYSTEM_NAVIGATION_RIGHT
- Exibição de destino.
Quando o usuário solta o controle giratório, a VHAL deve usar a mesma propriedade e
com ACTION_UP
. Deslocamentos em outras direções devem usar o
os códigos de tecla correspondentes.
Não há códigos de tecla para diagonais, mas a VHAL pode combinar uma combinação horizontal e vertical para produzir uma diagonal se o hardware oferecer suporte a diagonais. Por exemplo, chamar e à esquerda deve produzir:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
Em qualquer ordem (e posteriormente), soltar o controle giratório deve produzir:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
O usuário pode empurrar o controle giratório em uma direção perpendicular antes de liberá-lo. Por exemplo, o cenário a seguir:
Isso vai gerar a seguinte sequência de eventos:
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP
Nenhum evento repeat pode ser gerado enquanto o controle giratório estiver pressionado em uma direção.
Rotação
Quando o usuário gira o controle giratório no sentido horário em um ponto (clique), a VHAL
precisa usar a propriedade HW_ROTARY_INPUT
com o seguinte int32Values
para enviar um evento ao Android:
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- Um (1) limite.
- Exibição de destino.
O carimbo de data/hora do evento precisa ser definido como o tempo decorrido em nanossegundos.
Uma (1) rotação no sentido anti-horário deve gerar o mesmo evento, mas com -1 para o número de retenções.
Se várias barreiras de rotação na mesma direção ocorrerem em rápida sucessão, a VHAL
deve combinar os bloqueios em um único evento para não sobrecarregar o sistema com eventos.
Nesse caso, o carimbo de data/hora do evento deve ser o momento em que ocorreu a primeira retenção da rotação.
int32Values
precisa incluir o número de nanossegundos entre os dentes consecutivos
de rotação.
Por exemplo, a seguinte sequência de rotações:
- No tempo t0, o usuário girou um limite em sentido anti-horário.
- No tempo t0 + 5 ns, o usuário girou um ponto no sentido anti-horário.
- No tempo t0 + 8 ns, o usuário girou um ponto no sentido anti-horário.
deve gerar este evento:
- Propriedade:
HW_ROTARY_INPUT
- Carimbo de data/hora:
t0
int32Values
:ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- -3 (três pontos no sentido anti-horário).
- Exibição de destino.
- 5 ns entre o primeiro e o segundo recuo.
- 3 ns entre o segundo e o terceiro ponto de contenção.
Botão central
Quando o usuário pressiona o botão central, a VHAL precisa usar o HW_KEY_INPUT
com o seguinte int32Values
para enviar um evento ao Android:
ACTION_DOWN
KEYCODE_DPAD_CENTER
- Exibição de destino.
Quando o usuário solta o controle giratório, a VHAL precisa usar a mesma propriedade
e o código de tecla com ACTION_UP
.
Não gere eventos repeat quando o botão central for pressionado.
Botão "Voltar"
Quando o usuário pressiona o botão "Voltar", a VHAL precisa usar o HW_KEY_INPUT
.
com o seguinte int32Values
para enviar um evento ao Android:
ACTION_DOWN
KEYCODE_BACK
- Exibição de destino.
Quando o usuário solta o controle giratório, a VHAL precisa usar a mesma propriedade
e o código de tecla com ACTION_UP
.
Nenhum evento repeat deve ser gerado enquanto o botão central estiver pressionado.
Botão "Início"
Gerencie o botão home como faria com o botão "Voltar", mas com KEYCODE_HOME
.
de KEYCODE_BACK
.
Outros botões
Se o controle giratório incluir botões adicionais, a VHAL poderá processá-los.
o OEM gosta, porque eles não são considerados parte do seletor giratório do ponto de vista do Android.
Normalmente, eles são tratados da mesma forma que os botões "Voltar" e "Página inicial", mas com códigos de tecla diferentes.
Por exemplo, KEYCODE_CALL
ou KEYCODE_MUSIC
.
Configuração do build
A navegação por seletor giratório é fornecida por um serviço de acessibilidade chamado RotaryService
.
Para incluir este serviço na imagem do sistema do seu dispositivo, adicione a seguinte linha ao seu
makefile:
PRODUCT_PACKAGES += CarRotaryController
Também é possível incluir os seguintes pacotes em builds de depuração:
RotaryPlayground
Um app de referência para o seletor giratório (consulte RotaryPlayground).RotaryIME
Um IME giratório de demonstração (consulte Editores de método de entrada).CarRotaryImeRRO
A sobreposição paraRotaryIME
.
O serviço por seletor giratório é ativado automaticamente quando o dispositivo é inicializado e quando um usuário quando a mudança acontece. Isso garante que o usuário possa usar o controle giratório durante a configuração.
Se você usa a mesma versão para carros com e sem controle giratório,
Adicione CarRotaryController
, conforme mostrado acima, para que o código necessário seja incluído.
no build. Para evitar que o serviço giratório seja ativado em carros não giratórios, crie um
a RRO estática para sobrepor o recurso de string rotaryService
packages/services/Car/service
com uma string vazia. Você vai usar o mesmo build,
mas têm configurações de produto separadas, para dispositivos giratórios e não giratórios. Apenas o último caso
inclui a sobreposição.
Personalização
Os OEMs podem personalizar a lógica de localização de foco, o destaque e alguns outros itens usando sobreposições de recursos nos seguintes locais:
- car-ui-library está localizada em
packages/apps/Car/libs/car-ui-lib
RotaryService
está localizado empackages/apps/Car/RotaryController
Core
está localizado emframeworks/base/core
Deslocar histórico
O OEM pode configurar se cada um dos dois tipos de histórico de alertas está ativado e, em caso afirmativo, o tamanho do cache e a política de expiração. Isso é feito substituindo-se de várias bibliotecas do Google Cloud.
Focar o cache do histórico
(Android 11 QPR3, Android 11 Car,
Android 12)
Esse cache por FocusArea
armazena a visualização mais recentemente focada no
FocusArea
para que ele possa ser focado ao voltar para o FocusArea
.
Esse cache pode ser configurado sobrepondo os seguintes recursos da biblioteca car-ui-library:
-
car_ui_focus_history_cache_type
:- O cache está desativado.
- O cache expira após algum tempo (veja abaixo).
- O cache nunca expira.
car_ui_focus_history_expiration_period_ms
: quantos milissegundos antes do evento cache vai expirar se o tipo de cache for definido como dois (2) (veja acima).
Cache do histórico do FocusArea
(Android 11 QPR3, Android 11 Car,
Android 12)
Esse cache armazena um histórico de alertas para que o deslocamento na direção oposta possa
voltar o foco para o mesmo FocusArea
. Esse cache pode ser configurado sobrepondo
seguintes recursos da biblioteca car-ui:
-
car_ui_focus_area_history_cache_type
:- O cache está desativado.
- O cache expira após algum tempo (veja abaixo).
- O cache nunca expira.
car_ui_focus_area_history_expiration_period_ms
: quantos milissegundos antes o cache vai expirar se o tipo de cache for definido como 2 (veja acima).car_ui_clear_focus_area_history_when_rotating
: se o cache será anulado. quando o usuário gira o controle.
Rotação
(Android 11 QPR3, Android 11 Car,
Android 12)
O OEM pode substituir dois recursos de números inteiros no RotaryService
para especificar se
há aceleração para rotação, como aceleração do mouse:
rotation_acceleration_3x_ms
: intervalo de tempo (em milissegundos) usado para decidir se o Google deve acelerar a rotação do controlador para um período de rotação. Se o é menor que esse valor, ele será tratado como três perímetros de rotação. Defina como 2147483647 para desativar 3× e aceleração.rotation_acceleration_2x_ms
: semelhante arotation_acceleration_3x_ms
. Usado para aceleração 2×. Defina como2147483647
para desativar a aceleração 2×.
A aceleração funciona melhor quando há carimbos de data/hora individuais para cada retenção de
a rotação de chaves,
obrigatório
pela VHAL. Se elas não estiverem disponíveis, o RotaryService
vai presumir que as barreiras de
são espaçadas uniformemente.
/** * Property to feed H/W rotary events to android * * int32Values[0] : RotaryInputType identifying which rotary knob rotated * int32Values[1] : number of detents (clicks), positive for clockwise, * negative for counterclockwise * int32Values[2] : target display defined in VehicleDisplay. Events not * tied to specific display must be sent to * VehicleDisplay#MAIN. * int32values[3 .. 3 + abs(number of detents) - 2]: * nanosecond deltas between pairs of consecutive detents, * if the number of detents is > 1 or < -1 * * VehiclePropValue.timestamp: when the rotation occurred. If the number of * detents is > 1 or < -1, this is when the * first detent of rotation occurred. * * @change_mode VehiclePropertyChangeMode:ON_CHANGE * @data_enum RotaryInputType * @access VehiclePropertyAccess:READ */ HW_ROTARY_INPUT = ( 0x0A20 | VehiclePropertyGroup:SYSTEM | VehiclePropertyType:INT32_VEC | VehicleArea:GLOBAL),
Focar o destaque
O OEM pode substituir o destaque de foco padrão no framework do Android e vários recursos de destaque de foco em car-ui-library.
Destaque de foco padrão
O framework do Android fornece um destaque de foco padrão pelo atributo
selectableItemBackground
: Em Theme.DeviceDefault
, isso
refere-se a item_background.xml
em Core
. O OEM pode sobrepor
item_background.xml
para mudar o drawable de destaque de foco padrão.
Esse drawable precisa ser um StateListDrawable
, que ajusta o plano de fundo
com base em diferentes combinações de estados, incluindo android:state_focused
e android:state_pressed
. Quando o usuário usa o controle giratório para
focar uma visualização, android:state_focused
será true
, mas
android:state_pressed
será false
. Se o usuário pressionar
o botão Central no controle giratório, tanto android:state_focused
quanto
O valor de android:state_pressed
será true
enquanto o usuário mantiver o botão pressionado.
Quando o usuário soltar o botão, apenas android:state_focused
permanece
true
.
O car-ui-library usa um tema derivado de Theme.DeviceDefault
. Como resultado,
Essa sobreposição afeta os apps que usam essa biblioteca e os que usam qualquer tema derivado
Theme.DeviceDefault
: Isso não vai afetar apps que usam um tema não relacionado,
como Theme.Material
.
Focar os recursos de destaque na biblioteca car-ui-library
O OEM pode substituir vários recursos da biblioteca da interface do carro para controlar a forma como o foco destaca
observa as visualizações com um destaque não retangular (como redondo ou em forma de pílula) e em
Apps que usam um tema não derivado de Theme.DeviceDefault
. Esses
os recursos devem ser sobrepostos para que o destaque do foco seja consistente com o
drawable de destaque de foco padrão.
(Android 11 QPR3, Android 11 Car,
Android 12)
Os recursos a seguir são usados para indicar quando uma visualização está em foco, mas não é pressionada:
car_ui_rotary_focus_fill_color
: cor de preenchimento.car_ui_rotary_focus_stroke_color
: cor do contorno.car_ui_rotary_focus_stroke_width
: espessura do contorno.
(Android 11 QPR3, Android 11 Car,
Android 12)
Os recursos a seguir são usados para indicar quando uma visualização está em foco e pressionada:
car_ui_rotary_focus_pressed_fill_color
: cor de preenchimento.car_ui_rotary_focus_pressed_stroke_color
: cor do contorno.car_ui_rotary_focus_pressed_stroke_width
: espessura do contorno.
Às vezes, um botão recebe uma cor de fundo sólida para chamar a atenção do usuário, como no exemplo mostrado. Isso pode dificultar a visualização do destaque do foco.
Nessa situação, o desenvolvedor pode especificar um destaque de foco personalizado usando cores secundárias:
- (Android 11 QPR3, Android 11 Car,
Android 12)
car_ui_rotary_focus_fill_secondary_color
(
)car_ui_rotary_focus_stroke_secondary_color
- (Android 12)
car_ui_rotary_focus_pressed_fill_secondary_color
(
)car_ui_rotary_focus_pressed_stroke_secondary_color
Qualquer uma das cores pode ser transparente e qualquer dimensão pode ser zero se, por exemplo, você queria apenas um preenchimento ou apenas um contorno.
Destaque da área de foco
(Android 11 QPR3, Android 11 Car,
Android 12)
FocusArea
pode desenhar dois tipos de destaque quando um dos descendentes está
focada. Se preferir, é possível usar ambos em conjunto. Esse recurso fica desativado por padrão no
AOSP, mas pode ser ativado substituindo os recursos da biblioteca da interface do carro:
car_ui_enable_focus_area_foreground_highlight
: desenhe um destaque em cima de aFocusArea
e os descendentes dela. No AOSP, esse drawable é um contorno ao redor daFocusArea
. Os OEMs podem substituir Drawablecar_ui_focus_area_foreground_highlight
.car_ui_enable_focus_area_background_highlight
: desenhe um destaque na parte superior doFocusArea
, mas atrás dos descendentes. No AOSP, esse drawable é um preenchimento sólido. Os OEMs podem substituir o drawablecar_ui_focus_area_background_highlight
.
Editores do método de entrada
Os Editores de método de entrada (IME, na sigla em inglês) são métodos de entrada. Por exemplo, um teclado na tela.
(Android 11 QPR3, Android 11 Car,
Android 12)
O OEM precisa sobrepor o recurso de string default_touch_input_method
no objeto RotaryService
para especificar o ComponentName
do
IME baseado em toque. Por exemplo, se o OEM usar o IME fornecido com o Android Automotive,
ele deve especificar
com.google.android.apps.automotive.inputmethod/.InputMethodService
:
(Android 11 QPR3, Android 11 Car,
Android 12)
Se o OEM tiver criado um IME especificamente para o seletor giratório, ele deverá especificar o
ComponentName
no recurso rotary_input_method
. Se este recurso
for sobreposto, o IME especificado será usado sempre que o usuário estiver interagindo com a unidade principal
por meio do movimento, da rotação e do botão central do controle giratório. Quando o usuário toca
tela, o IME anterior será usado. O botão "Voltar" (e outros botões do
) não afetam a seleção do IME. Se esse recurso não for sobreposto, não haverá troca de IME
de segurança. O painel não é compatível com o seletor giratório, então o usuário não pode inserir texto nele
se o OEM não tiver fornecido um IME giratório.
RotaryIME
é um IME giratório de demonstração. Embora seja básico, é suficiente
teste a troca automática do IME descrita acima. O código-fonte de RotaryIME
podem ser encontrados em packages/apps/Car/tests/RotaryIME/
.
Alerta fora da tela
Por padrão, quando o usuário tenta desviar da borda da tela, nada acontece. O OEM pode configurar o que deve ocorrer para cada uma das quatro direções especificando combinação de:
- Uma ação global definida por
AccessibilityService
. Por exemplo,GLOBAL_ACTION_BACK
. - Um código de tecla, como
KEYCODE_BACK
. - Uma intent para iniciar uma atividade representada como um URL.
(Android 11 QPR3, Android 11 Car,
Android 12)
Eles são especificados sobrepondo os seguintes recursos de matriz na
RotaryService
:
off_screen_nudge_global_actions
: matriz de ações globais a serem executadas quando o usuário desvia a borda da tela para cima, para baixo, para a esquerda ou para a direita. Nenhuma ação global é executada se o elemento relevante dessa matriz for -1.off_screen_nudge_key_codes
: matriz de códigos de chave dos eventos de clique a serem injetados quando o usuário desvia da borda da tela para cima, para baixo, para a esquerda ou para a direita. Nenhum evento é injetado se o elemento relevante dessa matriz for 0 (KEYCODE_UNKNOWN
).off_screen_nudge_intents
: matriz de intents para iniciar uma atividade quando o usuário desvia a borda da tela para cima, para baixo, para a esquerda ou para a direita. Nenhuma atividade é será iniciado se o elemento relevante dessa matriz estiver vazio.
Outras configurações
Você precisa sobrepor os seguintes recursos RotaryService
:
- (Android 11 QPR3, Android 11 Car,
Android 12)
config_showHeadsUpNotificationOnBottom
: valor booleano que representa se as notificações de alerta devem ser exibidas na parte inferior, não na parte superior. Isso deve têm o mesmo valor deconfig_showHeadsUpNotificationOnBottom
; Recurso booleano emframeworks/base/packages/CarSystemUI/res/values/config.xml
- (Android 11 QPR3, Android 11 Car,
Android 12)
notification_headsup_card_margin_horizontal
: margens esquerda e direita de janela de notificação de alerta. Precisa ter o mesmo valor que onotification_headsup_card_margin_horizontal
recurso de dimensão empackages/apps/Car/Notification/res/values/dimens.xml
- (Android 12)
excluded_application_overlay_window_titles
: uma matriz de títulos de janelas que não devem ser consideradas janelas de sobreposição. Isso deve incluir títulos de janelas de apps que representamTaskViews
ouTaskDisplayAreas
. Por padrão, essa lista contém apenas "Maps".
É possível sobrepor o seguinte recurso RotaryService
:
- (Android 11 QPR3, Android 11 Car,
Android 12)
long_press_ms
: valor inteiro que representa quantos milissegundos o Mantenha o botão central pressionado para acionar um pressionamento longo. Zero indica que o sistema tempo limite padrão de pressionamento longo. Esse é o valor padrão.