Android 的系统属性包括两部分:文件保存的持久属性和每次开机导入的cache属性。前者主要保存在下面几个文件中:

bionic / libc / include / sys / _system_properties.h

  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"


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

  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.       }


该接口类在初始化运行环境中注册对应的cpp接口android_os_SystemProperties.cpp,实际操作通过JNI调用的是cpp文件对应的接口:

frameworks/base/core/jni/AndroidRuntime.cpp

  1.        namespace  android {
  2.        extern   int  register_android_os_SystemProperties(JNIEnv  * env);
  3.       }


frameworks/base/core/jni/android_os_SystemProperties.cpp



  1. static   void  SystemProperties_set(JNIEnv  * env, jobject clazz, jstring keyJ, jstring valJ)
  2.       {
  3.             int  err;
  4.             const   char *  key;
  5.             const   char *  val;
  6.           key  =  env -> GetStringUTFChars(keyJ, NULL);
  7.            if  (valJ  ==  NULL) {
  8.               val  =   "" ;        /*  NULL pointer not allowed here  */
  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.       }


设置keyvalue时,需要作鉴权,根据设置程序所在进程的fd获知uid值,比如system server进程可以设置net打头的key,不可以设置gsm打头的key,相关的定义如下:

system/core/include/private/android_filesystem_config.h

  1.        #define  AID_ROOT             0  /* traditional unix root user */
  2.        #define  AID_SYSTEM        1000  /* system server */
  3.        #define  AID_RADIO         1001  /* telephony subsystem, RIL */
  4.        #define  AID_DHCP          1014  /* dhcp client */
  5.        #define  AID_SHELL         2000  /* adb and debug shell user */
  6.        #define  AID_CACHE         2001  /* cache access */
  7.        #define  AID_APP          10000 /* first app user */


system/core/init/property_service.c



  1. #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,  0  }
  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.   
  37.           load_properties_from_file(PROP_PATH_SYSTEM_BUILD);
  38.           load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);
  39.           load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);
  40.            /*  Read persistent properties after all default values have been loaded.  */
  41.           load_persistent_properties();
  42.   
  43.           fd  =  create_socket(PROP_SERVICE_NAME, SOCK_STREAM,  0666 ,  0 ,  0 );
  44.            if (fd  <   0 )  return   -  ;
  45.           fcntl(fd, F_SETFD, FD_CLOEXEC);
  46.           fcntl(fd, F_SETFL, O_NONBLOCK);
  47.   
  48.          listen(fd,  8 );
  49.            return  fd;
  50.       }
  51.        void  handle_property_set_fd( int  fd)
  52.       {
  53.            switch (msg.cmd) {
  54.            case  PROP_MSG_SETPROP:
  55.               msg.name[PROP_NAME_MAX -  ]  =   0 ;
  56.               msg.value[PROP_VALUE_MAX -  ]  =   0 ;
  57.   
  58.                if (memcmp(msg.name, " ctl. " , 4 )  ==   0 ) {
  59.                    if  (check_control_perms(msg.value, cr.uid)) {
  60.                       handle_control_message(( char * ) msg.name  +   4 , ( char * ) msg.value);
  61.                   }  else  {
  62.                       ERROR( " sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n " ,
  63.                               msg.name  +   4 , msg.value, cr.uid, cr.pid);
  64.                   }
  65.              }  else  {
  66.                    if  (check_perms(msg.name, cr.uid)) {
  67.                       property_set(( char * ) msg.name, ( char * ) msg.value);
  68.                   }  else  {
  69.                       ERROR( " sys_prop: permission denied uid:%d  name:%s\n " ,
  70.                             cr.uid, msg.name);
  71.                   }
  72.               }
  73.               break ;
  74.   
  75.            default :
  76.                break ;
  77.           }
  78.       }


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

system/core/init/init.c

      

  1. 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[  ].fd  =  property_set_fd;
  19.           ufds[  ].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[  ].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.       }

来自:http://blog.csdn.net/mars5337/archive/200/07/0/5705840.aspx

更多相关文章

  1. Android安装apk文件,适配Android 7.0
  2. android 组件,xml布局中属性详解
  3. IDA调试Android so文件
  4. 《Android面试宝典》学习笔记(第五章:文件存储)
  5. Android 文件读写操作 总结
  6. Android基础知识:Day02 常见布局、logcat相关和文件读写

随机推荐

  1. Unable to resolve dependency for .....
  2. opencv manager package was not found
  3. Android(安卓)中使用 Proguard 混淆 Java
  4. Android控件 TimePicker
  5. ThreadPoolExecutor 快速实际应用
  6. 在Android(Java)开发中如何实现类似C语言中
  7. 关于Android(JAVA)实例化接口假象的讨论
  8. 利用Xposed Hook打印Java函数调用堆栈信
  9. 【Jetpack系列一】Jetpack介绍
  10. the user data image is used by another