当前位置:   article > 正文

Android系统Property属性的加载及使用_android properties 前缀

android properties 前缀
Property属性介绍

Property属性被大量使用在Android系统中,在整个系统中全局可见的,用来记录系统设置或进程之间的信息交换,每个进程可以get/set属性,每个属性都有一个名称和值(key=value),他们都是字符串格式。

属性" ctrl.start “和” ctrl.stop “是用来启动和停止服务。每一项服务必须在init.rc中定义系统启动时,与init守护进程将解析init.rc和启动属性服务。一旦收到设置“ ctrl.start ”属性的请求,属性服务将使用该属性值作为服务名找到该服务,启动该服务,这项服务的启动结果将会放入” init.svc.<服务名> "属性中。

在系统初始化时,Android将分配一个共享内存区来存储的属性。这些是由“init”守护进程完成的,其源代码位于device/system/init。"init"守护进程将启动一个属性服务,属性服务在“init”守护进程中运行,每一个客户端想要设置属性时,必须连接属性服务,再向其发送信息,属性服务将会在共享内存区中修改和创建属性。任何客户端想获得属性信息,可以从共享内存直接读取,提高了读取性能。

Property属性组成

Android 的系统属性包括两部分:文件保存的持久属性和每次开机导入的cache属性。
前者主要保存在prop文件中,需要注意的是android属性的名称是有一定的格式要求的

system/core/init/property_service.c

#定义的前缀
属性名以ro.开头,该属性被视为只读属性,一旦设置属性值不能改变
属性名以persist.开头,该属性值将写入/data/property
属性名以net.开头,当设置这个属性时,“net.change”属性将会自动设置,以加入到最后修改的属性名
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
bionic/libc/include/sys/_system_properties.h

//系统的prop属性文件
#define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
#define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
#define PROP_PATH_VENDOR_BUILD     "/vendor/build.prop"
#define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"
#define PROP_PATH_FACTORY          "/factory/factory.prop" 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

后者则通过frameworks/base/core/java/android/os/SystemProperties.java的接口定义

private static native String native_get(String key);
private static native String native_get(String key, String def);
private static native int native_get_int(String key, int def);
private static native long native_get_long(String key, long def);
private static native boolean native_get_boolean(String key, boolean def);
private static native void native_set(String key, String def);
private static native void native_add_change_callback();
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

该接口类在初始化运行环境中注册对应的cpp接口android_os_SystemProperties.cpp,实际操作通过JNI调用的是cpp文件对应的接口frameworks/base/core/jni/AndroidRuntime.cpp

关于build.prop生成过程的分析,可知属性的来源:

  • buildinfo.sh:系统默认属性一般是build/tool/buildinfo.sh,编译时写到文件build.prop
  • system.prop:
  • ADDITIONAL_BUILD_PROPERTIES或PRODUCT_PROPERTY_OVERRIDES:

一般我们自定义属性就在对应的项目下device/$(TARGET_DEVICE_DIR)/system.prop 定义自己的属性即可,建议修改属性在system.propPRODUCT_PROPERTY_OVERRIDES,这对应于具体特定平台或产品的修改。

Property属性加载

init.cpp文件main函数中会调用start_property_service(),而它分别调用load_properties_from_file()读取到.prop文件,存放系统属性的文件并设置到系统属性。同时会调用load_persistent_properties函数,该函数会在/data/property/中寻找用户的保存设置。

system/core/init/property_service.c
//属性服务启动后会从系统文件中读取默认的属性,并写入共享内存中,以下prop文件为按顺序读取
//后读入的属性将覆盖前面读取的相同的属性
void start_property_service(void)
{
    int fd; 
    load_properties_from_file(PROP_PATH_SYSTEM_BUILD);
    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);
	#ifdef ALLOW_LOCAL_PROP_OVERRIDE
    load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);
	#endif /* ALLOW_LOCAL_PROP_OVERRIDE */
    /* Read persistent properties after all default values have been loaded. */
    load_persistent_properties(); 
    update_legacy_atvc_properties();
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

开机过程中Loading properties顺序:

01-01 08:05:27.884     0     0 I init    : (Loading properties from /default.prop took 0.00s.)
01-01 08:05:29.509     0     0 I init    : (Loading properties from /persist/speccfg/vendor_ro.prop took 0.01s.)
01-01 08:05:29.511     0     0 I init    : (Loading properties from /system/vendor/vendor.prop took 0.00s.)
01-01 08:05:29.511     0     0 I init    : (Loading properties from /system/vendor/Default/system/vendor/vendor.prop took 0.00s.)
01-01 08:05:29.511     0     0 I init    : (Loading properties from /persist/speccfg/vendor_persist.prop took 0.00s.)
01-01 08:05:29.512     0     0 I init    : (Loading properties from /system/vendor/default.prop took 0.00s.)
01-01 08:05:29.512     0     0 I init    : (Loading properties from /system/vendor/power.prop took 0.00s.)
01-01 08:05:29.512     0     0 I init    : (Loading properties from /system/build.prop took 0.01s.)
01-01 08:05:29.512     0     0 I init    : (Loading properties from /vendor/build.prop took 0.00s.)
01-01 08:05:29.512     0     0 I init    : (Loading properties from /factory/factory.prop took 0.00s.)
01-01 00:05:29.490     0     0 I init    : (Loading properties from /system/vendor/Default/system/vendor/vendor.prop took 0.00s.)
...
01-01 08:05:30.351     0     0 E init    : load persistent properties start
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

我在load_persist_props()中加了log,可以发现加载persistent properties属性会有延迟,之前遇到一个项目的时候发现的在开机动画之后才加载persistent properties

system/core/init/property_service.cpp

void load_persist_props(void) {
     load_override_properties();
     /* Read persistent properties after all default values have been loaded. */
+    ERROR("load persistent properties start\n");
     load_persistent_properties();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
ADB设置使用Property

getprop读值
setprop设值

C:\Users\Admin>adb shell
trinket:/ $ su
trinket:/ # getprop qemu.hw.mainkeys
1
trinket:/ # setprop qemu.hw.mainkeys 0
  • 1
  • 2
  • 3
  • 4
  • 5
Property属性使用get/set
  • The Java API
import android.os.SystemProperties;
public static String get(String key, String def) {}
public static void set(String key, String val) {}

//示例
//Systemproperties类在android.os下,但这个类是隐藏的,上层程序开发无法直接使用
//需要系统属性设置的程序也必须有system或root权限,或者用Java的反射机制
需要注意的是android属性的名称是有一定的格式要求的,前缀必须用system\core\init\property_service.c中定义的前缀(后面会详细列出),
Systemproperties.set(name, value);//设置
Systemproperties.get(name);//读取
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • The Native API
#include <cutils/properties.h>
int property_get(const char *key, char *value, const char *default_value); 
int property_set(const char *key, const char *value);

//示例
//property_get有三个参数,第2个参数为数组,表示将get到的值放入此数组中,第3个参数为默认值,如果property_get读不到某属性(未定义此属性),则取默认值
char buf[20]="ssssssssssss";
char tempbuf[PROPERTY_VALUE_MAX];
property_set("phone.imei",buf);
property_get("phone.imei",tempbuf,"0");
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
属性相关

设置属性,ro.开头的属性将不能被更改属性值,persist.开头的属性会被永久纪录,其他属性值在重新开机后均将被丢弃:
int property_set(const char *name, const char *value)

当用户设置属性时,如果以属性名字以persist.开头,则会同时在/data/property目录下创建以该属性名字命名的文件,并写入属性值
#define PERSISTENT_PROPERTY_DIR “/data/property”
static void write_persistent_property(const char *name, const char *value)

加载永久属性时,会读入在目录/data/property下所有名字以persist.开头的文件内容,作为该名字对应的属性值
static void load_persistent_properties()

Android的启动后,在property_service.c的property_init中完成prop的初始化。系统中存在着几个文件,如build.prop和default.prop等,这些文件在系统构建时候生成的,里面包含很多系统的配置。系统开机时回去加载这些文件中的信息并保存到prop模块(内存)中去,以便其它程序进行读取和使用。

所有的persist类型的属性都是在/data/property/目录下以文件形式存在。

Env环境变量中有一个ANDROID_PROPERTY_WORKSPACE变量,该变量中存储着prop内存区域的大小,可查阅init_property_area()。

通过ps我们可以查到一些应用的USDER ID为system,radio,AID_USER + app_id ,如果我们碰到设置系统属性不成功,就可以升级应用用户属性来提升用户操作权限。

属性设置的两个地方:一个是配置文件读取的,一个是系统动态获取的

相关参考

https://blog.csdn.net/wdong_love_cl/article/details/52404692
Android 系统属性SystemProperty分析
MTK Android Framework用SystemProperties通过JNI调用访问系统属性
Android SystemProperties简介
Android SystemProperties设置/取得系统属性的用法总结
Android属性之build.prop生成过程

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/265081
推荐阅读
相关标签
  

闽ICP备14008679号