Android Binder机制

Android Binder机制为client-server的通讯实现两个进程之间的通讯,就是一个客户端一个服务端。

Server端:

/* Copyright 2008 The Android Open Source Project
 */
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <linux/types.h>
#include<stdbool.h>
#include <string.h>
#include <private/android_filesystem_config.h>
#include "binder.h"
#include "test_server.h"

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;
}

void sayhello(void)

{
static int cnt = 0;
fprintf(stderr, "say hello : %d\n", ++cnt);

}

/*

当Client调用sayhello_to("hello");的时候,会Server这里binder_loop(bs, test_server_handler); 

得到了一个binder_io,触发hello_service_handler(),并取出这里Client传过去的值,还有Code

hello_service_handler()里根据Code来最后调用到这里的sayhello_to("hello");

*/


int sayhello_to(char *name)
{
static int cnt = 0;
fprintf(stderr, "say hello to %s : %d\n", name, ++cnt);
return cnt;
}
void saygoodbye(void)
{
static int cnt = 0;
fprintf(stderr, "say goodbye : %d\n", ++cnt);
}
int saygoodbye_to(char *name)
{
static int cnt = 0;
fprintf(stderr, "say goodbye to %s : %d\n", name, ++cnt);
return cnt;

}

/*

当Client调用sayhello_to("hello");的时候,会Server这里binder_loop(bs, test_server_handler); 

得到了一个binder_io,触发hello_service_handler(),并取出这里Client传过去的值,还有Code

在hello_service_handler()里根据Code来最后调用到这里的相应函数

*/

int hello_service_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
/* 根据txn->code知道要调用哪一个函数
* 如果需要参数, 可以从msg取出
* 如果要返回结果, 可以把结果放入reply
*/
/* sayhello
* sayhello_to
*/
    uint16_t *s;
char name[512];
    size_t len;
    uint32_t handle;
    uint32_t strict_policy;
int i;

    // Equivalent to Parcel::enforceInterface(), reading the RPC
    // header with the strict mode policy mask and the interface name.
    // Note that we ignore the strict_policy and don't propagate it
    // further (since we do no outbound RPCs anyway).
    strict_policy = bio_get_uint32(msg);

    switch(txn->code) {
    case HELLO_SVR_CMD_SAYHELLO:
sayhello();
bio_put_uint32(reply, 0); /* no exception */
        return 0;

    case HELLO_SVR_CMD_SAYHELLO_TO:
/* 从msg里取出字符串 */
s = bio_get_string16(msg, &len);  //"IHelloService"
s = bio_get_string16(msg, &len);  // name
if (s == NULL) {
return -1;
}
for (i = 0; i < len; i++)
name[i] = s[i];
name[i] = '\0';

/* 处理 */
i = sayhello_to(name);
/* 把结果放入reply */
bio_put_uint32(reply, 0); /* no exception */
bio_put_uint32(reply, i);

        break;
    default:
        fprintf(stderr, "unknown code %d\n", txn->code);
        return -1;
    }
    return 0;
}

int goodbye_service_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
/* 根据txn->code知道要调用哪一个函数
* 如果需要参数, 可以从msg取出
* 如果要返回结果, 可以把结果放入reply
*/
/* sayhello
* sayhello_to

*/

        uint16_t *s;

char name[512];
        size_t len;
        uint32_t handle;
        uint32_t strict_policy;

int i;

        // Equivalent to Parcel::enforceInterface(), reading the RPC
        // header with the strict mode policy mask and the interface name.
        // Note that we ignore the strict_policy and don't propagate it

        // further (since we do no outbound RPCs anyway).

    strict_policy = bio_get_uint32(msg);

    switch(txn->code) {
    case GOODBYE_SVR_CMD_SAYGOODBYE:
saygoodbye();
bio_put_uint32(reply, 0); /* no exception */
        return 0;


    case GOODBYE_SVR_CMD_SAYGOODBYE_TO:
/* 从msg里取出字符串 */
s = bio_get_string16(msg, &len);  //"IGoodbyeService"
s = bio_get_string16(msg, &len);  // name
if (s == NULL) {
return -1;
}
for (i = 0; i < len; i++)
name[i] = s[i];
name[i] = '\0';

/* 处理 */
i = saygoodbye_to(name);
/* 把结果放入reply */
bio_put_uint32(reply, 0); /* no exception */
bio_put_uint32(reply, i);
        break;

        default:
        fprintf(stderr, "unknown code %d\n", txn->code);
        return -1;
    }
    return 0;
}
int test_server_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
int (*handler)(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply);          //函数指针


