O Google tem o compromisso de promover a igualdade racial para as comunidades negras. Saiba como.

Guia de integração para OEMs

Este artigo descreve como processar entradas rotativas no VHAL, configurar sua construção para incluir o serviço rotativo e como personalizar a experiência rotativa em todos os aplicativos. Para aplicações OEM pré-instalados, como um lançador de OEM-fornecido, consulte Biblioteca UI Car (carro-ui-biblioteca) .

VHAL

Um controlador rotativo suporta as seguintes ações:

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

Ver hardware/interfaces/automotive/vehicle/2.0/types.hal para documentação sobre as propriedades do sistema e correspondente int32Values .

O VHAL deve lidar com estas ações:

Cutucar

Quando o usuário aperta o direito controlador rotativo, o VHAL deve usar o HW_KEY_INPUT imóvel com as seguintes int32Values para enviar um evento para Android:

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. Visor de destino.

Quando o usuário libera o controlador rotativo, o VHAL deve usar a mesma propriedade e código de acesso com ACTION_UP . Deslocamentos em outras direções devem usar os códigos de tecla correspondentes.

Não há códigos de teclas para diagonais, mas o VHAL pode combinar um evento horizontal e vertical para produzir uma diagonal se o hardware suportar diagonais. Por exemplo, empurrar 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 posteriormente) 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 liberá-lo. Por exemplo, o seguinte cenário:

Direção perpendicular
Figura 1. direcção perpendicular

Isso deve gerar a seguinte sequência de eventos:

  1. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  2. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN
  3. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  4. HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

Não há eventos de repetição deve ser gerado enquanto o controlador rotativo é realizada em uma direção.

Girar

Quando gira o usuário no sentido horário controlador rotativo por um retentor (clique), o VHAL deve usar o HW_ROTARY_INPUT imóvel com as seguintes int32Values para enviar um evento para Android:

  1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
  2. Um (1) detentor.
  3. Visor de destino.

O carimbo de data / hora do evento deve ser definido como o tempo decorrido em nanossegundos.

Uma rotação de um (1) detentor no sentido anti-horário deve gerar o mesmo evento, mas com -1 para o número de detentores.

Se vários detentores de rotação na mesma direção ocorrerem em rápida sucessão, o VHAL deve combinar os detentores em um único evento para não sobrecarregar o sistema com eventos. Nesse caso, o carimbo de data / hora do evento deve ser quando o primeiro detentor de rotação ocorreu. Os int32Values deve incluir o número de nanosegundos entre detentores consecutivos 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
  • Timestamp: t0
  • int32Values :
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. -3 (três detenções no sentido anti-horário).
    3. Visor de destino.
    4. 5 ns entre o primeiro e o segundo batente.
    5. 3 ns entre o segundo e o terceiro detentor.

Botão central

Quando o usuário pressiona o botão central, o VHAL deve usar o HW_KEY_INPUT imóvel com as seguintes int32Values para enviar um evento para Android:

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Visor de destino.

Quando o usuário libera o controlador rotativo, o VHAL deve usar a mesma propriedade e código de acesso com ACTION_UP .

Não gerar eventos de repetição quando o botão central é pressionada.

Botão "voltar

Quando o usuário pressiona o botão Voltar, o VHAL deve usar o HW_KEY_INPUT imóvel com as seguintes int32Values para enviar um evento para Android:

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Visor de destino.

Quando o usuário libera o controlador rotativo, o VHAL deve usar a mesma propriedade e código de acesso com ACTION_UP .

Não há eventos de repetição deve ser gerado enquanto o botão central é pressionada.

Botão Home

Lidar com o botão Home como faria com o botão Voltar, mas com KEYCODE_HOME vez de KEYCODE_BACK .

Outros botões

Se o controlador rotativo incluir quaisquer botões adicionais, o VHAL pode manipulá-los da maneira que o OEM quiser, 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 Página inicial, mas com códigos de tecla diferentes. Por exemplo, KEYCODE_CALL ou KEYCODE_MUSIC .

Configuração de compilação

Rotary de navegação é fornecido por um serviço de acessibilidade chamado RotaryService . Para incluir este serviço na imagem do sistema para o seu dispositivo, adicione a seguinte linha ao seu makefile:

PRODUCT_PACKAGES += CarRotaryController

Você também pode querer incluir os seguintes pacotes em compilações de depuração:

O serviço rotativo é ativado automaticamente quando o dispositivo é inicializado e quando ocorre uma troca de usuário. Isso 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 um controlador rotativo, adicione CarRotaryController como mostrado acima, para que o código necessário está incluído na compilação. Para impedir que o serviço rotativo de ser ativado em carros não-rotativos, criar um RRO estática para sobrepor a rotaryService recurso de cadeia 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 o último inclui a sobreposição.

Costumização

Os OEMs podem personalizar a lógica de localização do foco, o destaque do foco e alguns itens adicionais por meio de sobreposições de recursos nos seguintes locais:

  • carro-ui-biblioteca está localizada em packages/apps/Car/libs/car-ui-lib
  • RotaryService está localizado em packages/apps/Car/RotaryController
  • Core está localizado na frameworks/base/core

