Android Binder机制的详解

1.Binder机制简介

Android Binder是源于Palm的OpenBinder,它为android设备跨进程访问而设计。Binder机制从表现上看可以实现java 和native层的对象实例可以从一个进程访问到另一个进程,从而透明的实现跨进程的调用。调用者感觉不到自己的请求是在另一个进程中完成并返回结果的。在android系统中使用Binder机制最多的是系统服务,这些服务一般运行在特定的进程中。服务的使用者成为Client,Client一般是应用程序,是跨进程访问的请求发起者。运行行在特定进程中的服务被成为server,这些server用于接受client端发起的请求并处理具体相关业务并返回结果。

Android系统中的Binder机制被涉及为java和c++层两部分,使得java和native层都可以实现Binder的client、server端通过系统的/dev/binder虚拟设备提供跨进程发起请求和接受请求处理业务返回结果的能力。其中java层的Binder是对C++层Binder机制的上层封装,通过JNI的方式调用到C++的实现逻辑中。

我将通过分别分析C++层的实现和java的封装两部分分析Binder机制。

#2.C++层Binder的实现
我通过分析MediaServer的实现逻辑通过阅读源码了解一下Binder的实现逻辑.MediaServer执行程序的入口是main()方法:

.../frameworks/av/media/mediaserver/main_mediaserver.cpp
int main(int argc __unused, char** argv)
{
    .....................
    
        //获取一个ProcessState对象,同时通过pen_driver()打开/dev/binder的虚拟设备,通过mmap()为binder分配一块空间用于通信读写,通过
        //iotrl()为binder指定线程数
        sp<ProcessState> proc(ProcessState::self());
        //获取一个IServerManager对象,用于服务注册
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        //初始化音频系统AudioFlinger
        AudioFlinger::instantiate();
        //多媒体服务初始化
        MediaPlayerService::instantiate();
        ResourceManagerService::instantiate();
        //cameraServer 相机服务
        CameraService::instantiate();
        //音频系统AudioPolicy服务
        AudioPolicyService::instantiate();
        SoundTriggerHwService::instantiate();
        RadioService::instantiate();
        registerExtensions();
        //创建线程池?
        ProcessState::self()->startThreadPool();
        //加入线程池?
        IPCThreadState::self()->joinThreadPool();
        
        ....................
}

1.1ProcessState的作用

从main_mediaServer.cpp的main()方法中可以看到 sp proc(ProcessState::self())获取一个ProcessState对象,先看一下ProcessState::self()函数都做了什么:

sp<ProcessState> ProcessState::self()
{
    Mutex::Autolock _l(gProcessMutex);
    if (gProcess != NULL) {
        return gProcess;
    }
    //创建一个新的ProcessState对象
    gProcess = new ProcessState;
    return gProcess;
}

实现很简单,self()方法就是一个简单的单例调用new 创建了一个ProcessState对象。那看一下ProcessState的构造方法都做了些什么:

.../frameworks/native/libs/binder/ProcessState.cpp

    ProcessState::ProcessState()
    : mDriverFD(open_driver())          //打开Binder
    , mVMStart(MAP_FAILED)              //映射内存的的起始地址
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mManagesContexts(false)
    , mBinderContextCheckFunc(NULL)
    , mBinderContextUserData(NULL)
    , mThreadPoolStarted(false)
    , mThreadPoolSeq(1)
{
    if (mDriverFD >= 0) {
#if !defined(HAVE_WIN32_IPC)
        //为Binder分配一块内存用于存取数据
        // mmap the binder, providing a chunk of virtual address space to receive transactions.
        mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
        if (mVMStart == MAP_FAILED) {
            // *sigh*
            ALOGE("Using /dev/binder failed: unable to mmap transaction memory.\n");
            close(mDriverFD);
            mDriverFD = -1;
        }
#else
        mDriverFD = -1;
#endif
    }

    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}

在ProcessState的构造函数中首先调用了open_driver()方法初始化了一个ProcessState的变量mDriverFD,这个open_driver()方法很重要,它打开/dev/binder这个虚拟设备为binder通信做准备。在打开binder设备后又调用系统函数mmap() 为打开的binder设备在内存中映射了一块内存空间并将内存地址返回给变量mVMStart。

那先看一下open_driver()是怎么样打开binder驱动设备的。