handler = (int (*)(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply))txn->target.ptr;          //从这个函数的参数里得到txn->target.ptr,然后强制转为一个函数指针

return handler(bs, txn, msg, reply);                          //从这个函数的参数里得到txn->target.ptr函数指针,调用 一下
}

int main(int argc, char **argv)
{
    int fd;
    struct binder_state *bs;   //binder_state  是一个binder设备文件的状态    
/*
binder_state定义:
struct binder_state
{
int fd;  //打开的文件描述符
void *mapped;  //通过mmap把"/dev/binder"设备文件映射到进程虚拟空间的地址(用户空间)
unsigned mapsize;  
};

*/

    uint32_t svcmgr = BINDER_SERVICE_MANAGER;
    uint32_t handle;
int ret;

    bs = binder_open(128*1024);   //初始化binder,打开/dev/binder设备;在内存中为binder映射128K字节空间
    if (!bs) {
        fprintf(stderr, "failed to open binder driver\n");
        return -1;
    }

/* add service */
    ret = svcmgr_publish(bs, svcmgr, "hello", hello_service_handler);                      //添加服务(注册服务)
    if (ret) {
        fprintf(stderr, "failed to publish hello service\n");
        return -1;
    }
ret = svcmgr_publish(bs, svcmgr, "goodbye", goodbye_service_handler);     //添加服务(注册服务)
    if (ret) {
        fprintf(stderr, "failed to publish goodbye service\n");
    }


#if 0
while (1)
{
/* read data */
/* parse data, and process */
/* reply */
}

#endif

    binder_set_maxthreads(bs, 10);                    //binder设置最大的进程个数

 /* Client调用sayhello_to(),会构造binder_io()

Client调用binder_call,会得到一个struct writebuf保存数据,这里相反,是调用binder_loop后得到readbuf 读取数据

   Client struct writebuf这个结构体里主要得到一个struct binder_transaction来构造数据,这里Server是得到struct binder_transaction来解析数据

     Client再构造一个binder_write_read结构体,这里相反,是调用binder_loop后得到binder_write_read结构体

     Client最后通过ioctl();函数把数据发出去。 然后Server调用binder_loop后也是通过ioctl();函数来得到数据的。  

    最终,这里Server通过binder_transaction会还原出一个binder_io,最后调用到Server里的sayhello_to()

   这里最后进入 test_server_handler函数里

 */

    binder_loop(bs, test_server_handler);         //循环的读取 数据,解析数据,返回数据
    return 0;
}

Client:

/* Copyright 2008 The Android Open Source Project
 */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <linux/types.h>
#include<stdbool.h>
#include <string.h>
#include <private/android_filesystem_config.h>
#include "binder.h"
#include "test_server.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;
}

struct binder_state *g_bs;
uint32_t g_hello_handle;
uint32_t g_goodbye_handle;
void sayhello(void)
{
    unsigned iodata[512/4];
    struct binder_io msg, reply;

    /* 构造binder_io */
    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    bio_put_string16_x(&msg, "IHelloService");


/* 放入参数 */


/* 调用binder_call */
    if (binder_call(g_bs, &msg, &reply, g_hello_handle, HELLO_SVR_CMD_SAYHELLO))
        return ;

/* 从reply中解析出返回值 */


    binder_done(g_bs, &msg, &reply);

}


int sayhello_to(char *name)
{
unsigned iodata[512/4];
struct binder_io msg, reply;
int ret;
int exception;
/* 构造binder_io */
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0);  // strict mode header
        bio_put_string16_x(&msg, "IHelloService");

/* 放入参数(data) ,这时候在Server那里会得到了一个binder_io,并取出这里Client传过去的值 */
        bio_put_string16_x(&msg, name);
 

