源码解读Binder机制四(深入解析)

本文详细剖析了Android系统中Binder通信机制的实现原理,从BpBinder::transact调用开始,深入探讨了IPCThreadState::transact的具体实现,包括writeTransactionData和waitForResponse等关键函数的工作流程。同时,文章还解释了binder_transaction_data结构体的作用,以及Binder驱动如何通过ioctl与用户空间进行数据交互,最终实现跨进程通信。

在第二篇中说到了 BpBinder::transact 调用了 IPCThreadState::self()->transact,我们看下具体实现细节,注意这里是 BpBinder 的 transact

status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    //数据检查
    status_t err = data.errorCheck();

    flags |= TF_ACCEPT_FDS;

    if (err == NO_ERROR) {      
        err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
    }

    if ((flags & TF_ONE_WAY) == 0) {
        
        if (reply) {
            //等待
            err = waitForResponse(reply);
        } else {
            Parcel fakeReply;
            err = waitForResponse(&fakeReply);
        }
        
    } else {
            //oneway,不需要等待replay场景
        err = waitForResponse(NULL, NULL);
    }

    return err;
}

handle 表示驱动的值,code 是传输的状态码,data 是传入的数据,reply 是返回数据,flags 标志

主要的函数就是 writeTransactionData 和 waitForResponse

writeTransactionData

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
    int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
    //申请一个binder_transaction_data 格式的tr
    binder_transaction_data tr;
    //设置它的属性
    tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
    tr.target.handle = handle;
    tr.code = code;
    tr.flags = binderFlags;
    tr.cookie = 0;
    tr.sender_pid = 0;
    tr.sender_euid = 0;
    //检查传入的数据是否正确
    const status_t err = data.errorCheck();
    if (err == NO_ERROR) {
        //读取data赋值给tr
        tr.data_size = data.ipcDataSize();
        tr.data.ptr.buffer = data.ipcData();
        tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
        tr.data.ptr.offsets = data.ipcObjects();
    } else if (statusBuffer) {
        //
    } else {
        return (mLastError = err);
    }
    //cmd = BC_TRANSACTION
    mOut.writeInt32(cmd);
    //写入binder_transaction_data 数据
    mOut.write(&tr, sizeof(tr));

    return NO_ERROR;
}

binder_transaction_data 这个结构体对象很重要,它拥有的属性:

struct binder_transaction_data {
  union {
    __u32 handle;//用它可以找到对应的binder_ref,通过它找到目标的binder_node,最后找到目标进程binder_proc
    binder_uintptr_t ptr;binder_node的指针
  } target;
  binder_uintptr_t cookie;
  __u32 code;//Client端与Server端双方约定的命令码,让Server端调用对应的方法处理数据。
  __u32 flags;
  pid_t sender_pid;//发送端进程的pid
  uid_t sender_euid;//发送端进程的uid
  binder_size_t data_size;//Parcel中数据的大小
  binder_size_t offsets_size;//Parcel中flat_binder_object个数
  union {
    struct {
      binder_uintptr_t buffer;//数据对应的指针。
      binder_uintptr_t offsets;//flat_binder_object对应的偏移量
    } ptr;
    __u8 buf[8];
  } data;
};

通过 writeTra

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值