Nudge history

O OEM pode configurar se cada um dos dois tipos de histórico de ajuste está habilitado ou não e, em caso afirmativo, o tamanho do cache e a política de expiração. Isso tudo é feito substituindo vários recursos da ui-library do carro.

Cache de histórico de foco

(Android 11 QPR3, Android 11 Car, Android 12)
Este per- FocusArea de cache armazena o mais recentemente vista focalizada dentro da FocusArea para que ele possa ser focado durante o deslocamento de volta para o FocusArea . Esse cache pode ser configurado sobrepondo os seguintes recursos da biblioteca de ui do carro:

  • car_ui_focus_history_cache_type :
    1. O cache está desabilitado.
    2. O cache irá expirar após algum tempo (veja abaixo).
    3. O cache nunca irá expirar.
  • car_ui_focus_history_expiration_period_ms : Quantos milissegundos antes do cache expira se o tipo de cache é definido como dois (2) (veja acima).

Cache de histórico FocusArea

(Android 11 QPR3, Android 11 Car, Android 12)
Esse cache armazena uma história de toques para que cutucando na direção oposta pode retornar o foco para o mesmo FocusArea . Esse cache pode ser configurado sobrepondo os seguintes recursos da biblioteca de ui do carro:

  • car_ui_focus_area_history_cache_type :
    1. O cache está desativado.
    2. O cache expira depois de algum tempo (veja abaixo).
    3. O cache nunca expira.
  • car_ui_focus_area_history_expiration_period_ms : Quantos milissegundos antes do cache expira se o tipo de cache é definido como 2 (veja acima).
  • car_ui_clear_focus_area_history_when_rotating : Se anular o cache quando o usuário gira o controlador.

Rotação

(Android 11 QPR3, Android 11 Car, Android 12)
O fabricante pode substituir dois recursos inteiros na RotaryService para especificar se há uma aceleração, tais como a aceleração do rato, para rotação:

  • rotation_acceleration_3x_ms : intervalo de tempo (em milissegundos) utilizado para decidir se o Google deve acelerar a rotação controlador para um detentor de rotação. Se o intervalo entre este batente e o batente anterior de rotação for menor que este valor, será tratado como três batentes de rotação. Defina como 2147483647 para desativar a aceleração de 3 ×.
  • rotation_acceleration_2x_ms : Similar ao rotation_acceleration_3x_ms . Usado para aceleração 2 ×. Defina esta opção para 2147483647 Para desativar 2 × aceleração.

Aceleração funciona melhor quando há marcas de tempo individuais para cada detentor de rotação, como exigido pela VHAL. Se estes não estiverem disponíveis, o RotaryService assume que os batentes de rotação são uniformemente espaçados.

