Google is committed to advancing racial equity for Black communities. See how.

Customizing Apps

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

  • Build-time overlay. This is overlay would add any resources needed for the RROs. This includes:

    • Drawables
    • Styles (for example, text appearances)
    • Shared resources (for example, colors)

  • RRO overlay. This folder contains the resources used to generate one RRO per target application. 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 applications.

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 Handling 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:

  • Cannot 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
      

Configuring RRO Overlays

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 overlayed.

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 will continue to 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.

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

Handling 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.

Adding 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.