Android fromwork Binder 分析

Binder分析

Main_MediaServer.cpp
源码地址 :http://aospxref.com/android-10.0.0_r47/xref/frameworks/av/media/mediaserver/main_mediaserver.cpp

 int main(int argc __unused, char **argv __unused){		
      signal(SIGPIPE, SIG_IGN);
      // 1、获得一个ProcessState实例
      sp<ProcessState> proc(ProcessState::self());
      // 2、获得一个IServiceManager
      sp<IServiceManager> sm(defaultServiceManager());
      ALOGI("ServiceManager: %p", sm.get());
      // 初始化音频系统的主要服务
      AIcu_initializeIcuOrDie();
      // 多媒体系统的MediaPlayer服务,我们将以它作为主切入点
      MediaPlayerService::instantiate();
      ResourceManagerService::instantiate();
      registerExtensions();
      // 3、处理Binder驱动的消息。
      ProcessState::self()->startThreadPool();
      IPCThreadState::self()->joinThreadPool();
  }  
1、独一无二的ProcessState

源码地址:
http://aospxref.com/android-10.0.0_r47/xref/frameworks/native/libs/binder/ProcessState.cpp
http://aospxref.com/android-10.0.0_r47/xref/frameworks/native/libs/binder/Static.cpp

ProcessState的self方法很简单,一个单例模式。重点主要在 ProcessState的构造函数中,通过open_driver打开一个Binder驱动,并通过mmap函数与Binder进行内存映射,析构函数主要做的就是解除与Binder驱动的内存映射,并关闭Binder。由于ProcessState的惟一性,因此一个进程只打开设备一次。

 sp<ProcessState> ProcessState::self()  {
      Mutex::Autolock _l(gProcessMutex);
      // gProcess 定义在Static.cpp
      if (gProcess != nullptr) {
          return gProcess;
      }
      gProcess = new ProcessState(kDefaultDriver);
      return gProcess;
  }
   ...............................
   ProcessState::ProcessState(const char *driver)
      : mDriverName(String8(driver))
      , mDriverFD(open_driver(driver))  // 打开Binder驱动
      , mVMStart(MAP_FAILED)
      ......
      , mBinderContextUserData(nullptr)
      , mThreadPoolStarted(false)
      , mThreadPoolSeq(1)
      , mCallRestriction(CallRestriction::NONE)
  {
      if (mDriverFD >= 0) {
          // 通过mmap创建内存映射文件,Binder会分配一块内存用来接收数据。
          mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
          if (mVMStart == MAP_FAILED) {
              // *sigh*
              ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
              close(mDriverFD);
              mDriverFD = -1;
              mDriverName.clear();
          }
      }
      LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
  }
  
  ProcessState::~ProcessState()
  {
      if (mDriverFD >= 0) {
          if (mVMStart != MAP_FAILED) {
              // munmap 取消与Binder驱动映射
              munmap(mVMStart, BINDER_VM_SIZE);
          }
          // 关闭Binder驱动。
          close(mDriverFD);
      }
      mDriverFD = -1;
  }
  
  };
static int open_driver()
{
    int fd =open("/dev/binder", O_RDWR);//打开/dev/binder设备
    if (fd>= 0) {
         ......
       size_t maxThreads = 15;
       //通过ioctl方式告诉binder驱动,这个fd支持的最大线程数是15个
       result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);  
   }
return fd;
......
}

有关于mmap可参考linux库函数mmap()原理及用法详解_linux mmap函数-CSDN博客

2、defaultServiceManage是如何创建并返回一个IServiceManager对象的?

源码地址:
http://aospxref.com/android-10.0.0_r47/xref/frameworks/native/libs/binder/IServiceManager.cpp
http://aospxref.com/android-10.0.0_r47/xref/frameworks/native/libs/binder/include/binder/IInterface.h
http://aospxref.com/android-10.0.0_r47/xref/frameworks/native/libs/binder/include/binder/IServiceManager.h
http://aospxref.com/android-10.0.0_r47/xref/frameworks/native/libs/binder/IPCThreadState.cpp
http://aospxref.com/android-10.0.0_r47/xref/frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
在main_mediaserver的main函数中调用defaultServiceManager()返回一个IServiceManager,defaultServiceManager方法如下,从第一行可见IServiceManager也是一个单例模式。

 sp<IServiceManager> defaultServiceManager()
  {
      if (gDefaultServiceManager != nullptr) return gDefaultServiceManager;
      {
          AutoMutex _l(gDefaultServiceManagerLock);
          while (gDefaultServiceManager == nullptr) {
              gDefaultServiceManager = interface_cast<IServiceManager>(
                  ProcessState::self()->getContextObject(nullptr));
              if (gDefaultServiceManager == nullptr)
                  sleep(1);
          }
      }
      return gDefaultServiceManager;
  }

