Android property system / service and how android sets and gets properties

Each property has a name and value, and they are all in string format. Each process can get/set properties. When the system is initialised, Android will allocate a shared memory area to store the properties. These are done by the “init” daemon. The “init” daemon will start an android property service.

platform/system/core/init/init.c

int main(int argc, char **argv)
{
    queue_builtin_action(property_service_init_action, "property_service_init");
}

static int property_service_init_action(int nargs, char **args)
{
    /* read any property files on system or data and
     * fire up the property service.  This must happen
     * after the ro.foo properties are set above so
     * that /data/local.prop cannot interfere with them.
     */
    start_property_service();
    return 0;
}

platform/system/core/init/property_service.c

#define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
#define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
#define PROP_PATH_SYSTEM_DEFAULT   "/system/default.prop"
#define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"

void start_property_service(void)
{
    int fd;
    load_properties_from_file(PROP_PATH_SYSTEM_BUILD);
    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);
    load_override_properties();
    /* Read persistent properties after all default values have been loaded. */
    load_persistent_properties();
    fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);
    if(fd < 0) return;
    fcntl(fd, F_SETFD, FD_CLOEXEC);
    fcntl(fd, F_SETFL, O_NONBLOCK);
    listen(fd, 8);
    property_set_fd = fd;
}

platform/system/core/libcutils/properties.c

int property_set(const char *key, const char *value)
{
    return __system_property_set(key, value);
}
int property_get(const char *key, char *value, const char *default_value)
{
    int len;
    len = __system_property_get(key, value);
    if(len > 0) {
        return len;
    }

    if(default_value) {
        len = strlen(default_value);
        memcpy(value, default_value, len + 1);
    }
    return len;
}

platform/bionic/libc/bionic/system_properties.c

int __system_property_get(const char *name, char *value)
{
    const prop_info *pi = __system_property_find(name)
    if(pi != 0) {
        return __system_property_read(pi, 0, value);
    } else {
        value[0] = 0;
        return 0;
    }
}

int __system_property_set(const char *key, const char *value)
{
    int err;
    prop_msg msg;
    if(key == 0) return -1;
    if(value == 0) value = "";
    if(strlen(key) >= PROP_NAME_MAX) return -1;
    if(strlen(value) >= PROP_VALUE_MAX) return -1;
    memset(&msg, 0, sizeof msg);
    msg.cmd = PROP_MSG_SETPROP;
    strlcpy(msg.name, key, sizeof msg.name);
    strlcpy(msg.value, value, sizeof msg.value);
    err = send_prop_msg(&msg);
    if(err < 0) {
        return err;
    }
    return 0;
}

init.rc
setprop
Set system property name to value. Properties are expanded within value.

wait_for_prop
Wait for system property name to be value. Properties are expanded within value. If property name is already set to value, continue immediately.

Leave a Comment