`

Android 的系统属性(SystemProperties)设置分析

 
阅读更多

作者:徐建祥(netpirate@gmail.com)
日期:2009/11/11
网址:http://www.anymobile.org

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      }


设置key的value时,需要作鉴权,根据设置程序所在进程的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   - 1 ;
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 - 1  =   0 ;
56              msg.value[PROP_VALUE_MAX - 1  =   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:1000  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[ 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      }


OVER!

分享到:
评论

相关推荐

    Android8.1 SystemUI源码

    在Android系统中,SystemUI是用户界面的核心组成部分,它负责管理状态栏、通知中心、快速设置等关键功能。本文将深入探讨Android 8.1版本的SystemUI源码,介绍其结构、工作原理以及如何利用提供的gradle配置进行开发...

    android bugreport 分析

    13. **SYSTEMPROPERTIES**:这部分显示了系统的关键属性,如版本号、服务状态和网络配置,有助于确定系统环境和配置。 14. **KERNELLOG**:执行`/system/bin/dmesg`命令,获取内核日志,这是底层硬件和驱动程序级别...

    AMS启动流程源码分析

    1. 记录进程启动信息:使用 `SystemProperties` 类将进程启动信息记录到系统属性中,包括启动次数、启动时间和启动 uptime。 2. 设置时区属性:如果时区属性 `persist.sys.timezone` 为空或无效,AMS 会将其设置为 ...

    android5.1 ethernet

    源码中,这部分功能可能位于`SettingsActivity.java`或`EthernetPreferenceController.java`等类,通过调用`SystemProperties.set()`方法修改系统属性来实现静态IP的设置。 4. **源码解析** Android系统的源码主要...

    Android Power On Off

    通过以上分析可以看出,Android系统中开关机动画的启动与停止均通过设置特定的属性来实现。`bootanimationservice`作为核心组件,负责响应这些属性变化并执行相应的动画播放逻辑。这一机制确保了系统的灵活性和可...

    Android build.prop生成过程y源码分析

    `build.prop`是Android系统中的一个关键配置文件,它记录了系统构建时的重要属性信息,如屏幕密度(LCD density)、默认语言设置、编译时间等。这些信息对于系统的初始化配置及运行时的性能优化至关重要。通常情况下...

    android-4.2-src.zip

    2. **编译源码**:使用Android的Build System (例如,make或repo) 编译源码,了解Android系统的构建过程,这对于定制ROM或开发自定义系统组件至关重要。 3. **系统调用分析**:通过阅读系统服务和库函数的源码,...

    Android源码——关机和重启(reboot and shutdown)源码.zip

    在Android中,`SystemProperties`类用于存储和读取系统属性。在关机和重启过程中,会修改特定的系统属性,如`sys.shutdown.requested`或`sys.reboot.reason`,来标记请求的状态和原因。 5. **HAL(Hardware ...

    Android 权限 大全

    SurfaceFlinger是Android系统中负责处理屏幕绘制的核心组件之一,拥有此权限的应用可以实现对屏幕显示的直接控制,但这种级别的访问需要非常谨慎,因为不正确的使用可能会导致系统不稳定。 #### android.permission...

    Android 如何启用user版本的adb源码分析

    ### Android如何启用User版本的ADB源码分析 #### 一、ADB概述与配置解析 ADB(Android Debug Bridge)是...通过上述步骤,开发者可以确保在不同版本的Android系统中都能够高效地使用ADB进行调试,从而提高开发效率。

    android动态加载dex

    Android系统提供了System.loadLibrary()方法来加载.so文件,这些文件通常放在项目的jniLibs目录下,根据不同的CPU架构(armeabi, armeabi-v7a, x86等)放置相应的版本。 为了实现动态加载dex和so库,开发者需要关注...

    Android应用源码获取手机信息.zip源码资源下载

    6. **其他信息**:还可以获取电池状态、存储空间、系统属性等,通过`BatteryManager`、`Environment`类和`SystemProperties`类等。 在Java编程中,我们通常会创建一个工具类,封装这些获取手机信息的函数,便于在...

    android手电筒源码及屏幕颜色、亮度调节

    在Android开发中,手电筒功能的实现是一个常见的需求,特别是在一些实用工具类应用中。本文将基于"android手电筒源码及屏幕颜色...通过分析和实践这些代码,开发者可以加深对Android系统工作原理的理解,提升开发技能。

    Android访问权限大全

    ### Android访问权限详解 在Android应用开发过程中,访问权限管理是一项至关重要的工作。...此外,随着Android系统的不断升级,某些权限可能会发生变化或新增其他类型权限,请开发者关注最新文档以获取最准确的信息。

    世上最全面的android权限大全,还等神马?

    标题与描述均提到了“世上最全面的android权限大全”,这表明文章旨在提供一个详尽的Android系统权限列表,帮助读者理解每个权限的功能及其在应用中的作用。Android系统的权限管理是其安全架构的重要组成部分,通过...

    安卓Android源码——FloatWindowDemo.zip

    【标签】"android 源码 安卓" 指出这是与Android平台相关的源代码,适用于Android开发者,特别是那些想要深入理解Android系统和开发过程的人。 【文件详解】 1. `.classpath`:这是Eclipse IDE的配置文件,用于...

    android permission(权限)

    以上列举了Android系统中的一些常见权限及其应用场景。开发者在设计应用时应谨慎考虑所需权限,并尽可能减少不必要的权限请求,以保障用户体验和隐私安全。同时,在向用户请求权限时应明确告知其用途,增加透明度,...

    android 权限解说

    为了保障用户的数据安全与隐私保护,Android系统对应用程序能够访问的功能和数据进行了严格的限制。本文将针对部分核心权限进行详细介绍,帮助开发者更好地理解和使用这些权限。 #### 1. `android.permission....

Global site tag (gtag.js) - Google Analytics