Guía de integración para OEM

En esta página, se describe cómo procesar entradas rotativas en la VHAL y configurar tu compilación para incluir el servicio rotativo y cómo personalizar la experiencia en todas las apps. Para apps del OEM preinstaladas, como un selector proporcionado por el OEM, consulta Biblioteca de IU del vehículo (car-ui-library).

VHAL

Un control rotativo admite las siguientes acciones:

  • Empujar hacia arriba, hacia abajo, hacia la izquierda y hacia la derecha.
  • Rotar en el sentido de las manecillas del reloj y en el sentido contrario.
  • Presiona el botón central.
  • Presiona el botón Atrás.
  • Presiona el botón de inicio.
  • Presiona otros botones, como Teléfono y Multimedia.

Consulta hardware/interfaces/automotive/vehicle/2.0/types.hal para ver la documentación sobre las propiedades del sistema y los int32Values correspondientes

La VHAL debe controlar las siguientes acciones:

Aviso

Cuando el usuario presiona el control rotativo hacia la derecha, la VHAL debe usar el Propiedad HW_KEY_INPUT con los siguientes int32Values para enviar un a Android:

  1. ACTION_DOWN
  2. KEYCODE_SYSTEM_NAVIGATION_RIGHT
  3. Visualización de destino.

Cuando el usuario suelta el control rotativo, la VHAL debe usar la misma propiedad y clave con ACTION_UP. Los movimientos en otras direcciones deben utilizar el con los códigos de teclas correspondientes.

No hay códigos de teclas para diagonales, pero el VHAL puede combinar una estructura horizontal y vertical. para producir una diagonal si el hardware admite diagonales. Por ejemplo, sugerir y a la izquierda debería producir lo siguiente:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_DOWN
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_DOWN

En cualquier orden (y posteriormente), liberar el control rotativo debería producir lo siguiente:

  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_LEFT ACTION_UP
  • HW_KEY_INPUT KEYCODE_SYSTEM_NAVIGATION_UP ACTION_UP

El usuario puede empujar el control rotativo en una dirección perpendicular antes de soltarlo. Por ejemplo, la siguiente situación:

Dirección perpendicular
Figura 1: dirección perpendicular

Esto debería generar la siguiente secuencia 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

No se deben generar eventos repetir mientras el control rotativo está presionado en una dirección.

Rotar

Cuando el usuario rota el control rotativo en el sentido de las manecillas del reloj un ajuste, la VHAL Debes usar la propiedad HW_ROTARY_INPUT con el siguiente int32Values Para enviar un evento a Android, sigue estos pasos:

  1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
  2. Un (1) tipo de retención.
  3. Visualización de destino.

La marca de tiempo del evento debe establecerse en el tiempo transcurrido en nanosegundos.

Una (1) rotación en sentido antihorario debería generar el mismo evento, pero con -1 para la cantidad de detenciones.

Si se producen varias retenciones de rotación en la misma dirección en una sucesión rápida, el VHAL debe se deben combinar los bloqueos en un solo evento para no sobrecargar el sistema con eventos. En este caso, la marca de tiempo del evento debe corresponder al momento en que se produjo el primer detención de la rotación. int32Values debe incluir la cantidad de nanosegundos entre detenciones consecutivas. de rotación.

Por ejemplo, la siguiente secuencia de rotaciones:

  • En el tiempo t0, el usuario giró un soporte en el sentido contrario a las manecillas del reloj.
  • En el tiempo t0 + 5 ns, el usuario giró un ajuste en sentido antihorario.
  • En el tiempo t0 + 8 ns, el usuario giró un ajuste en sentido antihorario.

debería generar este evento:

  • Propiedad: HW_ROTARY_INPUT
  • Marca de tiempo: t0
  • int32Values:
    1. ROTARY_INPUT_TYPE_SYSTEM_NAVIGATION
    2. -3 (tres bloqueos en sentido contrario a las manecillas del reloj).
    3. Visualización de destino.
    4. 5 ns entre el primer y el segundo detenimiento.
    5. 3 ns entre la segunda y la tercera retención.

Centrar botón

Cuando el usuario presiona el botón central, la VHAL debe usar el HW_KEY_INPUT con el siguiente int32Values para enviar un evento a Android:

  1. ACTION_DOWN
  2. KEYCODE_DPAD_CENTER
  3. Visualización de destino.

Cuando el usuario suelta el control rotativo, la VHAL debe usar la misma propiedad y el código de clave con ACTION_UP.

