• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            ++wythern++

            X presents Y for a better Z

            [轉]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, 066600);
            44         if(fd < 0return -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     }

            posted on 2012-09-29 10:35 wythern 閱讀(373) 評論(0)  編輯 收藏 引用

            久久久一本精品99久久精品88| 亚洲欧美日韩精品久久| 人人狠狠综合久久亚洲88| 久久毛片一区二区| 久久久久婷婷| 欧美国产精品久久高清| 国产成人精品久久亚洲| 中文字幕成人精品久久不卡| 亚洲综合精品香蕉久久网97| 久久亚洲精品中文字幕三区| 国产精品天天影视久久综合网| 久久国产精品久久国产精品| 国产一区二区三区久久| 国产成人无码精品久久久免费 | 国产精品久久久久久福利漫画| 久久久精品人妻一区二区三区四| 日韩人妻无码一区二区三区久久 | 久久精品国产亚洲麻豆| 99麻豆久久久国产精品免费| 国产精品久久国产精麻豆99网站 | 久久精品国产精品亚洲艾草网美妙| 亚洲欧美日韩精品久久| 久久精品国产99久久丝袜| 欧美久久久久久| 乱亲女H秽乱长久久久| 欧美777精品久久久久网| 国产免费久久精品丫丫| 性做久久久久久免费观看| 久久久一本精品99久久精品66| 国产精品18久久久久久vr | 久久久中文字幕日本| 久久亚洲精品无码aⅴ大香 | 久久久久青草线蕉综合超碰| 久久精品99久久香蕉国产色戒| 9久久9久久精品| 久久精品国产亚洲αv忘忧草| 久久精品国产亚洲77777| 久久人人超碰精品CAOPOREN | 久久A级毛片免费观看| 久久久精品国产Sm最大网站| 伊人久久大香线蕉av不卡|