.../frameworks/native/libs/binder/ProcessState.cpp
static int open_driver()
{
    //打开/dev/binder虚拟设备
    int fd = open("/dev/binder", O_RDWR);
    
    ```````````````````````
    //通过ioctl()告诉驱动最多支持的线程数 15
    size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
    result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
    return fd;
}

在open_driver()中直接调用了linux系统函数open()打开了/dev/binder设备并为启动的Binder虚拟设备通过ioctl()[系统函数]为binder 设备指定了最大线程数;

分析到这里基本上就是main_mediaserver–>main()函数中sp proc(ProcessState::self())这句代码做的事情。总结起来主要做了两件事情:

  • open_driver()打开/dev/binder虚拟设备驱动
  • 为打开的Binder虚拟设备分配内存映射空间

那下边继续回到main_mediaserver的main()方法中继续分析,看在获取到ProcessState后的sp sm =defaultServiceManager()干了什么。

defaultServerManager

defaultServerManager()函数会返回一个实现了IServerManager接口的对象,通过这个对象我们可以和另外一个进程的ServerManager进行通信.先看一下defaultServerManager()方法都干了点什么:

.../frameworks/native/libs/binder/IServiceManager.cpp
sp<IServiceManager> defaultServiceManager()
{
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
    
    {
        AutoMutex _l(gDefaultServiceManagerLock);
        while (gDefaultServiceManager == NULL) {
            //gDefaultServiceManager对象创建的地方
            gDefaultServiceManager = interface_cast<IServiceManager>(
                ProcessState::self()->getContextObject(NULL));
            if (gDefaultServiceManager == NULL)
                sleep(1);
        }
    }
    
    return gDefaultServiceManager;
}

这个方法在IServerManager.cpp中定义的,这个方法又是一个单例来获取一个IServerManger对象。内容很简单但是当我看到interface_cast(…)后我感觉一点都不好,但是它是很重要的不过暂时先不管它。先看看ProcessState::self()->getContextObject(NULL)方法都干了点什么:

.../frameworks/native/libs/binder/ProcessState.cpp

    sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    //好吧,这里直接调用了getStrongProxyForHande()方法。
    //但是传入的参数 0很重要
    return getStrongProxyForHandle(0);
}


sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    sp<IBinder> result;

    AutoMutex _l(mLock);
    //资源查找,找不到会创建一个新的对象
    handle_entry* e = lookupHandleLocked(handle);

    if (e != NULL) {
        IBinder* b = e->binder;
        //新创建的binder 一定为空
        if (b == NULL || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
            
               ························
               
                Parcel data;
                //这里是一次IPC的binder通信过程,暂时不分析
                //我们现在分析的是getStrongProxyForHander()方法返回的是什么
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, NULL, 0);
                if (status == DEAD_OBJECT)
                   return NULL;
            }
            //创建一个BpBinder对象
            b = new BpBinder(handle); 
            e->binder = b;      //填充
            if (b) e->refs = b->getWeakRefs();
            result = b;
            
            ···············
    }

    return result;
}

在getStrongProxyForHandle()函数中首先调用了lookupHandleLocked(0)方法获取一个handle_entry 类型的结构指针。lookupHandleLocked()就是在一个Vector中查找对象找不到就创建一个,不重要先忽略。然后这里创建了一个BpBinder对象,根据名字看应该是和Binder机制有关的我们先可以一下BpBinder的构造方法:

.../frameworks/native/libs/binder/BpBinder.cpp

//BpBinder构造函数
BpBinder::BpBinder(int32_t handle)
    : mHandle(handle)           //handle 为 0
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(NULL)
{
    ```````````````
    //另外一个重要对象?
    IPCThreadState::self()->incWeakHandle(handle);
}

在BpBinder的构造函数中出现了一个新对象IPCThreadState,对象名字竟然以IPC应该是和Binder的跨进程通信又关系的。

.../frameworks/native/libs/binder/IPCThreadState.cpp

IPCThreadState* IPCThreadState::self()
{
    if (gHaveTLS) {
restart:
        const pthread_key_t k = gTLS;
        //TLS = thread location storage 线程本地空间 是线程独有空间
        //getSpecific()和setSpecific()可以操作这部分空间
        IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
        if (st) return st;
        //返回一个创建的IPCThreadState对象
        return new IPCThreadState;
    }
    
    if (gShutdown) return NULL;
    
    ````````
    goto restart;
}

当我第一次看到这个方法时还是有点震惊的,我虽然没有学习过C++但是大一那会儿学习过C语言。当时老师就告诉我们尽量少用goto这个逻辑跳转。这里竟然用了。

这个方法中IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k)是从线程的TLS中获取一个IPCThreadState对象指针,第一次调用市肯定是不存在这个对象的所以会new 一个IPCThreadState对象。

TLS是操作系统为每个线程都单独分配的一块内存空间,当前线程独占其他线程无法访问。所以在多线程下对它的访问的线程安全的。

既然这里调用了IPCThreadState的构造函数我们就看看它长什么样子:

.../frameworks/native/libs/binder/IPCThreadState.cpp

IPCThreadState::IPCThreadState()
    : mProcess(ProcessState::self()),       //获取上边我们创建的ProcessState对象
      mMyThreadId(gettid()),
      mStrictModePolicy(0),
      mLastTransactionBinderFlags(0)
{
    //在构造函数中将自己设置到TLS中
    pthread_setspecific(gTLS, this);
    clearCaller();
    mIn.setDataCapacity(256);
    mOut.setDataCapacity(256);
}

IPCThreadState的构造函数很简单就是创建自己后将自己设置到当前线程的TLS中,下次就可以直接从当前线程的TLS中获取了。

我们分析了这么多其实都是gDefaultServiceManager = interface_cast(ProcessState::self()->getContextObject(NULL))的getContextObject(null)方法开始分析。好吧,要不是不是回到看一下我都已经不知道自己现在在分析什么了。那现在我们知道了getContextObject()返回的是一个BpBinder对象。那我们再看看interface_cast()设个什么东西:

.../frameworks/native/include/binder/IInterface.h
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