No generes eventos repetir cuando se mantenga presionado el botón central.

Botón Atrás

Cuando el usuario presiona el botón Atrás, la VHAL debe usar el HW_KEY_INPUT con el siguiente int32Values para enviar un evento a Android:

  1. ACTION_DOWN
  2. KEYCODE_BACK
  3. Visualización de destino.

Cuando el usuario suelta el control rotativo, la VHAL debe usar la misma propiedad y el código de clave con ACTION_UP.

No se deben generar eventos repetir mientras el botón central está presionado.

Botón Inicio

Controla el botón de inicio como lo harías con el botón Atrás, pero con KEYCODE_HOME. de KEYCODE_BACK.

Otros botones

Si el control rotativo incluye botones adicionales, el VHAL podrá controlarlos, sin embargo, que le gusta al OEM, ya que no se consideran parte de la versión rotativa desde la perspectiva de Android. Por lo general, se manejan como los botones Atrás y Inicio, pero con códigos de teclas diferentes. Por ejemplo, KEYCODE_CALL o KEYCODE_MUSIC.

Configuración de compilación

Un servicio de accesibilidad llamado RotaryService proporciona navegación rotativa. Para incluir este servicio en la imagen del sistema de tu dispositivo, agrega la siguiente línea a tu makefile:

PRODUCT_PACKAGES += CarRotaryController

Es posible que también desees incluir los siguientes paquetes en las compilaciones de depuración:

El servicio rotativo se habilita automáticamente cuando se inicia el dispositivo y cuando un usuario se produce el cambio. Esto garantiza que el usuario pueda usar el control rotativo durante la configuración.

Si usas la misma compilación para autos con y sin control rotativo, agrega CarRotaryController como se muestra más arriba para que se incluya el código necesario en la compilación. Para evitar que se habilite el servicio rotativo en automóviles no rotativos, crea un RRO estático para superponer el recurso de cadenas rotaryService en packages/services/Car/service con una cadena vacía. Usarás la misma compilación, pero tienen configuraciones de producto separadas, para dispositivos rotativos y no rotativos. Solo los últimos incluye la superposición.

Personalización

Los OEM pueden personalizar la lógica de búsqueda del enfoque, el enfoque destacado y algunos elementos adicionales a través de superposiciones de recursos en las siguientes ubicaciones:

  • car-ui-library se encuentra en packages/apps/Car/libs/car-ui-lib
  • RotaryService se encuentra en packages/apps/Car/RotaryController
  • Core se encuentra en frameworks/base/core

Historial de sugerencias

El OEM puede configurar si se habilita cada uno de los dos tipos de historial de sugerencias y, de ser así, el tamaño de caché y la política de caducidad. Para ello, se anulan varias de Google Cloud.

Enfocar la caché del historial

(Android 11 QPR3, Android 11 Car, Android 12)
Esta caché por FocusArea almacena la vista enfocada más reciente dentro del FocusArea para que se pueda enfocar cuando se vuelve a consultar FocusArea. Esta caché se puede configurar superponiendo los siguientes recursos car-ui-library:

  • car_ui_focus_history_cache_type:
    1. La caché está inhabilitada.
    2. La caché vencerá después de un tiempo (consulte a continuación).
    3. La caché nunca vencerá.
  • car_ui_focus_history_expiration_period_ms: Cantidad de milisegundos antes del se vence si el tipo de caché está establecido en dos (2) (ver arriba).

Caché del historial de FocusArea

(Android 11 QPR3, Android 11 Car, Android 12)
Esta caché almacena un historial de sugerencias, de manera que las sugerencias en la dirección opuesta puedan volver el enfoque a la misma FocusArea. Para configurar esta caché, puedes superponer Los siguientes recursos de car-ui-library:

  • car_ui_focus_area_history_cache_type:
    1. La caché está inhabilitada.
    2. La caché vence después de un tiempo (consulta a continuación).
    3. La caché nunca vence.
  • car_ui_focus_area_history_expiration_period_ms: Cuántos milisegundos antes la caché caduca si el tipo de caché se establece en 2 (ver arriba).
  • car_ui_clear_focus_area_history_when_rotating: Especifica si se debe anular la caché. cuando el usuario rota el control.

Rotación

