The Android Framework------Property Subsystem

Source: Internet
Author: User

Overview

Property is an important concept in the Android system, which is used primarily for system configuration and for simple information sharing among different services within the Android system. such as device name, Bluetooth name, compile information, network DNS address, and some other basic information. In addition to simple information sharing, there is also a function to start and stop the system services. Start a property by setting the Ctl.start.xxx property, or set Service.xxx.exit to stop the service.

The properties of the Android system property on the whole, is the key value to save, that is, the key-value method. While the system is running, the property is stored in memory in the form of a dictionary tree. But there are also some fixed, unmodified properties that are stored in a disk file. The properties stored in these files will not be used interactively during the run. It just loads these fixed, unmodified properties into memory at the beginning of the Android system. The main reason for choosing a dictionary tree as the data structure for property storage is that it is possible to store characters with the same prefix in the same node and subsequent characters to be stored as child nodes of the Trie node. This type of storage can be faster to find characters.

The property service is started in the init process. Start the property service as early as possible while initializing other services in the INIT process.
The following is a brief introduction to the process flow of property initiation, broadly divided into the following:

1. Property_init (); "System/core/init/init.c"
2. Property_load_boot_defaults (); "System/core/init/init.c"
3. property_service_init_action; "System/core/init/init.c"
4. Load_all_props; "System/core/rootdir/init.rc"
5. queue_property_triggers_action; "System/core/init/init.c"
6. HANDLE_PROPERTY_SET_FD (); "System/core/init/init.c"

For the property module, when the boot is complete, it is in a dead loop, checking to see if there are any properties of his service settings, if any, to receive and process the settings. In the process of reading the source code, there is a concept worth mentioning: memory barrier, the following from the encyclopedia, also known as memory fence, memory barriers, barrier directives, etc., is a kind of synchronization barrier instructions, so that the CPU or the compiler in the memory random access operation of a synchronization point, Causes all read and write operations before this point to be executed before the operation can begin after this point.

Data structure of the property module

The model of the property's storage is roughly as follows:

+-----+   Children    +----+   children    +--------+ |     | -------------->| Ro |-------------->| Secure | +-----+               +----+               +--------+                       /    \                /   |                 Left/      \ Right left   /    |  Prop   +===========+                     v        v     +-------->| ro.secure |                  +-----+   +-----+     +-----+            +-----------+                  | net |   | sys |     | com |            |     1     |                  +-----+   +-----+     +-----+            +===========+

Depending on how the dictionary tree is stored, the important data structures related to the property are related to the dictionary tree, as follows:

struct PROP_BT

Describes the information for each node, which corresponds to a part of the name in the attribute name. This information includes this node string, the left and right sibling node address, and the child node address. At the same time, when the struct declares, it also declares that the PROP_BT node is not assignable, and only when it is constructed can it initialize the information. An operation that cannot be assigned is done by using macro disallow_copy_and_assign (PROP_BT).

struct Prop_area {}

Describes the information that the property uses in memory, including the property's version information, and the usage space.

struct Prop_info {}

Describe the information of a property, such as an attribute [sys.boot_completed]:[1], which is a data structure that describes the overall information of the property, including the property name, attribute value, and the length of the property. In this struct, there is a property of serial, which is used to represent the length of the property value. Serial with the keyword volatile modifier, this value is constantly changing, every time you want to use this time, it should be read from memory, not from register or cache read. In addition, this property, in addition to representing the length of the property value, is a synchronous lock that allows only one process to operate on this property.

To summarize, take the attribute [sys.boot_completed]:[1] As an example, the property name sys.boot_completed with '. ' Dividing the delimiter into two parts requires two prop_bt to be stored. Finally, create Prop_info to save [sys.boot_completed]:[1] when it's worth saving. Finally, put the address of prop_info into the prop of the last node prop_bt.

The following is a little more specific to introduce the property of this module

Let's start with the process:
1.property_init (); "System/core/init/init.c"
When Android was started, it was called early in the Init process, and the main function was to initialize the memory space used by the property. The way to initialize is to create a Tmfs file System file/dev/properties, and then map this file to memory as a shared memory, mapped to memory size is 128KB. Finally, the address of this shared memory is exported in libc. In this way, there are two ways to read and write to the property, one is through the file read and write, and the other is memory sharing read and write. Using the property's address to read and write to the property is primarily Property_service, running in the init process. This process corresponds to the following code:

