Android系统开发--11.添加系统属性

在 Android 系统中有一个 Property Service 服务, 这个服务对外提供了两个接口:

  • SystemProperties.get(String key, String def) 读取系统属性
  • SystemProperties.set(String key, String val) 设置系统属性

有两个命令行对这两个接口进行了封装,我们可以直接在命令行输入:

  • getprop key 读取系统属性
  • setprop key val 设置系统属性

系统属性可以简单的理解为系统层级的全局变量,以 key-value 的形式保存, key-value 都是字符串。
这些属性可能是有些资源的使用状态,进程的执行状态,系统的特有属性等。
本文不会去分析系统属性服务的构架原理之类的东西,这些东西后面有时间再整理。
这里先从编译系统的角度介绍应该怎么添加一个系统属性。
在添加系统属性之前,我们先要了解一下系统属性的命名规则及系统属性文件路径。

特殊前缀属性

  • ro. :只读属性,不能修改。
  • persist. :修改属性后,重启依然有效。数据会保存到 /data/property 目录。其他前缀的属性被设置后,只是保存在内在中而已,并没有保存到磁盘,所以重启后就恢复默认值了。
  • ctrl. :用来启动和停止服务。每一项服务必须在 init.rc 中定义。init 一旦收到设置 ctrl.start 属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务。这项服务的启动结果将会放入 init.svc.<服务名> 属性中。

系统属性默认值配置文件

系统启动的时候会从几个配置文件中加载属性的默认值,大概有以下几个文件:

  • /default.prop 或者是 /prop.default, 在不同 Android 版本系统上可能不一样
  • /vendor/default.prop
  • /system/build.prop
  • /vendor/build.prop
  • /data/local.prop
  • /data/property/*

系统会按先后顺序依次加载以上文件,后加载的属性将覆盖原先的值。
default.prop 的值是通过 build/tools 目录下的 buildinfo.sh 和 vendor_buildinfo.sh 生成的。
要修改的话,就要修改编译系统了,这种方法不好维护,不推荐。
一般来说我们可以把属性加到 /system/build.prop 或者 /vendor/build.prop。

添加系统属性到 /system/build.prop

只要在 $TARGET_DEVICE_DIR 目录创建一个 system.prop 文件,在里面添加属性即可。
编译系统会把 $(TARGET_DEVICE_DIR)/system.prop 添加到 /system/build.prop 文件中去。
具体代码位置在编译系统的 build/make/core/Makefile 文件 255 行左右。

添加系统属性到 /vendor/build.prop

通过 PRODUCT_PROPERTY_OVERRIDES 变量添加即可。
编译系统会把 PRODUCT_PROPERTY_OVERRIDES 变量的值添加到 /vendor/build.prop 文件中去。
具体代码位置在编译系统的 build/make/core/Makefile 文件 349 行左右。

代码就不贴,想了解的同学可以去阅读一下编译系统源码。

实践

为了验证一下我们上面说的结论,我们来实际操作一下。
在 device/qiushao/generic_pure 目录添加 system.prop 文件:

1
ro.pure.img.name=update_pure.zip

在 device/qiushao/generic_pure 目录添加 vendor.prop.mk 文件:

1
2
3
4
5
PRODUCT_PROPERTY_OVERRIDES += \
ro.pure.support.bluetooth=true \
ro.pure.support.3D=false \
persist.pure.vol.level=50 \
pure.backlight.level=50

然后在 generic_pure.mk 中 include 进来

1
include device/qiushao/generic_pure/vendor.prop.mk

编译完后,打开 out/target/product/generic_pure/system/build.prop 发现其中有一段:

1
2
3
4
# from device/qiushao/generic_pure/system.prop
#
ro.pure.upgrade.img.name=update_pure.zip
#

打开 out/target/product/generic_pure/vendor/build.prop 发现其中有一段:

1
2
3
4
ro.pure.support.bluetooth=true
ro.pure.support.3D=false
persist.pure.vol.level=50
pure.backlight.level=50

启动虚拟机 getprop 看一下:

1
2
3
4
5
6
7
8
9
10
11
12
generic_pure:/ # getprop ro.pure.upgrade.img.name 
update_pure.zip
generic_pure:/ # getprop ro.pure.support.bluetooth
true
generic_pure:/ # getprop ro.pure.support.3D
false
generic_pure:/ # getprop persist.pure.vol.level
50
generic_pure:/ # setprop persist.pure.vol.level 100
generic_pure:/ # getprop pure.backlight.level
50
generic_pure:/ # setprop pure.backlight.level 100

设置完 persist.pure.vol.level 后,重启虚拟机, 发现之前设置的 persist.pure.vol.level 还是 100,
但 pure.backlight.level 的值恢复为 50 了。
验证结果跟我们之前的结论一样。