Android Binder(C语言版本)
Posted we1less
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Binder(C语言版本)相关的知识,希望对你有一定的参考价值。
android中存在用c语言写的Binder应用,接下来以这个文件开始分析
当进行Binder通信过程中
main frameworks/native/cmds/servicemanager/service_manager.c
1.打开Binder驱动
int main(int argc, char** argv)
{
...
if (argc > 1) {
driver = argv[1];
} else {
driver = "/dev/binder";
}
bs = binder_open(driver, 128*1024);
if (!bs) {
#ifdef VENDORSERVICEMANAGER
ALOGW("failed to open binder driver %s\\n", driver);
while (true) {
sleep(UINT_MAX);
}
#else
ALOGE("failed to open binder driver %s\\n", driver);
#endif
return -1;
}
main frameworks/native/cmds/servicemanager/service_manager.c
2.告诉驱动,此进程是service_manager
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\\n", strerror(errno));
return -1;
}
3.循环 main frameworks/native/cmds/servicemanager/service_manager.c
binder_loop(bs, svcmgr_handler);
binder_loop frameworks/native/cmds/servicemanager/binder.c
3.1读驱动获取数据
void binder_loop(struct binder_state *bs, binder_handler func)
{
...
for (;;) {
...
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
...
}
binder_parse frameworks/native/cmds/servicemanager/binder.c
3.2解析数据
void binder_loop(struct binder_state *bs, binder_handler func)
{
...
for (;;) {
...
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;
}
}
}
svcmgr_handler frameworks/native/cmds/servicemanager/service_manager.c
对于解析数据后处理是由3里面的svcmgr_handler回调处理 (根据code调用不同函数)
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
...
switch(txn->code) {
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
...
case SVC_MGR_ADD_SERVICE:
...
case SVC_MGR_LIST_SERVICES: {
...
}
default:
ALOGE("unknown code %d\\n", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
3.3调用 a.注册服务(在链表中记录服务名称)
SVC_MGR_CHECK_SERVICE 查询服务
SVC_MGR_ADD_SERVICE 注册服务
b.返回“server”进程的handle
service
main frameworks/native/cmds/servicemanager/bctest.c
1.打开Binder驱动
bs = binder_open("/dev/binder", 128*1024);
int main(int argc, char **argv)
{
struct binder_state *bs;
uint32_t svcmgr = BINDER_SERVICE_MANAGER;
uint32_t handle;
bs = binder_open("/dev/binder", 128*1024);
if (!bs) {
fprintf(stderr, "failed to open binder driver\\n");
return -1;
}
argc--;
argv++;
while (argc > 0) {
if (!strcmp(argv[0],"alt")) {
...
} else if (!strcmp(argv[0],"lookup")) {
...;
} else if (!strcmp(argv[0],"publish")) {
...
svcmgr_publish(bs, svcmgr, argv[1], &token);
argc--;
argv++;
} else {
fprintf(stderr,"unknown command %s\\n", argv[0]);
return -1;
}
argc--;
argv++;
}
return 0;
}
2.注册服务(向service_manager发送服务名称)
svcmgr_publish(bs, svcmgr, argv[1], &token);
binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE)
target 要把数据发送给哪个进程
这个例子中 target 为 uint32_t svcmgr = BINDER_SERVICE_MANAGER;
#define BINDER_SERVICE_MANAGER 0U
target 发 0 代表把数据发给 service_manager
SVC_MGR_ADD_SERVICE 表示要调用service_manager中
(3.3)SVC_MGR_ADD_SERVICE 注册服务函数
&msg 含有服务的名字
&reply 是service_manager回复的数据
int svcmgr_publish(struct binder_state *bs, uint32_t target, const char *name, void *ptr)
{
int status;
unsigned iodata[512/4];
struct binder_io msg, reply;
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
bio_put_string16_x(&msg, SVC_MGR_NAME);
bio_put_string16_x(&msg, name);
bio_put_obj(&msg, ptr);
if (binder_call(bs, &msg, &reply, target, SVC_MGR_ADD_SERVICE))
return -1;
status = bio_get_uint32(&reply);
binder_done(bs, &msg, &reply);
return status;
}
3.循环 3.1读驱动获取数据
3.2解析数据,调用对应函数
client
main frameworks/native/cmds/servicemanager/bctest.c
1.打开Binder驱动 (与上相同)
bs = binder_open("/dev/binder", 128*1024);
2.获取服务
handle = svcmgr_lookup(bs, svcmgr, "alt_svc_mgr");
binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE)
target 要把数据发送给哪个进程
0 向service_manager获取服务
SVC_MGR_CHECK_SERVICE表示要调用service_manager中的
(3.3)SVC_MGR_CHECK_SERVICE 获取服务函数
&msg 含有服务的名字
&reply 是service_manager回复的数据,表示提供服务的进程
uint32_t svcmgr_lookup(struct binder_state *bs, uint32_t target, const char *name)
{
uint32_t handle;
unsigned iodata[512/4];
struct binder_io msg, reply;
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0); // strict mode header
bio_put_string16_x(&msg, SVC_MGR_NAME);
bio_put_string16_x(&msg, name);
if (binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE))
return 0;
handle = bio_get_ref(&reply);
if (handle)
binder_acquire(bs, handle);
binder_done(bs, &msg, &reply);
return handle;
}
2.1向service_manager查询服务
2.2获取handle
3.向这个handle发送数据
binder_call frameworks/native/cmds/servicemanager/binder.c
target 向谁发数据
code 调用哪个函数
*msg 提供哪个参数
*reply 返回值
int binder_call(struct binder_state *bs,
struct binder_io *msg, struct binder_io *reply,
uint32_t target, uint32_t code)
binder_call 如何用
1.构造参数 struct binder_io
2.调用 ioctl 发数据
res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
struct binder_write_read bwr;
其中存在参数转换成驱动&bwr的过程 (struct binder_io --> struct binder_write_read)
3. ioctl 收数据 收到binder_write_read
还需要将 (struct binder_write_read --> struct binder_io)
以上是关于Android Binder(C语言版本)的主要内容,如果未能解决你的问题,请参考以下文章
Android Binder ServiceManager启动源码分析
Android C++语言 通过Binder通信调用activity: [android.app.IActivityManager] 服务发广播