Static intInit_property_area (void){    if(property_area_inited)//Flag        return-1; if(__system_property_area_init ())//[Bionic/libc/bionic/system_properties.cpp]        return-1; if(Init_workspace (&pa_workspace,0))        return-1; Fcntl (PA_WORKSPACE.FD, F_SETFD, fd_cloexec);//Fork a process, but this FD would be closedproperty_area_inited=1; return 0;}

2. Property_load_boot_defaults (); "System/core/init/init.c"

This function should be loaded before the Init.rc file is parsed. Because the Default.prop file contains some important properties * * ———— to check ———— * *. This function is primarily the/default.prop file that loads the root directory of the Android system. The build process for this file installed_default_prop_target the module in "/build/core/makefile". The main process of loading is summarized as follows:
Open the/default.prop file, which is parsed in the behavior unit during reading (the corresponding code is while (EOL = STRCHR (sol, ' \ n '))) (* *}),
Then find the content on both sides of ' = ' and call Property_set (key, value) to complete the property assignment process. The implementation of Property_set is as follows:

  

3. property_service_init_action; "system/core/init/init.c"  
First This function is made up of queue_builtin_action (Property_service_init_action, "Property_service_init"); call triggered,  
This call occurs after the Init.rc file has started parsing and has been executed after the Early-init, Init series action has been completed. But this execution of this function takes place prior to After-init. In fact, after the first step is successfully executed, you can start to set up and find properties. However, the Set property operation that occurs before this function is basically from Default.prop and init.rc. The property settings from these two places are the Init process parsing files, the initiated settings, which occur in the INIT process. So you can directly read and write to the memory space where the property resides, adding or modifying properties. The main function of this function is to create a socket, and then other processes want to set the properties of the time, you can communicate through the socket, you want to set the properties to send over, and then to the INIT process to set.

 void  start_property_service (void       Fd FD  = Create_socket (Prop_service_name, Sock_stream, 0666 , 0 , 0  , NULL);  if  (FD < 0 ) return  ;    Fcntl (FD, F_SETFD, fd_cloexec);    Fcntl (FD, F_SETFL, O_nonblock);    Listen (FD,  8  ); PROPERTY_SET_FD  = FD;}  

This function is relatively concise, although the function name means to start the property service, but in fact the property service is not a separate process, but runs in the current process--init. After this function is completed, a socket file/dev/socket/property_service is created in/dev/socket/. Later in the process, the socket file can be used to communicate with the Init process, and the content of the communication is to set the property properties on behalf of the INIT process. This communication process is explained later.

4. Load_all_props; "System/core/rootdir/init.rc"

This action is not found in the code of the function. It is a command defined in init.rc and will not be triggered until after late-init. The triggering process is as follows:

On load_all_props_action    load_all_props...on late-init    trigger early-FS    Trigger FS    trigger Post-FS    trigger post-fs-data    from/system/+ /  Factory after FS mount. Place    the  Another action so that the load would be scheduled after the prior    # issued FS triggers has completed.    Trigger Load_all_props_action     ...

This action is also loaded from the file some system properties, and the second step to load the/default.prop way, but this load of these properties is to/system,/factory file system after the mount can be done. You can refer to the second step for specific procedures.

5. queue_property_triggers_action; "System/core/init/init.c"
When the INIT process executes here, all the necessary properties of the system are already set up. This will trigger the operation of the Listener property. And the last action in the second step is the same as the truth.

6. HANDLE_PROPERTY_SET_FD (); "System/core/init/init.c"
This function is one of the most important functions in the property module. Because all other processes want to set properties, it is done through the socket communication, which is called when the init process hears a new message sent over. The init process is the file that listens to the socket of the property communication through the Linux poll mechanism.

     for(;;) {...        if(!property_set_fd_init && get_property_set_fd () >0) {UFDS[FD_COUNT].FD=get_property_set_fd (); Ufds[fd_count].events=Pollin; Ufds[fd_count].revents=0; Fd_count++; Property_set_fd_init=1; } ... nr=poll (UFDs, Fd_count, timeout); if(Nr <=0)            Continue;  for(i =0; i < Fd_count; i++) {            if(Ufds[i].revents &Pollin) {                if(UFDS[I].FD = =get_property_set_fd ()) handle_property_set_fd (); ...} }    }

At the end of the Init process, an infinite loop was opened, in which the poll mechanism was used to listen for a total of three files, and the property socket communication file/dev/socket/property_service was one of them. The HANDLE_PROPERTY_SET_FD () function is called when there is a new message coming from the socket. The entire process is described in the preceding code. The flow of the HANDLE_PROPERTY_SET_FD function is as follows:

This is the basic procedure for setting properties in the init process. However, for other processes, the process of converting the property to be set to a message and sending it through the socket to the INIT process is not yet accessible, as described in the following information about how to communicate with other modules and communication objects

