Esta página descreve como processar entradas rotativas no VHAL, configurar sua compilação para incluir o serviço rotativo e como personalizar a experiência rotativa em todos os aplicativos. Para aplicativos OEM pré-instalados, como um iniciador fornecido pelo OEM, consulte Car UI Library (car-ui-library) .
VHAL
Um controlador rotativo suporta as seguintes ações:
- Deslize 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 Início.
- Pressione outros botões, como Telefone e Mídia.
Consulte hardware/interfaces/automotive/vehicle/2.0/types.hal
para documentação sobre as propriedades do sistema e int32Values
correspondentes.
O VHAL deve lidar com estas ações:
Cutucar
Quando o usuário pressiona o controlador rotativo para a direita, o VHAL deve usar a propriedade HW_KEY_INPUT
com os seguintes int32Values
para enviar um evento ao Android:
-
ACTION_DOWN
-
KEYCODE_SYSTEM_NAVIGATION_RIGHT
- Exibição de destino.
Quando o usuário libera o controlador rotativo, o VHAL deve usar a mesma propriedade e código-chave com ACTION_UP
. Os empurrões em outras direções devem usar os códigos-chave correspondentes.
Não existem códigos-chave para diagonais, mas o VHAL pode combinar um evento horizontal e vertical para produzir uma diagonal se o hardware suportar diagonais. Por exemplo, deslocar-se para cima e para a 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 subsequentemente), a liberação do controlador rotativo 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 controlador rotativo em uma direção perpendicular antes de soltá-lo. Por exemplo, o seguinte cenário:
Isso deve 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 repetido deve ser gerado enquanto o controlador rotativo for mantido em uma direção.
Girar
Quando o usuário gira o controlador rotativo no sentido horário em uma posição (clique), o VHAL deve usar a propriedade HW_ROTARY_INPUT
com os seguintes int32Values
para enviar um evento ao Android:
-
ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
- Um (1) detentor.
- Exibição de destino.
O carimbo de data/hora do evento deve ser definido como o tempo decorrido em nanossegundos.
Uma (1) rotação de retenção no sentido anti-horário deve gerar o mesmo evento, mas com -1 para o número de detentores.
Se múltiplos detentores de rotação na mesma direção ocorrerem em rápida sucessão, o VHAL deverá combinar os detentores em um único evento para não sobrecarregar o sistema com eventos. Neste caso, o carimbo de data/hora do evento deve ser quando ocorreu o primeiro detentor de rotação. O int32Values
deve incluir o número de nanossegundos entre detenções consecutivas de rotação.
Por exemplo, a seguinte sequência de rotações:
- No tempo t0, o usuário girou um detentor no sentido anti-horário.
- No tempo t0 + 5 ns, o usuário girou um detentor no sentido anti-horário.
- No tempo t0 + 8 ns, o usuário girou um detentor 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 detentores no sentido anti-horário).
- Exibição de destino.
- 5 ns entre a primeira e a segunda retenção.
- 3 ns entre a segunda e a terceira retenção.
-
Botão central
Quando o usuário pressiona o botão Central, o VHAL deve usar a propriedade HW_KEY_INPUT
com os seguintes int32Values
para enviar um evento ao Android:
-
ACTION_DOWN
-
KEYCODE_DPAD_CENTER
- Exibição de destino.
Quando o usuário libera o controlador rotativo, o VHAL deve usar a mesma propriedade e código-chave com ACTION_UP
.
Não gere eventos repetidos quando o botão central for pressionado.
Botão "voltar
Quando o usuário pressiona o botão Voltar, o VHAL deve usar a propriedade HW_KEY_INPUT
com os seguintes int32Values
para enviar um evento ao Android:
-
ACTION_DOWN
-
KEYCODE_BACK
- Exibição de destino.
Quando o usuário libera o controlador rotativo, o VHAL deve usar a mesma propriedade e código-chave com ACTION_UP
.
Nenhum evento repetido deve ser gerado enquanto o botão central estiver pressionado.
Botão inicial
Manuseie o botão Home como faria com o botão Voltar, mas com KEYCODE_HOME
em vez de KEYCODE_BACK
.
Outros botões
Se o controlador rotativo incluir botões adicionais, o VHAL poderá lidar com eles da maneira que o OEM desejar, pois eles não são considerados parte do rotativo da perspectiva do Android. Normalmente, eles são tratados como os botões Voltar e Início, mas com códigos de acesso diferentes. Por exemplo, KEYCODE_CALL
ou KEYCODE_MUSIC
.
Configuração de compilação
A navegação rotativa é 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
Você também pode incluir os seguintes pacotes em compilações de depuração:
-
RotaryPlayground
Um aplicativo de referência para rotativo (veja RotaryPlayground ). -
RotaryIME
Um IME rotativo de demonstração (consulte Editores de método de entrada ). -
CarRotaryImeRRO
A sobreposição paraRotaryIME
.
O serviço rotativo é habilitado automaticamente quando o dispositivo é inicializado e quando ocorre uma troca de usuário. Isto garante que o usuário possa usar o controlador rotativo durante a configuração.
Se você usar a mesma compilação para carros com e sem controlador rotativo, adicione CarRotaryController
conforme mostrado acima para que o código necessário seja incluído na compilação. Para evitar que o serviço rotativo seja habilitado em carros não rotativos, crie um RRO estático para sobrepor o recurso de string rotaryService
em packages/services/Car/service
com uma string vazia. Você usará a mesma construção, mas terá configurações de produto separadas, para dispositivos rotativos e não rotativos. Apenas este último inclui a sobreposição.
Costumização
Os OEMs podem personalizar a lógica de localização de foco, o destaque de foco e alguns itens adicionais por meio de 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
História de cutucada
O OEM pode configurar se cada um dos dois tipos de histórico de nudge está habilitado ou não e, em caso afirmativo, o tamanho do cache e a política de expiração. Tudo isso é feito substituindo vários recursos da biblioteca car-ui.
Cache de histórico de foco
( Android 11 QPR3, carro Android 11, Android 12 )
Esse cache por FocusArea
armazena a visualização focada mais recentemente dentro do FocusArea
para que possa ser focada ao retornar ao FocusArea
. Esse cache pode ser configurado sobrepondo os seguintes recursos da car-ui-library:
-
car_ui_focus_history_cache_type
:- O cache está desativado.
- O cache irá expirar após algum tempo (veja abaixo).
- O cache nunca expirará.
-
car_ui_focus_history_expiration_period_ms
: Quantos milissegundos antes que o cache expire se o tipo de cache estiver definido como dois (2) (veja acima).
Cache de histórico FocusArea
( Android 11 QPR3, carro Android 11, Android 12 )
Esse cache armazena um histórico de deslocamentos para que os deslocamentos na direção oposta possam retornar o foco para o mesmo FocusArea
. Esse cache pode ser configurado sobrepondo os seguintes recursos da car-ui-library:
-
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 que o cache expire se o tipo de cache estiver definido como 2 (veja acima). -
car_ui_clear_focus_area_history_when_rotating
: se deve anular o cache quando o usuário gira o controlador.
Rotação
( Android 11 QPR3, carro Android 11, Android 12 )
O OEM pode substituir dois recursos inteiros no RotaryService
para especificar se há aceleração, como aceleração do mouse, para rotação:
-
rotation_acceleration_3x_ms
: intervalo de tempo (em milissegundos) usado para decidir se o Google deve acelerar a rotação do controlador para um limite de rotação. Se o intervalo entre este batente e o batente de rotação anterior for menor que este valor, será tratado como três batentes de rotação. Defina como 2147483647 para desativar a aceleração 3×. -
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 detentor de rotação, conforme exigido pelo VHAL. Se não estiverem disponíveis, o RotaryService
assume que os detentores de rotação estão espaçados 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),
Destaque de foco
O OEM pode substituir o destaque de foco padrão na estrutura Android e vários recursos de destaque de foco na car-ui-library.
Destaque de foco padrão
A estrutura Android fornece um destaque de foco padrão por meio do atributo selectableItemBackground
. Em Theme.DeviceDefault
, este atributo refere-se a item_background.xml
em Core
. O OEM pode sobrepor item_background.xml
para alterar o drawable de destaque de foco padrão.
Esse drawable normalmente deve 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 controlador rotativo 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 controlador rotativo, android:state_focused
e android:state_pressed
serão true
enquanto o usuário mantém o botão pressionado. Quando o usuário soltar o botão, apenas android:state_focused
permanecerá true
.
car-ui-library usa um tema derivado de Theme.DeviceDefault
. Como resultado, essa sobreposição afeta aplicativos que usam esta biblioteca e aplicativos que usam qualquer tema derivado de Theme.DeviceDefault
. Isso não afetará aplicativos que usam um tema não relacionado, como Theme.Material
.
Foco em recursos de destaque na car-ui-library
O OEM pode substituir vários recursos da car-ui-library para controlar a aparência do realce de foco em visualizações com realce de foco não retangular (como redondo ou em forma de pílula) e em aplicativos que usam um tema que não deriva do Theme.DeviceDefault
. Esses recursos devem ser sobrepostos para que o destaque do foco seja consistente com o drawable de destaque do foco padrão .
( Android 11 QPR3, carro Android 11, Android 12 )
Os seguintes recursos são usados para indicar quando uma visualização está focada, 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, carro Android 11, Android 12 )
Os seguintes recursos são usados para indicar quando uma visualização está focada 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 realce do foco.
Nessa situação, o desenvolvedor pode especificar um realce de foco personalizado usando cores secundárias :- ( Android 11 QPR3, carro Android 11, 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ê quiser apenas um preenchimento ou apenas um contorno.
Destaque FocusArea
( Android 11 QPR3, carro Android 11, Android 12 )
FocusArea
pode desenhar dois tipos de destaque quando um de seus descendentes está em foco. Ambos podem ser usados em conjunto, se desejado. Este recurso está desabilitado por padrão no AOSP, mas pode ser habilitado substituindo os recursos car-ui-library:
-
car_ui_enable_focus_area_foreground_highlight
: Desenhe um destaque no topo daFocusArea
e seus descendentes. No AOSP, esse drawable é um contorno em torno doFocusArea
. Os OEMs podem substituir o drawablecar_ui_focus_area_foreground_highlight
. -
car_ui_enable_focus_area_background_highlight
: desenhe um destaque no topo daFocusArea
, mas atrás de seus descendentes. No AOSP, esse drawable é um preenchimento sólido. Os OEMs podem substituir o drawablecar_ui_focus_area_background_highlight
.
Editores de método de entrada
Editores de método de entrada (IME) são métodos de entrada. Por exemplo, um teclado na tela.
( Android 11 QPR3, carro Android 11, Android 12 )
O OEM deve sobrepor o recurso de string default_touch_input_method
no RotaryService
para especificar o ComponentName
do IME baseado em toque. Por exemplo, se o OEM usar o IME fornecido com o Android Automotive, ele deverá especificar com.google.android.apps.automotive.inputmethod/.InputMethodService
.
( Android 11 QPR3, carro Android 11, Android 12 )
Se o OEM tiver criado um IME especificamente para rotativo, ele deverá especificar seu ComponentName
no recurso rotary_input_method
. Se esse recurso for sobreposto, o IME especificado será usado sempre que o usuário estiver interagindo com a unidade principal por meio do deslocamento, da rotação e do botão central do controlador rotativo. Quando o usuário tocar na tela, o IME anterior será utilizado. O botão Voltar (e outros botões no controlador rotativo) não têm efeito na seleção do IME. Se esse recurso não for sobreposto, nenhuma alternância de IME ocorrerá. O Carboard não suporta rotação, portanto o usuário não poderá inserir texto por meio do controlador rotativo se o OEM não tiver fornecido um IME rotativo.
RotaryIME
é um IME rotativo de demonstração. Embora básico, é suficiente experimentar a troca automática de IME descrita acima. O código fonte do RotaryIME
pode ser encontrado em packages/apps/Car/tests/RotaryIME/
.
Cutucadas fora da tela
Por padrão, quando o usuário tenta sair da borda da tela, nada acontece. O OEM pode configurar o que deve ocorrer para cada uma das quatro direções especificando qualquer combinação de:
- Uma ação global definida por
AccessibilityService
. Por exemplo,GLOBAL_ACTION_BACK
. - Um código-chave, como
KEYCODE_BACK
. - Uma intenção de iniciar uma atividade representada como uma URL.
( Android 11 QPR3, carro Android 11, Android 12 )
Eles são especificados sobrepondo os seguintes recursos de matriz no RotaryService
:
-
off_screen_nudge_global_actions
: matriz de ações globais a serem executadas quando o usuário desliza para cima, para baixo, para a esquerda ou para a direita na borda da tela. Nenhuma ação global será executada se o elemento relevante desta matriz for -1. -
off_screen_nudge_key_codes
: matriz de códigos-chave de eventos de clique a serem injetados quando o usuário move para cima, para baixo, para a esquerda ou para a direita na borda da tela. Nenhum evento será injetado se o elemento relevante desta matriz for 0 (KEYCODE_UNKNOWN
). -
off_screen_nudge_intents
: matriz de intenções para iniciar uma atividade quando o usuário desliza para cima, para baixo, para a esquerda ou para a direita na borda da tela. Nenhuma atividade é iniciada se o elemento relevante desta matriz estiver vazio.
Outras configurações
Você deve sobrepor os seguintes recursos RotaryService
:
- ( Android 11 QPR3, carro Android 11, Android 12 )
config_showHeadsUpNotificationOnBottom
: valor booleano para representar se as notificações de alerta devem ser mostradas na parte inferior e não na parte superior. Deve ter o mesmo valor que o recurso booleanoconfig_showHeadsUpNotificationOnBottom
emframeworks/base/packages/CarSystemUI/res/values/config.xml
- ( Android 11 QPR3, carro Android 11, Android 12 )
notification_headsup_card_margin_horizontal
: Margens esquerda e direita para janela de notificação de alerta. Deve ter o mesmo valor que o recurso de dimensãonotification_headsup_card_margin_horizontal
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 aplicativos que representemTaskViews
ouTaskDisplayAreas
. Por padrão, esta lista contém apenas “Mapas”.
Você pode sobrepor o seguinte recurso RotaryService
:
- ( Android 11 QPR3, carro Android 11, Android 12 )
long_press_ms
: valor inteiro para representar quantos milissegundos o botão central deve ser pressionado para acionar um toque longo. Zero indica que o tempo limite padrão do sistema para pressionar longamente deve ser usado. Este é o valor padrão.