从上面的代码可以看出真正的IServiceManager是通过ProcessState::self()->getContextObject(nullptr)方法创建的。这里需要注意的是interface_cast这个模板方法是我们后面获取到IServiceManager的关键。

 sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
  {
      return getStrongProxyForHandle(0);
  }
 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
  {
      sp<IBinder> result;  
      AutoMutex _l(mLock);
     /** 根据索引查找对应资源。如果lookupHandleLocked发现没有对应的资源项,则会创建一个新的项并返回。
		 这个新项的内容需要填充。
	  */
      handle_entry* e = lookupHandleLocked(handle); 
      if (e != nullptr) {
          IBinder* b = e->binder;
          if (b == nullptr || !e->refs->attemptIncWeak(this)) {
              if (handle == 0) {
                  Parcel data;
                  status_t status = IPCThreadState::self()->transact(
                          0, IBinder::PING_TRANSACTION, data, nullptr, 0);
                  if (status == DEAD_OBJECT)
                     return nullptr;
              }
              //对于新创建的资源项,它的binder为空,所以走这个分支。handle  = 0
              b = BpBinder::create(handle);
              e->binder = b;
              if (b) e->refs = b->getWeakRefs();
              result = b;
          } else {
              result.force_set(b);
              e->refs->decWeak(this);
          }
      }
      return result;
  }

从上面的代码可以看到getContextObject啥也没干,直接调用了getStrongProxyForHandle方法。看到这里可能会有点疑惑我们不是要创建IServiceManager吗?怎么变成了IBinder。IBinder有两个子类BpBinder、BBinder,其中BpBinder是客户端用来与Service交互的代理类,BBinder则是与BpBinder相对应的服务端。
注意:
我们给BpBinder构造函数传的参数handle的值是0。这个0在整个Binder系统中有重要含义—因为0代表的就是ServiceManager所对应的BBinder。

  BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
      : mHandle(handle)
      , mAlive(1)
      , mObitsSent(0)
      , mObituaries(nullptr)
      , mTrackedUid(trackedUid)
  {
      ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);  
      extendObjectLifetime(OBJECT_LIFETIME_WEAK);
      //另一个重要对象是IPCThreadState,我们稍后会详细讲解。
      IPCThreadState::self()->incWeakHandle(handle, this);
  }

看上面的代码,会觉得BpBinder确实简单,不过再仔细查看,你或许会发现,BpBinder、BBinder这两个类没有任何地方操作ProcessState打开的那个/dev/binder设备,换言之,这两个Binder类没有和binder设备直接交互。
不过还记得我们最开始获取IServiceManager的时候是通过interface_cast(ProcessState::self()>getContextObject(nullptr));这个方法来创建的,interface_cast的内容如下:

 template<typename INTERFACE>
 inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
 {
      return INTERFACE::asInterface(obj);
 }

这是一个模板方法,可以看到我们最终调用的是IServiceManager的asInterface方法返回,刚才提到,IBinder家族的BpBinder和BBinder是与通信业务相关的,那么业务层的逻辑又是如何巧妙地架构在Binder机制上的呢?关于这些问题,可以用一个绝好的例子来解释,它就是IServiceManager。

  1. 定义业务逻辑