原来interface_cast()是一个定义在IInterface.h头文件中的模范方法,那我们现在根据我们上边的调用翻译一下这个模版方法现在的样子:

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

***实话说分析到这里我有点懵了不知道怎么分析了。***既然模版方法中调用了IServiceManager::asInterface()方法我们就先看看IServiceManager接口的内容:

.../frameworks/native/include/binder/IServiceManager.h

class IServiceManager : public IInterface
{
public:
    //这个鸿定义在IInterface.h中,他主要做了如下工作
    //1.定义了一个描述字符串
    //2.定义了一个asInterface函数
    //3.定义了一个getInterfaceDescriptor函数用于返回上边定义的描述字符串
    //4.定义了构造函数和析构函数
    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) = 0;

    virtual Vector<String16>    listServices() = 0;

    enum {
        GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
        CHECK_SERVICE_TRANSACTION,
        ADD_SERVICE_TRANSACTION,
        LIST_SERVICES_TRANSACTION,
    };
};

我们都知道Android系统中的系统服务像AMS、WMS等都是有ServiceManager统一管理的。这里的IServiceManager.h就是定义了他的功能接口。在这个接口定义中我们看到一个宏DECLARE_META_INTERFACE(ServiceManager)的使用,那我们先分析一下这个宏定义是什么样子:

#define DECLARE_META_INTERFACE(INTERFACE)                               \
    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 const android::String16 descriptor;
    static android::sp<IServiceManager> asInterface(const android::sp<IBinder>& obj);
    virtual const android::String16 getInterfaceDescriptor() const;
    IServiceManager();
    virtual ~IServiceManager();

从对DECLARE_META_INTERFACE宏的翻译可以看出这是属性和方法的声明;

通过上边的对那个IServiceManager.h和对DECLARE_META_INTERFACE的翻译我们已经知道了IServiceManager接口定义的样子我们下面看一下他的具体实现,但是具体实现内容比较多我抽取其中重要部分分析一下:

.../frameworks/native/libs/binder/IServiceManager.cpp

 ............省略.............
 
 //IMPLEMENT_META_INTERFACE这个宏是定义在IInterface.h文件中的
//1.定义常量字符串android.os.IServiceManager
//2.实现getInterfaceDescriptor()函数
//3.实现asInterface()函数,并返回一个BpServiceManager对象
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");


status_t BnServiceManager::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    //printf("ServiceManager received: "); data.print();
    switch(code) {
        ...........继续省略..............
    }
}

在IServiceManager的实现中真正让我感兴趣的这个***IMPLEMENT_META_INTERFACE***宏的使用。同样我们找找这个宏的定义并将这个宏翻译一下:

宏定义在IInterface.h文件中
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    const android::String16 I##INTERFACE::descriptor(NAME);             \
    const android::String16&                                            \
            I##INTERFACE::getInterfaceDescriptor() const {              \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
            const android::sp<android::IBinder>& obj)                   \
    {                                                                   \
        android::sp<I##INTERFACE> intr;                                 \
        if (obj != NULL) {                                              \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \

感觉当前这个宏的使用场景翻译一下:

const android::String16 IServiceManager::descriptor("android.os.IServiceManager");
const android::String16& IServiceManager::getInterfaceDescriptor() const {
    return IServiceManager::descriptor;
}
android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj) {
    android::sp<IBinder> intr;
    if(obj != null) {
        //这里也很重要
        intr = static_cast<IServiceManager>(obj->queryLocalInterface(IServicManager:;descriptor).get());
        if(intr == NULL) {
        //重点看这里
            intr = new BpServieceManager(obj);
        }
    }
    return intr;
    //构造函数我就不翻译了。这翻译真要命
}

现在我们已经翻译完了***IMPLEMENT_META_INTERFACE***宏的内容现在将翻译后内容替换到IServiceManager.cpp中看看

.../frameworks/native/libs/binder/IServiceManager.cpp 

 ............省略.............
 
 //IMPLEMENT_META_INTERFACE这个宏是定义在IInterface.h文件中的
//1.定义常量字符串android.os.IServiceManager
//2.实现getInterfaceDescriptor()函数
//3.实现asInterface()函数,并返回一个BpServiceManager对象
<!--IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");-->

const android::String16 IServiceManager::descriptor("android.os.IServiceManager");
const android::String16& IServiceManager::getInterfaceDescriptor() const {
    return IServiceManager::descriptor;
}
android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj) {
    android::sp<IBinder> intr;
    if(obj != null) {
        //这里也很重要
        intr = static_cast<IServiceManager>(obj->queryLocalInterface(IServicManager:;descriptor).get());
        if(intr == NULL) {
        //重点看这里
            intr = new BpServieceManager(obj);
        }
    }
    return intr;
    //构造函数我就不翻译了。这翻译真要命

status_t BnServiceManager::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    //printf("ServiceManager received: "); data.print();
    switch(code) {
        ...........继续省略..............
    }
}

这就是翻译后的IServiceManager.cpp的样子我们重点看一下asInterface()方法, 这里这个方法竟然返回了一个BpServiceManager对象。还记得我们先变分析中哪里调用了这个asInterface()方法吗?没错就是我们在interface_cast()模版方法调用,现在我们知道在当前分析场景下interface_cast()返回的是一个***BpServiceManager***类型的对象。那么问题现在有来了,还记得interface_cast()方法是在哪里调用的吗?没错就是defaultServiceManager()方法中调用的。