(Android 11 QPR3, Android 11 Car, Android 12)
El OEM puede anular dos recursos enteros en RotaryService para especificar si hay aceleración, como la aceleración del mouse, para la rotación:

  • rotation_acceleration_3x_ms: Es el intervalo de tiempo (en milisegundos) que se utiliza para decidir. si Google debe acelerar la rotación del controlador para un descenso de la rotación. Si el botón entre este límite de rotación y el anterior es menor que este valor se tratará como tres restricciones de rotación. Establece este valor en 2147483647 para inhabilitar 3× aceleración.
  • rotation_acceleration_2x_ms: Es similar a rotation_acceleration_3x_ms. Se usa para una aceleración de 2 veces. Establece este valor en 2147483647 para inhabilitar la aceleración de 2 veces.

La aceleración funciona mejor cuando hay marcas de tiempo individuales para cada retención de rotación, ya que obligatorio por el VHAL. Si no están disponibles, RotaryService supone que los bloqueos de rotación están espaciados 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),

Enfocar destacado

El OEM puede anular el enfoque predeterminado destacado en el framework de Android. varios recursos destacados de enfoque en car-ui-library

Enfoque predeterminado destacado

El framework de Android proporciona un enfoque predeterminado con el atributo selectableItemBackground En Theme.DeviceDefault, esta hace referencia a item_background.xml en Core. El OEM puede superponer item_background.xml para cambiar el elemento de diseño de resalte del foco predeterminado

Por lo general, este elemento de diseño debería ser una StateListDrawable, que ajusta el fondo. según diferentes combinaciones de estados, como android:state_focused y android:state_pressed. Cuando el usuario utiliza el control rotativo para enfocar una vista, android:state_focused serán true, pero android:state_pressed serán false. Si el usuario presiona el botón central del control rotativo, tanto android:state_focused como android:state_pressed estará true mientras el usuario mantenga presionado el botón. Cuando el usuario suelte el botón, solo permanecerá android:state_focused true

car-ui-library usa un tema derivado de Theme.DeviceDefault. Como resultado, esta superposición afecta a las apps que usan esta biblioteca y a las que usan cualquier tema derivado de Theme.DeviceDefault No afectará a las apps que usen un tema no relacionado, como Theme.Material.

Enfócate en los recursos para destacar elementos en car-ui-library

El OEM puede anular varios recursos car-ui-library para controlar cómo se destaca el foco. busca en vistas con un enfoque no rectangular (como redondo o en forma de píldora) destacado y en Apps que usan un tema que no proviene de Theme.DeviceDefault. Estos recursos deben superponerse para que el enfoque destacado concuerde con elemento de diseño destacado del foco predeterminado.

(Android 11 QPR3, Android 11 Car, Android 12)
Los siguientes recursos se usan para indicar cuándo una vista está enfocada, pero no presionada:

  • car_ui_rotary_focus_fill_color: Color de relleno.
  • car_ui_rotary_focus_stroke_color: Color del contorno.
  • car_ui_rotary_focus_stroke_width: Es el grosor del contorno.

(Android 11 QPR3, Android 11 Car, Android 12)
Los siguientes recursos se usan para indicar cuándo una vista está enfocada y se la presiona:

  • car_ui_rotary_focus_pressed_fill_color: Color de relleno.
  • car_ui_rotary_focus_pressed_stroke_color: Color del contorno.
  • car_ui_rotary_focus_pressed_stroke_width: Es el grosor del contorno.

A veces, un botón recibe un color de fondo sólido para llamar la atención del usuario, como en el ejemplo que se muestra. Esto puede hacer que el enfoque destacado sea difícil de ver.

Botón con fondo sólido
Figura 2: Botón con fondo sólido