先回答第一个问题:如何表述应用的业务层逻辑。可以先分析一下IServiceManager是怎么做的。IServiceManager定义了ServiceManager所提供的服务,看它的定义可知,其中有很多有趣的内容。IServiceManager定义在IServiceManager.h中,代码如下所示:

  class IServiceManager : public IInterface
  {
  public:
      DECLARE_META_INTERFACE(ServiceManager)
	  ...............
      virtual sp<IBinder>         getService( const String16& name) const = 0;
      virtual sp<IBinder>         checkService( const String16& name) const = 0;
      virtual status_t addService(const String16& name, const sp<IBinder>& service,
                                  bool allowIsolated = false,
                                  int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;
      virtual Vector<String16> listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0;
 	  ...............
 };
  1. 业务与通信的挂钩
    Android巧妙地通过DECLARE_META_INTERFACEIMPLEMENT_META_INTERFACE宏,将业务和通信牢牢地钩在了一起。DECLARE_META_INTERFACEIMPLEMENT_META_INTERFACE这两个宏都定义在刚才的IInterface.h中。先看DECLARE_META_INTERFACE这个宏,如下所示:
  #define DECLARE_META_INTERFACE(INTERFACE)                               \
  public:                                                                 \
      static const ::android::String16 descriptor;                        \
      static ::android::sp<I##INTERFACE> asInterface(                     \
              const ::android::sp<::android::IBinder>& obj);              \
      virtual const ::android::String16& getInterfaceDescriptor() const;  \
      I##INTERFACE();                                                     \
      virtual ~I##INTERFACE();                                            \
      static bool setDefaultImpl(std::unique_ptr<I##INTERFACE> impl);     \
      static const std::unique_ptr<I##INTERFACE>& getDefaultImpl();       \
	  ........

将IServiceManager的DELCARE宏进行相应的替换后得到的代码如下所示:
DECLARE_META_INTERFACE(IServiceManager)

// 定义一个描述字符串
static const android::String16 descriptor; 
// 定义一个 asInterface 函数
static android::sp<IServiceManager> asInterface(const android::sp<android::IBinder>& obj);
// 定义一个getInterfaceDescriptor应该就是获取descriptor
virtual const android::String16& getInterfaceDescriptor() const;
// 定义IServiceManager的构造函数和析构函数
IServiceManager();
// 定义一个默认实现IServiceManager
static bool setDefaultImpl(std::unique_ptr<IServiceManager> impl);
// 定义一个获取默认实现
static const std::unique_ptr<IServiceManager>& getDefaultImpl();

DECLARE 宏声明了一些函数和一个变量,那么,IMPLEMENT宏的作用肯定就是定义它们了。IMPLEMENT的定义在IInterface.h中,IServiceManager是如何使用了这个宏呢?只有一行代码,在IServiceManager.cpp中,如下所示:

IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager");

很简单,可直接将IServiceManager中的IMPLEMENT宏的定义展开,如下所示:

const android::String16 IServiceManager::descriptor(NAME);           
const android::String16&  IServiceManager::getInterfaceDescriptor() 
const {             
           return IServiceManager::descriptor;                                
}                                                                   
android::sp<IServiceManager> IServiceManager::asInterface(              
              const ::android::sp<::android::IBinder>& obj) {                                                                   
          android::sp<IServiceManager> intr; 
          // 这个obj就是前面创建的BnBinder
          if (obj != nullptr) {                                          
              intr = static_cast<IServiceManager*>(                          
                  obj->queryLocalInterface(IServiceManager::descriptor).get());               
              if (intr == nullptr) {                                      
                  intr = new BpServiceManager(obj);                          
              }                                                           
          }                                                               
          return intr;                                                    
      }                                                                   
      std::unique_ptr<IServiceManager> IServiceManager::default_impl;           
      bool IServiceManager::setDefaultImpl(std::unique_ptr<IServiceManager> impl)
      {                                                                   
          if (!IServiceManager::default_impl && impl) {                      
              IServiceManager::default_impl = std::move(impl);               
              return true;                                                
          }                                                               
          return false;                                                   
      }                                                                   
      const std::unique_ptr<IServiceManager>& IServiceManager::getDefaultImpl() 
      {                                                                   
          return IServiceManager::default_impl;                              
      }                                                                   
      IServiceManager::IServiceManager() { }                                    
      IServiceManager::~IServiceManager() { }                                   

通过interface_cast利用BpBinder对象作为参数新建了一个BpServiceManager对象。BpServiceManager对象实现了IServiceManager的业务函数,现在又有BpBinder作为通信的代表,接下来的工作就简单了。下面,要通过分析MediaPlayerService的注册过程,进一步分析业务函数的内部是如何工作的。

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

根据前面的分析,defaultServiceManager()实际返回的对象是BpServiceManager,它是IServiceManager的后代,代码如下所示:

  virtual status_t addService(const String16& name, const sp<IBinder>& service,
                                  bool allowIsolated, int dumpsysPriority) {
       //Parcel:就把它当作是一个数据包。                           
      Parcel data, reply;
      data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
      data.writeString16(name);
      data.writeStrongBinder(service);
      data.writeInt32(allowIsolated ? 1 : 0);
      data.writeInt32(dumpsysPriority);
      // remote 这个就是前面创建的BnBinder对象,调用transact函数
      status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
      return err == NO_ERROR ? reply.readExceptionCode() : err;
  }

下面分析BpBinder的transact函数,它的实现代码如下所示:

status_t BpBinder::transact(
     uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
  {
     if (mAlive) {
     	 // BpBinder 将数据交给IPCThreadState真正的牛马
          status_t status = IPCThreadState::self()->transact(
              mHandle, code, data, reply, flags);
          if (status == DEAD_OBJECT) mAlive = 0;
         	return status;
      }
 
      return DEAD_OBJECT;
  }

这里面只做了一件事,调用了IPCThreadState中的transact方法,我们继续往下:

 IPCThreadState* IPCThreadState::self()
  { 
      if (gHaveTLS) {  // 第一次进来为false
  restart:
		  /*
		   TLS是Thread Local Storage(线程本地存储空间)的简称。
		   这里只需知晓:这种空间每个线程都有,而且线程间不共享这些空间。
		   通过pthread_getspecific/pthread_setspecific函数可以获取/设置这些空间中的内容。
		   从线程本地存储空间中获得保存在其中的IPCThreadState对象。
		   有调用pthread_getspecific的地方,肯定也有调用pthread_setspecific的地方
		 */
          const pthread_key_t k = gTLS;
          IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
          if (st) return st;
          // new一个对象,构造函数中会调用pthread_setspecific
          return new IPCThreadState;
      }
     ........
      pthread_mutex_lock(&gTLSMutex);
      if (!gHaveTLS) {
          int key_create_value = pthread_key_create(&gTLS, threadDestructor);
          if (key_create_value != 0) {
              pthread_mutex_unlock(&gTLSMutex);
              ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
                      strerror(key_create_value));
              return nullptr;
          }
          gHaveTLS = true;
      }
      pthread_mutex_unlock(&gTLSMutex);
      goto restart;
 }

接下来,有必要转向分析它的构造函数IPCThreadState(),如下所示:

IPCThreadState::IPCThreadState()
      : mProcess(ProcessState::self()),
        mWorkSource(kUnsetWorkSource),
        mPropagateWorkSource(false),
        mStrictModePolicy(0),
        mLastTransactionBinderFlags(0),
        mCallRestriction(mProcess->mCallRestriction)
  {
       //在构造函数中,把自己设置到线程本地存储中去。
      pthread_setspecific(gTLS, this);
      clearCaller();
      // 设置发送和接受数据缓冲区大小
      mIn.setDataCapacity(256);
      mOut.setDataCapacity(256);
      mIPCThreadStateBase = IPCThreadStateBase::self();
  }

每个线程都有一个IPCThreadState,每个IPCThreadState中都有一个mIn、一个mOut,其中mIn是用来接收来自Binder设备的数据的,而mOut则是用来存储发往Binder设备的数据的。
上面只是描述了IPCThreadState和线程之间的关系,transact才是真正与Binder完成通信的牛马。

  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;
 	  ..................
		/*
		 注意这里的第一个参数BC_TRANSACTION,它是应用程序向binder设备发送消息的消息码,
		而binder设备向应用程序回复消息的消息码以BR_开头。消息码的定义在binder_module.h中,
		 请求消息码和回应消息码的对应关系,需要查看Binder驱动的实现才能将其理清楚,我们这里暂时用不上。
		*/
      err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
      ..................
      err = waitForResponse(reply);
      ..................
      return err;
  }

