Android系统属性SystemProperties…

来源:互联网 发布:菜鸟网络加盟怎么赚钱 编辑:程序博客网 时间:2024/06/05 14:46
Android的系统属性包括两部分:文件保存的持久属性和每次开机导入的cache属性。前者主要保存在下面几个文件中:

1.bionic/libc/include/sys/_system_properties.h

 

[cpp] viewplaincopy
  1. #define PROP_SERVICE_NAME "property_service"  
  2. #define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"  
  3. #define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"  
  4. #define PROP_PATH_SYSTEM_DEFAULT   "/system/default.prop"  
  5. #define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"  

 

2.后者则通过frameworks/base/core/java/android/os/SystemProperties.java的接口定义,


[java] viewplaincopy
  1. private static native String native_get(String key);  
  2. private static native String native_get(String key, String def);  
  3. private static native void native_set(String key, String def);  
  4. public static void set(String key, String val)  
  5.     if (key.length() PROP_NAME_MAX)  
  6.         throw new IllegalArgumentException("key.length " PROP_NAME_MAX);  
  7.  
  8.     if (val != null && val.length() PROP_VALUE_MAX)  
  9.         throw new IllegalArgumentException("val.length "  
  10.         PROP_VALUE_MAX);  
  11.      
  12.     native_set(key, val);  
  13.  
3.该接口类在初始化运行环境中注册对应的cpp接口android_os_SystemProperties.cpp,实际操作通过JNI调用的是cpp文件对应的接口:

 

frameworks/base/core/jni/AndroidRuntime.cpp

 

[cpp] viewplaincopy
  1. namespace android  
  2.         extern int register_android_os_SystemProperties(JNIEnv *env);  
  3.      
frameworks/base/core/jni/android_os_SystemProperties.cpp

 

 

[cpp] viewplaincopy
  1. static void SystemProperties_set(JNIEnv *env, jobject clazz, jstring keyJ, jstring valJ)  
  2.  
  3.     int err;  
  4.     const charkey;  
  5.     const charval;  
  6.     key env->GetStringUTFChars(keyJ, NULL);  
  7.     if (valJ == NULL)  
  8.         val ""        
  9.     else  
  10.         val env->GetStringUTFChars(valJ, NULL);  
  11.      
  12.     err property_set(key, val);  
  13.     env->ReleaseStringUTFChars(keyJ, key);          
  14.     if (valJ != NULL)  
  15.         env->ReleaseStringUTFChars(valJ, val);  
  16.      
  17.  
4.设置key的value时,需要作鉴权,根据设置程序所在进程的fd获知uid值,比如systemserver进程可以设置net打头的key,不可以设置gsm打头的key,相关的定义如下:
system/core/include/private/android_filesystem_config.h

 

[cpp] viewplaincopy
  1. <span style="font-family:SimSun;font-size:16px;">#define AID_ROOT                
  2. #define AID_SYSTEM        1000    
  3. #define AID_RADIO         1001    
  4. #define AID_DHCP          1014    
  5. #define AID_SHELL         2000    
  6. #define AID_CACHE         2001    
  7. #define AID_APP          10000 </span>  
system/core/init/property_service.c

 

 

