Fabricated RRO簡(jiǎn)單理解

從system_neutral1_50來(lái)切入琐簇,簡(jiǎn)單理解Fabricated RRO茫陆。
android.R.color.system_neutral1_50的顏色實(shí)際打印出來(lái)的是#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

但是在framework下的xml中,定義的并不是這個(gè)數(shù)據(jù)筷畦。

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>

使用dumpsys overlay查看overlay,可以看到overlay path有2種類型文件,一種是apk文件豫尽,另一種是frro文件瑞信。SystemUIResOverlay中也沒有定義該值,實(shí)際是/data/resource-cache/com.android.systemui-neutral-xx.frro中定義的绩鸣。

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)

frro的原理是什么怀大?這里不做深入,大致應(yīng)該是是跟OverlayManagerService和Idmap2Service相關(guān)呀闻,具體可以參考這2條提交:
https://cs.android.com/android/_/android/platform/frameworks/base/+/2ed8bfa7fda3c42280e0816c6cf1af852981723b?hl=zh-cn

https://cs.android.com/android/_/android/platform/frameworks/base/+/6a2ca782d497e6fdb616f6a273409786a0b81f99?hl=zh-cn

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.

——————引用開始(由GPT生成)——————
這段話介紹了“Fabricated Runtime Resource Overlays”(制造的運(yùn)行時(shí)資源覆蓋化借,即 FRRO)的概念和生成機(jī)制,以及如何在 Android 系統(tǒng)的 libidmap2 庫(kù)中實(shí)現(xiàn)對(duì)這些 FRRO 的處理捡多。下面是對(duì)這段話的詳細(xì)解釋:

  1. FRRO 的定義和存儲(chǔ)

    • FRRO 是在設(shè)備運(yùn)行時(shí)生成的資源覆蓋文件蓖康,存儲(chǔ)在設(shè)備的 data/ 分區(qū)中。這允許系統(tǒng)動(dòng)態(tài)地應(yīng)用主題和樣式變更垒手,而不需要預(yù)先定義的資源文件蒜焊。
  2. 動(dòng)態(tài)生成與管理

    • 系統(tǒng)可以在運(yùn)行時(shí)生成 FRRO 來(lái)動(dòng)態(tài)地應(yīng)用主題到設(shè)備上。這意味著 Android 設(shè)備可以根據(jù)需要修改其 UI 的外觀科贬,而不必重新啟動(dòng)或進(jìn)行重大更新泳梆。
    • Idmap 工具現(xiàn)在可以從 APK 文件生成的 RRO 和動(dòng)態(tài)生成的 FRRO 創(chuàng)建資源映射(idmaps)。這擴(kuò)展了資源覆蓋的靈活性和應(yīng)用場(chǎng)景。
  3. libidmap2 的更新

    • libidmap2 是一個(gè)庫(kù)优妙,用于處理資源 ID 的映射乘综。它已被更新,以便不僅僅操作 ApkAssets(來(lái)自 APK 文件的資源)套硼,而是操作抽象的資源“容器”卡辰。
    • 這些容器提供資源值,并實(shí)現(xiàn)了查詢覆蓋信息和目標(biāo)資源信息所需的方法邪意。
    • 目前看政,只有 APK 文件可以被加載作為目標(biāo)資源容器。而覆蓋資源容器則實(shí)現(xiàn)了提供目標(biāo)資源到覆蓋值映射的方法抄罕。
  4. FRRO 文件格式

    • FRRO 文件具有特定的二進(jìn)制格式允蚣,以標(biāo)識(shí)文件類型、版本和內(nèi)容呆贿。格式包括:
      • 文件開始的幾個(gè)字節(jié)定義了“魔術(shù)數(shù)字”(FRRO)嚷兔,用于快速識(shí)別文件是否為制造的覆蓋文件。
      • 文件版本信息跟隨魔術(shù)數(shù)字做入,用于標(biāo)識(shí)文件格式的版本冒晰。每當(dāng)文件格式發(fā)生向后不兼容的變化時(shí),版本號(hào)會(huì)增加竟块。
      • 文件還包含了一個(gè) CRC 校驗(yàn)和壶运,用于驗(yàn)證版本信息和協(xié)議數(shù)據(jù)的完整性。
      • 文件的剩余部分包含了實(shí)際的覆蓋數(shù)據(jù)浪秘,采用 protobuf 格式蒋情。
  5. 版本兼容性和管理

    • Idmap 必須能夠?qū)⑴f版本的 FRRO 升級(jí)到新版本,這要求所有歷史版本的信息都必須被檢入到代碼庫(kù)中耸携,以保證覆蓋文件在系統(tǒng)更新后仍能被正確處理棵癣。

