• <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

            [轉(zhuǎn)]Android系統(tǒng)systemProperties設(shè)置分析

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

            Android 的系統(tǒng)屬性包括兩部分:文件保存的持久屬性和每次開機(jī)導(dǎo)入的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     }

            該接口類在初始化運(yùn)行環(huán)境中注冊對應(yīng)的cpp接口android_os_SystemProperties.cpp,實(shí)際操作通過JNI調(diào)用的是cpp文件對應(yīng)的接口:

            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     }

            設(shè)置key的value時,需要作鑒權(quán),根據(jù)設(shè)置程序所在進(jìn)程的fd獲知uid值,比如system server進(jìn)程可以設(shè)置net打頭的key,不可以設(shè)置gsm打頭的key,相關(guān)的定義如下:

            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     }

            在開機(jī)啟動后的init操作中,會執(zhí)行一個loop循環(huán),當(dāng)檢測到有新的設(shè)置時,進(jìn)入設(shè)置流程,鑒權(quán)失敗會提示相關(guān)的異常,如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)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            狠狠狠色丁香婷婷综合久久俺| 亚洲?V乱码久久精品蜜桃| 精品午夜久久福利大片| 久久中文骚妇内射| 色欲综合久久躁天天躁蜜桃 | 久久精品国产亚洲一区二区三区 | 91精品国产91久久| 久久精品国产亚洲AV嫖农村妇女| 精品国产99久久久久久麻豆| 欧美一级久久久久久久大片| 久久无码人妻精品一区二区三区| 久久九九久精品国产| 欧美一级久久久久久久大片| 思思久久99热只有频精品66| 久久久久久精品免费看SSS| 亚洲人成网亚洲欧洲无码久久| 亚洲日韩中文无码久久| www.久久热.com| 久久精品无码免费不卡| 久久这里都是精品| 婷婷久久香蕉五月综合加勒比 | 粉嫩小泬无遮挡久久久久久| 精品综合久久久久久97超人| 久久国产精品免费一区| 亚洲欧美精品一区久久中文字幕| 久久人妻AV中文字幕| 精品久久久久久综合日本| 久久精品无码一区二区三区免费| 国产69精品久久久久9999APGF| 人妻少妇久久中文字幕| 爱做久久久久久| 久久强奷乱码老熟女网站| 久久国产高清字幕中文| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 精品一二三区久久aaa片| 青草影院天堂男人久久| 久久久久久亚洲精品影院| 久久国产精品77777| 久久影院午夜理论片无码| 国产成人综合久久综合| 久久久久久精品久久久久|