En esta situación, el desarrollador puede especificar un enfoque destacado personalizado usando secondary (secundarios):
  • (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

Cualquiera de los colores puede ser transparente y cualquier dimensión puede ser cero si, por ejemplo, solo querían un relleno o solo un contorno.

Elemento destacado del área de enfoque

(Android 11 QPR3, Android 11 Car, Android 12)
FocusArea puede dibujar dos tipos de resaltado cuando uno de sus subordinados es enfocados. Si se desea, ambos pueden usarse en conjunto. Esta función está inhabilitada de forma predeterminada en AOSP, pero se puede habilitar anulando los recursos de car-ui-library:

  • car_ui_enable_focus_area_foreground_highlight: Dibuja un resaltado encima de el FocusArea y sus elementos subordinados. En AOSP, este elemento de diseño es un esquema alrededor de la FocusArea. Los OEM pueden anular el Elemento de diseño car_ui_focus_area_foreground_highlight.
  • car_ui_enable_focus_area_background_highlight: Dibuja un resaltado en la parte superior de la FocusArea, pero detrás de sus elementos subordinados. En AOSP, este elemento de diseño es un relleno sólido. Los OEMs pueden anular el elemento de diseño car_ui_focus_area_background_highlight.

Editores de método de entrada

Los editores de métodos de entrada (IME) son métodos de entrada. Por ejemplo, un teclado en pantalla.

(Android 11 QPR3, Android 11 Car, Android 12)
El OEM debe superponer el recurso de cadenas default_touch_input_method. en el RotaryService para especificar el ComponentName de la un IME táctil. Por ejemplo, si el OEM usa el IME proporcionado con Android Automotive, deberían especificar com.google.android.apps.automotive.inputmethod/.InputMethodService

(Android 11 QPR3, Android 11 Car, Android 12)
Si el OEM creó un IME específicamente para rotativos, debe especificar su ComponentName en el recurso rotary_input_method. Si este recurso se superpone, se usa el IME especificado cada vez que el usuario interactúa con la consola central a través del botón de empuje, la rotación y el botón Centrar del control rotativo. Cuando el usuario toca la pantalla, se usará el IME anterior. El botón Atrás (y otros botones de la controlador) no influyen en la selección del IME. Si este recurso no está superpuesto, no habrá cambios de IME de que ocurra. El cartón no es compatible con el rotativo, por lo que el usuario no puede ingresar texto a través del rotativo si el OEM no proporcionó un IME rotativo.

RotaryIME es un IME rotativo de demostración. Aunque es básico, es suficiente prueba el cambio automático de IME descrito anteriormente. El código fuente de RotaryIME se encuentran en packages/apps/Car/tests/RotaryIME/.

Sugerencias fuera de pantalla

De forma predeterminada, cuando el usuario intenta salir del borde de la pantalla, no sucede nada. El OEM puede configurar lo que debe ocurrir para cada una de las cuatro direcciones especificando cualquier combinación de:

  1. Es una acción general definida por AccessibilityService. Por ejemplo, GLOBAL_ACTION_BACK.
  2. Un código de tecla, como KEYCODE_BACK
  3. Es un intent para iniciar una actividad representada como una URL.

(Android 11 QPR3, Android 11 Car, Android 12)
Estas se especifican superponiendo los siguientes recursos de array en el RotaryService:

  • off_screen_nudge_global_actions: Array de acciones globales que se deben realizar cuando el usuario se desplaza hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha fuera del borde de la pantalla. No se aplica ninguna acción global si el elemento relevante de este array es -1.
  • off_screen_nudge_key_codes: Es el array de códigos clave de eventos de clic para insertar. cuando el usuario se desplaza hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha fuera del borde de la pantalla. No hay eventos Se inserta si el elemento relevante de este array es 0 (KEYCODE_UNKNOWN).
  • off_screen_nudge_intents: Es el array de intents para iniciar una actividad cuando el usuario se desplaza hacia arriba, hacia abajo, hacia la izquierda o hacia la derecha fuera del borde de la pantalla. No hay actividad se inicia si el elemento relevante de este array está vacío.

Otras configuraciones

Debes superponer los siguientes recursos RotaryService:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    config_showHeadsUpNotificationOnBottom: valor booleano para representar si las notificaciones de atención deben aparecer en la parte inferior y no en la parte superior. Debe tienen el mismo valor que config_showHeadsUpNotificationOnBottom Recurso booleano en frameworks/base/packages/CarSystemUI/res/values/config.xml
  • (Android 11 QPR3, Android 11 Car, Android 12)
    notification_headsup_card_margin_horizontal: Margen izquierdo y derecho para de notificación de atención. Debe tener el mismo valor que Recurso de notification_headsup_card_margin_horizontal dimensión en packages/apps/Car/Notification/res/values/dimens.xml
  • (Android 12)
    excluded_application_overlay_window_titles: Un array de títulos de ventanas que no deben considerarse ventanas superpuestas; Esto debe incluir los títulos de ventanas de apps que representan TaskViews o TaskDisplayAreas. De forma predeterminada, esta lista solo contiene "Maps".

Puedes superponer el siguiente recurso RotaryService:

  • (Android 11 QPR3, Android 11 Car, Android 12)
    long_press_ms: Es un número entero que representa la cantidad de milisegundos del Debes mantener presionado el botón central para mantenerlo presionado. El cero indica que el sistema se debe usar el tiempo de espera predeterminado de presión prolongada. Este es el valor predeterminado.