這種機(jī)制使 Android 系統(tǒng)能夠更加動(dòng)態(tài)和靈活地處理資源覆蓋,支持更加豐富的用戶定制和即時(shí)主題變更夺衍,而無(wú)需深入修改系統(tǒng)底層或進(jìn)行重啟狈谊。
——————引用結(jié)束(由GPT生成)——————

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.

——————引用開始(由GPT生成)——————
這段話描述了與 Android 系統(tǒng)中的“OverlayManager”(疊加層管理器)和“Fabricated RROs”(即時(shí)生成的運(yùn)行時(shí)資源覆蓋)的相關(guān)功能。以下是詳細(xì)解釋:

  1. 添加注冊(cè)與注銷功能:系統(tǒng)允許注冊(cè)和注銷“FabricatedOverlay”(即時(shí)生成的資源覆蓋層)到 Overlay Manager Service(OMS沟沙,疊加層管理服務(wù))河劝。即時(shí)生成的覆蓋層由創(chuàng)建它的進(jìn)程擁有,并且只有該進(jìn)程有權(quán)限注銷它矛紫。

  2. 覆蓋層的生命周期

    • 注冊(cè)時(shí):當(dāng)一個(gè)即時(shí)生成的覆蓋層被注冊(cè)時(shí)赎瞎,它的設(shè)置會(huì)為所有用戶初始化。這意味著一旦注冊(cè)含衔,所有用戶都可以使用這個(gè)覆蓋層煎娇。
    • 注銷時(shí):當(dāng)一個(gè)即時(shí)生成的覆蓋層被注銷時(shí)二庵,它會(huì)被禁用并從所有用戶中移除贪染。
    • 新用戶創(chuàng)建時(shí):新用戶也將能夠使用已注冊(cè)的即時(shí)生成的覆蓋層缓呛。
  3. 系統(tǒng)啟動(dòng)時(shí)的處理:在系統(tǒng)啟動(dòng)時(shí),任何在覆蓋層設(shè)置中未被引用的即時(shí)生成的覆蓋層將被刪除杭隙。這是一種清理機(jī)制哟绊,確保不再需要的覆蓋層不會(huì)繼續(xù)占用資源。

  4. 關(guān)聯(lián)包被卸載時(shí)的處理:當(dāng)創(chuàng)建即時(shí)生成覆蓋層的包(應(yīng)用)被卸載時(shí)痰憎,其所創(chuàng)建的所有即時(shí)生成覆蓋層也會(huì)被注銷票髓。

這一機(jī)制主要用于動(dòng)態(tài)地管理和控制應(yīng)用生成和使用的資源覆蓋層,使得系統(tǒng)能夠更靈活地處理主題或其他資源的動(dòng)態(tài)變化铣耘,同時(shí)確保系統(tǒng)的整潔和資源的有效管理洽沟。
——————引用結(jié)束(由GPT生成)——————

apk文件是vendor/mediatek/proprietary/packages/overlay這種文件下定義的,那frro文件是怎么來(lái)的呢蜗细。關(guān)鍵是frameworks/base/packages/SystemUI/src/com/android/systemui/theme這個(gè)目錄裆操。
android13,使用FabricatedOverlay.Builder,使用FabricatedOverlayInternal.aidl等構(gòu)建neutral.frro文件炉媒,然后使用ColorScheme去定義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();
    }

——————引用開始(由GPT生成)——————
這段代碼定義了一個(gè)名為 getOverlay 的方法,該方法用于根據(jù)給定的顏色生成一個(gè)“fabricated overlay”(即在運(yùn)行時(shí)生成的資源覆蓋)吊骤。這個(gè)方法主要應(yīng)用于 Android 系統(tǒng)界面(如 SystemUI)的主題定制中缎岗,用于動(dòng)態(tài)調(diào)整顏色主題。下面是對(duì)這段代碼的詳細(xì)解釋:

參數(shù)

  • color: 一個(gè)整數(shù)白粉,表示用作生成顏色方案的基礎(chǔ)顏色传泊。
  • type: 一個(gè)整數(shù),表示生成的是 "accent" 色彩方案還是 "neutral" 色彩方案鸭巴。
  • style: 一個(gè) Style 枚舉或渤,可能包含額外的風(fēng)格定義,用于顏色方案的創(chuàng)建奕扣。

