从零开始自定义安卓系统(8) 用复制文件与叠加层自定义系统


从零开始自定义安卓系统(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 启用.

执行后可以看到 contacts