Android源代码定制:Overlay目录定制|调试Overlay资源是否生效

前言

Android的构建系统中,有一些机制和工具可以帮助我们实现源代码的定制和优化,例如:

  • overlay:这是一种用于修改或替换系统资源(如字符串、图标、布局等)的机制。可以在不修改源代码的情况下,实现对系统资源的定制和优化。

Android源代码定制:移除无用lunch|新建lunch|自定义customize.mk
Android源代码定制:MK文件执行顺序|属性覆盖

在本文中,将介绍这些机制和工具的基本概念和用法,并且通过一些实例来展示如何使用它们来实现Android源代码的定制和优化。还将介绍如何调试我们的修改是否生效,以及如何查看我们的修改的详细信息。

1. 如何自定义overlay目录

在Android中,overlay是一种用于修改或替换系统资源(如字符串、图标、布局等)的机制。overlay可以在不修改源代码的情况下,实现对系统资源的定制和优化。overlay通常位于设备相关或厂商相关的目录下,例如:

  • device/rockchip/common/overlay
  • vendor/customize/rk3568_s_beta/overlay(这是自定义的目录)

当构建系统生成系统镜像时,它会根据不同的目标平台和产品选择相应的overlay目录,并将其添加到DEVICE_PACKAGE_OVERLAYS变量中。这个变量用于指定哪些目录包含了overlay资源。

# 这是系统默认的
DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay

因为我这个是customize.mk 是被 device/rockchip/rk356x/device.mk包含的,所以我测试过在vendor/customize/customize.mk中打印$(LOCAL_PATH)结果是device/rockchip/rk356x。如果想使用$(LOCAL_PATH)并确保它指向正确的目录,需要确保尝试访问它之前没有其他Makefile修改它,并且是直接从构建系统中调用vendor/customize/customize.mk,而不是从另一个Makefile中包含它。

所以自定义一个变量MY_CUSTOM_PATH := $(TOP)/vendor/customize 打印出来就是./vendor/customize

MY_CUSTOM_PATH := $(TOP)/vendor/customize
$(warning Enter $(MY_CUSTOM_PATH)/rk3568_s_beta)
# 这句话的意思就是加载当前设备厂商的overlay路径./vendor/customize/rk3568_s_beta/overlay
DEVICE_PACKAGE_OVERLAYS += $(MY_CUSTOM_PATH)/rk3568_s_beta/overlay

这样当执行make时,构建系统会将这目录都加入到overlay资源的搜索路径中。

当一个系统资源在多个overlay目录中都被修改或替换时,它们可能会产生冲突和覆盖。为了避免这种情况,Android的构建系统提供了一些规则和工具来检查和处理资源的冲突和覆盖。

资源的覆盖顺序是由DEVICE_PACKAGE_OVERLAYS变量中指定的目录顺序决定的。也就是说,后面指定的目录会覆盖前面指定的目录中相同名称和类型的资源。

  • 来测试下 比如系统SettingsProvider叫做def_bluetooth_on,它用于指定蓝牙是否默认开启。它在以下几个地方被定义和赋值:
# 这是系统源码目录下的
ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk/frameworks/base/packages/SettingsProvider$ grep -rn "def_bluetooth_on"
src/com/android/providers/settings/DatabaseHelper.java:2476:                    R.bool.def_bluetooth_on);
res/values/defaults.xml:39:    <bool name="def_bluetooth_on">true</bool>

# 源码默认overlay部分:
ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk/device/rockchip$ grep -rn "def_bluetooth_on"
common/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:22:    <bool name="def_bluetooth_on">false</bool>
common/overlay_go/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:26:    <bool name="def_bluetooth_on">false</bool>
rk356x/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:26:    <bool name="def_bluetooth_on">false</bool>

# 自定义overlay部分,这里我明明是写的true,但我编译测试发现蓝牙还是没有默认打开
ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk/vendor/customize$ grep -rn "def_bluetooth_on"
rk3568_s_beta/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:27:    <bool name="def_bluetooth_on">true</bool>

