Personalizar apps

Agora que os componentes e recursos da biblioteca Car UI estão nos apps, para personalizar esses apps, os OEMs precisam fornecer duas sobreposições:

  • A sobreposição no build adiciona todos os recursos necessários para a sobreposição de recursos no ambiente de execução (RROs, na sigla em inglês). Isso inclui:

    • Drawables
    • Estilos (por exemplo, aparências de texto)
    • Recursos compartilhados (por exemplo, cores)
  • A pasta RRO overlay contém os recursos usados para gerar um RRO por app de destino. Esses recursos só podem se referir a:

    • Valores definidos no mesmo RRO (por exemplo, para uma cor, esse seria um valor hexadecimal).
    • Recursos do framework do Android (por exemplo, @android:color/accent).
    • Um recurso definido na sobreposição de build acima.

Estrutura geral

A estrutura de sobreposição de personalização proposta é a seguinte:

  • <path-to-OEM-overlays>/

    • overlay/framework/base/core/res/. Recursos de sobreposição no momento da criação

    • rro/

      • Android.mk. Makefile usado para gerar os RROs de cada pacote de destino com base nos recursos contidos nesta pasta.

      • AndroidManifest.xml. Um modelo de arquivo de manifesto usado pelo makefile acima.

      • res/. Sobreposições de ambiente de execução para aplicar a todos os apps de destino.

Os OEMs podem ter mais de uma dessas estruturas, dependendo do número de marcas que eles querem gerenciar em um único destino de build. Consulte Gerenciar várias marcas.

Sobreposições de recursos de tempo de execução

A pasta RRO na pasta de sobreposição do OEM precisa conter recursos a serem aplicados a todos os apps de destino. As RROs têm limitações que afetam a capacidade de sobrepor recursos compostos. Em resumo, uma RRO:

  • Não pode se referir a identificadores de recursos definidos no APK de destino ou no próprio RRO. Isso significa que as RROs não podem adicionar novos identificadores, como novos drawables, cores ou estilos.

  • Pode se referir a identificadores de recursos definidos no framework, mesmo que esses recursos sejam definidos em /frameworks/base/core/res ou por meio de uma sobreposição no momento de build. Esses identificadores precisam ser referenciados usando o namespace android::

    • Para RROs DeviceDefault públicos, use android.
      Por exemplo, @android:style/TextAppearance.DeviceDefault.Large.

    • Para todos os outros (não públicos ou recursos adicionados pela sobreposição no tempo de build), use *android.
      Por exemplo, @*android/style:TextAppearance.OEM.Brand1.Title.

Além dos recursos, a pasta RRO precisa conter:

  • AndroidManifest.xml. No exemplo abaixo, RRO_PACKAGE_NAME e TARGET_PACKAGE_NAME são marcadores de posição para os arquivos 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 em que oem no makefile a seguir define o prefixo que todos os RROs gerados teriam.
      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
      

Configurar RROs

Um novo arquivo de configuração, overlayable.xml, tem suporte e pode ser usado para definir controles de acesso. Por exemplo, é possível especificar quem pode sobrepor recursos e quais recursos podem ser sobrepostos. Como resultado, os recursos agora podem ser agrupados de maneiras diferentes para que sejam disponibilizados para sobreposição por diferentes RROs.

Para configurar o controle de acesso do RRO:

  1. Na pasta res/values, crie overlayable.xml.
  2. Crie as tags de recursos <overlayable>.
  3. Defina o atributo name para a tag <overlayable>, que precisa ser exclusivo no pacote. Cada sobreposição pode segmentar apenas um grupo sobreponível.
  4. Defina a tag <policy> dentro de <overlayable>.
  5. Defina os grupos de recursos que podem ser sobrepostos. Exemplo:
      <resources>
          <overlayable name="OverlayableResources">
              <policy type="public">
                  <item type="string" name="app_title" />
              </policy>
          </overlayable>
      </resources>
      

Para aplicar as seguintes mudanças ao seu projeto de RRO:

  1. Na pasta res/xml, crie overlays.xml. Confira a entrada no exemplo de código abaixo para overlay.
  2. Defina os recursos a serem substituídos.
  3. Adicione android:resourcesMap="@xml/overlays" à tag <overlay> em AndroidManifest.xml. Por exemplo, no exemplo de código abaixo, confira a entrada para <overlay> .
  4. Defina android:isStatic=”true” para uma sobreposição estática. Cada sobreposição pode segmentar apenas um dos grupos que podem ser sobrepostos.

Considere este exemplo. A primeira seção pertence a AndroidManifest.xml, e a segunda, 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>
  

Com uma ressalva, as RROs já existentes funcionam no Android 10. A ressalva é que, para serem instalados com o PackageManagerRRO, os pacotes precisam ser pré-instalados ou assinados com a mesma chave do app de destino. No Android 10, os arquivos de layout podem ser sobrepostos. No entanto, isso exige o uso de requireViewById() ao receber a visualização em vez de findViewById(). No Android 10, essa mudança foi implementada na car-ui-lib para oferecer suporte a sobreposições de layout.

A próxima versão principal do Android vai permitir que você sobreponha um arquivo de layout e defina novos recursos no pacote RRO, além de se referir a eles internamente.

Adicionar recursos específicos do OEM

Para superar as limitações do RRO que impedem a adição de recursos OEM:

  • Estenda frameworks/base usando uma sobreposição no tempo de build, adicionando os recursos necessários.
  • Consulte esses recursos dos RROs do OEM usando o namespace *android:.

Por exemplo, esta é uma maneira de adicionar um drawable específico do OEM e usá-lo em um 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>

Processar várias marcas

Os arquivos de manifesto RRO têm uma sintaxe que permite que eles sejam aplicados condicionalmente com base nas propriedades do sistema. Para processar várias marcas em uma única imagem do sistema, os OEMs podem usar o seguinte procedimento (consulte Estrutura geral).

<?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>

A sintaxe de android:requiredSystemPropertyName e android:requiredSystemPropertyValue faria com que esse RRO fosse ativado somente se a propriedade do sistema correspondente correspondesse ao valor fornecido. Os OEMs podem definir várias dessas RROs, todas ativadas estaticamente, e ter apenas uma ativa por vez.

Adicionar a biblioteca Car UI a um destino

Para incorporar a biblioteca Car App a um destino do Android, inclua o snippet de código abaixo:

# 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 \
      ...
  • Faz com que <path-to-OEM-overlays>/rro/Android.mk gere uma RRO para cada um dos pacotes nomeados em CAR_UI_RRO_PACKAGE_NAMES.

  • Inclui as RROs geradas em PRODUCT_PACKAGES.

  • Inclui uma sobreposição no momento de build em PRODUCT_PACKAGE_OVERLAYS para adicionar recursos específicos do OEM.

Para saber quais pacotes oferecem suporte a car-ui-lib, consulte Lista de pacotes que contêm car-ui-lib.