Search for property

From the previous narrative, we already know that the property's storage is stored using the data structure of the dictionary tree. The purpose of using the Dictionary tree store is to find faster, so let's look at the property from the dictionary tree to find the process:

Some considerations in the property module:

The information of the problem 1:property itself is described using Prop_info, and the information stored is described by PROP_BT, so how can the information received from the socket to the PROP_INFO structure be stored in the process? How is the structure Prop_info and the structure PROP_BT stored? When modifying an existing property, how do I find the desired property from memory?
A: Before answering a series of questions above, we have seen the process of function find_property (): This question can be answered in the following few small points:

  1. How to turn the socket information into a structural prop_info?
    The message sent from the socket is encapsulated into the MSG structure. The structure contains the desired action to set the property, as well as the Key,value value required for the > Setting property. The two variables required for the property setting are all available, and the following is the creation of the property information Prop_info struct, and the storage property structure Body PROP_BT are all working with the properties service.

  2. How to convert from structural PROP_BT to Prop_info? To_prop_obj () function PROP_BT is local information, Prop_info is the whole information. That's not good.
    The Find_property () function completes this work. "Bionic/libc/bionic/system_properties.cpp"
    Search from the root node, and if not found, do not request space for prop_info in the current function. Begin by dividing the name of the property to be set to '. ' As a delimiter, find out if there is a corresponding node exists, if it exists, then find the name of the second part of the corresponding node exists, and so on. If all exists, then it means that the property already exists, and this time through the To_prop_obj () function, the corresponding information is constructed into Prop_info return. If a part of the attribute name is not found, then it is necessary to apply the memory space, create the attribute, and store it.

  3. How to convert from structural Prop_info to PROP_BT?
    The FIND_PROP_BT () function completes this work. "Bionic/libc/bionic/system_properties.cpp"
    Flow chart
    Whether you add an attribute, updating an existing property is handled by the distribution in the function Find_property (). "Bionic/libc/bionic>/system_properties.cpp"
    Compare the target name in the attribute with the name in the node, in ascending alphabetical order, if the name in the node is back, then the return value is < 0, the return value is > 0; if the target name in the attribute is the same as the name of the node, the return value is 0. After this comparison, if the return value is greater than 0, then go to the right side of the property dictionary tree to find it, or vice versa, go to the left of the dictionary tree. If the return value is equal to 0, it means that the node is found.

The difference between __system_property_add and __system_property_find is that in the lookup node, if there is no node that you want to find, do you want to create a new node. __system_property_add is to be created. __system_property_find is not created.

how the property communicates with other modules and the communication object

In Android, there are only two actions related to attributes: Find properties, read properties, and set properties. No property action was removed. In addition, lookup properties occur during the reading of properties and setting properties, and other modules generally do not use the find operation directly. In both common read and set properties, the Read attribute is not involved in interprocess communication. As we said earlier, property properties are stored in memory and memory-shared mappings are made, so when you read a property, it is read directly from the shared memory, which occurs in the current process and does not use interprocess communication. The use of interprocess communication is to set property operations. Because other services may be started when the property is set, or some system configuration may be modified, which requires permission checks, so the process is not allowed to set the property directly, but through socket communication, the property to be set is sent to the Init process, which is set by the INIT process on its behalf.
The following is an example of setting a property, supplementing the operation before receiving a message in HANDLE_PROPERTY_SET_FD () in step sixth above. Suppose we want to set a property Property_set ("Test.test.test", "1"), first find the Property_set function in SYSTEM/CORE/LIBCUTILS/PROPERTIES.C file. For the property settings that are made in the Java layer, this function is eventually called through JNI, and the detailed procedure is no longer described. Property_set calls the __system_property_set () function in the Android system library libc in the Bionic/libc/bionic/system_properties.cpp file, in the __system The _property_set () function, after encapsulating the attribute to be set as MSG, starts sending the message through the socket. The function that sends the message is send_prop_msg (&AMP;MSG), and also in the same file. This function is the focus of communication. In the Send_prop_msg () function, the main is to create a socket and send a message through the socket. To create a socket to communicate with the INIT process, you must know the socket file on the receiving side of the init process segment. On Android, the property receive-side socket file is the default path to the/dev/socket/property_service file. This file is created by the third step in front of Create_socket (Prop_service_name, Sock_stream, 0666, 0, 0, NULL); The Create_socket () function is a custom function of the Android system, and the default is to create the specified socket file in the/dev/socket/directory. Here, the current process will find the property in the INIT process of the receiver end of the socket file, you can send information through the socket, the properties are set.

The Android Framework------Property Subsystem

Related Article

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.