我怀疑是因为有几个overlay的地方 疑点 : 一个是device/rockchip/
common/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml ,二是/vendor/customize/
rk3568_s_beta/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml

扫描二维码关注公众号,回复: 17160210 查看本文章
  • device/rockchip/common/overlay目录中,有一个资源文件叫做defaults.xml,它用于修改或替换系统资源。它在以下地方修改了def_bluetooth_on的值为false
device/rockchip/common/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:22:    <bool name="def_bluetooth_on">false</bool>
  • vendor/customize/rk3568_s_beta/overlay目录中,我自定义了overlay目录 也有一个资源文件叫做defaults.xml,它用于修改或替换系统资源。它在以下地方修改了def_bluetooth_on的值为true
rk3568_s_beta/overlay/frameworks/base/packages/SettingsProvider/res/values/defaults.xml:27:    <bool name="def_bluetooth_on">true</bool>

我最开始理解是执行make时,构建系统会将这以上这几个目录都加入到overlay资源的搜索路径中,并按照它们在DEVICE_PACKAGE_OVERLAYS变量中的顺序来处理资源的覆盖。因为先指定了device/rockchip/common/overlay,然后指定了vendor/customize/rk3568_s_beta/overlay,所以后者会覆盖前者中相同名称和类型的资源。也就是说,最终生成的系统镜像中,def_bluetooth_on的值会被设置为true,但结果还是false。。。

后面实际测试,压根不是跟理解是一样的,所以我打算先注释掉系统厂商目录原有的overlay目录,只走自定义的overlay目录。

+++ b/device/rockchip/rk356x/rk3568_s/rk3568_s.mk
@@ -13,7 +13,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 #

 # First lunching is S, api_level is 31
 PRODUCT_SHIPPING_API_LEVEL := 31
 PRODUCT_DTBO_TEMPLATE := $(LOCAL_PATH)/dt-overlay.in
@@ -26,7 +31,7 @@ $(call inherit-product, device/rockchip/rk356x/device.mk)
 $(call inherit-product, device/rockchip/common/device.mk)
 $(call inherit-product, frameworks/native/build/tablet-10in-xhdpi-2048-dalvik-heap.mk)
 
-DEVICE_PACKAGE_OVERLAYS += $(LOCAL_PATH)/../overlay
+#DEVICE_PACKAGE_OVERLAYS += $(LOCAL_PATH)/../overlay
 
 PRODUCT_CHARACTERISTICS := tablet
 
ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk$ git diff device/rockchip/common/BoardConfig.mk
diff --git a/device/rockchip/common/BoardConfig.mk b/device/rockchip/common/BoardConfig.mk
index 4724a3bd46..d164031bf5 100755
--- a/device/rockchip/common/BoardConfig.mk
+++ b/device/rockchip/common/BoardConfig.mk
@@ -199,12 +199,12 @@ VENDOR_SECURITY_PATCH := $(PLATFORM_SECURITY_PATCH)
 
 TARGET_BOOTLOADER_BOARD_NAME ?= rk30sdk
 TARGET_NO_BOOTLOADER ?= true
-ifeq ($(filter atv box, $(strip $(TARGET_BOARD_PLATFORM_PRODUCT))), )
-DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay
-ifneq ($(BOARD_HAS_RK_4G_MODEM), true)
-DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay_wifi_only
-endif
-endif
+#ifeq ($(filter atv box, $(strip $(TARGET_BOARD_PLATFORM_PRODUCT))), )
+#DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay
+#ifneq ($(BOARD_HAS_RK_4G_MODEM), true)
+#DEVICE_PACKAGE_OVERLAYS += device/rockchip/common/overlay_wifi_only
+#endif
+#endif

2.调试overlay资源是否生效

当我们修改或替换了系统资源后,可能想要验证我们的修改是否正确地应用到了系统镜像中。为了快速调试做到这一点,可以使用一些工具来查看系统镜像中的资源信息,比较它们和我们的overlay资源是否一致。