流程很清晰,通过writeTransactionData写入到IPCThreadState的缓冲区中然后通过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 是和binder设备通信的数据结构。   
      binder_transaction_data tr;
      tr.target.ptr = 0; 
      //果然,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();
      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();
      } else if (statusBuffer) {
          tr.flags |= TF_STATUS_CODE;
          *statusBuffer = err;
          tr.data_size = sizeof(status_t);
          tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
          tr.offsets_size = 0;
          tr.data.ptr.offsets = 0;
      } else {
          return (mLastError = err);
      }
      //把命令写到mOut中。
      mOut.writeInt32(cmd);
      mOut.write(&tr, sizeof(tr));
      return NO_ERROR;
 }

原来writeTransactionData并不是把数据发送给Binder而是将数据写入到IPCThreadState的mOut中,看来最后发送数据的操作是在waitForResponse中进行了:

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
  {
      uint32_t cmd;
      int32_t err;  
      while (1) {
         // 好了到这就是最终发送数据的地方了talkWithDriver
         if ((err=talkWithDriver()) < NO_ERROR) break;
          err = mIn.errorCheck();
          if (err < NO_ERROR) break;
          if (mIn.dataAvail() == 0) continue;
          cmd = (uint32_t)mIn.readInt32();  
          switch (cmd) {
          case BR_TRANSACTION_COMPLETE:
              if (!reply && !acquireResult) goto finish;
              break;
         ......................
          default:
          // 这
              err = executeCommand(cmd);
              if (err != NO_ERROR) goto finish;
              break;
          }
      }
  
...................

哪talkWithDriver是如何发送数据的呢?

status_t IPCThreadState::talkWithDriver(bool doReceive)
 {
      if (mProcess->mDriverFD <= 0) {
          return -EBADF;
      }
      binder_write_read bwr;
      const bool needRead = mIn.dataPosition() >= mIn.dataSize();  
      const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
      bwr.write_size = outAvail;
      bwr.write_buffer = (uintptr_t)mOut.data();
      if (doReceive && needRead) {
          bwr.read_size = mIn.dataCapacity();
          bwr.read_buffer = (uintptr_t)mIn.data();
      } else {
          bwr.read_size = 0;
          bwr.read_buffer = 0;
      }
      if ((bwr.write_size == 0) && (bwr.read_size == 0)) return NO_ERROR;  
      bwr.write_consumed = 0;
      bwr.read_consumed = 0;
     status_t err;
     do {
  #if defined(__ANDROID__)
           // 通过ioctl方法将数据发送给Binder驱动。
           if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
                 err = NO_ERROR;
          else
              err = -errno;
  #else
          err = INVALID_OPERATION;
  ........................................
      return err;
  }

到现在数据的发送已经完成了,那么是在什么时候去处理其他进程发送的消息呢,答案在IPCThreadState中的joinThreadPool函数中,还记得MediaServer最后的哪两个函数吗,ProcessState::self()->startThreadPool(); 和 IPCThreadState::self()->joinThreadPool();
我们先看startThreadPool:

  void ProcessState::startThreadPool()
  {      
      AutoMutex _l(mLock);
      if (!mThreadPoolStarted) {
          mThreadPoolStarted = true;
          // 看来走了这里
          spawnPooledThread(true);
      }
  }
 void ProcessState::spawnPooledThread(bool isMain)
  {
      if (mThreadPoolStarted) {
          String8 name = makeBinderThreadName();
          // 创建了一个PoolThread 参数是true
          sp<Thread> t = new PoolThread(isMain);
          t->run(name.string());
      }
  }

PoolThread是在IPCThreadState中定义的一个Thread子类,它的实现,如下所示:

  class PoolThread : public Thread
  {
  public:
      explicit PoolThread(bool isMain)
          : mIsMain(isMain)
      {
      }
  
  protected:
      virtual bool threadLoop()
      {
          IPCThreadState::self()->joinThreadPool(mIsMain);
          return false;
      }
  
      const bool mIsMain;
  };

在这里我们可以看到最终还是调用了IPCThreadState::self()->joinThreadPool这个函数,说明最终数据处理的地方就在这里了:

  void IPCThreadState::joinThreadPool(bool isMain)
  {
     //注意,如果isMain为true,我们需要循环处理。把请求信息写到mOut中,待会儿一起发出去
      mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);  
      status_t result;
      do {
          processPendingDerefs();
          //发送命令,读取请求,并处理数据
          result = getAndExecuteCommand();
          if (result < NO_ERROR && result != TIMED_OUT && result != -ECONNREFUSED && result != -EBADF) {
              ALOGE("getAndExecuteCommand(fd=%d) returned unexpected error %d, aborting",
                    mProcess->mDriverFD, result);
              abort();
          }
          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);
      talkWithDriver(false);
  }
  void IPCThreadState::processPendingDerefs()
  {
      if (mIn.dataPosition() >= mIn.dataSize()) {
          while (mPendingWeakDerefs.size() > 0 || mPendingStrongDerefs.size() > 0) {
              while (mPendingWeakDerefs.size() > 0) {
                  RefBase::weakref_type* refs = mPendingWeakDerefs[0];
                  mPendingWeakDerefs.removeAt(0);
                  refs->decWeak(mProcess.get());
              }
              // //处理已经死亡的BBinder对象
              if (mPendingStrongDerefs.size() > 0) {
                  BBinder* obj = mPendingStrongDerefs[0];
                  mPendingStrongDerefs.removeAt(0);
                  obj->decStrong(mProcess.get());
              }
          }
      }
  }

至此通过Binder的发送添加服务流程已经完成,最后总结一下Binder是如何进行数据发送的:
1、在创建进程的时候会去打开Binder驱动,通过mmap函数创建内存映射文件。
2、获得一个IServiceManager,期间我们借助了DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE以及这两个宏创建了BpServiceManager,将BnBinder与BpServiceManager进行绑定。
3、当我们调用IServiceManager.addService函数会去调用BnBinder中的transact方法,BnBinder只做了一个中间人并没有去做具体的操作,他将数据交给了IPCThreadState。
4、IPCThreadState在构造函数设置与Binder通信的缓冲区大小,并把自己设置到线程本地存储中去,在transact函数中,主要有两个函数writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);, waitForResponse(reply);writeTransactionData主要将数据结构转换成与Binder通信对应的数据结构,并把数据写入到IPCThreadState的缓冲区中,waitForResponse将数据通过ioctl函数将数据发送给Binder,并处理响应结果。
5、通过IPCThreadState中的joinThreadPool函数处理其他进程的数据。

