版权声明:本文为博主(Tower)自学笔记,欢迎转载! :-) https://blog.csdn.net/qq_33443989/article/details/77150862
1>. Android Framework框架 之 Binder系统
1<. Binder系统核心
1<. IPC 过程间通信
假设有两个进程 A: Client , B: Server;
1<. 源 :A 进程
2<. 目的 :
1<. B 向 ServiceManager 注册 led 服务
2<. A 向 ServiceManager 查询 led 服务,得到一个Handle(指向进程B)
3<. 数据本身: 属于双方约定好的数据格式, eg: char buf[50]
2<. RPC 远程过程调用
RPC 是基于 IPC 的一些封装
1<. 问题:
调用哪一个函数:Server 的函数编号
传给它什么参数 & 返回值:通过 IPC 的 buf 参数。
2<. 分析参考代码
/* 参考代码 : android_system_code\frameworks\native\cmds\servicemanager */
binder.h :
binder.c :封装好的 C 函数 1<. binder_call /* 实现远程调用 */ 1<. 函数定义: int binder_call(struct binder_state *bs, struct binder_io *msg, struct binder_io *reply, uint32_t target, uint32_t code) 2<. 函数功能: 1<. 向谁发数据 : taget 2<. 调用那个函数 : code 3<. 提供什么参数 : msg 4<. 返回值 : reply 3<. binder_call 内部实现 1<. 构造数据 : 用 binder_io 来描述数据 [中间过程] : binder_io => binder_write_read 过程: 2<. 调用 ioctl 发送数据 res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); 1<. 解析 bwr : struct binder_write_read bwr; 1<. 结构体定义: struct binder_write_read { signed long write_size; /* bytes to write */ signed long write_consumed; /* bytes consumed by driver */ unsigned long write_buffer; signed long read_size; /* bytes to read */ signed long read_consumed; /* bytes consumed by driver */ unsigned long read_buffer; }; 3<. ioctl 也会接受数据,收到一个 binder_write_read 结构体 同时需要转换为 binder_io。
bctest.c : 注册服务的过程: 1<. bs = binder_open(128*1024); 2<. svcmgr_publish(bs, svcmgr, argv[1], &token); 1<. binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE) 1<. 函数定义: int binder_call(struct binder_state *bs, struct binder_io *msg, struct binder_io *reply, uint32_t target, uint32_t code) 2<. 参数解析: target : BINDER_SERVICE_MANAGER 0U code : 表示要调用 servicemanager 中的 "addservice" 函数 msg : 含有服务的名字 reply : 它会收到 servicemanager 回复的数据 bs : 被打开的驱动的fd; 获取服务的过程: 1<. bs = binder_open(128*1024); 2<. handle = svcmgr_lookup(bs, svcmgr, "alt_svc_mgr"); 1<. binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE) 1<. 函数定义: int binder_call(struct binder_state *bs, struct binder_io *msg, struct binder_io *reply, uint32_t target, uint32_t code) 2<. 参数解析: target : BINDER_SERVICE_MANAGER 0U code : 表示要调用 servicemanager 中的 "getservice" 函数 msg : 含有服务的名字 reply : 它会收到 servicemanager 回复的数据 bs : 被打开的驱动的fd;
service_manager.c : 1<. bs = binder_open(128*1024); 2<. binder_become_context_manager(bs); 3<. binder_loop(bs, svcmgr_handler); 1<. res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr); /* 解析并且处理数据 */ 2<. binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func); /* 解析 */ 1<. res = func(bs, txn, &msg, &reply); /* 处理 */ 2<. svcmgr_handler /* 根据传入的命令 */ switch(txn->code) { /* 获取服务 */ 1<. SVC_MGR_GET_SERVICE / SVC_MGR_CHECK_SERVICE /* 注册服务 */ 2<. SVC_MGR_ADD_SERVICE } /* 回复 */ 3<. binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
3<. 如何写应用程序
1<. client
1<. binder_open
2<. 获得服务:handle
3<. 构造参数: binder_io
4<. 调用binder_call(hande, code, ...), 并且传入一些必要的参数
5<. 分析返回binder_io, 取出返回值
2<. server
1<. binder_open
2<. 注册服务
3<. ioctl(BINDER_WRITE_READ);
4<. 解析数据:解析 binder_write_read.readbuf->binder_transationdata这个结构体
5<. 根据第四步解析出来的 code 决定调用那个函数,并且从 binder_io 中取出参数,传入
6<. 将返回值转换为 binder_io 发送给 client