熟悉的味道,熟悉的Binder他他他又来了

853 阅读13分钟

一.序言

说到Binder这个东西大家都不陌生,为什么今天又聊起Binder呢?最近看到大家都在Android群里都在卷fw层,所以我也就开始学起了Binder。本文主要从Native层面讲起,系统版本Android13

二.概述

Binder是Android系统提供的IPC机制。由于Android是基于Linux内核的,因此除了Binder,Android还有其他机制,例如管道和socket。Binder机制相比其他IPC来说更加方便和灵活了。 在基于Binder的C/S架构中,除了C端和S端,还有一个全局的Android的ServiceManager端,它是管理系统中的各种服务(Service)的。client和Service关系如下:

image.png

通过图中可以得出一个结论:

1.Service要先注册到ServiceManager,Service就是ServiceManager的客户端了,而ServiceManager就是服务端了。 2.client要想使用Service,必须先到ServiceManager获取Service相关的信息,所以client是ServiceManager客户端。 3.client拿到Service后建立通信的通路,client就可以和Service进行通信了。

三.进程

一个进程是不能访问到另一个进程的,也就是说进程是具有独立性的。

那么进程之间要通信,就不能使用属于进程的资源,而应该使用一份公共的资源。

所以进程间通信的本质是:由OS参与,提供一份所有进程都能访问的公共资源。

Binder跨进程通信首先得有进程的吧,那就从进程创建的那时候说起。一个APP至少一个进程,进程创建的时候会调用onZygoteInit函数

xref: /frameworks/base/cmds/app_process/app_main.cpp

 virtual void onZygoteInit()
      {
          //创建ProcessState对象
          sp<ProcessState> proc = ProcessState::self();
          proc->startThreadPool();
      }

ProcessState翻译过来就是进程状态,我们看看ProcessState是什么?它负责打开 Binder 驱动设备以及mmap

sp<ProcessState> ProcessState::self()
  {
      return init(kDefaultDriver, false /*requireDefault*/);
  }

sp<ProcessState> ProcessState::init(const char *driver, bool requireDefault)
  {
      //call_once保证函数只调用一次
      [[clang::no_destroy]] static std::once_flag gProcessOnce;
      std::call_once(gProcessOnce, [&](){
          if (access(driver, R_OK) == -1) {
              driver = "/dev/binder";
          }
          std::lock_guard<std::mutex> l(gProcessMutex);、
          //调用ProcessState构造函数 并且一个进程对应一个gProcess
          gProcess = sp<ProcessState>::make(driver);
      });
  
      verifyNotForked(gProcess->mForked);
      return gProcess;
  }
ProcessState::ProcessState(const char* driver)
        : mDriverName(String8(driver)),
          mDriverFD(-1),
          ......
          mCallRestriction(CallRestriction::NONE) {
          //打开驱动driver参数 /dev/binder
      base::Result<int> opened = open_driver(driver);
      
    if (opened.ok()) {
          // mmap,提供一块虚拟地址空间来接收事务
                  mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,
           }
      }
static base::Result<int> open_driver(const char* driver) {
          //打开驱动driver参数 /dev/binder
      int fd = open(driver, O_RDWR | O_CLOEXEC);
      //通过ioctl方式告诉binder驱动线程最大数
      status_t result = ioctl(fd, BINDER_VERSION, &vers);
      if (result == -1) {
          close(fd);
      }
      
      return fd;
  }

通过上述代码得知当进程创建的时候会创建一个ProcessState对象且一个进程只有一个ProcessState。在ProcessState构造函数里面打开通过open函数打开binder驱动,这就相当于与内核的 Binder 驱动有了交互的通道。然后通过mmap,提供一块虚拟地址空间来接收事务。它可以将文件直接映射到进程的地址空间(虚拟内存)。实现了文件和虚拟内存地址一一映射的关系.在完成映射后,进程就可以使用指针直接读写文件,而系统会自动回写被修改过得脏页到磁盘对应位置。mmap 在完成了 read、write 相同效果的同时不仅省去了内核到进程的内存拷贝过程,而且还可以实现数据的共享操作:一个文件可以同时被多个进程、内核映射,如果映射的文件被内核或其他进程修改,那么最终的结果也会反映到映射当中。

