3 Binder--sayHello之ioctl.md

文章目录1.5 #.6 # 二. ioctl介绍 总结
参考资料详解 msm-4.14 Code linux 内核 - ioctl 函数详解 ioctl(2) — Linuxpage ioctl()分析——从用户空间到设备驱动简介
接上文,首先回顾一下相关接口的类图:
我们知道在 App中获取的实际上是类型的对象 。那么在上一文中 App调用方法过程的的#2.3.2中,我们卡住了,现在可以继续了:
virtual status_ttransact(uint32_t code,const Parcel& data,Parcel* reply,uint32_t flags = 0) = 0;
一. . ..Stub.Proxy..(Stub., …) 1.1 .
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {// ......try {// 不多废话,直接开始, 注意我们现在的进程环境是Client App哦return transactNative(code, data, reply, flags);}// ......}
1.2 #
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException{// ......// 获取IBinder对象,这里我们已经知道了,是BinderProxy对应Native的IBinder对象// 也就是对应Server App存入的JavaBBinder, 是Parcel:flattenBinder中存入cookie的BBinder// 然后在通信过程中经过Binder驱动转成了对应的BpBinderIBinder* target = getBPNativeData(env, obj)->mObject.get();// ......// 1.3 上一篇文章我们就分析了,这个target就是BpBinderstatus_t err = target->transact(code, *data, reply, flags);// ......return JNI_FALSE;}
【3Binder--sayHello之ioctl.md】1.3 #
// NOLINTNEXTLINE(google-default-arguments)status_t BpBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){// 一旦Binder对象死掉,就不会复活if (mAlive) {// ......// 1.4 IPCThreadState!status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);if (status == DEAD_OBJECT) mAlive = 0;return status;}return DEAD_OBJECT;}
1.4 #
status_t IPCThreadState::transact(int32_t handle,uint32_t code, const Parcel& data,Parcel* reply, uint32_t flags){status_t err;flags |= TF_ACCEPT_FDS;// 1.4.1 将数据写入mOut中存储, cmd 是BC_TRANSACTIONerr = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);// ......if ((flags & TF_ONE_WAY) == 0) {// TF_ONE_WAY 是代表这个binder调用是one_way的,不需要等待回传// 这个分支表示需要回传数据// ......if (reply) {// 1.5 当传入的reply Parcel不为null时err = waitForResponse(reply);} else {// 当直接传入一个null的Parcel作为reply时// 创建一个假的Parcel接收可能的回写数据Parcel fakeReply;err = waitForResponse(&fakeReply);}// ......} else {// 不需要回传数据err = waitForResponse(nullptr, nullptr);}return err;}
的flag一共有四种:
0x01

3  Binder--sayHello之ioctl.md

文章插图
代表的调用,不需要回传数据
0x04
内容是组件的根对象
0x08
内容是32位的状态代码
0x10
允许使用文件描述符答复
首先将需要传递的数据写入out中存储,然后去和 通信 。
这里我们先忽略的初始化过程 。
1.4.1 #
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;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) {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();} // ......// cmd为BC_TRANSACTIONmOut.writeInt32(cmd);// 将data保存在mOut中mOut.write(&tr, sizeof(tr));return NO_ERROR;}