现在终于将defaultServiceManager()函数分析完了,最终这个方法会返回一个BpServiceManager类型的对象(累死人了,分析了这么多终于知道了这个方法返回了什么。要疯了,特别想爆粗口)。那现在我是特别想知道BpServiceManager到底是个什么东西。但是现在不着急,defautServiceManager()方法引发这么多的联动分析我还是先回味一下defaultServiceManager()函数都干了些啥:

  • 首先调用了ProcessState::getContextObject(null)函数,但是这个函数什么都没有干就直接调用了自己的getStrongProxyForHandle(0)函数。在getStrongProxyForHandle()函数中创建了一个BpBinder对象。
  • 在BpBinder构造函数中又引出了一个重要的类IPCThreadState类。在这里调用了IPCThreadState::self();
  • 在IPCThreadState::self()函数中首先从线程的TLS中获取IPCThreadState对象。到那时在首次点用时TLS中并未存储,所以会调用它的构造方法创建一个IPCThreadState对象并将创建的对象保存到TLS中。以后就可以直接从TLS中获取。
  • interface_cast()模版方法中调用了IServiceManager的asInterface()函数。通过我们对模版方法、DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE宏的分析翻译知道最终asInterface()返回了一个BpServiceManager对象。

在整个defaultServiceManager()函数中涉及到BpBinder、ProcessState、IPCThreadState、BpServiceManager等新的类。我们有必要分析一下目前他们的关系如何。

BpBinder类图

现在我们可以根据类图关系再来分析一下他们。首先看一下BpServiceManager:

class BpServiceManager : public BpInterface<IServiceManager>
{
//impl参数是IBinder类型,实际上就是上边创建的BpBinder
public BpServiceManager(const sp<IBinder>& impl)
        //调用了父类的构造方法,参数impl 是 BpBinder
        : BpInterface<IServiceManager>(impl)
    {
    }
}

BpServiceManager继承自BpInterface。现在看一下BpInterface:

模版类
template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
                                BpInterface(const sp<IBinder>& remote);

protected:
    virtual IBinder*            onAsBinder();
};

----------------------------
模版方法
template<typename INTERFACE>
//remote参数是BpBinder
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    //调用父类的构造方法
    : BpRefBase(remote)
{
}

继续看一下BpRefBase的实现:

//mRemote最终等于BpBinder(0)对象
BpRefBase::BpRefBase(const sp<IBinder>& o)
//重点在这里,Bpbinder本传递给了mRemote.Binder的通信需要通过mRemote来完成。
    : mRemote(o.get()), mRefs(NULL), 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实现了IServiceManager接口同时持有了BpBinder,BpBinder可以用于进程的通信。此时BpServiceManager是ServiceManager客户端的代理对象,BpBinder是Binder通信机制的Client端代表。

2. MediaPlayerService addService()

我们继续回到MediaServer的main()函数中继续分析。看看MediaPlayerService::instantiate()实现:

void MediaPlayerService::instantiate() {
//通过上边的分析我们已经知道defaultServiceManager()返回的是一个BpServiceManager对象。在这里调用了他的addService()方法。
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}

在instantiate()函数中调用了BpServiceManager的addService():

.../frameworks/native/libs/binder/IServiceManager.cpp的内嵌类BpServiceManager

    virtual status_t addService(const String16& name, const sp<IBinder>& service,
            bool allowIsolated)
    {
        Parcel data, reply;
        //
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
        data.writeString16(name);
        data.writeStrongBinder(service);
        data.writeInt32(allowIsolated ? 1 : 0);
        //remote()函数返回的是mRemote,就是BpRefBase中的mRemote,即BpBinder对象。这里调用了BpBinder的transact()方法。
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
        return err == NO_ERROR ? reply.readExceptionCode() : err;
    }

从BpServiceManager的addService()方法可以看出最终将调用转移到了BpBinder中。由此我们知道BpBinder才是代表client进行跨进程通信的代表。下面我们继续分析一下BpBinder;

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) {
       //BpBinder将通信委托给了IPCThreadState的transcat()方法
       status_t status = IPCThreadState::self()->transact(
           mHandle, code, data, reply, flags);
       if (status == DEAD_OBJECT) mAlive = 0;
       return status;
   }

   return DEAD_OBJECT;
}