/* 调用binder_call,会得到一个struct writebuf,

        这个结构体里主要得到一个struct binder_transaction来构造数据

        再构造一个binder_write_read结构体

        最后通过ioctl();函数把数据发出去。

        然后Server也是通过ioctl();函数来得到数据的。

        */

if (binder_call(g_bs, &msg, &reply, g_hello_handle, HELLO_SVR_CMD_SAYHELLO_TO))
return 0;

/* 从reply中解析出返回值 */
exception = bio_get_uint32(&reply);
if (exception)
ret = -1;
else
ret = bio_get_uint32(&reply);


binder_done(g_bs, &msg, &reply);
return ret;
}
void saygoodbye(void)
{
    unsigned iodata[512/4];
    struct binder_io msg, reply;


/* 构造binder_io */
    bio_init(&msg, iodata, sizeof(iodata), 4);
    bio_put_uint32(&msg, 0);  // strict mode header
    bio_put_string16_x(&msg, "IGoodbyeService");


/* 放入参数 */


/* 调用binder_call */
    if (binder_call(g_bs, &msg, &reply, g_goodbye_handle, GOODBYE_SVR_CMD_SAYGOODBYE))
        return ;

/* 从reply中解析出返回值 */


    binder_done(g_bs, &msg, &reply);

}


int saygoodbye_to(char *name)
{
unsigned iodata[512/4];
struct binder_io msg, reply;
int ret;
int exception;


/* 构造binder_io */
bio_init(&msg, iodata, sizeof(iodata), 4);
bio_put_uint32(&msg, 0);  // strict mode header
    bio_put_string16_x(&msg, "IGoodbyeService");


/* 放入参数 */
    bio_put_string16_x(&msg, name);


/* 调用binder_call */
if (binder_call(g_bs, &msg, &reply, g_goodbye_handle, GOODBYE_SVR_CMD_SAYGOODBYE_TO))
return 0;

/* 从reply中解析出返回值 */
exception = bio_get_uint32(&reply);
if (exception)
ret = -1;
else
ret = bio_get_uint32(&reply);


binder_done(g_bs, &msg, &reply);


return ret;

}

/* ./test_client hello
 * ./test_client hello <name>
 */
int main(int argc, char **argv)
{
    int fd;
    struct binder_state *bs;
    uint32_t svcmgr = BINDER_SERVICE_MANAGER;
    uint32_t handle;
int ret;


if (argc < 2){
        fprintf(stderr, "Usage:\n");
        fprintf(stderr, "%s <hello|goodbye>\n", argv[0]);
        fprintf(stderr, "%s <hello|goodbye> <name>\n", argv[0]);
        return -1;
}


    bs = binder_open(128*1024);
    if (!bs) {
        fprintf(stderr, "failed to open binder driver\n");
        return -1;
    }
g_bs = bs;

        /* get service */
handle = svcmgr_lookup(bs, svcmgr, "goodbye");
if (!handle) {
        fprintf(stderr, "failed to get goodbye service\n");
        return -1;
}
g_goodbye_handle = handle;
fprintf(stderr, "Handle for goodbye service = %d\n", g_goodbye_handle);


handle = svcmgr_lookup(bs, svcmgr, "hello");
if (!handle) {
        fprintf(stderr, "failed to get hello service\n");
        return -1;
}
g_hello_handle = handle;
fprintf(stderr, "Handle for hello service = %d\n", g_hello_handle);


/* send data to server */
if (!strcmp(argv[1], "hello"))
{
if (argc == 2) {
sayhello();
} else if (argc == 3) {
ret = sayhello_to(argv[2]);    //这里调用的时候,会构造一个binder_io,放入argv[2]用户输入的字符串
       fprintf(stderr, "get ret of sayhello_to = %d\n", ret);
}
} else if (!strcmp(argv[1], "goodbye"))
{
if (argc == 2) {
saygoodbye();
} else if (argc == 3) {
ret = saygoodbye_to(argv[2]);
       fprintf(stderr, "get ret of sayhello_to = %d\n", ret);
}
}


binder_release(bs, handle);


    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值