前面我们只是向Binder发送了一个注册MediaplayManager的请求,那么这个请求在哪被处理呢,这时候就需要用到我们的ServiceManager:
http://aospxref.com/android-10.0.0_r47/xref/frameworks/native/cmds/servicemanager/service_manager.c
ServiceManager的入口函数:

  int main(int argc, char** argv)
  {
      struct binder_state *bs;
      union selinux_callback cb;
      char *driver;
  
      if (argc > 1) {
          driver = argv[1];
      } else {
          driver = "/dev/binder";
      }
  	  // 打开Binder驱动
      bs = binder_open(driver, 128*1024);  
      ...............................
      // 将自己设置为service
      if (binder_become_context_manager(bs)) {
          ALOGE("cannot become context manager (%s)\n", strerror(errno));
          return -1;
      }
      // 轮询处理Binder数据
      binder_loop(bs, svcmgr_handler);
      return 0;
  }

这里很简单就三个步骤:
1、打开Binder驱动
2、将自己设置为service
3、处理其他进程发送的数据。
怎么成为服务端为其他进程服务呢,binder_become_context_manager实现如下:

  int binder_become_context_manager(struct binder_state *bs)
  {
      struct flat_binder_object obj;
      memset(&obj, 0, sizeof(obj));
      obj.flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
      //实现太简单了!前面我们发送数据的时候handle的值为0,所以这里也是0,是不是就是这样对应上的呢?
      int result = ioctl(bs->fd, BINDER_SET_CONTEXT_MGR_EXT, &obj);  
      if (result != 0) {
          android_errorWriteLog(0x534e4554, "121035042");
          result = ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
      }
      return result;
  }

最后一个函数binder_loop,这个函数主要进行数据接收然后把数据交给svcmgr_handler进行处理,感兴趣自行阅读。

  • 29
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xpq_lrh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值