Android Binder事务调用方法梳理

Binder交互过程中协议命令

Binder交互过程中协议命令

  AIDL里的Proxy里的mRemote是BinderProxy。
  Java层的BinderProxy与C++层的BinderProxyNativeData相对应。(BinderProxyNativeData里面的mObject 指向 BpBinder)。
  Java层
  Proxy 实现接口方法 ——》BinderProxy transact() ——》
  JNI进入C++层
  android_util_Binder.cpp文件 android_os_BinderProxy_transact() ——》 BpBinder transact() ——》 IPCThreadState::self()->transact() (这里还会调用writeTransactionData()将 cmd2(写成cmd2为区分下面cmd) 写入mOut中) ——》 IPCThreadState waitForResponse(reply) ——》 IPCThreadState talkWithDriver() ——》 ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) 这里设置 cmd=BINDER_WRITE_READ 。——》
  系统调用进入驱动层 代码在 kernel\common\drivers\android\binder.c 中
  binder_ioctl() ——》 根据 cmd=BINDER_WRITE_READ ,进入 binder_ioctl_write_read() ——》1、如果 bwr.write_size > 0,执行 binder_thread_write()。2、如果 bwr.read_size > 0,执行 binder_thread_read()。

  binder_thread_write(): 会根据 cmd2 == BC_TRANSACTION或BC_REPLY,调用 binder_transaction()。可知上图中的BC_TRANSACTION和BC_REPLY协议的处理是在binder_transaction()中。
  在调用线程在处理BC_TRANSACTION结束时,会将类型为BINDER_WORK_TRANSACTION_COMPLETE的binder_work放入线程的待处理事件链表thread->todo中,等待线程进入binder_thread_read()中进行处理;还会将事务事件添加到目标进程的线程的待处理事件链表中,并且唤醒目标进程中的线程。
  调用线程在进入binder_thread_read()中处理类型为BINDER_WORK_TRANSACTION_COMPLETE的binder_work,这个就对应着 图 Binder交互过程中协议命令 中 BR_TRANSACTION_COMPLETE协议。驱动处理完之后,会返回用户态的IPCThreadState::talkWithDriver() ——》 IPCThreadState::waitForResponse()。处理完BR_TRANSACTION_COMPLETE,又通过talkWithDriver()进入内核态等待目标进程的处理结果。这次因为bwr.write_size ==0,所以直接跳入binder_thread_read()中,进行等待目标进程的返回结果。
  目标进程里的线程唤醒以后,是从binder_thread_read()中,接着执行,是继续处理BR_TRANSACTION协议。返回到用户态,IPCThreadState::talkWithDriver() ——》 IPCThreadState::waitForResponse()——》IPCThreadState::executeCommand(),处理BR_TRANSACTION,调用目标进程中BBinder对象的transact()。这个BBinder对象也是JavaBBinder对象,进入它的onTransact(),因为JavaBBinder对象的mObject指向Java层的Binder对象,所以会调用Java层的Binder对象的Transact()。然后,他会通过sendReply()写入BC_REPLY。再通过waitForResponse()——》talkWithDriver(),进入内核中binder_transaction()。
  目标进程线程处理完BC_REPLY,也会收到BR_TRANSACTION_COMPLETE协议。它还会唤醒调用进程的线程。处理完BR_TRANSACTION_COMPLETE协议,目标进程线程就完成任务了,他会继续进入binder_thread_read()中等待睡眠。
  调用进程的线程被唤醒,他会接着处理BR_REPLY,处理完毕,整个事务处理就完成。

猜你喜欢

转载自blog.csdn.net/q1165328963/article/details/126374771