Android7.1 属性:Build.BRAND Build.MODEL Build.DEVICE Build.BOARD Build.PRODUCT Build.MANUFACTURER
进入build仓库,查看build/core/Makefile ,发现第197行用到build/tool/buildinfo.sh写prop属性
# Accepts a whitespace separated list of product locales such as
# (en_US en_AU en_GB...) and returns the first locale in the list with
# underscores replaced with hyphens. In the example above, this will
# return "en-US".
define get-default-product-locale
$(strip $(subst _,-, $(firstword $(1))))
endef
BUILDINFO_SH := build/tools/buildinfo.sh
# TARGET_BUILD_FLAVOR and ro.build.flavor are used only by the test harness to distinguish builds.
TARGET_BUILD_FLAVOR := $(TARGET_PRODUCT)-$(TARGET_BUILD_VARIANT)
ifdef SANITIZE_TARGET
TARGET_BUILD_FLAVOR := $(TARGET_BUILD_FLAVOR)_asan
endif
\build\tools,修改build/tool/buildinf.sh 即可
属性:Build.HARDWARE
\system\core\init\init.cpp init进程里的main 函数 显示把内核属性导出来,然后开启property_service服务
//做一些初始化并将内核属性导入system_property服务里
if (!is_first_stage) {
// Indicate that booting is in progress to background fw loaders, etc.
close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000));
property_init();
// If arguments are passed both on the command line and in DT,
// properties set in DT always have priority over the command-line ones.
process_kernel_dt();
process_kernel_cmdline();
//add by xzj to set ro.rk.soc read from /proc/cpuinfo if not set
set_soc_if_need();
// Propagate the kernel variables to internal variables
// used by init as well as the current required properties.
export_kernel_boot_props();
}
.....................................
//开启property_service 服务
start_property_service();
到system\core\init\property_service.cpp里开启服务
void start_property_service() {
property_set_fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK,
0666, 0, 0, NULL);
if (property_set_fd == -1) {
ERROR("start_property_service socket creation failed: %s\n", strerror(errno));
exit(1);
}
listen(property_set_fd, 8);
register_epoll_handler(property_set_fd, handle_property_set_fd);
}
到rameworks\base\core\jni\android_os_SystemProperties.cpp 修改返回的属性
static jstring SystemProperties_getSS(JNIEnv *env, jobject clazz,
jstring keyJ, jstring defJ)
{
int len;
const char* key;
char buf[PROPERTY_VALUE_MAX];
jstring rvJ = NULL;
if (keyJ == NULL) {
jniThrowNullPointerException(env, "key must not be null.");
goto error;
}
key = env->GetStringUTFChars(keyJ, NULL);
len = property_get(key, buf, "");
if ((len <= 0) && (defJ != NULL)) {
rvJ = defJ;
} else if (len >= 0) {
//----以下是老的代码
rvJ = env->NewStringUTF(buf);
//----以下是老的代码
//+++++++以下是添加的代码+++++++++++
jstring temp = env->NewStringUTF("ro.hardware");
const char *key2=env->GetStringUTFChars(temp, NULL);
if (strcmp(key,key2) == 0 ) {
rvJ = env->NewStringUTF("qcom");
} else {
rvJ = env->NewStringUTF(buf);
}
//+++++++以下是添加的代码+++++++++++
} else {
rvJ = env->NewStringUTF("");
}
env->ReleaseStringUTFChars(keyJ, key);
error:
return rvJ;
}
注意:\system\core\init\property_service.cpp ro属性只能设置一次
static int property_set_impl(const char* name, const char* value) {
size_t namelen = strlen(name);
size_t valuelen = strlen(value);
if (!is_legal_property_name(name, namelen)) return -1;
if (valuelen >= PROP_VALUE_MAX) return -1;
if (strcmp("selinux.reload_policy", name) == 0 && strcmp("1", value) == 0) {
if (selinux_reload_policy() != 0) {
ERROR("Failed to reload policy\n");
}
} else if (strcmp("selinux.restorecon_recursive", name) == 0 && valuelen > 0) {
if (restorecon_recursive(value) != 0) {
ERROR("Failed to restorecon_recursive %s\n", value);
}
}
prop_info* pi = (prop_info*) __system_property_find(name);
if(pi != 0) {
/* ro.* properties may NEVER be modified once set */
ro属性只能设置一次
if(!strncmp(name, "ro.", 3)) return -1;
__system_property_update(pi, value, valuelen);
} else {
int rc = __system_property_add(name, namelen, value, valuelen);
if (rc < 0) {
return rc;
}
}
/* If name starts with "net." treat as a DNS property. */
if (strncmp("net.", name, strlen("net.")) == 0) {
if (strcmp("net.change", name) == 0) {
return 0;
}
/*
* The 'net.change' property is a special property used track when any
* 'net.*' property name is updated. It is _ONLY_ updated here. Its value
* contains the last updated 'net.*' property.
*/
property_set("net.change", name);
} else if (persistent_properties_loaded &&
strncmp("persist.", name, strlen("persist.")) == 0) {
/*
* Don't write properties to disk until after we have read all default properties
* to prevent them from being overwritten by default values.
*/
write_persistent_property(name, value);
}
property_changed(name, value);
return 0;
}