从零开始自定义安卓系统(8) 用复制文件与叠加层自定义系统
复制文件
产品级拥有一个选项可以直接复制文件到系统
1
| PRODUCT_COPY_FILES += test.sh:$(TARGET_COPY_OUT_VENDOR)/bin/test.sh \
|
格式上很简单, 一个:分割的对应关系. 比较特殊的是使用$(TARGET_COPY_OUT_VENDOR)来获取指定目录.
这样有利于后续维护,这些常用的全局变量位于build/core/envsetup.sh
里面定义了全局变量, 如
1
2
3
4
5
6
7
8
9
10
| TARGET_COPY_OUT_SYSTEM := system
TARGET_COPY_OUT_SYSTEM_DLKM := system_dlkm
TARGET_COPY_OUT_SYSTEM_OTHER := system_other
TARGET_COPY_OUT_DATA := data
TARGET_COPY_OUT_ASAN := $(TARGET_COPY_OUT_DATA)/asan
TARGET_COPY_OUT_OEM := oem
TARGET_COPY_OUT_ROOT := root
TARGET_COPY_OUT_RECOVERY := recovery
# 节选 全列表在此文件中搜索 `TARGET_OUT`即可
|
如果要复制到 /system/xxx 可以使用$(TARGET_COPY_OUT_SYSTEM)/xxx
一般用于放一些配置文件 例如init.rc
叠加层
叠加层也叫overlay层, 比起直接复制文件的区别在于. 复制文件是面向最终输出, 会复制到输出目录, 支持任意文件.
叠加层是面向编译系统, 可以实现在编译时替换资源文件. 但是也只能修改资源文件.
但是可以实现修改已有代码的配置,而无需修改安卓源代码.
要使用叠加层只需要
1
| PRODUCT_PACKAGE_OVERLAYS += ${LOCAL_PATH}/overlay
|
然后根据要修改的文件路径新建对应的目录
例如要修改frameworks/base/core/res/res/values/config.xml
1
2
| mkdir -p overlay/frameworks/base/core/res/res/values
touch overlay/frameworks/base/core/res/res/values/config.xml
|
然后按照xml格式 写上需要修改的内容
1
2
3
| <resouce>
<bool name="config_disableLockscreenByDefault">false</bool>
</resouce>
|
只会影响所写的值,不影响其他默认值.
要使用叠加层并不容易, 首先要知道到底有什么配置项,和在哪个路径. 而在了解这些之前几乎没什么用, 需要先阅读源码中的framework/base/core/res/里的xml文件中的注释.
动态叠加层
也称为运行时资源覆盖(RRO), 其实就是从编译时覆盖变成了系统运行时覆盖,为了加入系统, 实际上安装形式是apk
要想使用RRO,首先需要新建一个模块目录,然后添加Android.bp
1
2
3
4
| runtime_resource_overlay {
name: "ExampleOverlay",
sdk_version: "current",
}
|
然后添加app必要的AndroidManifest.xml
1
2
3
4
5
6
7
8
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.overlay">
<application android:hasCode="false" />
<overlay android:targetPackage="com.android.contacts"
android:targetName="OverlayableResources"
android:resourcesMap="@xml/overlays"
/>
</manifest>
|
targetPackage 是想要覆盖的apk名, 这里是aosp自带的联系人应用
@xml/overlays是覆盖资源文件名 实际路径是res/xml/overlays.xml
实际内容像这样
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| <?xml version="1.0" encoding="utf-8"?>
<overlay xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- Overlays string/config1 and string/config2 with the same resource. -->
<item target="string/config1" value="@string/overlay1" />
<item target="string/config2" value="@string/overlay1" />
<!-- Overlays string/config3 with the string "yes". -->
<item target="string/config3" value="@android:string/yes" />
<!-- Overlays string/config4 with the string "Hardcoded string". -->
<item target="string/config4" value="Hardcoded string" />
<!-- Overlays integer/config5 with the integer "42". -->
<item target="integer/config5" value="42" />
</overlay>
|
value的格式与apk 定义资源格式没有区别, target是需要替换的资源id, 需要查看源码或反编译目标app读取资源文件.
安卓自带的联系人资源文件位于packages/apps/Contacts/res/ 然后默认的英语在values, 如果要修改字符串在strings.xml
如果想要修改开屏显示的Add account , 搜索这个文件可以看到是
1
| <string name="contacts_unavailable_add_account">Add account</string>
|
然后在覆盖层文件添加一行
1
| <item target="string/contacts_unavailable_add_account" value="Add account by code" />
|
添加到产品
PRODUCT_PACKAGES += rro
然后执行mm编译 后会出现在system/product/overlay
动态覆盖层管理
更新完系统后可以用adb shell cmd overlay 查看动态叠加层状态
cmd overlay list查看当前的rro apk
可以看到这种输出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| android
[ ] com.android.internal.display.cutout.emulation.corner
[ ] com.android.internal.display.cutout.emulation.double
[ ] com.android.internal.systemui.navbar.gestural_wide_back
[ ] com.android.internal.display.cutout.emulation.hole
[ ] com.android.internal.display.cutout.emulation.tall
[ ] com.android.internal.systemui.navbar.threebutton
[ ] com.android.internal.systemui.navbar.gestural_extra_wide_back
[ ] com.android.theme.font.notoserifsource
[ ] com.android.internal.display.cutout.emulation.waterfall
[ ] com.android.internal.systemui.navbar.gestural
[ ] com.android.internal.systemui.navbar.gestural_narrow_back
[x] com.android.systemui:neutral
[x] com.android.systemui:accent
com.android.contacts
[ ] com.example.overlay
|
包出现在列表但是没有启用, 需要使用 cmd overlay enable com.example.overlay 启用.
执行后可以看到