image.png

通过ioctl方式告诉binder驱动线程最大数。

设置Server端线程池中支持的最大线程数,保存在binder驱动中的binder_proc结构体中。由于Client端是并发向Server发送请求的,所以Server端必须有线程池来处理并发请求。binder驱动中会记录Client端请求的线程数,如果超过最大线程数,则不再处理Client端发送的请求。

创建完ProcessState后调用startThreadPool函数,通过方法名称顾名思义就是启动线程池

void ProcessState::startThreadPool()
  {
      AutoMutex _l(mLock);
      if (!mThreadPoolStarted) {
          if (mMaxThreads == 0) {  
          mThreadPoolStarted = true;
          spawnPooledThread(true);
      }
  }
  
void ProcessState::spawnPooledThread(bool isMain)
  {
      if (mThreadPoolStarted) {
          String8 name = makeBinderThreadName();
          ALOGV("Spawning new pooled thread, name=%s\n", name.string
          //PoolThread继承Thread 也就是说调用Thread的run函数执行任务
          //isMain=true;
          sp<Thread> t = sp<PoolThread>::make(isMain);
          t->run(name.string());
      }
  }

PoolThread继承Thread,PoolThread又把任务交给了IPCThreadState的joinThreadPool函数,那IPCThreadState这个又是个什么东西呢?它才是实际干活的跨进程通信的。PoolThread在 ProcessState.cpp

protected:
virtual bool threadLoop()
{
IPCThreadState::self()->joinThreadPool(mIsMain);
return false;
}

IPCThreadState.cpp

IPCThreadState* IPCThreadState::self()
  {
      if (gHaveTLS.load(std::memory_order_acquire)) {
          restart:
          const pthread_key_t k = gTLS;
          IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
          if (st) return st;
          return new IPCThreadState;
      }
      
        goto restart;

首次进入self函数的时候gHaveTLS.load(std::memory_order_acquire)是false的,然后同goto函数执行restart。TLS是本地线程存储空间,全程叫做Thread local storage。并且这种空间每个线程都有,线程空间不共享这些空间。

通过pthread_getspecific/pthread_setspecific函数可以获取│设置这些空间中的内客。从线程本地存储空间中荻得保存在其中的IPCThreadstate对象。 有调用pthread_getspecific的地方,肯定也有调用pthread_setspecific的地方。

IPCThreadState::IPCThreadState()
        : mProcess(ProcessState::self()),
          mServingStackPointer(nullptr),
          mServingStackPointerGuard(nullptr),
          mWorkSource(kUnsetWorkSource),
          mPropagateWorkSource(false),
          mIsLooper(false),
          mIsFlushing(false),
          mStrictModePolicy(0),
          mLastTransactionBinderFlags(0),
          mCallRestriction(mProcess->mCallRestriction) {
//在构造函数中,把自已设置到线程本地存储中去。
      pthread_setspecific(gTLS, this);
      clearCaller();
//mIn和mOut是两个Parcel。把它看成是发送和接收命令的缓冲区即可。
      mIn.setDataCapacity(256);
      mOut.setDataCapacity(256);
  }

一个线程一个,每个IPCThreadState都有mIn和mOut,mIn是接收binder的数据,而mOut是用来发送数据的。 构造函数展示就分析这里,接着分析threadLoop函数里面调用的joinThreadPool函数出传入的参数true

void IPCThreadState::joinThreadPool(bool isMain)
  {
        //此时isMain是true代表主线程 isMain是false 代表普通的binder线程
       //BC_ENTER_LOOPER代表的是Binder主线程,不会退出的线程 
       //BC_REGISTER_LOOPER,表示是由binder驱动创建的线程
      mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
  
      mIsLooper = true;
      status_t result;
      do {
          //进程挂起引用
          processPendingDerefs();
          // 现在获取要处理的下一个命令,如果需要,请等待
          result = getAndExecuteCommand();
  
          if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
              LOG_ALWAYS_FATAL("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
                    mProcess->mDriverFD, result);
          }
  
          // Let this thread exit the thread pool if it is no longer
          // needed and it is not the main process thread.
          if(result == TIMED_OUT && !isMain) {
              break;
          }
      } while (result != -ECONNREFUSED && result != -EBADF);
  
      LOG_THREADPOOL("**** THREAD %p (PID %d) IS LEAVING THE THREAD POOL err=%d\n",
          (void*)pthread_self(), getpid(), result);
  
      mOut.writeInt32(BC_EXIT_LOOPER);
      mIsLooper = false;
      talkWithDriver(false);
  }
  
 
tatus_t IPCThreadState::talkWithDriver(bool doReceive)
  {
      //此时doReceive是false
      ......
      binder_write_read bwr;
      
     
 if (doReceive && needRead) {
          bwr.read_size = mIn.dataCapacity();
          bwr.read_buffer = (uintptr_t)mIn.data();
      } else {
          bwr.read_size = 0;
          bwr.read_buffer = 0;
      }
      
     
      // Return immediately if there is nothing to do.
      //如果数据空的话 被NO_ERROR调了 
      if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;

      
      do{
          //特殊的read,write, 当你用read,write不能完成某一功能时,就用ioctl
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0){
      
      
         }
      }
  }

这里请注意bwr是与binder交互数据,如果write和read都是空的话就返回NO_ERROR。

进程创建后的准备工作就基本是这些了,接下来我们就用 main_mediaserver.cpp来分析两个进程之间如何用binder通信的。

四.如何跨进程

我们就从 main_mediaserver.cpp作为切入点, AudioPolicyService是android音频系统的两大服务之一,另一个服务是AudioFliger。这两个服务都是在系统启动时由MediaServer加载

int main(int argc __unused, char **argv __unused)
  {
      signal(SIGPIPE, SIG_IGN);
      //创建ProcessState,在进程里面已经讲过。创建ProcessState对象
      sp<ProcessState> proc(ProcessState::self());
      //创建了BpServiceManager
      sp<IServiceManager> sm(defaultServiceManager());
      ALOGI("ServiceManager: %p", sm.get());
      //添加服务
      MediaPlayerService::instantiate();
      ResourceManagerService::instantiate();
      registerExtensions();
      ::android::hardware::configureRpcThreadpool(16, false);
      //启动线程池
      ProcessState::self()->startThreadPool();
      //内部也回调用joinThreadPool
      IPCThreadState::self()->joinThreadPool();
      ::android::hardware::joinRpcThreadpool();
  }

ProcessState::self()函数前面已经见过了,简单概括下就是创建了IPCThreadState每个IPCThreadState都有mIn和mOut,mIn是接收binder的数据,而mOut是用来发送数据的

1.defaultServiceManager函数

defaultServiceManager函数它位于xref: /frameworks/native/libs/binder/IServiceManager.cpp

sp<IServiceManager> defaultServiceManager()
  {
  //call_once只调用一次
      std::call_once(gSmOnce, []() {
          sp<AidlServiceManager> sm = nullptr;
          while (sm == nullptr) {
              sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
            ......
          }
          gDefaultServiceManager = sp<ServiceManagerShim>::make(sm);
      });
  
      return gDefaultServiceManager;
  }

call_once用于保证某个函数只调用一次,即使是多线程环境下,它也可以可靠地完成一次函数调用。也就是只有一个实例。先是调用 getContextObject函数

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
  {
      sp<IBinder> context = getStrongProxyForHandle(0);
      ......
      return context;
  }
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
  {
      sp<IBinder> result;
      ......
      //句柄值查询handle_entry
      handle_entry* e = lookupHandleLocked(handle);
      if (e != nullptr) {
          IBinder* b = e->binder;
          if (b == nullptr || !e->refs->attemptIncWeak(this)) {
              if (handle == 0) { //此时handle是0满足这个条件
                  IPCThreadState* ipc = IPCThreadState::self();
                      
                  CallRestriction originalCallRestriction = ipc->getCallRestriction();
                  ipc->setCallRestriction(CallRestriction::NONE);
  
                  Parcel data;
                  status_t status = ipc->transact(
                          0, IBinder::PING_TRANSACTION, data, nullptr, 0);
                //设置调用限制
                  ipc->setCallRestriction(originalCallRestriction);
  
                  if (status == DEAD_OBJECT)
                     return nullptr;
              }
             //主要是创建BpBinder
              sp<BpBinder> b = BpBinder::PrivateAccessor::create(handle);
              e->binder = b.get();
              if (b) e->refs = b->getWeakRefs();
              result = b;
          } else {
          
              result.force_set(b);
              e->refs->decWeak(this);
          }
      }
  
      return result;
  }

getStrongProxyForHandle函数的作用就是创建了一个BpBinder。BpBinder是IBinder的子类,BpBinder是客户端(p代表proxy代理的意思) BBinder是服务端。

sp<BpBinder> BpBinder::create(int32_t handle) {
      .....
      return sp<BpBinder>::make(BinderHandle{handle}, trackedUid);
  }
  
//handle等于0  代表serviceManager对应的BBinder
BpBinder::BpBinder(Handle&& handle)
        : mStability(0),
          mHandle(handle),
          mAlive(true),
          mObitsSent(false),
          mObituaries(nullptr),
          mTrackedUid(-1) {
      extendObjectLifetime(OBJECT_LIFETIME_WEAK);
  }

简化下 interface_cast(ProcessState::self()->getContextObject(nullptr))代码就是 interface_cast((BpBinder(0)))

我们继续往下分析interface_cast函数,在IServiceManager.cpp里面并没有搜到interface_cast具体代码,其实在头文件里面IServiceManager.h里面的IServiceManager.h有一段这样的代码

    inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
  {
      return INTERFACE::asInterface(obj);
  }
    #define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE0(ITYPE, INAME, BPTYPE)                     \
      const ::android::String16& ITYPE::getInterfaceDescriptor() const { return ITYPE::descriptor; } \
      ::android::sp<ITYPE> ITYPE::asInterface(const ::android::sp<::android::IBinder>& obj) {        \
          ::android::sp<ITYPE> intr;                                                                 \
          if (obj != nullptr) {                                                                      \
              intr = ::android::sp<ITYPE>::cast(obj->queryLocalInterface(ITYPE::descriptor));        \
              if (intr == nullptr) {    
                 /* 这里创建的是BpServiceManager对象 */      
                  intr = ::android::sp<BPTYPE>::make(obj);                                           \
              }                                                                                      \
          }                                                                                          \
          return intr;                                                                               \
      }                                                                                              \
      ::android::sp<ITYPE> ITYPE::default_impl;                                                      \
      bool ITYPE::setDefaultImpl(::android::sp<ITYPE> impl) {                                      
          assert(!ITYPE::default_impl);                                                              \
          if (impl) {                                                                                \
              ITYPE::default_impl = std::move(impl);                                                 \
              return true;                                                                           \
          }                                                                                          \
          return false;                                                                              \
      }                                                                                              \
      const ::android::sp<ITYPE>& ITYPE::getDefaultImpl() { return ITYPE::default_impl; }            \
      ITYPE::INAME() {}                                                                              \
      ITYPE::~INAME() {}  
    

这里的BpServiceManager不再通过手动实现,而是采用 AIDL(文件为 IServiceManager.aidl),生成 IServiceManager、BnServiceManager、BpServiceManager 的头文件及具体实现。BpServiceManager内部的持有BpBinder,它是怎么持有的呢?代码如下:

xref: /frameworks/native/libs/binder/aidl/android/os/IServiceManager.aidl

简化一下代码就是BpServiceManager(BpBinder(0))。我们再来分析下BpServiceManager构造函数,它是父类是BpInterface

在BpServiceManager的父类BpInterface,把BpBinder(0)又传给了BpInterface,而BpInterface又把BpBinder(0)传给了BpRefBase,然后传给了它的BpRefBase父类。

    class BpServiceManager : public BpInterface<IServiceManager>
  {
  public:
     explicit BpServiceManager(const sp<IBinder>& impl)
          : BpInterface<IServiceManager>(impl)
      {
      }
    
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
      : BpRefBase(remote)
  {
  }
    
   // mRemote就是BpBinder(0)
BpRefBase::BpRefBase(const sp<IBinder>& o)
      : mRemote(o.get()), mRefs(nullptr), mState(0)
  {
      extendObjectLifetime(OBJECT_LIFETIME_WEAK);
  
      if (mRemote) {
          mRemote->incStrong(this);           // Removed on first IncStrong().
          mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
      }
  }

也就是说BpServiceManager的一个变量mRemote指向了BpBinder。回想一下defaultServiceManager 函数,可以得到以下两个关键对象:

有一个BpBinder对象,它的handle值是0。
有一个BpServiceManager对象,它的 mRemote值是BpBinder。

2.instantiate如何添加服务

MediaPlayerService.cpp

void MediaPlayerService::instantiate() {
     defaultServiceManager()->addService(
             String16("media.player"), new MediaPlayerService());
 }

defaultServiceManager通过之前的分析知道这是一个BpServiceManager,也就是说BpServiceManager.addService函数

        namespace android {
    namespace os {

BpServiceManager::BpServiceManager(const ::android::sp<::android::IBinder>& _aidl_impl)
    : BpInterface<IServiceManager>(_aidl_impl){//_aidl_impl 就是 BpBinder(0) 实例
}
--------------------------------------------------
    ::android::binder::Status BpServiceManager::addService(const ::std::string& name, const ::android::sp<::android::IBinder>& service, bool allowIsolated, int32_t dumpPriority) {
  ::android::Parcel _aidl_data;
  _aidl_data.markForBinder(remoteStrong());//0、和 Rpc Binder有关
  ::android::Parcel _aidl_reply;
  ::android::status_t _aidl_ret_status = ::android::OK;
  ::android::binder::Status _aidl_status;
  //1、写 interface
  _aidl_ret_status = _aidl_data.writeInterfaceToken(getInterfaceDescriptor());
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  //2、写 name
  _aidl_ret_status = _aidl_data.writeUtf8AsUtf16(name);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  //3、写 binder 对象
  _aidl_ret_status = _aidl_data.writeStrongBinder(service);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  //4、写 allowIsolated
  _aidl_ret_status = _aidl_data.writeBool(allowIsolated);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  //5、写 dumpPriority
  _aidl_ret_status = _aidl_data.writeInt32(dumpPriority);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
	//这里的remote就是我们BpBinder的
  //6、借助 BpBinder(0)#transact 来发起 Binder 通信  
  _aidl_ret_status = remote()->transact(BnServiceManager::TRANSACTION_addService, _aidl_data, &_aidl_reply, 0);
  if (UNLIKELY(_aidl_ret_status == ::android::UNKNOWN_TRANSACTION && IServiceManager::getDefaultImpl())) {
     return IServiceManager::getDefaultImpl()->addService(name, service, allowIsolated, dumpPriority);
  }
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  //7、如果有返回值就从这个 parcel 包里读
  _aidl_ret_status = _aidl_status.readFromParcel(_aidl_reply);
  if (((_aidl_ret_status) != (::android::OK))) {
    goto _aidl_error;
  }
  if (!_aidl_status.isOk()) {
    return _aidl_status;
  }
  _aidl_error:
  _aidl_status.setFromStatusT(_aidl_ret_status);
  return _aidl_status;
}
     

在addService函数可能发现了一个remote()是不是有点熟悉。remote()这话就是我们前面提到BpBinder(0)也就说调用了 Binder.cpp的transact函数

status_t BpBinder::transact(
      uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
  {
      // Once a binder has died, it will never come back to life.
      if (mAlive) {
            ```
     if (CC_UNLIKELY(isRpcBinder())) {
              status = rpcSession()->transact(sp<IBinder>::fromExisting(this), code, data,   reply,
                                             flags);
          } else {
        //把工作又交给了IPCThreadState的函数了
              status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
          }    
          return status;
      }
  
      return DEAD_OBJECT;
  }

    

前面提到的IPCThreadState是实际干活的 ,transact里面调用了writeTransactionData函数写入了事务数据。

  
status_t IPCThreadState::transact(int32_t handle,
                                    uint32_t code, const Parcel& data,
                                    Parcel* reply, uint32_t flags)
  {
      LOG_ALWAYS_FATAL_IF(data.isForRpc(), "Parcel constructed for RPC, but being used with binder.");
  
      status_t err;
  
      flags |= TF_ACCEPT_FDS;
  
      //注意这里的第一个参数BC_TRANSACTION,它是应用程序向binder发备发运消息的消总码,
    //而binder设备向应用程序回复消息的消息码以BR_开头。消息码的定义在binder_module.h 中,
//请求消息码和回应消息码的对应关系,需要查看Binder驱动的实现才能将其理清楚,。
        //writeTransactionData
      err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
       
    if ((flags & TF_ONE_WAY) == 0){
        
    if (reply) {
       err = waitForResponse(reply);
     } else {
       Parcel fakeReply;
       err = waitForResponse(&fakeReply);
     }
    } else {
        //等待响应
          err = waitForResponse(nullptr, nullptr);
      }
  
      return err;
  }
//写入事物数据
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是和binder设备通信的数据结构。简单来说就是通信的一个对象
      binder_transaction_data tr; 
  
      tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
      //handle的值传递给了target,用来标识目的端,其中0是ServiceManager的标志。
      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();
      ......
      //把命令写到mout中,而不是直接发出去,可见这个函数有点名不刮实。
      mOut.writeInt32(cmd);
      mOut.write(&tr, sizeof(tr));
  
      return NO_ERROR;
  }

现在,已经把addService的请求信息写到mOut中了。接下来再看发送请求和接收回复部分的实现,代码在 waitForResponse函数中,从函数名称就是一个等待响应,现在我们可以假设收到回复了,如下所示:

status_t  IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
  {
      uint32_t cmd;
      int32_t err;
  
      while (1) {
            //将IPC数据通过Binder驱动发送给服务进程,talkWithDriver是和Binder驱动交互的核心、阻塞型函数
          if ((err=talkWithDriver()) < NO_ERROR) break;
          
          //检查服务进程返回来的数据   
         err = mIn.errorCheck(); 
         if (err < NO_ERROR) break;
         if (mIn.dataAvail() == 0) continue;                              
          .....
          default:
            //关注这个函数
              err = executeCommand(cmd);
              if (err != NO_ERROR) goto finish;
              break;
          }
      }
  
  finish:
      if (err != NO_ERROR) {
          if (acquireResult) *acquireResult = err;
          if (reply) reply->setError(err);
          mLastError = err;
      }
  
      return err;
  }
    
  status_t IPCThreadState::executeCommand(int32_t cmd){
   
    BBinder* obj;      
    RefBase::weakref_type* refs;
    status_t result = NO_ERROR;
    
switch ((uint32_t)cmd) {
    case BR_TRANSACTION:
    //读取mIn中的数据到一个binder_transaction_data中
     binder_transaction_data_secctx tr_secctx;
     binder_transaction_data& tr = tr_secctx.transaction_data;
    
    
    if (cmd == (int) BR_TRANSACTION_SEC_CTX) {
        result = mIn.read(&tr_secctx, sizeof(tr_secctx));
     } else {
       result = mIn.read(&tr, sizeof(tr));
       tr_secctx.secctx = 0;
     }


    if (tr.target.ptr) {
       if (reinterpret_cast<RefBase::weakref_type*>(
        tr.target.ptr)->attemptIncStrong(this)) {
        //cookie域存放的是Binder对象
         error = reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,&reply, tr.flags);
                     reinterpret_cast<BBinder*>(tr.cookie)->decStrong(this);
     } else {
       error = UNKNOWN_TRANSACTION;
    }
  } else {
    //the_context_object它是一个全局变量,也是一个BBinder对象
     error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
   }
    
    
case BR_DEAD_BINDER:
          {
    //收到驱动发来Service挂掉的消息,只有BpBinder能收到
              BpBinder *proxy = (BpBinder*)mIn.readPointer();
              proxy->sendObituary();
              mOut.writeInt32(BC_DEAD_BINDER_DONE);
              mOut.writePointer((uintptr_t)proxy);
          } break;
    
 case BR_SPAWN_LOOPER:
    //收到驱动层发来的消息,创建一个新的线程用于和binder通信的
          mProcess->spawnPooledThread(false);
          break;



}

waitForResponse函数的作用比较简单,就是根据(uint32_t)cmd做出相应的事情。

我们再来分析下talkWithDriver里面的ioctl函数

tatus_t IPCThreadState::talkWithDriver(bool doReceive)  {
    
//与binder交互数据
binder_write_read bwr;

//命令的填充 
    const bool needRead = mIn.dataPosition() >= mIn.dataSize();
      const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;

//重点是ioctl函数
    if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0){
        
   err = NO_ERROR;
    else
  err = -errno;
        
    }
}  

 
ioctl 是设备驱动程序中设备控制接口函数,一个字符设备驱动通常会实现设备打开、关闭、读、写等功能,在一些需要细分的情境下,如果需要扩展新的功能,通常以增设 ioctl() 命令的方式实现。

startThreadPool函数

这个函数在进程里面已经讲过,简单来说调用了IPCThreadState::self()->joinThreadPool(mIsMain);

joinThreadPool函数

void IPCThreadState::joinThreadPool(bool isMain)  {
     do {
      ......
// 现在获取要处理的下一个命令,如果需要,请等待
        result = getAndExecuteCommand();
      } 
    while (result != -ECONNREFUSED && result != -EBADF);
    
 //向Binder驱动发BC_REGISTER_LOOPER通知驱动用户空间线程已经创建

  mOut.writeInt32(BC_EXIT_LOOPER);
  mIsLooper = false;
  talkWithDriver(false);


}
        
    status_t IPCThreadState::getAndExecuteCommand(){

          status_t result;
          int32_t cmd;
         //发送命令读取请求
          result = talkWithDriver();
          if (result >= NO_ERROR) {
              size_t IN = mIn.dataAvail();
              if (IN < sizeof(int32_t)) return result;
              cmd = mIn.readInt32();
            
          pthread_mutex_lock(&mProcess->mThreadCountLock);
          mProcess->mExecutingThreadsCount++;
          if (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads &&
                  mProcess->mStarvationStartTimeMs == 0) {
              mProcess->mStarvationStartTimeMs = uptimeMillis();
          }
          pthread_mutex_unlock(&mProcess->mThreadCountLock);
           //处理消息 
          result = executeCommand(cmd);
          //**阻塞调用**
          pthread_mutex_lock(&mProcess->mThreadCountLock);
          mProcess->mExecutingThreadsCount--;
          if (mProcess->mExecutingThreadsCount < mProcess->mMaxThreads &&
                  mProcess->mStarvationStartTimeMs != 0) {
              int64_t starvationTimeMs = uptimeMillis() - mProcess->mStarvationStartTimeMs;
              if (starvationTimeMs > 100) {
                  ALOGE("binder thread pool (%zu threads) starved for %" PRId64 " ms",
                        mProcess->mMaxThreads, starvationTimeMs);
              }
              mProcess->mStarvationStartTimeMs = 0;
          }
  
          // Cond broadcast can be expensive, so don't send it every time a binder
          // call is processed. b/168806193
          if (mProcess->mWaitingForThreads > 0) {
              pthread_cond_broadcast(&mProcess->mThreadCountDecrement);
          }
          pthread_mutex_unlock(&mProcess->mThreadCountLock);
      }
  
      return result;
    }

这里用do while循环用来检查是否client端有信息发过来并且处理信息。通过pthread_mutex_lock返回时,该互斥锁已被锁定。线程调用该函数让互斥锁上锁,如果该互斥锁已被另一个线程锁定和拥有,则调用该线程将阻塞,直到该互斥锁变为可用为止。到这里binder的就基本分析完成一部分,下一篇计划写ServiceManager

binder支持多线程

通过前面的分析startThreadPool创建的线程启动joinThreadPool读取binder是否有请求以及主线程调用的joinThreadPool。 参考资料如下:

-<<深入理解android>>

本文在写作过程中参考了很多文章、在这里感谢大佬们的无私分享!