Cómo personalizar apps

Ahora que los componentes y recursos de la biblioteca de la IU del vehículo están en las apps, para personalizarlas, los OEMs deben proporcionar dos superposiciones:

  • La superposición del tiempo de compilación agrega los recursos necesarios para la superposición de recursos en tiempo de ejecución (RRO). Esto incluye lo siguiente:

    • Elementos de diseño
    • Estilos (por ejemplo, apariencias de texto)
    • Recursos compartidos (por ejemplo, colores)
  • La carpeta superposición de RRO contiene los recursos que se usan para generar un RRO por app de destino. Estos recursos solo pueden hacer referencia a lo siguiente:

    • Valores definidos dentro del mismo RRO (por ejemplo, para un color, este sería un valor hexadecimal).
    • Recursos del framework de Android (por ejemplo, @android:color/accent)
    • Un recurso definido en la superposición del tiempo de compilación anterior.

Estructura general

La estructura de superposición de personalización propuesta es la siguiente:

  • <path-to-OEM-overlays>/

    • overlay/framework/base/core/res/. Recursos de superposición en el tiempo de compilación

    • rro/

      • Android.mk. Makefile que se usa para generar los RRO de cada paquete de destino según los recursos que contiene esta carpeta.

      • AndroidManifest.xml: Es una plantilla de archivo de manifiesto que usa el makefile anterior.

      • res/. Superposiciones del entorno de ejecución que se aplicarán a todas las apps de destino.

Los OEMs pueden tener más de una de estas estructuras, según la cantidad de marcas que deseen controlar en un solo objetivo de compilación (consulta Cómo controlar varias marcas).

Superposiciones de recursos en tiempo de ejecución

La carpeta RRO en la carpeta de superposición del OEM debe contener recursos que se aplicarán a todas las apps de destino. Los RRO tienen limitaciones que afectan su capacidad para superponer recursos compuestos. En resumen, una RRO tiene las siguientes características:

  • No se puede hacer referencia a los identificadores de recursos definidos en el APK de destino ni en el RRO. Esto significa que los RRO no pueden agregar identificadores nuevos, como elementos de diseño, colores o estilos nuevos.

  • Pueden hacer referencia a los identificadores de recursos definidos en el framework, ya sea que esos recursos se definan en /frameworks/base/core/res o a través de una superposición de tiempo de compilación. Estos identificadores se deben consultar con el espacio de nombres android::

    • Para los RRO de DeviceDefault públicos, usa android.
      Por ejemplo, @android:style/TextAppearance.DeviceDefault.Large.

    • Para todos los demás (recursos no públicos o agregados a través de la superposición del tiempo de compilación), usa *android.
      Por ejemplo, @*android/style:TextAppearance.OEM.Brand1.Title.

Además de los recursos, la carpeta RRO debe contener lo siguiente:

  • AndroidManifest.xml. En el siguiente ejemplo, RRO_PACKAGE_NAME y TARGET_PACKAGE_NAME son marcadores de posición para los archivos de configuración de make:

    <?xml version=1.0 encoding=utf-8?>
    <manifest xmlns:android=http://schemas.android.com/apk/res/android”
        package={{RRO_PACKAGE_NAME}} />
        <application android:hasCode=false />
        <overlay android:priority=10
            android:targetPackage={{TARGET_PACKAGE_NAME}}
            android:requiredSystemPropertyName=ro.product.sku
            android:requiredSystemPropertyValue=<your-product-sku> />
    </manifest>
  • Android.mk en el que oem en el siguiente makefile define el prefijo que tendrían todos los RRO generados.
      LOCAL_PATH := $(call my-dir)
      include $(CLEAR_VARS)
      CAR_UI_RRO_SET_NAME := oem
      CAR_UI_RESOURCE_DIR := $(LOCAL_PATH)/res
      CAR_UI_RRO_TARGETS := $(CAR_UI_RRO_PACKAGE_NAMES)
      include packages/apps/Car/libs/car-ui-lib/generate_rros.mk
      

Cómo configurar RRO

Se admite un nuevo archivo de configuración, overlayable.xml, que puedes usar para definir controles de acceso. Por ejemplo, puedes especificar quién puede superponer recursos y cuáles recursos se pueden superponer. Como resultado, los recursos ahora se pueden agrupar de diferentes maneras para que diferentes RRO los superpongan.

Para configurar el control de acceso de RRO, haz lo siguiente:

  1. En la carpeta res/values, crea overlayable.xml.
  2. Crea las etiquetas de recursos <overlayable>.
  3. Define el atributo name para la etiqueta <overlayable>, que debe ser única en el paquete. Cada superposición puede segmentarse para un solo grupo superponible.
  4. Define la etiqueta <policy> dentro de <overlayable>.
  5. Define los grupos de recursos que se pueden superponer. Por ejemplo:
      <resources>
          <overlayable name="OverlayableResources">
              <policy type="public">
                  <item type="string" name="app_title" />
              </policy>
          </overlayable>
      </resources>
      

