您的位置:首页 > 其它

安卓系统属性值相关介绍

2017-07-10 20:50 134 查看
安卓系统中的系统属性值包括两个部分:文件保存的持久属性和每次开机导入的cache属性。可以在build.prop文件中看到,即out/target/product/~/system/build.prop(以ro.开头的系统属性值具有只读属性)。如下:



1.系统属性值类型及特点

①以“ro.”开头,具有只读属性。一旦设置,属性值不能再改变。

②以“persist.”开头。当设置这个属性值时,其值将写入/data/property。

③以“net.”开头。当设置这个属性值时,“net.change”属性将会自动设置,以加入到最后修改的属性名

④属性“ctrl.start”和“ctrl.stop”是用来启动和停止服务的。

2.使用adb
操作系统属性值

adb shell prop                                                                                 可以查看安卓系统的系统属性

adb shell getprop 属性名                获取单个系统属性值

adb shell setprop 属性名 新的属性值             设置新的属性值(对于非只读属性)

 

3.build.prop文件生成过程

build/core/Makefile相关变量定义:

intermediate_system_build_prop := $(call intermediates-dir-for,ETC, system_build_prop)/build.prop
//  obj下的路径out/target/product/~/obj/ETC/system_build_prop_intermediates/build.prop


INSTALLED_BUILD_PROP_TARGET := $(TARGET_OUT)/build.prop
// system下的路径,即out/target/product/~/system/builg.prop

BUILDINFO_SH := build/tools/buildinfo.sh


build.prop文件中的系统属性值主要包括三个部分—buildinfo.sh文件中的值,systen.prop文件中的值以及ADDITIONAL_BUILD_PROPERTIES:

相关Makfile中的target:

(1) system/build.prop

$(INSTALLED_BUILD_PROP_TARGET): $(intermediate_system_build_prop)
$(INSTALLED_RECOVERYIMAGE_TARGET)
@echo "Target build info: $@"
$(hide) cat $(intermediate_system_build_prop) > $@
// 将etc下build.prop中的值写入system下的build.prop文件中
ifdef INSTALLED_RECOVERYIMAGE_TARGET
$(hide) echo ro.expect.recovery_id=`cat $(RECOVERYIMAGE_ID_FILE)`


(2) etc/system_build_prop_intermediates/build.prop

$(if $(ADDITIONAL_BUILD_PROPERTIES), \
$(hide) echo >> $@; \
echo "#" >> $@; \
echo "# ADDITIONAL_BUILD_PROPERTIES" >> $@; \
echo "#" >> $@; )
$(hide) $(foreach line,$(ADDITIONAL_BUILD_PROPERTIES), \
echo "$(line)" >> $@;)
$(hide) cat $(INSTALLED_ANDROID_INFO_TXT_TARGET) | grep 'require version-' | sed -e 's/require version-/ro.build.expect./g' >> $@
$(hide) build/tools/post_process_props.py $@
$(PRODUCTS.$(INTERNAL_PRODUCT).PRODUCT_SYSTEM_PROPERTY_BLACKLIST)


(3)build/tools/buildinfo.sh

buildinfo.sh中主要是echo一些属性:

echo "ro.build.id=$BUILD_ID"
echo "ro.build.display.id=$BUILD_DISPLAY_ID"
echo "ro.build.version.incremental=$BUILD_NUMBER"
echo "ro.build.version.sdk=$PLATFORM_SDK_VERSION"
echo "ro.build.version.preview_sdk=$PLATFORM_PREVIEW_SDK_VERSION"
echo "ro.build.version.codename=$PLATFORM_VERSION_CODENAME"
echo "ro.build.version.all_codenames=$PLATFORM_VERSION_ALL_CODENAMES"
........
echo "ro.product.model=$PRODUCT_MODEL"
echo "ro.product.brand=$PRODUCT_BRAND"
echo "ro.product.name=$PRODUCT_NAME"
echo "ro.product.device=$TARGET_DEVICE"
echo "ro.product.board=$TARGET_BOOTLOADER_BOARD_NAME"


