Android Systemproperties System Properties Detailed

Source: Internet
Author: User

Systemproperties class in the Android.os, but this class is hidden, the upper program development can not be used directly, with the Java reflection mechanism can be.
Java code to create and modify Android properties with Systemproperties.set (name, value), get Android properties with Systemproperties.get (name),
Native code through Property_get (const char *key, char *value, const char *default_value)/property_set (const char *name, const CHA R *value) to read and set properties. It is important to note that the name of the Android attribute is in a certain format, and the prefix must be system\core\init\property_ The prefixes defined in the SERVICE.C (which are listed later), the program that makes the system property settings must have either system or root permissions, how to elevate the Android program permissions to the system permissions? The method is like this:
1, in the Androidmanifest.xml, add android:shareduserid= "Android.uid.system".
2, in Android.mk, set local_certificate: = platform.
Note: Using Property_get/property_set, these two APIs must contain header files Cutils/properties.h and link libcutils libraries.
The shell script in Android provides command-line tools SetProp and Getprop to set and get properties. Usage Example: Getprop sys.settingkeys.disabled,setprop sys.settingkeys.disabled 1
The usage is finished, how is it simple? Let's take a look at the process of reading and setting system properties:
Read properties:
Native_get () [Systemproperties.java]
Property_get () [Android_os_systemproperties.cpp]-->__system_property_read () [SYSTEM_PROPERTIES.C]
In \BIONIC\LIBC\BIONIC\SYSTEM_PROPERTIES.C:
int __system_property_get (const char *name, char *value) {    ///data is already stored in shared memory and can be obtained by __system_property_area__. After waiting for the read to return    const Prop_info *PI = __system_property_find (name);    Return __system_property_read (pi, 0, value);//Blocking Read}
Set properties (client):
Native_set () [Systemproperties.java]
__system_property_set () [SYSTEM_PROPERTIES.C]-->send_prop_msg () [SYSTEM_PROPERTIES.C]
int __system_property_set (const char *key, const char *value) {    msg.cmd = Prop_msg_setprop;    strlcpy (Msg.name, key, sizeof msg.name);    strlcpy (msg.value, value, sizeof msg.value);    Err = send_prop_msg (&msg);} Send a message to notify Property_service to start the service or set the property static int send_prop_msg (Prop_msg *msg) {    //communicate with/dev/socket/property_service    s = socket (af_local, sock_stream, 0);    Connect (s, (struct sockaddr *) &addr, Alen)    send (S, msg, sizeof (PROP_MSG), 0)    close (s);}
It can be seen that the Read property is simple, is to read the data in the shared memory directly through __system_property_read, and the setting property is to send the socket message through the client so that Property_service can start the service or set properties.
Server-side:
\system\core\init\init.c
int main (int argc, char **argv) {    //joins to the action queue queue    queue_builtin_action (property_service_init_action, " Property_service_init ");//Add the property system initialization function to the action queue queue_builtin_action (property_init_action," Property_init ") ;...    for (;;)        Execute action Queue        //Receive data sent via socket to property service        NR = Poll (UFDs, Fd_count, timeout);        ... HANDLE_PROPERTY_SET_FD ();} static int property_service_init_action (int nargs, char **args) {    start_property_service ();} void property_changed (const char *name, const char *value) {  if (property_triggers_enabled) {  queue_property_ Triggers (name, value);  Drain_action_queue ();  }}
\SYSTEM\CORE\INIT\PROPERTY_SERVICE.C:
void Property_init (bool load_defaults) {    //Initialize shared memory space    Init_property_area ();    Load Properties File  load_properties_from_file (prop_path_ramdisk_default);}

\bionic\libc\bionic\system_properties.c

static int Init_property_area (void) {//Create anonymous memory space pa_size = 32768 init_workspace (&pa_workspace, pa_size)//Will        The memory area is divided into two parts: the property system basic information and the attribute key value pair Pa_info_array = (void*) (((char*) pa_workspace.data) + Pa_info_start);    Initialize the property system Information PA = pa_workspace.data;    memset (PA, 0, pa_size);    Pa->magic = Prop_area_magic;    Pa->version = prop_area_version; /* Plug into the Lib property services each process uses this variable, pointing to the system properties shared memory area, accessing system Properties, important/__system_property_area__ = PA;} static int init_workspace (workspace *w, size_t size) {//dev is a TMPFS is a virtual memory file system int FD = open ("/dev/__properties__ ", O_RDWR |    O_creat, 0600); Map files to shared process space memory so that they can be consistent with how memory is manipulated void *data = Mmap (NULL, size, Prot_read |    Prot_write, map_shared, FD, 0);        Close (FD);    Delete file FD = open ("/dev/__properties__", o_rdonly);    Unlink ("/dev/__properties__"); Save FD size will be passed as an environment variable to each process W->data = data; w->size = size; W->FD = FD;} static void Load_properties_from_file (const char *FN) {    Read System attribute key value writes data to the shared memory. Data = Read_file (FN, &sz); Load_properties (data);} void Start_property_service (void) {//Load property profile, the loaded property overrides the original value.    After these properties are loaded, the last loaded properties are persisted in/data/property.    Load_properties_from_file (Prop_path_system_build);    Load_properties_from_file (Prop_path_system_default);    Load_properties_from_file (Prop_path_local_override);        Load_persistent_properties ();    Create a socket resource and bind FD = Create_socket (Prop_service_name, Sock_stream, 0666, 0, 0); Monitor Listen (FD, 8);}    void Handle_property_set_fd () {//wait to establish communication s = Accept (property_set_fd, (struct sockaddr *) &addr, &addr_size);    Get socket related Information UID GID getsockopt (S, Sol_socket, so_peercred, &CR, &cr_size);    Receive property settings Request message recv (s, &msg, sizeof (msg), 0); Process message switch (msg.cmd) {case Prop_msg_setprop://Process CTL by setting System Properties. The start message if (MEMCMP (Msg.name, "ctl.", 4          ) = = 0) {//permission detection if (Check_control_perms (Msg.value, Cr.uid, Cr.gid))   {handle_control_message (char*) Msg.name + 4, (char*) msg.value);                }} else {//Change system property value if (Check_perms (Msg.name, Cr.uid, Cr.gid)) {            Property_set ((char*) Msg.name, (char*) msg.value);    }} break; } close (s);}    void Handle_control_message (const char *msg, const char *arg) {if (!STRCMP (msg, "start")) {Msg_start (ARG);    } else if (!STRCMP (msg, "Stop")) {msg_stop (ARG);        } else if (!STRCMP (msg, "restart")) {msg_stop (ARG);    Msg_start (ARG); }}static void Msg_start (const char *name) {Service_start (svc, args);}    void Service_start (struct service *svc, const char *dynamic_args) {//create process PID = fork (); if (PID = = 0) {if (properties_inited ()) {///Get System attribute Space file Description Get_property_workspace (&FD, &am            P;SZ);            DUP minimum available file descriptor sprintf (tmp, "%d,%d", DUP (FD), SZ); Join Android_property_workSpace environment variable to env//contains shared memory fd add_environment ("Android_property_workspace", TMP);        }//Execute program PASS environment variable env EXECVE (Svc->args[0], (char**) Svc->args, (char**) ENV)//Set Service System Properties    Notify_service_state (Svc->name, "running");   }}void get_property_workspace (int *fd, int *sz) {*fd = PA_WORKSPACE.FD; *sz = pa_workspace.size;}

in the BIONIC\LIBC\BIONIC\LIBC_INIT_DYNAMIC.C:
Mapping system property memory space to the current process virtual space, the process will load the dynamic library Bionic libc Library when it starts: void __attribute__ ((constructor)) __libc_preinit (void);          void __libc_preinit (void) {       __libc_init_common (elfdata);} void __libc_init_common (uintptr_t *elfdata) {    __system_properties_init ();} int __system_properties_init (void) {    Prop_area *pa;    int s, FD;        unsigned sz;        char *env;    Get environment variable Android_property_workspace//set corresponding    env = getenv ("Android_property_workspace") with the above Init process;    Shared memory file descriptor memory size    FD = atoi (env);    SZ = atoi (env + 1);    Maps a file descriptor to the current process virtual space memory, implementing shared memory    PA = mmap (0, SZ, Prot_read, map_shared, FD, 0);    Global variables point to shared System Properties memory header address    __system_property_area__ = PA;}
static int check_perms (const char *name, unsigned int uid, unsigned int gid) {//permission detection for (i = 0; Property_perms[i] . prefix;        i++) {int tmp; if (strncmp (Property_perms[i].prefix, Name, strlen (property_perms[i].prefix)) = = 0) {if (U                ID && property_perms[i].uid = = UID) | | (gid && Property_perms[i].gid = = gid))            {return 1; }}} return 0;} Property_perms[] = {"Net.rmnet0.",      aid_radio,    0},    {"Net.gprs.", &nbs P      aid_radio,    0},    {"NET.PPP",          aid_radio, &N Bsp  0},    {"Ril.",             Aid_radio,    0},    {"G Sm.,             Aid_radio,    0},    {"Persist.radio",     Aid_radio,    0},    {"Net.dns ",          aid_radio,    0},    {" net. ",       &NBSP ;     Aid_system,   0},    {"Dev.",             Aid_system,   0},    {"Runtime.",         Aid_system,   0},    {"HW.",     &N Bsp        aid_system,   0},    {"sys.",             Aid_sy STEM,   0},    {"Service.",         Aid_system,   0},    {"WLAN.", & nbsp          aid_system,   0},    {"DHCP.",           &NBSP ; Aid_system,   0},    {"DHCP.",            AID_DHCP,     0},&nbsp ;   {"VPN.",             Aid_system,   0},    {"VPN.",     &N Bsp &nbSp     AID_VPN      0},    {"Debug.",           Aid_shell, &NB Sp  0},    {"Log.",             Aid_shell,    0},    {"s Ervice.adb.root ", Aid_shell,    0},    {" Persist.sys. ",     Aid_system,   0},    {"Persist.service.", Aid_system,   0},    {"persist.security.", Aid_system,   0},  &NB Sp {NULL, 0, 0}}; int Property_set (const char *name, const char *value) {property_changed (name, value); return 0;}
The relevant macro definitions used above are defined here:
Bionic/libc/include/sys/_system_properties.h
#define PROP_SERVICE_NAME "Property_service" #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"

And here system/core/include/private/android_filesystem_config.h.

#define AID_SYSTEM        /  * * SYSTEM server */#define AID_RADIO         1001/  * Telephony subsystem, RIL */#define Aid_dhcp          1014/  * DHCP client */#define AID_VPN           1016/  * VPN system */#define AID_SHELL/  * ADB and debug Shell user */

The code is a bit long, specifically to explain that this code has done God horse ~

Init Main ()
1, Property_init
Initializes the shared memory space, which is to map the file (/dev/__properties__) to the shared process space memory so that it can be consistent with the operating memory, and __system_property_area__ points to the System Properties shared memory area. Each process will use this variable.
Loads the property profile (/default.prop) and writes it to shared memory.
2, Start_property_service
Load the property profile, the loaded properties will overwrite the original values, and after these properties are loaded, the last loaded properties are persisted in/data/property and written to shared memory.
The order is:
/system/build.prop
/system/default.prop
/data/local.prop
It then creates the socket Property_service and listens for messages from the client.
3, HANDLE_PROPERTY_SET_FD
There is a dead loop inside main () that keeps getting the message out and then using HANDLE_PROPERTY_SET_FD to do what the function does: if you receive a PROP_MSG_SETPROP message,
If you are using the CTL. Start message, then it is used to start and shut down the service, the shutdown/start services are in the new process, the shared memory of the FD is added to the environment variables.
For example:
Start boot animation
Property_set ("Ctl.start", "Bootanim");
Of course, it is also possible to indicate whether the service is started at boot time in init.rc, such as:
Service ADBD/SBIN/ADBD
Class Core
Disabled//does not start automatically
If it is not a message starting with the CTL, it is setting the system property value.
To facilitate understanding, the previous picture:

(Image from Network)
We can see that the Android property system consists of three processes, a set of properties files, and a piece of shared memory. This shared memory holds all the attribute records in the system, only the property service can write the shared memory, and the property service is responsible for loading the attribute records in the properties file into shared memory.
The attribute read process (property consumer) maps this shared memory to its own process space and then reads it directly.
The properties set process (property setter) also loads this share into his process space, but he cannot directly write this piece of shared memory. When he needs to add or modify attributes, the property service,property service will write to the shared memory and properties file on behalf of the setup process through the UNIX socket.
The property service runs in the INIT process. The init process first creates a piece of shared memory and stores his handle FD in this memory, and the INIT process maps the memory to his virtual space by mmap the system call with the MAP_SHARE flag, and eventually all of this memory's updates will be seen by all the processes that map this shared memory. The shared memory handle FD and the shared memory size are stored in the system environment variable "android_property_workspace", and all processes including the property setting process and the property read process will obtain the handle FD and size of the shared memory through this system environment variable, This memory is then mapped to their own virtual space. The init process then loads the properties from the following files:
/default.prop
/system/build.prop
/system/default.prop
/data/local.prop
The next step is to start the property service. In this step, you will create a UNIX socket server, which has a well-known name of "/dev/socket/property_service". Finally Init enters the dead loop, waiting for the connection request of the socket.
In the read process, when it initializes the LIBC library, it gets the handle and size of the property system shared memory (BIONIC/LIBC/BIONIC/LIBC_INIT_COMMON.C __libc_init_common function). and map this shared memory to its own process virtual space (bionic/libc/bionic/system_properties.c __system_properties_init function). This allows the read process to access the shared memory of the property system as if it were accessing normal memory.
Finally, to an extension:
If the property name is "Ro." Begins, then this property is treated as a read-only property. Once set, the property value cannot be changed.
If the property name is "persist." At the beginning, when this property is set, its value is also written to/data/property.
If the property name is in "net." At the beginning, when this property is set, the "Net.change" property is automatically set to add to the last modified property name. (This is very ingenious.) The Netresolve module uses this property to track any changes on the Net.* property. )
The properties "Ctrl.start" and "ctrl.stop" are used to start and stop the service.
Reference Documentation:
Http://www.cnblogs.com/bastard/archive/2012/10/11/2720314.html
http://blog.csdn.net/ameyume/article/details/8056492

Android Systemproperties System Properties Detailed

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.