The Init property service is like the registry of Windows, where apps can manipulate information for property operations
The following describes the principle of the property service:
Property Key methods:
*void property_init (void) >> analysis
void Property_init (void) { init_property_area ();} static int Init_property_area (void) {Prop_area *pa;//Create shared memory if (Init_workspace (&pa_workspace, pa_size)) return-1;/** Set the space size and other information *///the system automatically calls the __libc_prenit function to complete the work of shared memory to the local process __system_property_area__ = PA;
Notifying other processes
void __libc_preinit (void) {__libc_init_common (elfdata);} void __libc_init_common (uintptr_t *elfdata) {__system_properties_init ();} int __system_properties_init (void) {///Remove INIT Create environment variable get file descriptor env = getenv ("Android_property_workspace"); FD = atoi (env);//Map init created memory to local process space//so that other processes can share this memory//here the client can only do read operation PA = mmap (0, SZ, Prot_read, map_shared, FD, 0);}
*void start_property_service (void) >> analysis
1) Load the properties file into the attribute space and create the scoket.
*void Start_property_service (void) {//Load Properties file Load_properties_from_file (prop_path_system_build); Load_properties_from_file (Prop_path_system_default); Load_override_properties ();//Load Persistent file load_persistent_properties ();//Create SOCKETFD = Create_socket (prop_service_ NAME, Sock_stream, 0666, 0, 0);} Init.c::int Main () {nr = Poll (UFDs, Fd_count, timeout); if (ufds[i].revents = = Pollin) { if (ufds[i].fd = = Get_property_ SET_FD ()) handle_property_set_fd ();}}}
2) The main function waits for other processes to call on the Scoket and make the processing modification properties
void Handle_property_set_fd () {//Receive scoket if (s = Accept (property_set_fd, (struct sockaddr *) &addr, &addr_size )) < 0) {return; }//Remove the permission properties of the process if (getsockopt (S, Sol_socket, so_peercred, &CR, &cr_size) < 0) {close (s); Return }//receives data R = Temp_failure_retry (recv (S, &msg, sizeof (msg), 0)); if (memcmp (Msg.name, "ctl.", 4) = = 0) {//ctl.* Control messages//such as SetProp Ctl.start Bootanim close (s); if (Check_control_perms (Msg.value, Cr.uid, Cr.gid, Source_ctx)) {handle_control_message (char*) Msg.name + 4, (char*) msg.value); } else {ERROR ("sys_prop:unable to%s service ctl [%s] uid:%d gid:%d pid:%d\n", msg . name + 4, Msg.value, Cr.uid, Cr.gid, cr.pid); }} else {//check permissions if (Check_perms (Msg.name, Cr.uid, Cr.gid, Source_ctx)) {//Set properties Property_ Set ((char*) Msg.name, (char*) msg.value); } else { ERROR ("Sys_prop:permission denied uid:%d name:%s\n", Cr.uid, Msg.name); }}}int Property_set (const char *name, const char *value) {Prop_info *pi = (prop_info*) __system_property_find (name); if (pi! = 0) The {/* ro.* properties Read-only property cannot be set */if (!STRNCMP (name, "Ro.", 3)) return-1;//Update Properties Update_prop_info (PI, Value, Valuelen); } else {//increase property up to 247 items}//Handle Persistent Property/net.*/.....................//Modify the property to perform the operation property_changed (name, value);}
3) client creates Scoket request
//android provides system.getproperty to get the property service. The following takes android2.3 as an example
/**systemproperties.java*/
private static native string Native_get (string key); public static string get (String key) { if (key.length () > Prop_name_max) { throw new IllegalArgumentException ( "Key.length >" + Prop_name_max); } return Native_get (key); }
/**jni calls partially with dynamically registered android_os_systemproperties.cpp*/
Static Jninativemethod method_table[] = {{"Native_get", "(ljava/lang/string;) ljava/lang/string;", (void*) Systemproperties_gets}, ...//Omit part of code}}static jstring systemproperties_gets (jnienv *env, Jobject clazz, Jstring Keyj) {return systemproperties_getss (env, Clazz, Keyj, NULL);} 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;.............//Omit part code key = Env->getstringutfchars (KeyJ, NULL); len = Property_get (Key, buf, "");//Construct the obtained property RVJ = Env->newstringutf (BUF); ...}
/**properties.c*///View Property_get Get property Service source code
int property_get (const char *key, char *value, const char *default_value) {char Sendbuf[1+property_key_max];char recvbuf[ 1+property_value_max];int len = -1;...............//Executes the init function to get the property pthread_once (&ginitonce, init); ... return Len;} static void init (void) {..... GPROPFD = Connecttoserver (System_property_pipe_name); .................} static int connecttoserver (const char* fileName) {int sock = -1;int cc;struct sockaddr_un addr;................./* Connect to socket; Fails if file doesn ' t exist *///uses a TCP connection server to define the address and protocol family af_unixstrcpy (Addr.sun_path, fileName); Max 108 bytesaddr.sun_family = AF_UNIX;CC = Connect (sock, (struct sockaddr*) &addr, Sun_len (&ADDR)); if (CC < 0) {close (sock); return-1;} Return sock;}
Android-init Process (2)