從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ì)解釋:
-
FRRO 的定義和存儲(chǔ):
- FRRO 是在設(shè)備運(yùn)行時(shí)生成的資源覆蓋文件蓖康,存儲(chǔ)在設(shè)備的
data/
分區(qū)中。這允許系統(tǒng)動(dòng)態(tài)地應(yīng)用主題和樣式變更垒手,而不需要預(yù)先定義的資源文件蒜焊。
- FRRO 是在設(shè)備運(yùn)行時(shí)生成的資源覆蓋文件蓖康,存儲(chǔ)在設(shè)備的
-
動(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)景。
-
libidmap2
的更新:-
libidmap2
是一個(gè)庫(kù)优妙,用于處理資源 ID 的映射乘综。它已被更新,以便不僅僅操作ApkAssets
(來(lái)自 APK 文件的資源)套硼,而是操作抽象的資源“容器”卡辰。 - 這些容器提供資源值,并實(shí)現(xiàn)了查詢覆蓋信息和目標(biāo)資源信息所需的方法邪意。
- 目前看政,只有 APK 文件可以被加載作為目標(biāo)資源容器。而覆蓋資源容器則實(shí)現(xiàn)了提供目標(biāo)資源到覆蓋值映射的方法抄罕。
-
-
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 格式蒋情。
- FRRO 文件具有特定的二進(jìn)制格式允蚣,以標(biāo)識(shí)文件類型、版本和內(nèi)容呆贿。格式包括:
-
版本兼容性和管理:
-
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ì)解釋:
添加注冊(cè)與注銷功能:系統(tǒng)允許注冊(cè)和注銷“FabricatedOverlay”(即時(shí)生成的資源覆蓋層)到 Overlay Manager Service(OMS沟沙,疊加層管理服務(wù))河劝。即時(shí)生成的覆蓋層由創(chuàng)建它的進(jìn)程擁有,并且只有該進(jìn)程有權(quán)限注銷它矛紫。
-
覆蓋層的生命周期:
- 注冊(cè)時(shí):當(dāng)一個(gè)即時(shí)生成的覆蓋層被注冊(cè)時(shí)赎瞎,它的設(shè)置會(huì)為所有用戶初始化。這意味著一旦注冊(cè)含衔,所有用戶都可以使用這個(gè)覆蓋層煎娇。
- 注銷時(shí):當(dāng)一個(gè)即時(shí)生成的覆蓋層被注銷時(shí)二庵,它會(huì)被禁用并從所有用戶中移除贪染。
- 新用戶創(chuàng)建時(shí):新用戶也將能夠使用已注冊(cè)的即時(shí)生成的覆蓋層缓呛。
系統(tǒng)啟動(dòng)時(shí)的處理:在系統(tǒng)啟動(dòng)時(shí),任何在覆蓋層設(shè)置中未被引用的即時(shí)生成的覆蓋層將被刪除杭隙。這是一種清理機(jī)制哟绊,確保不再需要的覆蓋層不會(huì)繼續(xù)占用資源。
關(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)建奕扣。
方法邏輯
-
夜間模式檢測(cè):
- 通過檢查系統(tǒng)配置(
mResources.getConfiguration().uiMode
)薪鹦,確定當(dāng)前是否處于夜間模式。
- 通過檢查系統(tǒng)配置(
-
顏色方案生成:
- 使用給定的顏色惯豆、夜間模式標(biāo)志和風(fēng)格定義池磁,創(chuàng)建一個(gè)
ColorScheme
對(duì)象。這個(gè)對(duì)象負(fù)責(zé)生成一系列基于基礎(chǔ)顏色的調(diào)色板楷兽。
- 使用給定的顏色惯豆、夜間模式標(biāo)志和風(fēng)格定義池磁,創(chuàng)建一個(gè)
-
獲取色調(diào)和顏色列表:
- 根據(jù)
type
參數(shù)(ACCENT 或 NEUTRAL)地熄,從ColorScheme
對(duì)象中獲取對(duì)應(yīng)的顏色列表。
- 根據(jù)
-
Overlay 名稱設(shè)定:
- 根據(jù)顏色類型確定 overlay 的名稱("accent" 或 "neutral")芯杀。
-
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]"。其中裂明,
luminosity
和paletteIndex
由顏色列表中的位置決定椿浓,以確保不同深淺度和色系的顏色能被正確配置。
- 使用
-
資源值設(shè)置:
- 對(duì)每一個(gè)顏色資源闽晦,使用
overlay.setResourceValue
設(shè)置 ARGB 形式的顏色值扳碍,這里確保顏色的透明度始終為不透明(alpha 值為 0xFF)。
- 對(duì)每一個(gè)顏色資源闽晦,使用
返回值
- 方法返回構(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í)資源疊加層問題