日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【Binder 机制】Native 层 Binder 机制分析 ( binder_loop | svcmgr_handler | binder.c | binder_parse )

發(fā)布時間:2025/6/17 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Binder 机制】Native 层 Binder 机制分析 ( binder_loop | svcmgr_handler | binder.c | binder_parse ) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 一、binder_loop 方法調(diào)用
  • 二、binder_loop 方法參數(shù) svcmgr_handler
  • 三、binder_loop 方法
  • 四、binder_parse 方法

前言

在上一篇博客 【Binder 機制】Native 層 Binder 機制分析 ( service_manager.c | 開啟 Binder | 注冊 Binder 進程上下文 | 開啟 Binder 循環(huán) ) 中分析了 Binder Native 實現(xiàn)中的 service_manager.c 中的 main 函數(shù)的啟動過程 ;

  • 開啟 Binder : bs = binder_open(driver, 128*1024);
  • 將自己注冊成 Binder 進程的上下文 : binder_become_context_manager(bs)
  • 開啟 Binder 循環(huán) : binder_loop(bs, svcmgr_handler);




一、binder_loop 方法調(diào)用



在 service_manager.c 中的 main 函數(shù)中 , 執(zhí)行了 binder_loop 方法 , 傳入了 svcmgr_handler 方法名作為回調(diào)函數(shù) ;

int main(int argc, char** argv) {binder_loop(bs, svcmgr_handler);return 0; }

完整代碼參考 /frameworks/native/cmds/servicemanager/service_manager.c





二、binder_loop 方法參數(shù) svcmgr_handler



svcmgr_handler 方法定義在 service_manager.c 中 ; svcmgr_handler 方法名是 Service Manager Handler 的簡寫 ;

struct binder_io *msg 是傳入的消息 ;

struct binder_io *reply 參數(shù)是返回參數(shù) ;

svcinfo 結構體是一個鏈表 ;

傳入不同的消息執(zhí)行不同的處理 :

  • SVC_MGR_ADD_SERVICE : 收到消息 , 添加一個 Binder 服務 ;
  • SVC_MGR_CHECK_SERVICE : 收到消息 , 找到一個 Binder 服務 ;
struct svcinfo {struct svcinfo *next; //指向下一個 svcinfo 結構體元素uint32_t handle; struct binder_death death; int allow_isolated; // 是否允許獨立于進程 uint32_t dumpsys_priority;size_t len; // 長度uint16_t name[0]; // 名稱 };int svcmgr_handler(struct binder_state *bs,struct binder_transaction_data *txn,struct binder_io *msg,struct binder_io *reply) {// 鏈表 struct svcinfo *si;uint16_t *s;size_t len;uint32_t handle;uint32_t strict_policy;int allow_isolated;uint32_t dumpsys_priority;// 根據(jù)不同的 txn->code 執(zhí)行不同的方法 switch(txn->code) {case SVC_MGR_GET_SERVICE:case SVC_MGR_CHECK_SERVICE:// 收到消息 , 找到一個 Binder 服務 s = bio_get_string16(msg, &len);if (s == NULL) {return -1;}handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);if (!handle)break;bio_put_ref(reply, handle);return 0;case SVC_MGR_ADD_SERVICE:// 收到消息 , 添加一個 Binder 服務s = bio_get_string16(msg, &len);if (s == NULL) {return -1;}handle = bio_get_ref(msg);allow_isolated = bio_get_uint32(msg) ? 1 : 0;dumpsys_priority = bio_get_uint32(msg);if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,txn->sender_pid))return -1;break;case SVC_MGR_LIST_SERVICES: { // 獲取服務列表 uint32_t n = bio_get_uint32(msg);uint32_t req_dumpsys_priority = bio_get_uint32(msg);if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {ALOGE("list_service() uid=%d - PERMISSION DENIED\n",txn->sender_euid);return -1;}si = svclist;// walk through the list of services n times skipping services that// do not support the requested prioritywhile (si) {if (si->dumpsys_priority & req_dumpsys_priority) {if (n == 0) break;n--;}si = si->next;}if (si) {bio_put_string16(reply, si->name);return 0;}return -1;}default:ALOGE("unknown code %d\n", txn->code);return -1;}bio_put_uint32(reply, 0);return 0; }

完整代碼參考 /frameworks/native/cmds/servicemanager/service_manager.c





三、binder_loop 方法



在開啟 Binder 循環(huán)的 binder_loop 方法中 , 如果收到 Binder 讀寫消息信息 , 調(diào)用 binder_parse 方法處理 , 調(diào)用代碼如下 :

res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);