看到这里还是有点震惊的,我本来认为BpBinder已经是实现通信的客户端的代表了。现在发现它竟然将通信委托给IPCThreadState来完成。原来BpBinder还是个壳子。继续看一下IPCThreadState::transact():

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

   `````````````````````````````
   
   if (err == NO_ERROR) {
       LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
           (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
           //发送Binder通信消息
       err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
   }
   
   if (err != NO_ERROR) {
       if (reply) reply->setError(err);
       return (mLastError = err);
   }
   
   if ((flags & TF_ONE_WAY) == 0) {
       #if 0
       if (code == 4) { // relayout
           ALOGI(">>>>>> CALLING transaction 4");
       } else {
           ALOGI(">>>>>> CALLING transaction %d", code);
       }
       #endif
       if (reply) {
           //等待通讯结果
           err = waitForResponse(reply);
       } else {
           Parcel fakeReply;
           err = waitForResponse(&fakeReply);
       }
       
       ````````````````````````
   } else {
       err = waitForResponse(NULL, NULL);
   }
   
   return err;
}

在IPCThreadState的transact()方法中有两个重要的方法调用, err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL)和err = waitForResponse(reply)。我们先来分析一下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 是binder通信的数据结构

   tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
   tr.target.handle = handle;      //现在handle是0;0代表ServiceManager。
   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的类型是Pracel.它是准备发送给Binder的Server端。
   mOut.writeInt32(cmd);
   //将Binder通信的数据写入到mOut中
   mOut.write(&tr, sizeof(tr));
   
   return NO_ERROR;
}

从writeTransactionData()方法的分析发现里边主要做了数据准备并将数据序列化到Pracel中。

我们继续分析分析waitForResponse(reply)函数:

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();
        
        IF_LOG_COMMANDS() {
            alog << "Processing waitForResponse Command: "
                << getReturnString(cmd) << endl;
        }

        switch (cmd) {
        case BR_TRANSACTION_COMPLETE:
            if (!reply && !acquireResult) goto finish;
            break;
        
        case BR_DEAD_REPLY:
            err = DEAD_OBJECT;
            goto finish;

        case BR_FAILED_REPLY:
            err = FAILED_TRANSACTION;
            goto finish;
        
        case BR_ACQUIRE_RESULT:
            {
                ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
                const int32_t result = mIn.readInt32();
                if (!acquireResult) continue;
                *acquireResult = result ? NO_ERROR : INVALID_OPERATION;
            }
            goto finish;
        
        case BR_REPLY:
            {
                binder_transaction_data tr;
                err = mIn.read(&tr, sizeof(tr));
                ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
                if (err != NO_ERROR) goto finish;

                if (reply) {
                    if ((tr.flags & TF_STATUS_CODE) == 0) {
                        reply->ipcSetDataReference(
                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                            tr.data_size,
                            reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(binder_size_t),
                            freeBuffer, this);
                    } else {
                        err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
                        freeBuffer(NULL,
                            reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                            tr.data_size,
                            reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                            tr.offsets_size/sizeof(binder_size_t), this);
                    }
                } else {
                    freeBuffer(NULL,
                        reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                        tr.data_size,
                        reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                        tr.offsets_size/sizeof(binder_size_t), this);
                    continue;
                }
            }
            goto finish;

        default:
            //重点
            err = executeCommand(cmd);
            if (err != NO_ERROR) goto finish;
            break;
        }
    }

BR_开头的case都是Binder Server端的,BC_开头的case是Binder Client端使用。
在IPCThreadState的waitForResponse()函数中重要的方法有talkWithDriver()和case 的default:分支中的executeCommand()函数。现在我们先分析一下talkWithDriver():

status_t IPCThreadState::talkWithDriver(bool doReceive)
{
    if (mProcess->mDriverFD <= 0) {
        return -EBADF;
    }
    
    binder_write_read bwr;          //binder通信的数据结构
    
    // Is the read buffer empty?
    const bool needRead = mIn.dataPosition() >= mIn.dataSize();
    
    // We don't want to write anything if we are still reading
    // from data left in the input buffer and the caller
    // has requested to read the next data.
    const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
    
    bwr.write_size = outAvail;
    bwr.write_buffer = (uintptr_t)mOut.data();

    // This is what we'll read.
    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_LOG_COMMANDS() {
        TextOutput::Bundle _b(alog);
        if (outAvail != 0) {
            alog << "Sending commands to driver: " << indent;
            const void* cmds = (const void*)bwr.write_buffer;
            const void* end = ((const uint8_t*)cmds)+bwr.write_size;
            alog << HexDump(cmds, bwr.write_size) << endl;
            while (cmds < end) cmds = printCommand(alog, cmds);
            alog << dedent;
        }
        alog << "Size of receive buffer: " << bwr.read_size
            << ", needRead: " << needRead << ", doReceive: " << doReceive << endl;
    }
    
    // Return immediately if there is nothing to do.
    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_LOG_COMMANDS() {
            alog << "About to read/write, write size = " << mOut.dataSize() << endl;
        }
#if defined(HAVE_ANDROID_OS)
        //通过ioctl()进行读写
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
            err = NO_ERROR;
        else
            err = -errno;
#else
        err = INVALID_OPERATION;
#endif
        if (mProcess->mDriverFD <= 0) {
            err = -EBADF;
        }
        IF_LOG_COMMANDS() {
            alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
        }
    } while (err == -EINTR);

    IF_LOG_COMMANDS() {
        alog << "Our err: " << (void*)(intptr_t)err << ", write consumed: "
            << bwr.write_consumed << " (of " << mOut.dataSize()
                        << "), read consumed: " << bwr.read_consumed << endl;
    }

    if (err >= NO_ERROR) {
        //清空客户端的Pracel的内存空间
        if (bwr.write_consumed > 0) {
            if (bwr.write_consumed < mOut.dataSize())
                mOut.remove(0, bwr.write_consumed);
            else
                mOut.setDataSize(0);
        }
        //将ioctl()从sever端获取的数据写入到mIn中准备发送给client端
        if (bwr.read_consumed > 0) {
            mIn.setDataSize(bwr.read_consumed);
            mIn.setDataPosition(0);
        }
        
        ````````````
        return NO_ERROR;
    }
    
    return err;
}

完成Binder通信其实是通过Binder驱动的共享内存来完成不同进程之间的通信,从对talkWithDriver()函数分析来看完成对Binder驱动的共享内存的操作是ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)函数来完成的。ioctl()是一个linux系统API。对ioctl()方法调用是在do{}while()中调用的,由此可见这个ioctl()会多次调用来完成通信。在ioctl()完成后请求结果被放到binder_write_read类型的bwr中,然后将bwr的结果内容写入到Pracel的mIn中为下一步返回客户端做做准备。

我们在回到IPCThreadState::waitForResponse()函数中分析一下另外一个executeCommand(cmd)方法:

status_t IPCThreadState::executeCommand(int32_t cmd)
{
    BBinder* obj;
    RefBase::weakref_type* refs;
    status_t result = NO_ERROR;
    
    switch ((uint32_t)cmd) {
    case BR_ERROR:
        result = mIn.readInt32();
        break;
        
    case BR_OK:
        break;
        
    case BR_ACQUIRE:
        ```````````
        break;
    case BR_RELEASE:
        ```````````
        break;
        
    case BR_INCREFS:
        `````````````
        break;
        
    `````````
    
    case BR_TRANSACTION:
        {
            binder_transaction_data tr;
            result = mIn.read(&tr, sizeof(tr));
            ALOG_ASSERT(result == NO_ERROR,
                "Not enough command data for brTRANSACTION");
            if (result != NO_ERROR) break;
            
            Parcel buffer;
            buffer.ipcSetDataReference(
                reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
                tr.data_size,
                reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
                tr.offsets_size/sizeof(binder_size_t), freeBuffer, this);
            
            const pid_t origPid = mCallingPid;
            const uid_t origUid = mCallingUid;
            const int32_t origStrictModePolicy = mStrictModePolicy;
            const int32_t origTransactionBinderFlags = mLastTransactionBinderFlags;

            mCallingPid = tr.sender_pid;
            mCallingUid = tr.sender_euid;
            mLastTransactionBinderFlags = tr.flags;

            int curPrio = getpriority(PRIO_PROCESS, mMyThreadId);
            if (gDisableBackgroundScheduling) {
                if (curPrio > ANDROID_PRIORITY_NORMAL) {
                    setpriority(PRIO_PROCESS, mMyThreadId, ANDROID_PRIORITY_NORMAL);
                }
            } else {
                if (curPrio >= ANDROID_PRIORITY_BACKGROUND) {
                    set_sched_policy(mMyThreadId, SP_BACKGROUND);
                }
            }

            Parcel reply;
            status_t error;
        
            if (tr.target.ptr) {
            //BnService从BBinder派生
            //这里的B实际上实现了BnServiceXXX的对象
                sp<BBinder> b((BBinder*)tr.cookie);
                error = b->transact(tr.code, buffer, &reply, tr.flags);

            } else {
                error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
            }

            if ((tr.flags & TF_ONE_WAY) == 0) {
                LOG_ONEWAY("Sending reply to %d!", mCallingPid);
                if (error < NO_ERROR) reply.setError(error);
                sendReply(reply, 0);
            } else {
                LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
            }
            
            mCallingPid = origPid;
            mCallingUid = origUid;
            mStrictModePolicy = origStrictModePolicy;
            mLastTransactionBinderFlags = origTransactionBinderFlags;
            
        }
        break;
·····································
    return result;
}

看到executeCommand()函数中那么多的switch分支真不知道从哪里分析,脑子已经懵懵的。还是从BR_TRANSACTION:这个分支看看吧。在这个分支中我们可以看到//BnService从BBinder派生sp b((BBinder*)tr.cookie);error = b->transact(tr.code, buffer, &reply, tr.flags);我们又看到了一个BBinder类的对象,有我们从BpBinder是Binder Client的代表可以猜测BBinder可能是Binder的Server端的代表。实际上这里的b是BnSerciceManager对象。那先放下executeCommaond()函数,这里我们先来分析一下BBinder和BnServiceManaer是什么然后在回来分析:

```/frameworks/native/include/binder/IServiceManager.h
class BnServiceManager : public BnInterface<IServiceManager>
{
public:
   virtual status_t    onTransact( uint32_t code,
                                   const Parcel& data,
                                   Parcel* reply,
                                   uint32_t flags = 0);
};

