Customize apps

Now that Car UI library components and resources into the apps, in order to customize these apps, OEMs must provide two overlays:

  • Build-time overlay adds any resources needed for the runtime resource overlay (RROs). This includes:

    • Drawables
    • Styles (for example, text appearances)
    • Shared resources (for example, colors)
  • The RRO overlay folder contains the resources used to generate one RRO per target app. These resources can only refer to:

    • Values defined within the same RRO (for example, for a color this would be a hexadecimal value).
    • Android framework resources (for example, @android:color/accent).
    • A resource defined in the above build-time overlay.

General structure

The proposed customization overlay structure is as follows:

  • <path-to-OEM-overlays>/

    • overlay/framework/base/core/res/. Build-time overlay resources

    • rro/

      • Android.mk. Makefile used to generate the RROs for each target package based on the resources contained in this folder.

      • AndroidManifest.xml. A manifest file template used by the above makefile.

      • res/. Runtime overlays to apply to all target apps.

OEMs may have more than one of these structures, depending on the number of brands they want to handle in a single build target (see Handle multiple brands).

Runtime resource overlays

RRO folder in the OEM overlay folder should contain resources to be applied to all target apps. RROs have limitations affecting their ability to overlay compound resources. In summary, an RRO:

  • Can't refer to resource identifiers defined in the target APK, or in the RRO itself. This means that RROs can not add new identifiers such as new drawables, colors, or styles.

  • Can refer to resource identifiers defined in the framework, whether those resources are defined in /frameworks/base/core/res or by means of a build-time overlay. These identifiers must be referred using the android: name-space:

    • For public DeviceDefault RROs, use android.
      For example, @android:style/TextAppearance.DeviceDefault.Large.

    • For all others (non-public or resources added through build-time overlay), use *android.
      For example, @*android/style:TextAppearance.OEM.Brand1.Title.

In addition to resources, the RRO folder must contain:

  • AndroidManifest.xml. In the sample below, RRO_PACKAGE_NAME and TARGET_PACKAGE_NAME are placeholders for the makefiles:

    <?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 in which oem in the following makefile defines the prefix that all generated RROs would have.
      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
      

Configure RROs

A new configuration file is supported, overlayable.xml, which you can use to define access controls. For example, you can specify who can overlay resources as well as which resources can be overlaid. As a result, resources can now be grouped in different ways to make them available to be overlaid by different RROs.

To set up RRO access control:

  1. In the res/values folder, create overlayable.xml.
  2. Create the <overlayable> resource tags.
  3. Define the name attribute for the <overlayable> tag, which must be unique in the package. Each overlay can target only one overlayable group.
  4. Define the <policy> tag inside <overlayable>.
  5. Define the groups of resources that can be overlaid. For example:
      <resources>
          <overlayable name="OverlayableResources">
              <policy type="public">
                  <item type="string" name="app_title" />
              </policy>
          </overlayable>
      </resources>
      

To apply the following changes to your RRO project:

  1. In the res/xml folder, create overlays.xml. See the entry in the code sample below for overlay.
  2. Define the resources to be overridden.
  3. Add android:resourcesMap="@xml/overlays" to the <overlay> tag in AndroidManifest.xml. For example, in the code sample below, see the entry for <overlay> .
  4. Set android:isStatic=”true” for a static overlay. Each overlay can target only one of the groups that can be overlaid.

Consider the following example. The first section belongs to AndroidManifest.xml while the second section pertains to 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>
  

With one caveat, previously existing RROs work in Android 10. The caveat being that to be installed with the PackageManagerRRO, packages must be either pre-installed or signed with the same key as the target app. In Android 10, layout files can be overlaid. However, doing so requires the use of requireViewById() while getting the view instead of findViewById(). In Android 10, this change has been implemented to car-ui-lib to support layout overlays.

The next major release of Android will enable you to overlay a layout file and define new resources in the RRO package and refer to them internally.

Add OEM-specific resources

To overcome the RRO limitations that prevent OEM resources from being added:

  • Extend frameworks/base using a build-time overlay, adding any necessary resources.
  • Refer to these resources from the OEM RROs using *android: namespacing.

For example, the following is a way to add a OEM specific drawable and use it in an 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>
        

Handle multiple brands

RRO manifest files have a syntax to allow them be conditionally applied based on system properties. To handle multiple brands in a single system image, OEMs can use this as follows (see General structure).

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

The syntax for android:requiredSystemPropertyName and android:requiredSystemPropertyValue would cause this RRO to be enabled only if the corresponding system property matches the provided value. OEMs can then define multiple of these RROs, all of them statically enabled, and have only one active at a time.

Add Car UI library to a target

To incorporate Car UI library to an Android target, you must include the following code snippet:

# 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 \
      ...
  • Causes <path-to-OEM-overlays>/rro/Android.mk generate one RRO for each of the packages named in CAR_UI_RRO_PACKAGE_NAMES.

  • Includes the generated RROs in PRODUCT_PACKAGES.

  • Includes a build-time overlay in PRODUCT_PACKAGE_OVERLAYS to add OEM-specific resources.

To learn which packages support car-ui-lib, see List of packages containing car-ui-lib.