方法邏輯

  1. 夜間模式檢測(cè):

    • 通過檢查系統(tǒng)配置(mResources.getConfiguration().uiMode)薪鹦,確定當(dāng)前是否處于夜間模式。
  2. 顏色方案生成:

    • 使用給定的顏色惯豆、夜間模式標(biāo)志和風(fēng)格定義池磁,創(chuàng)建一個(gè) ColorScheme 對(duì)象。這個(gè)對(duì)象負(fù)責(zé)生成一系列基于基礎(chǔ)顏色的調(diào)色板楷兽。
  3. 獲取色調(diào)和顏色列表:

    • 根據(jù) type 參數(shù)(ACCENT 或 NEUTRAL)地熄,從 ColorScheme 對(duì)象中獲取對(duì)應(yīng)的顏色列表。
  4. Overlay 名稱設(shè)定:

    • 根據(jù)顏色類型確定 overlay 的名稱("accent" 或 "neutral")芯杀。
  5. Fabricated Overlay 構(gòu)建:

    • 使用 FabricatedOverlay.Builder端考,為 SystemUI 創(chuàng)建一個(gè) overlay雅潭,目標(biāo)包名為 "android"。
    • 遍歷色調(diào)列表却特,為每種色調(diào)生成一個(gè)資源定義扶供,資源名稱格式為 "android:color/system_[name][paletteIndex]_[luminosity]"。其中裂明,luminositypaletteIndex 由顏色列表中的位置決定椿浓,以確保不同深淺度和色系的顏色能被正確配置。
  6. 資源值設(shè)置:

    • 對(duì)每一個(gè)顏色資源闽晦,使用 overlay.setResourceValue 設(shè)置 ARGB 形式的顏色值扳碍,這里確保顏色的透明度始終為不透明(alpha 值為 0xFF)。

返回值

  • 方法返回構(gòu)建好的 FabricatedOverlay 對(duì)象仙蛉,這個(gè)對(duì)象包含了所有的資源修改定義笋敞,可以被應(yīng)用于系統(tǒng)界面,以改變相應(yīng)的顏色主題荠瘪。

這個(gè)方法的設(shè)計(jì)允許在不同的用戶界面環(huán)境下(如日間模式和夜間模式)動(dòng)態(tài)調(diào)整系統(tǒng)主題的顏色夯巷,提高了 Android 系統(tǒng)界面的可定制性和適應(yīng)性。
——————引用結(jié)束(由GPT生成)——————

參考鏈接:
Android兩種查看overlay的方法
Android Overlay 機(jī)制解析
運(yùn)行時(shí)資源疊加層 (RRO)
排查運(yùn)行時(shí)資源疊加層問題

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末巧还,一起剝皮案震驚了整個(gè)濱河市鞭莽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌麸祷,老刑警劉巖澎怒,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異阶牍,居然都是意外死亡喷面,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門走孽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)惧辈,“玉大人,你說我怎么就攤上這事磕瓷『谐荩” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵困食,是天一觀的道長(zhǎng)边翁。 經(jīng)常有香客問我,道長(zhǎng)硕盹,這世上最難降的妖魔是什么符匾? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮瘩例,結(jié)果婚禮上啊胶,老公的妹妹穿的比我還像新娘甸各。我一直安慰自己,他們只是感情好焰坪,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布趣倾。 她就那樣靜靜地躺著,像睡著了一般琳彩。 火紅的嫁衣襯著肌膚如雪誊酌。 梳的紋絲不亂的頭發(fā)上部凑,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天露乏,我揣著相機(jī)與錄音,去河邊找鬼涂邀。 笑死瘟仿,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的比勉。 我是一名探鬼主播劳较,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼浩聋!你這毒婦竟也來(lái)了观蜗?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤衣洁,失蹤者是張志新(化名)和其女友劉穎墓捻,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坊夫,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡砖第,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了环凿。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片梧兼。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖智听,靈堂內(nèi)的尸體忽然破棺而出羽杰,到底是詐尸還是另有隱情,我是刑警寧澤到推,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布考赛,位于F島的核電站,受9級(jí)特大地震影響环肘,放射性物質(zhì)發(fā)生泄漏欲虚。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一悔雹、第九天 我趴在偏房一處隱蔽的房頂上張望复哆。 院中可真熱鬧欣喧,春花似錦、人聲如沸梯找。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)锈锤。三九已至驯鳖,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間久免,已是汗流浹背浅辙。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留阎姥,地道東北人记舆。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像呼巴,于是被迫代替她去往敵國(guó)和親泽腮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容