Let’s start with system_neutral1_50 and briefly understand Fabricated RRO.


android.R.color.system_neutral1_50The colors actually printed are #FAEFE8.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        String colorHex = getColorValueAsString(this, android.R.color.system_neutral1_50);
        Log.d("MainActivity", "Color value: " + colorHex);
    }

    public String getColorValueAsString(Context context, int resourceId) {
        int color = ContextCompat.getColor(context, resourceId);
        return String.format("#%06X", (0xFFFFFF & color));
    }

D/MainActivity: Color value: #FAEFE8

But in the xml under the framework, this data is not defined.

frameworks/base/core/res/res/values/public.xml
    <public type="color" name="system_neutral1_50" id="0x0106001f" />


frameworks/base/core/res/res/values/colors.xml
    <color name="system_neutral1_50">#F0F0F3</color>


Using dumpsys overlayView overlay, you can see overlay paththat there are 2 types of files, one is apka file and the other is frroa file. SystemUIResOverlayThis value is not defined in , but is actually /data/resource-cache/com.android.systemui-neutral-xx.frrodefined in .

com.android.internal.systemui.navbar.gestural_narrow_back:0 {
  mPackageName...........: com.android.internal.systemui.navbar.gestural_narrow_back
  mOverlayName...........: null
  mUserId................: 0
  mTargetPackageName.....: android
  mTargetOverlayableName.: null
  mBaseCodePath..........: /product/overlay/NavigationBarModeGesturalNarrowBack/NavigationBarModeGesturalOverlayNarrowBack.apk
  mState.................: STATE_DISABLED
  mIsEnabled.............: false
  mIsMutable.............: true
  mPriority..............: 2147483647
  mCategory..............: com.android.internal.navigation_bar_mode
  mIsFabricated..........: false
}
com.android.systemui:neutral:0 {
  mPackageName...........: com.android.systemui
  mOverlayName...........: neutral
  mUserId................: 0
  mTargetPackageName.....: android
  mTargetOverlayableName.: 
  mBaseCodePath..........: /data/resource-cache/com.android.systemui-neutral-xx.frro
  mState.................: STATE_ENABLED
  mIsEnabled.............: true
  mIsMutable.............: true
  mPriority..............: 2147483647
  mCategory..............: null
  mIsFabricated..........: true
}


IDMAP OF com.android.systemui:neutral
Paths:
    target path  : /system/framework/framework-res.apk
    overlay path : /data/resource-cache/com.android.systemui-neutral-xx.frro
Overlay name: neutral
Mapping:
    0x0106001e -> color 0xfffffbff (color/system_neutral1_10)
    0x0106001f -> color 0xfffaefe8 (color/system_neutral1_50)
    0x01060020 -> color 0xffece0da (color/system_neutral1_100)
    0x01060021 -> color 0xffcfc4be (color/system_neutral1_200)
    0x01060022 -> color 0xffb3a9a3 (color/system_neutral1_300)
    0x01060023 -> color 0xff988f89 (color/system_neutral1_400)
    0x01060024 -> color 0xff7d746f (color/system_neutral1_500)
    0x01060025 -> color 0xff655d58 (color/system_neutral1_600)
    0x01060026 -> color 0xff4c4541 (color/system_neutral1_700)
    0x01060027 -> color 0xff352f2b (color/system_neutral1_800)
    0x01060028 -> color 0xff201b17 (color/system_neutral1_900)
    0x01060029 -> color 0xff000000 (color/system_neutral1_1000)
    0x0106002b -> color 0xfffffbff (color/system_neutral2_10)
    0x0106002c -> color 0xffffeee2 (color/system_neutral2_50)
    0x0106002d -> color 0xfff2dfd1 (color/system_neutral2_100)
    0x0106002e -> color 0xffd6c3b6 (color/system_neutral2_200)
    0x0106002f -> color 0xffb9a89b (color/system_neutral2_300)
    0x01060030 -> color 0xff9e8e82 (color/system_neutral2_400)
    0x01060031 -> color 0xff827368 (color/system_neutral2_500)
    0x01060032 -> color 0xff6a5c51 (color/system_neutral2_600)
    0x01060033 -> color 0xff51443a (color/system_neutral2_700)
    0x01060034 -> color 0xff3a2e25 (color/system_neutral2_800)
    0x01060035 -> color 0xff231a11 (color/system_neutral2_900)
    0x01060036 -> color 0xff000000 (color/system_neutral2_1000)

