前言
我们在开发过程中经常会使用到系统属性,例如获取系统软件版本,获取设备名名称,boardid等;有时也需要内置自己的属性,系统属性简单来说是用来存储系统中某些键值对数据,具有全局性、存取灵活方便的特点。
一 终端prop命令的使用
1.1 查看系统所有props
#查看系统所有props
$getprop
...
[persist.sys.timezone]: [Asia/Shanghai] //时区
[ro.system.build.type]: [userdebug] //系统编译类型
[vendor.display.lcd_density]: [320] //屏幕密度
...
#获取时区属性persist.sys.timezone的值
$getprop persist.sys.timezone
Asia/Shanghai
#过滤属性名或属性值含有关键字"timezone"的属性
$getprop | grep timezone
[persist.sys.timezone]: [Asia/Shanghai]
#获取不存在的属性时结果为空
$getprop hello
1.2 设置prop
$getprop my.prop.test //属性my.prop.test为空
$setprop my.prop.test 123 //设置属性my.prop.test为123
$getprop my.prop.test //获取属性my.prop.test为123
123
setprop 可以给属性设置int,bool,string等基本类型
二 代码中如何调用prop属性
2.1 java代码中使用prop
在java代码中使用prop 一般需要满足一下条件
import android.os.Systemproperties;
具有system权限
在AndroidManifest.xml中,配置android:sharedUserId=“android.uid.system”
在Android.mk中,配置LOCAL_CERTIFICATE :=platform 或Android.bp 配置 certificate: platform
Systemproperties源码位置:
frameworks/base/core/java/android/os/SystemProperties.java
如果没有没有system权限 则需要利用java反射原理进行调用 因为Systemproperties属于隐藏类且get/set方法属于隐藏方法
/**
* Get the String value for the given {@code key}.
* @param key the key to lookup
* @return an empty string if the {@code key} isn't found
* @hide
*/
@NonNull
@SystemApi
public static String get(@NonNull String key) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get(key);
}
/**
* Set the value for the given {@code key} to {@code val}.
* @throws IllegalArgumentException for non read-only properties if the {@code val} exceeds
* 91 characters
* @throws RuntimeException if the property cannot be set, for example, if it was blocked by
* SELinux. libc will log the underlying reason.
* @hide
*/
@UnsupportedAppUsage
public static void set(@NonNull String key, @Nullable String val) {
if (val != null && !key.startsWith("ro.") && val.getBytes(StandardCharsets.UTF_8).length
> PROP_VALUE_MAX) {
throw new IllegalArgumentException("value of system property '" + key
+ "' is longer than " + PROP_VALUE_MAX + " bytes: " + val);
}
if (TRACK_KEY_ACCESS) onKeyAccess(key);
native_set(key, val);
}
如何利用反射调用Systemproperties
2.2 C++ 代码中使用prop
在c++代码中使用prop 需要:
include<cutils/properties.h>
Android.mk或者Android.bp或者Makefile需要链接libcutils库
properties.h源码位置:
system/core/libcutils/include/cutils/
intproperty_get(constchar* key, char* value, constchar* default_value)
intproperty_set(constchar *key, constchar *value);
intproperty_list(void (*propfn)(constchar *key, constchar *value, void *cookie), void *cookie)
三 特殊属性的介绍
3.1 ro只读属性
ro即read only属性通常是系统默认属性 在系统编译或初始化时设置的
ro属性一旦设置,属性值不能改变。重启不会失效,是永恒的固定值,不能修改值,只能刷机改变
projectname:/ # getprop ro.miui.support.pocket.mode
1
projectname:/ # setprop ro.miui.support.pocket.mode 2
Failed to set property 'ro.miui.support.pocket.mode' to '2'.
See dmesg for error reason.
3.2 persist属性
如果属名称以persist开头,当设置该属性,其值会保留在磁盘中目录为/data/property /persistent_properties,可以修改这种属性,重启后就是修改后的属性值
C:\Users\lct>adb shell "setprop persist.vendor.test 1"
C:\Users\lct>adb shell "getprop persist.vendor.test"
1
C:\Users\lct>adb reboot
C:\Users\lct>adb shell "getprop persist.vendor.test"
1
C:\Users\lct>adb shell "cat data/property/persistent_properties |grep persist.vendor.test"
persist.vendor.test1
3.3 ctl控制属性
服务需要在rc文件里面注册
setprop ctl.start xxx //启动某服务
setprop ctl.stop xxx //关闭某服务
setprop ctl.restart xxx //重启某服务
getprop init.svc.xxx //服务运行状态
projectname:/ # setprop ctl.start sdlog
projectname:/ # getprop init.svc.sdlog
running
projectname:/ # setprop ctl.stop sdlog
projectname:/ # getprop init.svc.sdlog
stopped
projectname:/ # setprop ctl.restart sdlog
projectname:/ # getprop init.svc.sdlog
running
3.4 sys.powerctl属性
控制设备重启,关机,一般上层触发重启,关机(高温关机,低电量关机)最后都是设置的该属性
android系统的关机和重启最终都是通过修改SystemProperties的属性来完成的
C:\Users\lct>adb shell "setprop sys.powerctl reboot" //重启
C:\Users\lct>adb shell "setprop sys.powerctl shutdown" //关机
C:\Users\lct>adb shell "setprop sys.powerctl reboot,recovery" //recovery模式
C:\Users\lct>adb shell setprop sys.powerctl shutdown,battery
C:\Users\lct>adb shell getprop sys.boot.reason
shutdown,battery
C:\Users\lct>adb shell setprop sys.powerctl shutdown,thermal,battery
C:\Users\lct>adb shell getprop sys.boot.reason
shutdown,thermal,battery
C:\Users\lct>adb shell "setprop sys.powerctl reboot,recovery"
C:\Users\lct>adb shell getprop sys.boot.reason
recovery
3.5 其他属性
设置其他格式的开头的属性,属性值保留在内存中,断电重启后不能保存
C:\Users\lct>adb shell "setprop sys.vendor.test 1"
C:\Users\lct>adb shell "getprop sys.vendor.test"
1
C:\Users\lct>adb reboot
C:\Users\lct>adb shell "getprop sys.vendor.test"
四 如何添加系统默认属性
4.1 .prop文件位置
system/build/build.prop
system_ext/etc/build.prop
system_dlkm/etc/build.prop
product/etc/build.prop
vendor/build.prop
odm/etc/build.prop
4.2 mk文件属性配置
PRODUCT_SYSTEM_PROPERTIES
PRODUCT_SYSTEM_DEFAULT_PROPERTIES
PRODUCT_VENDOR_PROPERTIES
PRODUCT_PROPERTY_OVERRIDES
PRODUCT_DEFAULT_PROPERTY_OVERRIDES
PRODUCT_ODM_PROPERTIES
PRODUCT_SYSTEM_EXT_PROPERTIES
PRODUCT_PRODUCT_PROPERTIES
4.3 system分区prop
PRODUCT_SYSTEM_PROPERTIES
PRODUCT_SYSTEM_DEFAULT_PROPERTIES
PRODUCT_SYSTEM_DEFAULT_PROPERTIES` is highly discouraged. Will be deprecated.
system分区属性一般在设置的路径:
device/xxxxx/missi/system.prop
device/qcom/qssi/system.prop
device/qcom/qssi/qssi.mk
编译产物:system/build.prop
4.4 vendor分区prop
PRODUCT_VENDOR_PROPERTIES
PRODUCT_PROPERTY_OVERRIDES
PRODUCT_DEFAULT_PROPERTY_OVERRIDES
`PRODUCT_PROPERTY_OVERRIDES` is highly discouraged. Will be deprecated.
`PRODUCT_DEFAULT_PROPERTY_OVERRIDES` is also discouraged. Will be deprecated.
可在如下mk文件中进行添加
device/xxxxx/mivendor/mivendor_sm6225.mk
编译产物:vendor/build.prop
4.5 product分区prop
PRODUCT_PRODUCT_PROPERTIES
可在如下mk文件进行添加(以M7为例)
device/xxxxx/projectname/product/common.mk
device/xxxxx/projectname/product/common.mk
编译产物:product/etc/build.prop
4.6 odm分区prop
PRODUCT_ODM_PROPERTIES
可在如下mk文件进行添加(以M7为例)
device/xxxxx/projectname/odm/projectname.mk
device/xxxxx/projectname/odm/projectname.mk
编译产物:odm/etc/build.prop
4.7 实例分析
/lc-t-projectname-pre-vendor/device/xxxxx/projectname/product/common.mk34 PRODUCT_PRODUCT_PROPERTIES += persist.vendor.ims.no_stapa=1
/lc-t-projectname-pre-vendor/device/xxxxx/projectname/product/common.mk51 PRODUCT_PRODUCT_PROPERTIES += persist.vendor.ims.no_stapa=1
/lc-t-projectname-pre-vendor/device/xxxxx/projectname/odm/projectname.mk57 PRODUCT_PRODUCT_PROPERTIES += persist.vendor.ims.no_stapa=1
/lc-t-projectname-pre-vendor/device/xxxxx/projectname/odm/projectname.mk80 PRODUCT_PRODUCT_PROPERTIES += persist.vendor.ims.no_stapa=1
/lc-t-projectname-pre-vendor/device/xxxxx/mivendor/system.prop203 persist.vendor.ims.no_stapa=1
mivendor_sm6225.mk656 PRODUCT_PRODUCT_PROPERTIES += persist.vendor.ims.no_stapa=1
上面截图中 哪个仓库下的persist.vendor.ims.no_stapa属性会被编译到?
是否有优先级,如果product、odm、mivendor仓库下面该属性值都不一样 最后会显示哪个属性值?
patch:
C:\Users\lct>adb shell "cat vendor/build.prop |grep persist.vendor.ims.no_stapa"
persist.vendor.ims.no_stapa=1
C:\Users\lct>adb shell "cat product/etc//build.prop |grep persist.vendor.ims.no_stapa"
persist.vendor.ims.no_stapa=0
C:\Users\lct>adb shell "cat odm/etc//build.prop |grep persist.vendor.ims.no_stapa"
persist.vendor.ims.no_stapa=2
C:\Users\lct>adb shell "getprop persist.vendor.ims.no_stapa"
0
添加prop属性优先级级别 product > odm > vendor > system_ext > system
参考文件源码路径: /build/make/Changes.md
4.8 添加属性SEpolicy
如果在对应mk文件添加默认属性后 有时会发现不生效 类似报错log如下
这样因为init在loadpropfile会check 属性的sepolicy
解决方案步骤:
添加vendor属性标签
分配属性标签
vendor_init.te文件中添加set_prop权限
参考gerrit提交:
https://gerrit.odm.mioffice.cn/c/device/qcom/sepolicy_vndr/+/346379
https://gerrit.odm.mioffice.cn/c/device/xxxxx/mivendor/+/335042
如果其他进程需要访问该属性 则需要在对应的.te文件中set_prop/get_prop权限即可
五 如何客制化.prop
为了方便统一管理定制化属性,有时会将定制化属性都写在定制的.prop文件中,下面以添加example.prop为例说明添加过程。
涉及到代码路径:
5.1 system分区添加example.prop
涉及到的代码路径:
device/xxxxx/missi/
/system/core/init/property_service.cpp
device/qcom/sepolicy/generic/private/property_contexts
device/xxxxx/missi下添加example.prop
device/xxxxx/missi/missi.mk copy到system分区
device/qcom/sepolicy/generic/private/property_contexts分配标签 使得init可设置prop
/system/core/init/property_service.cpp 添加load prop文件
烧录版本 验证如下
C:\Users\lct>adb shell "cat system/example.prop"
ro.hello.year=2023
persist.hello.month=01
hello.day=06
C:\Users\lct>adb shell "getprop ro.hello.year"
2023
C:\Users\lct>adb shell "getprop persist.hello.month"
01
C:\Users\lct>adb shell "getprop hello.day"
06
C:\Users\lct>adb shell "getprop -Z hello.day"
u:object_r:system_prop:s0
5.2 vendor分区添加example.prop
涉及到的代码路径:
/device/xxxxx/mivendor/
/system/core/init/property_service.cpp
/device/xxxxx/mivendor/下添加example.prop
/device/xxxxx/mivendor/mivendor_sm6225.mk copy到vendor分区
/system/core/init/property_service.cpp 添加load example.prop文件
烧录版本 验证如下:
C:\Users\lct>adb shell "cat vendor/example.prop"
ro.vendor.year=2023
persist.vendor.month=01
vendor.day=06
C:\Users\lct>adb shell "getprop ro.vendor.year"
2023
C:\Users\lct>adb shell "getprop persist.vendor.month"
01
C:\Users\lct>adb shell "getprop vendor.day"
06
C:\Users\lct>adb shell "getprop -Z ro.vendor.year"
u:object_r:vendor_default_prop:s0
C:\Users\lct>adb shell "getprop -Z persist.vendor.month"
u:object_r:vendor_default_prop:s0
C:\Users\lct>adb shell "getprop -Z vendor.day"
u:object_r:vendor_default_prop:s0
在这里没有重新分配标签,使用的默认的vendor_default_prop标签 vendor_init默认有权限设该标签属性
system/sepolicy/prebuilts/api/32.0/private/property_contexts文章来源:https://www.toymoban.com/news/detail-732332.html
# Common default properties for vendor, odm, vendor_dlkm, and odm_dlkm.
init.svc.odm. u:object_r:vendor_default_prop:s0
init.svc.vendor. u:object_r:vendor_default_prop:s0
ro.hardware. u:object_r:vendor_default_prop:s0
ro.odm. u:object_r:vendor_default_prop:s0
ro.vendor. u:object_r:vendor_default_prop:s0
ro.vendor_dlkm. u:object_r:vendor_default_prop:s0
ro.odm_dlkm. u:object_r:vendor_default_prop:s0
odm. u:object_r:vendor_default_prop:s0
persist.odm. u:object_r:vendor_default_prop:s0
persist.vendor. u:object_r:vendor_default_prop:s0
vendor. u:object_r:vendor_default_prop:s0
system/sepolicy/public/vendor_init.te文章来源地址https://www.toymoban.com/news/detail-732332.html
set_prop(vendor_init, vendor_default_prop)
到了这里,关于Android System Property讲解前言的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!