binder_loop 方法代碼如下 :

void binder_loop(struct binder_state *bs, binder_handler func) {int res;struct binder_write_read bwr;uint32_t readbuf[32];bwr.write_size = 0;bwr.write_consumed = 0;bwr.write_buffer = 0;readbuf[0] = BC_ENTER_LOOPER;// binder_write(bs, readbuf, sizeof(uint32_t));// 開啟無限循環(huán) for (;;) {bwr.read_size = sizeof(readbuf);bwr.read_consumed = 0;bwr.read_buffer = (uintptr_t) readbuf;res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);if (res < 0) {ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));break;}// 如果收到 Binder 讀寫消息信息 , 調(diào)用 binder_parse 方法處理 ;res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);if (res == 0) {ALOGE("binder_loop: unexpected reply?!\n");break;}if (res < 0) {ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));break;}} }

完整代碼參考 /frameworks/native/cmds/servicemanager/binder.c





四、binder_parse 方法



binder_parse 方法中接收的 binder_handler func 參數(shù)是一個回調(diào)方法 ; 該方法是 Binder 服務收到了客戶端請求后的回調(diào)函數(shù) ;

int binder_parse(struct binder_state *bs, struct binder_io *bio,uintptr_t ptr, size_t size, binder_handler func) {int r = 1;uintptr_t end = ptr + (uintptr_t) size;while (ptr < end) {uint32_t cmd = *(uint32_t *) ptr;ptr += sizeof(uint32_t); #if TRACEfprintf(stderr,"%s:\n", cmd_name(cmd)); #endif// 根據(jù)不同指令 , 執(zhí)行不同操作 ; switch(cmd) {case BR_NOOP:break;case BR_TRANSACTION_COMPLETE:break;case BR_INCREFS:case BR_ACQUIRE:case BR_RELEASE:case BR_DECREFS: #if TRACEfprintf(stderr," %p, %p\n", (void *)ptr, (void *)(ptr + sizeof(void *))); #endifptr += sizeof(struct binder_ptr_cookie);break;case BR_TRANSACTION: {struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;if ((end - ptr) < sizeof(*txn)) {ALOGE("parse: txn too small!\n");return -1;}binder_dump_txn(txn);if (func) {unsigned rdata[256/4];struct binder_io msg;struct binder_io reply;int res;bio_init(&reply, rdata, sizeof(rdata), 4);bio_init_from_txn(&msg, txn);// 執(zhí)行回調(diào)方法 res = func(bs, txn, &msg, &reply);if (txn->flags & TF_ONE_WAY) {binder_free_buffer(bs, txn->data.ptr.buffer);} else {binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);}}ptr += sizeof(*txn);break;}case BR_REPLY: {struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;if ((end - ptr) < sizeof(*txn)) {ALOGE("parse: reply too small!\n");return -1;}binder_dump_txn(txn);if (bio) {bio_init_from_txn(bio, txn);bio = 0;} else {/* todo FREE BUFFER */}ptr += sizeof(*txn);r = 0;break;}case BR_DEAD_BINDER: {struct binder_death *death = (struct binder_death *)(uintptr_t) *(binder_uintptr_t *)ptr;ptr += sizeof(binder_uintptr_t);death->func(bs, death->ptr);break;}case BR_FAILED_REPLY:r = -1;break;case BR_DEAD_REPLY:r = -1;break;default:ALOGE("parse: OOPS %d\n", cmd);return -1;}}return r; }

總結

以上是生活随笔為你收集整理的【Binder 机制】Native 层 Binder 机制分析 ( binder_loop | svcmgr_handler | binder.c | binder_parse )的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。