What is the principle of frro? I won’t go into details here. It should be roughly related to OverlayManagerService and Idmap2Service. For details, you can refer to these two submissions:
https://cs.android.com/android/_/android/platform/frameworks/base/+/2ed8bfa7fda3c42280e0816c6cf1af852981723b
and
https://cs.android.com/android/_/android/platform/frameworks/base/+/6a2ca782d497e6fdb616f6a273409786a0b81f99

Add fabricated RRO generation to libidmap2

Fabricated Runtime Resource Overlays are overlays that are generated
at runtime and are stored in the data/ partition.

The system can fabricate RROs at runtime to dynamically theme the
device. Idmaps can now be created from APK RROs and fabricated RROs.

Rather than operating on ApkAssets, libidmap2 now operates on abstract
resource "containers" that supply resource values. Target resource
containers implement methods needed to query overlayable and target
overlay information. Currently only APKs can be loaded as target
resource containers. Overlay resource containers implement methods to
supply the mapping of target resource to overlay value and other
overlay information.

The format of a fabricated RRO is as follows:
0x00 - 0x04 : fabricated overlay magic (always FRRO)
0x04 - 0x08 : file format version
0x08 - 0x0c : crc of version + proto data
0x0c - EOF  : proto fabricated overlay data

The magic is used to quickly detect if the file is a fabricated overlay.
The version is incremented whenever backwards incompatible changes are
made to the proto file format. Idmap must always be able to upgrade
fabricated overlays from previous versions to new versions, so all
previous versions must be checked into the tree.

This paragraph introduces the concept and generation mechanism of “Fabricated Runtime Resource Overlays” (Fabricated Runtime Resource Overlays, or FRRO), and how to libidmap2implement the processing of these FRROs in the Android system library. Here is a detailed explanation of this passage:

  1. Definition and storage of FRRO :
    • FRRO is a resource overlay file generated when the device is running and stored in the device’s data/partition. This allows the system to apply theme and style changes dynamically without the need for pre-defined resource files.
  2. Dynamic generation and management :
    • The system can generate FRRO at runtime to dynamically apply themes to devices. This means that Android devices can modify the appearance of their UI as needed without having to reboot or perform a major update.
    • IdmapTools can now create resource maps (idmaps) from RROs generated from APK files and from dynamically generated FRROs. This expands the flexibility and application scenarios of resource coverage.
  3. libidmap2Updates :
    • libidmap2Is a library used to handle the mapping of resource IDs. It has been updated to operate not just on ApkAssetsresources (from APK files), but on abstract “containers” of resources.
    • These containers provide resource values ​​and implement the methods needed to query coverage information and target resource information.
    • Currently, only APK files can be loaded as target resource containers. The coverage resource container implements a method of mapping target resources to coverage values.
  4. FRRO file format :
    • FRRO files have a specific binary format that identifies the file type, version, and content. Format includes:
      • The first few bytes of the file define a “magic number” (FRRO) that is used to quickly identify whether the file is a manufactured overlay file.
      • File version information follows a magic number that identifies the version of the file format. Whenever a backward-incompatible change occurs to the file format, the version number is incremented.
      • The file also contains a CRC checksum to verify the integrity of the version information and protocol data.
      • The remainder of the file contains the actual coverage data, in protobuf format.
  5. Version compatibility and management :
    • IdmapIt must be possible to upgrade the old version of FRRO to the new version, which requires that all historical version information must be checked into the code base to ensure that the overwritten files can still be processed correctly after the system is updated.

This mechanism enables the Android system to handle resource coverage more dynamically and flexibly, supporting richer user customization and instant theme changes without the need to deeply modify the underlying system or restart.

OverlayManager Fabricated RROs

Adds registering and unregistering of FabricatedOverlay to the OMS.
The process that creates the fabricated overlays owns it and is the
only process allowed to unregister it.

When a fabricated overlay is registered, overlay settings for it are
initialized in all users. When a fabricated overlay is unregistered,
it is disabled and removed from all users. When a new user is created,
it will be able to use the fabricated overlay as well.

On boot, fabricated overlays that are not referenced in overlay
settings will be deleted.

When the package that created the fabricated overlay is uninstalled,
its fabricated overlays are also unregistered.

This paragraph describes the functionality related to the “OverlayManager” (overlay manager) and “Fabricated RROs” (instantly generated runtime resource overlays) in the Android system. Here is a detailed explanation:

  1. Added registration and deregistration functions : The system allows registration and deregistration of “FabricatedOverlay” (instantly generated resource overlay) to the Overlay Manager Service (OMS, overlay management service). An on-the-fly overlay is owned by the process that created it, and only that process has permission to unregister it.
  2. Overlay life cycle :
    • On registration : When an instant-generated overlay is registered, its settings are initialized for all users. This means that once registered, this overlay is available to all users.
    • On logout : When an instant-generated overlay is logged out, it is disabled and removed from all users.
    • When a new user is created : New users will also be able to use registered on-the-fly overlays.
  3. System startup handling : On system startup, any on-the-fly generated overlays that are not referenced in the overlay settings will be deleted. This is a cleanup mechanism to ensure that overlays that are no longer needed do not continue to occupy resources.
  4. Handling when the associated package is uninstalled : When the package (application) that created the instant generation overlay is uninstalled, all the instant generation overlays it created will also be unregistered.