/**
     * 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 do Android e vários recursos de destaque de foco na biblioteca de ui do carro.

Destaque de foco padrão

O quadro Android fornece um destaque foco padrão através do atributo selectableItemBackground . Em Theme.DeviceDefault , este atributo refere-se a item_background.xml no Core . O OEM pode sobrepor item_background.xml para mudar o drawable padrão foco destaque.

Este drawable normalmente deve ser um StateListDrawable , que ajusta o fundo com base em diferentes combinações de estados, incluindo android:state_focused e android:state_pressed . Quando o usuário utiliza o controlador rotativo para focar um ponto de vista, android:state_focused será true , mas android:state_pressed será false . Se o usuário pressiona o botão central do controlador rotativo, tanto android:state_focused e android:state_pressed será true quando o usuário mantém o botão pressionado. Quando o usuário solta o botão, única android:state_focused permanecerá true .

usos carro-ui-biblioteca um tema derivado do Theme.DeviceDefault . Como resultado, esta sobreposição afeta aplicativos que usam esta biblioteca e aplicativos que usam qualquer tema derivado do Theme.DeviceDefault . Não vai afetar aplicativos que usam um tema não relacionado, como Theme.Material .

Concentre-se em recursos de destaque em auto-ui-library

O OEM pode substituir vários recursos carro-ui-biblioteca para controlar a forma como os olhares foco destaque para pontos de vista com um não-retangular (tais como redondo ou em forma de pílula) destaque foco e em aplicativos que usam um tema que não derivam de Theme.DeviceDefault . Esses recursos devem ser sobrepostos para que o destaque foco é consistente com o padrão de foco destaque drawable.

(Android 11 QPR3, Android 11 Car, Android 12)
Os seguintes recursos são usados para indicar quando uma vista está focado, mas não pressionado:

  • car_ui_rotary_focus_fill_color : cor de preenchimento.
  • car_ui_rotary_focus_stroke_color : Cor de contorno.
  • car_ui_rotary_focus_stroke_width : Espessura do contorno.

(Android 11 QPR3, Android 11 Car, Android 12)
Os seguintes recursos são usados para indicar quando uma visão é focalizada e pressionado:

  • car_ui_rotary_focus_pressed_fill_color : cor de preenchimento.
  • car_ui_rotary_focus_pressed_stroke_color : Cor de 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.

Botão com fundo sólido
Figura 2. Botão com sólida formação

Nesta situação, o desenvolvedor pode especificar um foco personalizado destaque 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ê quiser apenas um preenchimento ou apenas um contorno.

Destaque da FocusArea

(Android 11 QPR3, Android 11 Car, Android 12)
FocusArea pode desenhar dois tipos de destaque quando um de seus descendentes é focado. Ambos podem ser usados ​​em conjunto, se desejado. Este recurso é desabilitado por padrão no AOSP, mas pode ser habilitado substituindo os recursos da biblioteca de ui do carro:

  • car_ui_enable_focus_area_foreground_highlight : Desenhe um destaque no topo da FocusArea e seus descendentes. Em AOSP, este drawable é um contorno ao redor do FocusArea . OEMs podem substituir o car_ui_focus_area_foreground_highlight drawable.
  • car_ui_enable_focus_area_background_highlight : Desenhe um destaque no topo da FocusArea mas por trás de seus descendentes. No AOSP, esse drawable é um preenchimento sólido. OEMs podem substituir o car_ui_focus_area_background_highlight drawable.

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, Android 11 Car, Android 12)
O OEM deve sobrepor a default_touch_input_method recurso de cadeia no RotaryService para especificar o ComponentName do IME baseada em toque. Por exemplo, se o OEM utiliza o IME fornecido com Automotive Android, eles devem especificar com.google.android.apps.automotive.inputmethod/.InputMethodService .

(Android 11 QPR3, Android 11 Car, Android 12)
Se o OEM criou um IME especificamente para rotativo, eles devem especificar seu ComponentName na rotary_input_method recurso. Se este recurso for sobreposto, o IME especificado será usado sempre que o usuário estiver interagindo com a unidade principal por meio de deslocamento, rotação e botão central do controlador rotativo. Quando o usuário toca na tela, o IME anterior será usado. O botão Voltar (e outros botões no controlador giratório) não têm efeito na seleção de IME. Se este recurso não for sobreposto, nenhuma alternância de IME ocorrerá. Carboard não oferece suporte rotativo, portanto, o usuário não pode inserir texto por meio do controlador rotativo se o OEM não tiver fornecido um IME rotativo.

RotaryIME é um IME demonstração rotativo. Embora básico, é suficiente experimentar a troca automática de IME descrita acima. O código fonte para RotaryIME podem ser encontrados em packages/apps/Car/tests/RotaryIME/ .

Cutucadas fora da tela

Por padrão, quando o usuário tenta empurrar a 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:

  1. A ação global definida por AccessibilityService . Por exemplo, GLOBAL_ACTION_BACK .
  2. Um código de chave, tais como KEYCODE_BACK .
  3. Uma intenção de lançar uma atividade representada como um URL.

(Android 11 QPR3, Android 11 Car, Android 12)
Estes são especificados sobrepondo os seguintes recursos matriz na RotaryService :

  • off_screen_nudge_global_actions : Disposição de ações globais para executar quando o usuário empurra para cima, baixo, esquerda ou direita para fora da borda da tela. Nenhuma ação global é executada se o elemento relevante desta matriz for -1.
  • off_screen_nudge_key_codes : Disposição de códigos de chaves de eventos de clique para injetar quando o usuário empurra para cima, baixo, esquerda ou direita para fora da borda da tela. Nenhum evento é injetado se o elemento relevante desta matriz é 0 ( KEYCODE_UNKNOWN ).
  • off_screen_nudge_intents : Disposição de intenções para lançar uma atividade quando o usuário empurra para cima, baixo, esquerda ou direita para fora da borda da tela. Nenhuma atividade é iniciada se o elemento relevante desta matriz estiver vazio.

Outras configurações

Você deve cobrir as seguintes RotaryService recursos:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    config_showHeadsUpNotificationOnBottom : valor booleano para representar se as notificações heads-up deve ser mostrado na parte inferior, em oposição ao topo. Este deve ter o mesmo valor que o config_showHeadsUpNotificationOnBottom recurso booleana em frameworks/base/packages/CarSystemUI/res/values/config.xml
  • (Android 11 QPR3, Android 11 Car, Android 12)
    notification_headsup_card_margin_horizontal : margem esquerda e direita para a janela de notificação de heads-up. Este deve ter o mesmo valor que o notification_headsup_card_margin_horizontal recurso dimen em packages/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 considerados sobreposição de janelas. Isto deve incluir títulos de janelas de aplicativos que representam TaskViews ou TaskDisplayAreas . Por padrão, esta lista contém apenas "Mapas".

Você pode sobrepor o seguinte RotaryService recurso:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    long_press_ms : Valor inteiro para representar quantos milissegundos o botão central deve ser mantida pressionada para disparar um longo imprensa. Zero indica que o tempo limite padrão do pressionamento longo deve ser usado. Este é o valor padrão.