Para aplicar los siguientes cambios a tu proyecto de RRO, haz lo siguiente:

  1. En la carpeta res/xml, crea overlays.xml. Consulta la entrada en la muestra de código que aparece a continuación para overlay.
  2. Define los recursos que se anularán.
  3. Agrega android:resourcesMap="@xml/overlays" a la etiqueta <overlay> en AndroidManifest.xml. Por ejemplo, en la siguiente muestra de código, consulta la entrada para <overlay> .
  4. Establece android:isStatic=”true” para una superposición estática. Cada superposición solo puede segmentarse para uno de los grupos que se pueden superponer.

Ten en cuenta el siguiente ejemplo. La primera sección pertenece a AndroidManifest.xml, mientras que la segunda sección pertenece a overlays.xml.

  <manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.android.car.ui.rro"
      android:versionCode="1"
      android:versionName="1.0">
      <overlay android:targetName="OverlayableResources"
               android:resourcesMap="@xml/overlays"
               android:targetPackage="com.android.car.ui"
               android:priority="1"
               android:isStatic="false" />
  </manifest>
  <overlay>
      <item target="string/app_title" value="@ string/app_title" />
  </overlay>
  

Con una salvedad, los RRO existentes anteriormente funcionan en Android 10. La salvedad es que, para instalarse con PackageManagerRRO, los paquetes deben estar preinstalados o firmados con la misma clave que la app de destino. En Android 10, los archivos de diseño se pueden superponer. Sin embargo, para ello, se debe usar requireViewById() mientras se obtiene la vista en lugar de findViewById(). En Android 10, este cambio se implementó en car-ui-lib para admitir superposiciones de diseño.

La próxima versión principal de Android te permitirá superponer un archivo de diseño y definir recursos nuevos en el paquete de RRO y hacer referencia a ellos de forma interna.

Cómo agregar recursos específicos del OEM

Para superar las limitaciones de RRO que impiden que se agreguen recursos del OEM, haz lo siguiente:

  • Extiende los frameworks o la base con una superposición de tiempo de compilación y agrega los recursos necesarios.
  • Consulta estos recursos desde los RRO del OEM con el espacio de nombres *android:.

Por ejemplo, la siguiente es una forma de agregar un elemento de diseño específico del OEM y usarlo en un RRO:

  • <path-to-OEM-overlays>

    • overlay/framework/base/core/res/res/drawable/

      • oem_background_drawable.xml

    • rro/res/values

      • drawables.xml

        <resources>
            <item type="drawable" name="car_ui_toolbar_background">
                @*android:drawable/oem_background_drawable
            </item>
        </resources>

Cómo administrar varias marcas

Los archivos de manifiesto de RRO tienen una sintaxis que les permite aplicarse de forma condicional según las propiedades del sistema. Para controlar varias marcas en una sola imagen del sistema, los OEMs pueden usar lo siguiente (consulta Estructura general).

<?xml version=1.0 encoding=utf-8?>
<manifest xmlns:android=http://schemas.android.com/apk/res/android”
    package={{RRO_PACKAGE_NAME}}/>
    <application android:hasCode=false/>
    <overlay android:priority=10
        android:targetPackage={{TARGET_PACKAGE_NAME}}
        android:requiredSystemPropertyName=ro.product.sku
        android:requiredSystemPropertyValue=<your-product-sku>/>
</manifest>

La sintaxis de android:requiredSystemPropertyName y android:requiredSystemPropertyValue haría que este RRO se habilitara solo si la propiedad del sistema correspondiente coincide con el valor proporcionado. Luego, los OEMs pueden definir varios de estos RRO, todos habilitados de forma estática, y tener solo uno activo a la vez.

Cómo agregar la biblioteca de la IU del vehículo a un destino

Para incorporar la biblioteca de la IU de Car a un destino de Android, debes incluir el siguiente fragmento de código:

# Include build-time overlays
    PRODUCT_PACKAGE_OVERLAYS += \
      <path-to-oem-overlays>/overlay
    # Define package names to generate RROs for
    CAR_UI_RRO_PACKAGE_NAMES += \
      com.android.car.ui.paintbooth \
      com.android.car.media \
      com.android.car.dialer \
      com.android.car.linkviewer \
      com.android.car.settings \
      com.android.car.systemupdater \
      com.google.android.apps.automotive.inputmethod \
      com.google.android.apps.automotive.templates.host \
      ...
    # Include generated RROs
    PRODUCT_PACKAGES += \
      oem-com-android-car-ui-paintbooth \
      oem-com-android-car-media \
      oem-com-android-car-dialer \
      oem-com-android-car-linkviewer \
      oem-com-android-car-settings \
      oem-com-android-car-systemupdater \
      oem-com-google-android-apps-automotive-inputmethod \
      oem-com-google-android-apps-automotive-templates-host \
      ...
  • Hace que <path-to-OEM-overlays>/rro/Android.mk genere un RRO para cada uno de los paquetes nombrados en CAR_UI_RRO_PACKAGE_NAMES.

  • Incluye los RRO generados en PRODUCT_PACKAGES.

  • Incluye una superposición de tiempo de compilación en PRODUCT_PACKAGE_OVERLAYS para agregar recursos específicos del OEM.

Para saber qué paquetes admiten car-ui-lib, consulta la lista de paquetes que contienen car-ui-lib.