This mechanism is mainly used to dynamically manage and control the resource overlays generated and used by applications, so that the system can handle dynamic changes in themes or other resources more flexibly, while ensuring the cleanliness of the system and the effective management of resources.

The apk file is vendor/mediatek/proprietary/packages/overlaydefined under this kind of file, so frrowhere does the file come from? The key is frameworks/base/packages/SystemUI/src/com/android/systemui/themethis directory.
android13, use FabricatedOverlay.Builder, use FabricatedOverlayInternal.aidl, etc. to build the neutral.frro file, and then use ColorScheme to define the colors in neutral.frro.

//frameworks/base/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
    /**
     * Given a color candidate, return an overlay definition.
     */
    protected @Nullable FabricatedOverlay getOverlay(int color, int type) {
        boolean nightMode = (mContext.getResources().getConfiguration().uiMode
                & Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES;

        mColorScheme = new ColorScheme(color, nightMode);
        List<Integer> colorShades = type == ACCENT
                ? mColorScheme.getAllAccentColors() : mColorScheme.getAllNeutralColors();
        String name = type == ACCENT ? "accent" : "neutral";
        int paletteSize = mColorScheme.getAccent1().size();
        FabricatedOverlay.Builder overlay =
                new FabricatedOverlay.Builder("com.android.systemui", name, "android");
        for (int i = 0; i < colorShades.size(); i++) {
            int luminosity = i % paletteSize;
            int paletteIndex = i / paletteSize + 1;
            String resourceName;
            switch (luminosity) {
                case 0:
                    resourceName = "android:color/system_" + name + paletteIndex + "_10";
                    break;
                case 1:
                    resourceName = "android:color/system_" + name + paletteIndex + "_50";
                    break;
                default:
                    int l = luminosity - 1;
                    resourceName = "android:color/system_" + name + paletteIndex + "_" + l + "00";
            }
            overlay.setResourceValue(resourceName, TypedValue.TYPE_INT_COLOR_ARGB8,
                    ColorUtils.setAlphaComponent(colorShades.get(i), 0xFF));
        }

        return overlay.build();
    }

This code defines a getOverlaymethod called which is used to generate a “fabricated overlay” (i.e. a resource overlay generated at runtime) based on the given color. This method is mainly used in theme customization of Android system interfaces (such as SystemUI) to dynamically adjust color themes. Here is a detailed explanation of this code:

parameter

  • color: An integer representing the base color used to generate the color scheme.
  • type: An integer indicating whether the “accent” color scheme or the “neutral” color scheme is generated.
  • style: An Styleenumeration that may contain additional style definitions for use in color scheme creation.

method logic

  1. Night mode detection :
    • Determine whether you are currently in night mode by checking the system configuration ( mResources.getConfiguration().uiMode).
  2. Color scheme generation :
    • ColorSchemeCreates an object using the given color, night mode flag, and style definition . This object is responsible for generating a palette of base colors.
  3. Get a list of shades and colors :
    • According to typethe parameter (ACCENT or NEUTRAL), ColorSchemeget the corresponding color list from the object.
  4. Overlay name setting :
    • Determines the name of the overlay based on the color type (“accent” or “neutral”).
  5. Fabricated Overlay build :
    • Using FabricatedOverlay.Builder, create an overlay for SystemUI with the target package name “android”.
    • Traverse the list of hues and generate a resource definition for each hue. The resource name is in the format “android:color/system_[name][paletteIndex]_[luminosity]”. Among them, luminosityand paletteIndexare determined by the position in the color list to ensure that colors of different shades and colors can be configured correctly.
  6. Resource value settings :
    • For each color resource, use overlay.setResourceValueto set the color value in ARGB form, where the transparency of the color is always opaque (alpha value is 0xFF).

return value

  • The method returns the constructed FabricatedOverlayobject. This object contains all resource modification definitions and can be applied to the system interface to change the corresponding color theme.

The design of this method allows the color of the system theme to be dynamically adjusted in different user interface environments (such as day mode and night mode), improving the customizability and adaptability of the Android system interface.

Leave a Reply

Your email address will not be published. Required fields are marked *