Problem: the property value set by adb sehll setProp is cleared after the next restart.
Adb shell setprop testing. mediascanner. skiplist/storage/sdcard1/test
Conclusion: The attribute names starting with persist can be permanently saved.
On system initialization, Android will allocates a block of shared memory for storing the properties. this is done in "init" daemon whose sourcecode is at: device/system/init. the "init" daemon will start a PropertyService.
The Property Service is running in the process of "init" daemon. every client that wants to SET property needs to connect to theProperty Service and send message to Property Service. property Servicewill update/create the property in shared memory. any client that wants to GET property can read the property from the shared memory directly. this promotes the read performance.
Java API:
Import android. OS. SystemProperties;
[Javascript] view plaincopyprint?
Public static String get (String key, String def ){}
Public static void set (String key, String val ){}
The Native API:
[Cpp]
Int property_get (const char * key, char * value, const char * default_value );
Int property_set (const char * key, const char * value );
Bionic/libc/include/sys/system_properties.h
[Cpp] view plaincopyprint?
# Define PROP_NAME_MAX 32
# Define PROP_VALUE_MAX 92
According to the above definition, the maximum length of the attribute is 32, and the maximum length of the attribute value is 92 bytes.
Bionic/libc/include/sys/_ system_properties.h
[Cpp]
# 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"
After the property service starts, it reads the default properties from the system file and writes them to the shared memory. The following four files are read in order:
/Default. prop
/System/build. prop
/System/default. prop
/Data/local. prop
The attributes read later will overwrite the same attributes read earlier.
System/core/init/property_service.c
[Cpp]
Void start_property_service (void)
{
Int fd;
Load_properties_from_file (PROP_PATH_SYSTEM_BUILD );
Load_properties_from_file (PROP_PATH_SYSTEM_DEFAULT );
# Ifdef ALLOW_LOCAL_PROP_OVERRIDE
Load_properties_from_file (PROP_PATH_LOCAL_OVERRIDE );
# Endif/* ALLOW_LOCAL_PROP_OVERRIDE */
/* Read persistent properties after all default values have been loaded .*/
Load_persistent_properties ();
Update_legacy_atvc_properties ();
Set attributes. Attributes starting with ro. cannot be changed. Attributes starting with persist. will be permanently recorded. Other attributes will be discarded after being restarted:
[Cpp]
Int property_set (const char * name, const char * value)
{
If (namelen <1) return-1;
Pi = (prop_info *) _ system_property_find (name );
If (pi! = 0 ){
/* Ro. * properties may NEVER be modified once set */
If (! Strncmp (name, "ro.", 3) return-1;
Pa = _ system_property_area __;
Update_prop_info (pi, value, valuelen );
Pa-> serial ++;
_ Futex_wake (& pa-> serial, INT32_MAX );
} Else {
Pa = _ system_property_area __;
If (pa-> count = PA_COUNT_MAX) return-1;
Pi = pa_info_array + pa-> count;
Pi-> serial = (valuelen <24 );
Memcpy (pi-> name, name, namelen + 1 );
Memcpy (pi-> value, value, valuelen + 1 );
Pa-> toc [pa-> count] =
(Namelen <24) | (unsigned) pi)-(unsigned) pa ));
Pa-> count ++;
Pa-> serial ++;
_ Futex_wake (& pa-> serial, INT32_MAX );
}
/* 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;
}
When you set an attribute, if the attribute name starts with persist., a file named after this attribute is created in the/data/property directory and the attribute value is written.
[Cpp]
# Define PERSISTENT_PROPERTY_DIR "/data/property"
Static void write_persistent_property (const char * name, const char * value)
{
Const char * tempPath = PERSISTENT_PROPERTY_DIR "/. temp ";
Char path [PATH_MAX];
Int fd, length;
Snprintf (path, sizeof (path), "% s/% s", PERSISTENT_PROPERTY_DIR, name );
Fd = open (tempPath, O_WRONLY | O_CREAT | O_TRUNC, 0600 );
If (fd <0 ){
ERROR ("Unable to write persistent property to temp file % s errno: % d \ n", tempPath, errno );
Return;
}
Write (fd, value, strlen (value ));
Close (fd );
If (rename (tempPath, path )){
Unlink (tempPath );
ERROR ("Unable to rename persistent property file % s to % s \ n", tempPath, path );
}
}
When a permanent attribute is loaded, all files whose names start with persist in the directory/data/property are read as the attribute values corresponding to the name.
[Cpp]
Static void load_persistent_properties ()
{
DIR * dir = opendir (PERSISTENT_PROPERTY_DIR );
...
If (dir) {www.2cto.com
While (entry = readdir (dir ))! = NULL ){
If (strncmp ("persist.", entry-> d_name, strlen ("persist .")))
Continue;
Author: cloudwu007