4.系统属性值的使用

①Java文件中

获取系统属性值,例如:

String newBuildId = SystemProperties.get("ro.build.id", null);


修改系统属性值,例如:

private static final String PROPERTY_BOOT_SOUNDS = "persist.sys.bootanim.play_sound";
SystemProperties.set(PROPERTY_BOOT_SOUNDS, mBootSounds.isChecked() ? "1" : "0");


②Native代码

获取系统属性值,例如:

property_get("bluetooth.mock_stack", value, "");


设置系统属性值:

property_set("ctl.start", "surfaceflinger");
property_set("persist.sys.actionsafe.width", actionsafeWidth);


5.系统属性值设置分析

开机导入的cache属性主要是通过frameworks/base/core/java/android/os/SystemProperties.java的接口定义

private static native void native_set(String key, String def);

public static void set(String key, String val) {
if (key.length() > PROP_NAME_MAX) {
throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);
}
if (val != null && val.length() > PROP_VALUE_MAX) {
throw new IllegalArgumentException("val.length > " +
PROP_VALUE_MAX);
}
native_set(key, val);
}


native_set()实际操作通过JNI调用的是cpp文件对应的接口:

frameworks/base/core/jni/android_os_SystemProperties.cpp

static const JNINativeMethod method_table[] = {
{
……
"native_set", "(Ljava/lang/String;Ljava/lang/String;)V",
(void*) SystemProperties_set },
……
}

int register_android_os_SystemProperties(JNIEnv *env)
{
return RegisterMethodsOrDie(env, "android/os/SystemProperties", method_table,
NELEM(method_table));
}
static void SystemProperties_set(JNIEnv *env, jobject clazz,
jstring keyJ, jstring valJ)
{
int err;
const char* key;
const char* val;

if (keyJ == NULL) {
jniThrowNullPointerException(env, "key must not be null.");
return ;
}
key = env->GetStringUTFChars(keyJ, NULL);

if (valJ == NULL) {
val = "";       /* NULL pointer not allowed here */
} else {
val = env->GetStringUTFChars(valJ, NULL);
}

err = property_set(key, val);
env->ReleaseStringUTFChars(keyJ, key);
if (valJ != NULL) {
env->ReleaseStringUTFChars(valJ, val);
}

if (err < 0) {
jniThrowException(env, "java/lang/RuntimeException",
"failed to set system property");
}
}


system/core/init/property_service.cpp

int property_set(const char* name, const char* value) {
int rc = property_set_impl(name, value);
if (rc == -1) {
ERROR("property_set(\"%s\", \"%s\") failed\n", name, value);
}
return rc;
}


设置key的value时,需要鉴定属性值的权限,Android5.0以后的系统中使用SELinux进行权限管理。

system/core/init/property_service.cpp

static int check_mac_perms(const char *name, char *sctx, struct ucred *cr)
{                          									      // 判断请求进程是否有权限修改属性值
char *tctx = NULL;
int result = 0;
property_audit_data audit_data;

……

audit_data.name = name;
audit_data.cr = cr;

if (selinux_check_access(sctx, tctx, "property_service", "set", reinterpret_cast<void*>(&audit_data)) == 0)
// 检查property_contexts中是否定义了目标sctx,将源sctx和目标tctx进行比较,判断是否具有相关权限,sctx是调用set操作进程的sContext
result = 1;

freecon(tctx);
err:
return result;
}


external/sepolicy/ property_contexts

##########################
# property service keys
net.rmnet0              u:object_r:radio_prop:s0
net.gprs                u:object_r:radio_prop:s0
net.ppp                 u:object_r:radio_prop:s0
// 表示只有有权限访问Type为radio_prop的资源的进程可以访问
……
gsm.                    u:object_r:radio_prop:s0
net.                    u:object_r:system_prop:s0
dev.                    u:object_r:system_prop:s0
// 表示只有有权限访问Type为system_prop的资源的进程可以访问
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: