binder是一种进程间通信机制,采用C/S机制,框架如下:
一:Client 1.open驱动2.获取服务(a.向servicemanager查询服务 b.获得一个handle)3.向handle发送数据
二:servicemanager 1.open驱动,告诉驱动我是servicemanager
2.while{
读取驱动数据
解析数据
调用:a.注册服务(在链表中记录服务)
b.获取服务(链表中查询有无服务,返回server进程得handle)
}
三:server 1.open驱动
2.注册服务(向servicemanager发送服务名)
3.while{
读驱动
解析数据
调用对应函数
}
我们看servicemanager.c得部分代码
int main(int argc, char** argv)
375{
。。。。。。
386 bs = binder_open(driver, 128*1024);
387 if (!bs) {
388#ifdef VENDORSERVICEMANAGER
389 ALOGW("failed to open binder driver %s\n", driver);
390 while (true) {
391 sleep(UINT_MAX);
392 }
393#else
394 ALOGE("failed to open binder driver %s\n", driver);
395#endif
396 return -1;
397 }
398
399 if (binder_become_context_manager(bs)) {
400 ALOGE("cannot become context manager (%s)\n", strerror(errno));
401 return -1;
402 }
403
404 cb.func_audit = audit_callback;
405 selinux_set_callback(SELINUX_CB_AUDIT, cb);
406 cb.func_log = selinux_log_callback;
407 selinux_set_callback(SELINUX_CB_LOG, cb);
408
409#ifdef VENDORSERVICEMANAGER
410 sehandle = selinux_android_vendor_service_context_handle();
411#else
412 sehandle = selinux_android_service_context_handle();
413#endif
414 selinux_status_open(true);
415
416 if (sehandle == NULL) {
417 ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
418 abort();
419 }
420
421 if (getcon(&service_manager_context) != 0) {
422 ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
423 abort();
424 }
425
426
427 binder_loop(bs, svcmgr_handler);
428
429 return 0;
430}
1.首先open驱动,bs=binder_open
2.告诉驱动我是serviemanager,binder_become_context_manager(bs)
3.循环binder_loop(bs,svcmgr_handle),a.res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
b.binder_parse
b1.解析,
b2.处理,svcmgr_handle,根据code是SVC_MGR_ADD_SERVICE则注册服务,或其他code
b2回复
再看注册服务得过程
Android系统给出一个半成品得例子bctest.c,全部源码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "binder.h"
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;
}
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;
}
unsigned token;
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")) {
handle = svcmgr_lookup(bs, svcmgr, "alt_svc_mgr");
if (!handle) {
fprintf(stderr,"cannot find alt_svc_mgr\n");
return -1;
}
svcmgr = handle;
fprintf(stderr,"svcmgr is via %x\n", handle);
} else if (!strcmp(argv[0],"lookup")) {
if (argc < 2) {
fprintf(stderr,"argument required\n");
return -1;
}
handle = svcmgr_lookup(bs, svcmgr, argv[1]);
fprintf(stderr,"lookup(%s) = %x\n", argv[1], handle);
argc--;
argv++;
} else if (!strcmp(argv[0],"publish")) {
if (argc < 2) {
fprintf(stderr,"argument required\n");
return -1;
}
svcmgr_publish(bs, svcmgr, argv[1], &token);
argc--;
argv++;
} else {
fprintf(stderr,"unknown command %s\n", argv[0]);
return -1;
}
argc--;
argv++;
}
return 0;
}
main函数->binder_open->svcmgr_publish->binder_call
最后会调用binder_call(bs, &msg, &reply, 0, code),具体参数 &msg:含有服务得名字
&reply:含有servicemanager回复得数据
target:0,表示servecemanager
code:操作要调用得函数
获取服务得过程类似:
最后也是调用binder_call,向servicemanager服务调用SVC_MGR_CHECK_SERVICE方法
binder_call(bs, &msg, &reply, target, SVC_MGR_CHECK_SERVICE)
在binder.c中binder_call构造数据binder_io通过iotrl发送数据
cpp类结构分析
IXXXService.h声明进程间通信得函数
BnXXXService.c中include IXXXService.h实现声明得函数(B表示binder,n表示native)
onTransact函数解析数据,调用对应函数
BpXXXService.c中include IXXXService.h实现声明得函数(B表示binder,p表示proxy)
声明得函数构造/发送数据
XXX_Service.c中while循环接受数据并调用onTransact函数
XXX_Client.c中调用对应函数