开始看张类图直观一些,手画丑的不行:
image

BnServiceManager继承自BnInterface,再看一下BnInterface是什么:

template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
   virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
   virtual const String16&     getInterfaceDescriptor() const;

protected:
   virtual IBinder*            onAsBinder();
};

BnInterface是个模版类继承自BBinder,在BnServiceManager继承BnInterface时模版类中的INTERFACE 是 IServiceManager。用于BnInterface继承了INTERFACE,所以BnServicManager继承了ISeviceManager接口。下面看一下BBinder的定义:

```/frameworks/native/include/binder/Binder.h
class BBinder : public IBinder
{
.............
}

这样以来继承关系已经很明确。再BnServiceManager的接口声明中重新声明了onTransact()函数并在IServiceManager.cpp中实现了它:

status_t BnServiceManager::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    //printf("ServiceManager received: "); data.print();
    switch(code) {
        case GET_SERVICE_TRANSACTION: {
            ········
        } break;
        case CHECK_SERVICE_TRANSACTION: {
            ········
        } break;
        case ADD_SERVICE_TRANSACTION: {
            CHECK_INTERFACE(IServiceManager, data, reply);
            String16 which = data.readString16();
            sp<IBinder> b = data.readStrongBinder();
            //在这里有调用了addService()完成真正的服务添加。
            status_t err = addService(which, b);
            reply->writeInt32(err);
            return NO_ERROR;
        } break;
        case LIST_SERVICES_TRANSACTION: {
            ········
            return NO_ERROR;
        } break;
        default:
            //调用父类默认实现
            return BBinder::onTransact(code, data, reply, flags);
    }
}

我们对BnServiceManager和BBinder的分析先分析到这里,回到executeCommond()方法中再结合sp b((BBinder*)tr.cookie);error = b->transact(tr.code, buffer, &reply,tr.flags);调用bnServiceManager的transact()方法。以分析的addService()最终会进入到case ADD_SERVICE_TRANSACTION:分支当中并在这里调用了addService()方法。
***看到这里我是有点模糊的这个分支中的addService()方法的实现在哪里,也没有找到一个类继承自BnServiceManager。***后来网上看别人的分析发现还是有个文件实现了这里的ServiceManager的功能,具体实现在Service_manager.c中实现的。

不太明白为什么不继续继承BnServiceManager来实现具体逻辑呢?

ServiceManager

ServiceManager的实现在Service_manager.c中,先从这个文件的main()函数开始了解一下它干了啥:

int main(int argc, char **argv)
{
    struct binder_state *bs;
    //打开binder虚拟设备
    bs = binder_open(128*1024);
    if (!bs) {
        ALOGE("failed to open binder driver\n");
        return -1;
    }
        //角色转换
    if (binder_become_context_manager(bs)) {
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
    
    //重点,处理客户端发过来的请求
    binder_loop(bs, svcmgr_handler);

    return 0;
}

main()函数比较简单主要通过调用了binder_open()函数打开Binder的虚拟设备.先看一下binder_open()都做了些什么:

/打开Binder设备
struct binder_state *binder_open(size_t mapsize)
{
    struct binder_state *bs;
    struct binder_version vers;

    bs = malloc(sizeof(*bs));
    if (!bs) {
        errno = ENOMEM;
        return NULL;
    }
    //打开虚拟设备,调用Linux系统方法打开文件
    bs->fd = open("/dev/binder", O_RDWR);
    if (bs->fd < 0) {
        fprintf(stderr,"binder: cannot open device (%s)\n",
                strerror(errno));
        goto fail_open;
    }

    if ((ioctl(bs->fd, BINDER_VERSION, &vers) == -1) ||
        (vers.protocol_version != BINDER_CURRENT_PROTOCOL_VERSION)) {
        fprintf(stderr,
                "binder: kernel driver version (%d) differs from user space version (%d)\n",
                vers.protocol_version, BINDER_CURRENT_PROTOCOL_VERSION);
        goto fail_open;
    }

    bs->mapsize = mapsize;
    //调用mmap()函数给binder驱动做内存映射
    bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);
    if (bs->mapped == MAP_FAILED) {
        fprintf(stderr,"binder: cannot map device (%s)\n",
                strerror(errno));
        goto fail_map;
    }

    return bs;

fail_map:
    close(bs->fd);
fail_open:
    free(bs);
    return NULL;
}

我在这个方法中又看到了goto的使用。有点兴奋!

在open_binder()函数中打开了Binder驱动,并给起映射了内存空间。我们继续看一下binder_become_context_manager(bs)干了什么:

int binder_become_context_manager(struct binder_state *bs)
{
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}

很简单但是我没有看太懂,主要是对ioctl()这个函数不太懂。大概是给打开的Binder设备指定了映射名称为0;(谁懂给我普及一下

ioctl是设备驱动程序中对设备的I/O通道进行管理的函数。所谓对I/O通道进行管理,就是对设备的一些特性进行控制,例如串口的传输波特率、马达的转速等等。它的参数个数如下:int ioctl(int fd, int cmd, …);其中fd就是用户程序打开设备时使用open函数返回的文件标示符,cmd就是用户程序对设备的控制命令,至于后面的省略号,那是一些补充参数,一般最多一个,有或没有是和cmd的意义相关的。ioctl函数是文件结构中的一个属性分量,就是说如果你的驱动程序提供了对ioctl的支持,用户就能在用户程序中使用ioctl函数控制设备的I/O通道。百度百科

还有一个处理Binder请求的方法binder_loop(bs, svcmgr_handler):

//binder_handler 是个函数指针,func现在是svcmgr_handler
void binder_loop(struct binder_state *bs, binder_handler func)
{
    int res;
    struct binder_write_read bwr;
    uint32_t readbuf[32];

    bwr.write_size = 0;
    bwr.write_consumed = 0;
    bwr.write_buffer = 0;

    readbuf[0] = BC_ENTER_LOOPER;
    //在binder_write中调用了ioctl函数,调用Binder设备的函数,标志serviceManager进入的Loop 状态。
    binder_write(bs, readbuf, sizeof(uint32_t));
    //循环不断的
    for (;;) {
        bwr.read_size = sizeof(readbuf);
        bwr.read_consumed = 0;
        bwr.read_buffer = (uintptr_t) readbuf;
        //通过ioctl()方法从Binder设备中读取缓冲区,检查是不是又IPC请求。
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
        if (res < 0) {
            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }
        //接受到请求,然后解析结果 调用func函数
        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
        if (res == 0) {
            ALOGE("binder_loop: unexpected reply?!\n");
            break;
        }
        if (res < 0) {
            ALOGE("binder_loop: io error %d %s\n", res, strerror(errno));
            break;
        }
    }
}

在binder_loop()中让binder设备进入loop状态,通过循环不断通过ioctl()方法获取Binder设备是不是有IPC请求,如果有将获取到的数据交给binder_parse()函数进行解析.

int binder_parse(struct binder_state *bs, struct binder_io *bio,
                 uintptr_t ptr, size_t size, binder_handler func)
{
    .................数据处理.............................
    
        case BR_TRANSACTION: {
            
            ....................
            
            if (func) {
                unsigned rdata[256/4];
                struct binder_io msg;
                struct binder_io reply;
                int res;
                bio_init(&reply, rdata, sizeof(rdata), 4);
                bio_init_from_txn(&msg, txn);
                //调用了func()函数,有func()函数去做真正的服务管理
                res = func(bs, txn, &msg, &reply);
                binder_send_reply(bs, &reply, txn->data.ptr.buffer, res);
            }
            ptr += sizeof(*txn);
            break;
        }
        ...................................
        }
    }
    return r;
}

在binder_prase()方法的binder_handler func参数指向的是svcmgr_handler函数,下面看看这个函数:

.../frameworks/native/cmds/servicemanager/service_manager.c

//binder 通信处理数据的回调函数
int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
    struct svcinfo *si;
    uint16_t *s;
    size_t len;
    uint32_t handle;
    uint32_t strict_policy;
    int allow_isolated;

    //ALOGI("target=%p code=%d pid=%d uid=%d\n",
    //      (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);

    if (txn->target.ptr != BINDER_SERVICE_MANAGER)
        return -1;

    if (txn->code == PING_TRANSACTION)
        return 0;

    strict_policy = bio_get_uint32(msg);
    s = bio_get_string16(msg, &len);
    if (s == NULL) {
        return -1;
    }

    if ((len != (sizeof(svcmgr_id) / 2)) ||
        memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
        fprintf(stderr,"invalid id %s\n", str8(s, len));
        return -1;
    }

    if (sehandle && selinux_status_updated() > 0) {
        struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
        if (tmp_sehandle) {
            selabel_close(sehandle);
            sehandle = tmp_sehandle;
        }
    }

    switch(txn->code) {
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
         ..........

    case SVC_MGR_ADD_SERVICE:
        //注册服务
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        //注册服务真正工作的地方
        if (do_add_service(bs, s, len, handle, txn->sender_euid,
            allow_isolated, txn->sender_pid))
            return -1;
        break;

    case SVC_MGR_LIST_SERVICES: {
       ......
    }
    default:
        ALOGE("unknown code %d\n", txn->code);
        return -1;
    }

    bio_put_uint32(reply, 0);
    return 0;
}

在svcmgr_handler()函数中SVC_ADD_SERVICES分支中注册服务,其中注册服务的实际处理交给了do_add_service()方法继续处理。

int do_add_service(struct binder_state *bs,
                   const uint16_t *s, size_t len,
                   uint32_t handle, uid_t uid, int allow_isolated,
                   pid_t spid)
{
    struct svcinfo *si;
    
    if (!handle || (len == 0) || (len > 127))
        return -1;
    //验证UID是否有添加服务的权限。
    if (!svc_can_register(s, len, spid)) {
        ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
             str8(s, len), handle, uid);
        return -1;
    }
    //检查服务是不是已经注册
    si = find_svc(s, len);
    if (si) {
        if (si->handle) {
            ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
                 str8(s, len), handle, uid);
            svcinfo_death(bs, si);
        }
        si->handle = handle;
    } else {
        //如果没有注册分配内存
        si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
        //si这个结构体
        si->handle = handle;
        si->len = len;
        memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
        si->name[len] = '\0';
        si->death.func = (void*) svcinfo_death;
        si->death.ptr = si;
        si->allow_isolated = allow_isolated;
        si->next = svclist;
        //插入链表
        svclist = si;
    }

    binder_acquire(bs, handle);
    binder_link_to_death(bs, handle, &si->death);
    return 0;
}

//存储注册服务的结构体,是个链表结构
struct svcinfo
{
    struct svcinfo *next;
    uint32_t handle;
    struct binder_death death;
    int allow_isolated;
    size_t len;
    uint16_t name[0];
};

do_add_service()方法通过坚定要注册的服务是否有权限被注册,然后再检查服务是否已经注册了,如果没有被注册则将其插入到链表中。这样我们的服务注册工作已经完成。
C++层的Binder通信的分析基本上分析完了。想抽时间再分析一下Java层对c++层的封装。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章