[cpp] viewplaincopy
  1. <span style="font-family:SimSun;font-size:16px;">#define PERSISTENT_PROPERTY_DIR  "/data/property"  
  2. struct  
  3.     const char *prefix;  
  4.     unsigned int uid;  
  5. property_perms[]  
  6.     "net.rmnet0."   AID_RADIO },  
  7.     "net.gprs."     AID_RADIO },  
  8.     "ril."          AID_RADIO },  
  9.     "gsm."          AID_RADIO },  
  10.     "net.dns"       AID_RADIO },  
  11.     "net.usb0"      AID_RADIO },  
  12.     "net."          AID_SYSTEM },  
  13.     "dev."          AID_SYSTEM },  
  14.     "runtime."      AID_SYSTEM },  
  15.     "hw."           AID_SYSTEM },  
  16.     "sys."       AID_SYSTEM },  
  17.     "service."   AID_SYSTEM },  
  18.     "wlan."       AID_SYSTEM },  
  19.     "dhcp."       AID_SYSTEM },  
  20.     "dhcp."       AID_DHCP },  
  21.     "debug."       AID_SHELL },  
  22.     "log."       AID_SHELL },  
  23.     "service.adb.root"   AID_SHELL },  
  24.     "persist.sys."   AID_SYSTEM },  
  25.     "persist.service."  AID_SYSTEM },  
  26.     NULL,  
  27. };  
  28. int property_set(const char *name, const char *value)  
  29.  
  30.     property_changed(name, value);  
  31.     return 0;  
  32.  
  33. int start_property_service(void 
  34.  
  35.     int fd;  
  36.     load_properties_from_file(PROP_PATH_SYSTEM_BUILD);  
  37.     load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);  
  38.     load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);  
  39.       
  40.     load_persistent_properties();  
  41.       
  42.     fd create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);  
  43.     if(fd 0) return -1;  
  44.     fcntl(fd, F_SETFD, FD_CLOEXEC);  
  45.     fcntl(fd, F_SETFL, O_NONBLOCK);  
  46.   
  47.     listen(fd, 8);  
  48.     return fd;  
  49.  
  50. void handle_property_set_fd(int fd)  
  51.  
  52.     switch(msg.cmd)  
  53.     case PROP_MSG_SETPROP:  
  54.         msg.name[PROP_NAME_MAX-1] 0;  
  55.         msg.value[PROP_VALUE_MAX-1] 0;  
  56.   
  57.     if(memcmp(msg.name,"ctl.",4) == 0)  
  58.         if (check_control_perms(msg.value, cr.uid))  
  59.             handle_control_message((char*) msg.name 4, (char*) msg.value);  
  60.         else  
  61.             ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n" 
  62.             msg.name 4, msg.value, cr.uid, cr.pid);  
  63.          
  64.     else  
  65.         if (check_perms(msg.name, cr.uid))  
  66.             property_set((char*) msg.name, (char*) msg.value);  
  67.         else  
  68.         ERROR("sys_prop: permission denied uid:%d  name:%s\n" 
  69.             cr.uid, msg.name);  
  70.          
  71.      
  72.     break 
  73.   
  74.     default 
  75.         break 
  76.      
  77. }</span>  

5.在开机启动后的init操作中,会执行一个loop循环,当检测到有新的设置时,进入设置流程,鉴权失败会提示相关的异常,如sys_prop:permission denied uid:1000 name:gsm.phone.id

 

system/core/init/init.c

 

[cpp] viewplaincopy
  1. <span style="font-family:SimSun;font-size:16px;">void property_changed(const char *name, const char *value)  
  2.  
  3.     if (property_triggers_enabled)  
  4.         queue_property_triggers(name, value);  
  5.         drain_action_queue();  
  6.      
  7.  
  8. int main(int argc, char **argv)  
  9.  
  10.     parse_config_file("/init.rc");  
  11.     qemu_init();  
  12.     device_fd device_init();  
  13.     property_init();  
  14.     fd open(console_name, O_RDWR);  
  15.     property_set_fd start_property_service();  
  16.     ufds[0].fd device_fd;  
  17.     ufds[0].events POLLIN;  
  18.     ufds[1].fd property_set_fd;  
  19.     ufds[1].events POLLIN;  
  20.     ufds[2].fd signal_recv_fd;  
  21.     ufds[2].events POLLIN;  
  22.     fd_count 3;  
  23.     for(;;)  
  24.         if (ufds[0].revents == POLLIN)  
  25.             handle_device_fd(device_fd);  
  26.   
  27.         if (ufds[1].revents == POLLIN)  
  28.             handle_property_set_fd(property_set_fd);  
  29.         if (ufds[3].revents == POLLIN)  
  30.             handle_keychord(keychord_fd);  
  31.      
  32.     return 0;  
  33. }</span>  

FYI
原创粉丝点击