一个常用的工具是aapt,它是一个用于处理Android应用程序包的命令行工具。它可以用于查看、添加、删除或修改APK中的资源和元数据。可以使用aapt来查看系统镜像中的某个APK文件中的资源信息,例如:

aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk

这个命令会打印出SettingsProvider.apk中所有的资源信息,包括资源名称、ID、类型、值、大小、引用等。如果我们想要查看某个特定的资源,我们可以使用grep命令来过滤输出,例如:


aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk  | grep def_bluetooth_on

这个命令会打印出与def_bluetooth_on相关的资源信息,例如:

ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk$ aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk  | grep def_bluetooth_on
      spec resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: flags=0x00000000
        resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: t=0x12 d=0xffffffff (s=0x0008 r=0x00)

这个输出表示def_bluetooth_on是一个布尔类型的资源,其值为true(0xffffffff)。可以根据这个输出来判断我们的overlay资源是否生效。

vendor\customize\rk3568_s_beta\overlay\frameworks\base\packages\SettingsProvider\res\values\defaults.xml中修改def_bluetooth_on<bool name="def_bluetooth_on">true</bool>

编译后看到以下输出:

ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk$ aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk  | grep def_bluetooth_on
      spec resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: flags=0x00000000
        resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: t=0x12 d=0xffffffff (s=0x0008 r=0x00)

那么说明我们的overlay资源生效了,最终我实际测试也发现了,开机默认打开了蓝牙。

vendor\customize\rk3568_s_beta\overlay\frameworks\base\packages\SettingsProvider\res\values\defaults.xml中修改def_bluetooth_on<bool name="def_bluetooth_on">false</bool>

ln28@ln28-pc:~/sourcecode/rk_android12.0_sdk$ aapt d resources out/target/product/rk3568_s/system/priv-app/SettingsProvider/SettingsProvider.apk  | grep def_bluetooth_on
      spec resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: flags=0x00000000
        resource 0x7f02000d com.android.providers.settings:bool/def_bluetooth_on: t=0x12 d=0x00000000 (s=0x0008 r=0x00)

那么说明overlay资源生效了,但结果是def_bluetooth_on为关闭的。

为了方便地比较不同overlay设置下的资源信息,用一个表格来展示方便对比:

资源名 资源ID 类型 大小 资源的引用
com.android.providers.settings:bool/def_bluetooth_on(overlay set to true) 0x7f02000d bool 0xffffffff (true) 0x0008 0x00
com.android.providers.settings:bool/def_bluetooth_on(overlay set to false) 0x7f02000d bool 0x00000000 (false) 0x0008 0x00
  • 0xffffffff 通常在这种上下文中表示true
  • 0x00000000 表示false
  • r=0x00:这是资源的引用。在这种情况下,它是0,这意味着资源不引用其他资源。

测试

vendor\customize\rk3568_s_beta\overlay\frameworks\base\packages\SettingsProvider\res\values\defaults.xml中添加,这个目的是想默认打开wifi,蓝牙,默认背光244。

<resources>
    <bool name="def_wifi_on">true</bool>
    <bool name="def_bluetooth_on">true</bool>
    <integer name="def_screen_brightness">244</integer>
</resources>

vendor\customize\rk3568_s_beta\overlay\frameworks\base\core\res\res\drawable-sw720dp-nodpi中添加default_wallpaper.png,这个目的是想overlay桌面壁纸。在这里插入图片描述
OK , 编译烧机测试 结果和烧录前一致,这是因为我在编译后通过aapt就知道了烧录后的结果,也再也不用担心系统默认的overlay会覆盖导致改代码混乱了。

在这里插入图片描述
在这里插入图片描述

总结

在本文中介绍了Android源代码定制的一些机制和工具,包括:

  • overlay:介绍了overlay的概念和目录结构,以及如何自定义overlay目录和资源。
  • 调试工具:介绍了aapt工具的用法,以及如何查看系统镜像中的资源信息。

希望这篇文章能够对你有所帮助,如果你有任何问题或建议,请在评论区留言。谢谢!

猜你喜欢

转载自blog.csdn.net/SHH_1064994894/article/details/133972246
今日推荐