Android-init進程(2)

來源:互聯網
上載者:User

標籤:android   style   blog   io   ar   color   os   sp   java   

init屬性服務就好比windows的註冊表,應用可以對其應用資訊進行屬性操作

以下介紹屬性服務的原理:


屬性關鍵方法:
*void property_init(void)>>分析
void property_init(void){    init_property_area();}static int init_property_area(void){prop_area *pa;//建立共用記憶體if(init_workspace(&pa_workspace, PA_SIZE))        return -1;/**設定空間大小等其他資訊*///系統自動調用__libc_prenit函數,完成共用記憶體到本地進程的工作__system_property_area__ = pa;}

//通知其他進程
void __libc_preinit(void){__libc_init_common(elfdata);}void __libc_init_common(uintptr_t *elfdata){__system_properties_init();}int __system_properties_init(void){//取出init建立環境變數獲得檔案描述符env = getenv("ANDROID_PROPERTY_WORKSPACE");    fd = atoi(env);//映射 init建立的記憶體到本地進程空間//這樣其他進程就可以共用這個記憶體了//在這裡 用戶端只能做讀取的操作pa = mmap(0, sz, PROT_READ, MAP_SHARED, fd, 0);}

*void start_property_service(void)>>分析

1)載入屬性檔案到屬性空間裡面去 同時建立scoket

*void start_property_service(void){//載入屬性檔案load_properties_from_file(PROP_PATH_SYSTEM_BUILD);    load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);    load_override_properties();//載入持久化檔案    load_persistent_properties();//建立socketfd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);}init.c::int main(){nr = poll(ufds, fd_count, timeout);if (ufds[i].revents == POLLIN) {                if (ufds[i].fd == get_property_set_fd())                    handle_property_set_fd();}}}

2)main函數等待其他進程對該scoket調用並做出處理 修改屬性
void handle_property_set_fd(){//接收scoket    if ((s = accept(property_set_fd, (struct sockaddr *) &addr, &addr_size)) < 0) {        return;    }    //取出進程的許可權屬性    if (getsockopt(s, SOL_SOCKET, SO_PEERCRED, &cr, &cr_size) < 0) {        close(s);         return;    }//接收資料r = TEMP_FAILURE_RETRY(recv(s, &msg, sizeof(msg), 0));if(memcmp(msg.name,"ctl.",4) == 0) {            // ctl.* 控制訊息    //如setprop  ctl.start bootanim            close(s);            if (check_control_perms(msg.value, cr.uid, cr.gid, source_ctx)) {                handle_control_message((char*) msg.name + 4, (char*) msg.value);            } else {                ERROR("sys_prop: Unable to %s service ctl [%s] uid:%d gid:%d pid:%d\n",                        msg.name + 4, msg.value, cr.uid, cr.gid, cr.pid);            }    } else {    //檢查許可權            if (check_perms(msg.name, cr.uid, cr.gid, source_ctx)) {    //設定屬性            property_set((char*) msg.name, (char*) msg.value);            } else {                ERROR("sys_prop: permission denied uid:%d  name:%s\n",cr.uid, msg.name);            }    } }int property_set(const char *name, const char *value){prop_info *pi = (prop_info*) __system_property_find(name);if(pi != 0) {        /* ro.* properties 唯讀屬性 不能設定 */        if(!strncmp(name, "ro.", 3)) return -1;//更新屬性        update_prop_info(pi, value, valuelen);    } else {        //增加屬性最多247項    }//處理持久屬性/net.*/.....................//修改屬性同時執行的操作property_changed(name, value);}

3)用戶端建立scoket請求
//Android提供System.getProperty來獲得屬性服務。 以下以android2.3為例
/**SystemProperties.java*/

private static native String native_get(String key);    public static String get(String key) {        if (key.length() > PROP_NAME_MAX) {            throw new IllegalArgumentException("key.length > " + PROP_NAME_MAX);        }        return native_get(key);    }

/**jni調用部分採用動態註冊的 android_os_SystemProperties.cpp*/
static JNINativeMethod method_table[] = {{ "native_get", "(Ljava/lang/String;)Ljava/lang/String;",  (void*) SystemProperties_getS },    .......//省略部分代碼}}static jstring SystemProperties_getS(JNIEnv *env, jobject clazz,jstring keyJ){return SystemProperties_getSS(env, clazz, keyJ, NULL);}static jstring SystemProperties_getSS(JNIEnv *env, jobject clazz,jstring keyJ, jstring defJ){int len;const char* key;char buf[PROPERTY_VALUE_MAX];jstring rvJ = NULL;.............//省略部分代碼key = env->GetStringUTFChars(keyJ, NULL);len = property_get(key, buf, "");//構造獲得的屬性rvJ = env->NewStringUTF(buf);.............}

/**Properties.c*/ //查看property_get擷取屬性服務源碼
int property_get(const char *key, char *value, const char *default_value){char sendBuf[1+PROPERTY_KEY_MAX];char recvBuf[1+PROPERTY_VALUE_MAX];int len = -1;...............//執行init函數擷取屬性pthread_once(&gInitOnce, init);...............return len;}static void init(void){................gPropFd = connectToServer(SYSTEM_PROPERTY_PIPE_NAME);................}static int connectToServer(const char* fileName){int sock = -1;int cc;struct sockaddr_un addr;................./* connect to socket; fails if file doesn't exist *///採用TCP串連伺服器 定義地址和協議族AF_UNIXstrcpy(addr.sun_path, fileName);    // max 108 bytesaddr.sun_family = AF_UNIX;cc = connect(sock, (struct sockaddr*) &addr, SUN_LEN(&addr));if (cc < 0) {close(sock);return -1;}return sock;}


Android-init進程(2)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.