美文网首页
深入理解Android Binder机制

深入理解Android Binder机制

作者: Liekkas_BJ | 来源:发表于2023-06-22 21:15 被阅读0次

    一.概述

    1.1 概念

    Binder是Android提供的一种IPC机制(进程间通信机制)。
    特点:更加方便灵活
    Android其他IPC机制:管道、socket
    作用:Android系统基本可以看作是基于Binder机制的C/S架构,binder把系统的各部分连接在一起

    1.2 ServiceManager、Client、Server之间的关系

    ServiceManager:管理系统中的各种服务(Service)
    三者交互关系如图:

    ServiceManager、Client、Server关系图

    总结:
    1.一个Server进程可以注册多个Service
    2.Server要先注册一些Service到ServiceManager中,所以Server是ServiceManager的客户端,ServiceManager是服务端
    3.如果Client进程想使用某个Service服务,则先要到ServiceManager获取服务相关信息,所以Client是ServiceManager的客户端
    4.Client根据得到的Service信息与Service所在的Server进程建立通信通路,然后就可以直接与Service直接交互了,所以Client也是Server的客户端
    5.三者之间通信均是基于Binder机制

    二.MediaServer

    本文章以MediaServer为例,来分析Binder机制。之所以选择MediaServer作为切入点,是因为这个Server是系统诸多重要Service的栖息地,它们包括:

    AudioFlinger:音频系统中的核心服务。
    AudioPolicyService:音频系统中关于音频策略的重要服务。
    MediaPlayerService:多媒体系统中的重要服务。
    CameraService:有关摄像/照相的重要服务。

    2.1 MediaServer入口函数

    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.MediaServer作为ServiceManager的客户端,要向ServiceManager注册服务
        //调用defaultServiceManager()得到一个IServiceManager
        sp<IServiceManager> sm(defaultServiceManager());
        ALOGI("ServiceManager: %p", sm.get());
        InitializeIcuOrDie();
        //3.初始化服务
        MediaPlayerService::instantiate();
        ResourceManagerService::instantiate();
        registerExtensions();
        //4.创建一个线程池
        ProcessState::self()->startThreadPool();
        //5.将IPCThreadState加入线程池
        IPCThreadState::self()->joinThreadPool();
    }
    

    MediaServer的入口函数,主要做了5件事
    1.获取当前进程的一个ProcessState对象,ProcessState在同一进程单例
    2.向ServiceManager注册服务
    3.初始化服务
    4.创建一个线程池
    5.将当前IPC线程状态加入线程池

    2.2 ProcessState

    每个进程只有一个ProcessState对象,它的调用方式如下:

    //获取一个ProcessState实例
    sp<ProcessState> proc(ProcessState::self());
    

    下面来分析下ProcessState

    2.2.1ProcessState::self()函数

    frameworks/native/libs/binder/ProcessState.cpp

    sp<ProcessState> ProcessState::self()
    {
        Mutex::Autolock _l(gProcessMutex);
        if (gProcess != NULL) {
            return gProcess;
        }
        //创建一个ProcessState
        gProcess = new ProcessState("/dev/binder");
        return gProcess;
    }
    

    self()方法使用了单例模式,保证了每个进程只有一个ProcessState对象

    1 ProcessState的构造函数

    frameworks/native/libs/binder/ProcessState.cpp

    ProcessState::ProcessState(const char *driver)
        : mDriverName(String8(driver))
        //打开dev/binder驱动
        , mDriverFD(open_driver(driver))
        , mVMStart(MAP_FAILED)
        , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
        , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
        , mExecutingThreadsCount(0)
        , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
        , mStarvationStartTimeMs(0)
        , mManagesContexts(false)
        , mBinderContextCheckFunc(NULL)
        , mBinderContextUserData(NULL)
        , mThreadPoolStarted(false)
        , mThreadPoolSeq(1)
    {
        if (mDriverFD >= 0) {
            // mmap the binder, providing a chunk of virtual address space to receive transactions.
            //2.mmap与binder的驱动建立映射关系
            //BINDER_VM_SIZE定义为(1*1024*1024)- (4096*2)= 1M-8K,这也是Intent传递的数据为何不能超过1M的原因,因为Intent传递数据使用到了binder机制,所以会受到BINDER_VM_SIZE的定义限制
            //binder驱动会分配一块内存来接收数据
            mVMStart = mmap(0, 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.");
    }
    

    2 打开binder设备

    open_driver的作用就是打开/dev/binder这个设备,它是Android在内核中为完成进程间通信而专门设置的一个虚拟设备,具体实现如下所示:
    frameworks/native/libs/binder/ProcessState.cpp

    static int open_driver(const char *driver)
    {
        int fd = open(driver, O_RDWR | O_CLOEXEC);
        if (fd >= 0) {
            int vers = 0;
            status_t result = ioctl(fd, BINDER_VERSION, &vers);
            if (result == -1) {
                ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
                close(fd);
                fd = -1;
            }
            if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
              ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
                    vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
                close(fd);
                fd = -1;
            }
            //这个fd支持的最大线程数为DEFAULT_MAX_BINDER_THREADS=15
            size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
            result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
            if (result == -1) {
                ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
            }
        } else {
            ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
        }
        return fd;
    }
    

    至此,ProcessState::self()函数就分析完毕。ProcessState::self()函数主要有两个作用
    1.打开dev/binder设备,可以与内核的Binder驱动进行交互
    2.对返回的fd对象使用mmap,内核分配一块儿内存,这样binder驱动就可以接收数据

    2.3 defaultServiceManager()

    //调用defaultServiceManager()得到一个IServiceManager
    sp<IServiceManager> sm = defaultServiceManager();
    

    defaultServiceManager实际调用的是IServiceManager的defaultServiceManager()函数,源码如下:
    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;
    }
    

    defaultServiceManager函数调用了interface_cast函数进行对gDefaultServiceManager的赋值,最终发现,调用了ProcessState的getContextObject函数,getContextObject函数代码如下:

    sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
    {
        return getStrongProxyForHandle(0);
    }
    

    getContextObject函数中调用了getStrongProxyForHandle(0)的函数,如下
    frameworks/native/libs/binder/ProcessState.cpp

    sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
    {
        sp<IBinder> result;
    
        AutoMutex _l(mLock);
    
        handle_entry* e = lookupHandleLocked(handle);
    
        if (e != NULL) {
            // We need to create a new BpBinder if there isn't currently one, OR we
            // are unable to acquire a weak reference on this current one.  See comment
            // in getWeakProxyForHandle() for more info about this.
            IBinder* b = e->binder;
            if (b == NULL || !e->refs->attemptIncWeak(this)) {
                if (handle == 0) {
                    // Special case for context manager...
                    // The context manager is the only object for which we create
                    // a BpBinder proxy without already holding a reference.
                    // Perform a dummy transaction to ensure the context manager
                    // is registered before we create the first local reference
                    // to it (which will occur when creating the BpBinder).
                    // If a local reference is created for the BpBinder when the
                    // context manager is not present, the driver will fail to
                    // provide a reference to the context manager, but the
                    // driver API does not return status.
                    //
                    // Note that this is not race-free if the context manager
                    // dies while this code runs.
                    //
                    // TODO: add a driver API to wait for context manager, or
                    // stop special casing handle 0 for context manager and add
                    // a driver API to get a handle to the context manager with
                    // proper reference counting.
    
                    Parcel data;
                    status_t status = IPCThreadState::self()->transact(
                            0, IBinder::PING_TRANSACTION, data, NULL, 0);
                    if (status == DEAD_OBJECT)
                       return NULL;
                }
                //创建一个BpBinder,对于新创建的资源,b为空,此处handle为0
                b = BpBinder::create(handle);
                e->binder = b;
                if (b) e->refs = b->getWeakRefs();
                result = b;
            } else {
                // This little bit of nastyness is to allow us to add a primary
                // reference to the remote proxy when this team doesn't have one
                // but another team is sending the handle to us.
                result.force_set(b);
                e->refs->decWeak(this);
            }
        }
        //返回一个BpBinder
        return result;
    }
    
    

    2.3.1 BpBinder

    BpBinder是IBinder的派生类,BpBinder的p意味着proxy,也就是用于客户端与服务端通信的代理类。
    提到BpBinder就不得不提一下BBinder,它们都是IBinder的派生类,如下


    IBinder家族图谱

    BBinder是与BpBinder为一对的,也用于通信的类。BpBinder代表的是客户端的proxy,BBinder则代表与之交互的服务端。一个BpBinder只能和对应的BBinder进行通信,即BpBinderA只能与BBinderA进行通信,不会出现与BBinderB进行通信现象,通过handle的值来标识对应的BBinder,保障正确性。getStrongProxyForHandle方法中handle的值为0,代表的正是ServiceManager中对应的BBinder。

    来看一下BpBinder的create方法
    frameworks/native/libs/binder/BpBinder.cpp

    BpBinder* BpBinder::create(int32_t handle) {
        int32_t trackedUid = -1;
        if (sCountByUidEnabled) {
            trackedUid = IPCThreadState::self()->getCallingUid();
            AutoMutex _l(sTrackingLock);
            uint32_t trackedValue = sTrackingMap[trackedUid];
            if (CC_UNLIKELY(trackedValue & LIMIT_REACHED_MASK)) {
                if (sBinderProxyThrottleCreate) {
                    return nullptr;
                }
            } else {
                if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
                    ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
                          getuid(), trackedUid, trackedValue);
                    sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
                    if (sLimitCallback) sLimitCallback(trackedUid);
                    if (sBinderProxyThrottleCreate) {
                        ALOGI("Throttling binder proxy creates from uid %d in uid %d until binder proxy"
                              " count drops below %d",
                              trackedUid, getuid(), sBinderProxyCountLowWatermark);
                        return nullptr;
                    }
                }
            }
            sTrackingMap[trackedUid]++;
        }
        return new BpBinder(handle, trackedUid);
    }
    

    紧跟着看下BpBinder(handle, trackedUid)构造函数
    frameworks/native/libs/binder/BpBinder.cpp

    BpBinder::BpBinder(int32_t handle, int32_t trackedUid)
        : mHandle(handle)
        , mAlive(1)
        , mObitsSent(0)
        , mObituaries(NULL)
        , mTrackedUid(trackedUid)
    {
        ALOGV("Creating BpBinder %p handle %d\n", this, mHandle);
    
        extendObjectLifetime(OBJECT_LIFETIME_WEAK);
        IPCThreadState::self()->incWeakHandle(handle, this);
    }
    

    这里出现了IPCThreadState::self()函数。到这里并没有发现任何与通信动作相关的操作。到此处为止,我们只是创建了一个BpBinder的对象,具体还并没有对它进行任何调用,所以我们要翻回头再去看当时接受BpBinder参数的方法,即interface_cast函数,继续跟进

    frameworks/native/include/binder/IInterface.h

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

    此处的INTERFACE是IServiceManager,所以此处代码相当于返回了IServiceManager.asInterface(obj),又回到了IServiceManager中去了。继续看IServiceManger的asInterface函数。注意,此处的IServiceManger为IServiceManger.h而不是IServiceManger.cpp。
    frameworks/native/include/binder/IServiceManager.h

    class IServiceManager : public IInterface
    {
    public:
        //非常重要的一个宏
        DECLARE_META_INTERFACE(ServiceManager)
        /**
         * Must match values in IServiceManager.java
         */
        /* Allows services to dump sections according to priorities. */
        static const int DUMP_FLAG_PRIORITY_CRITICAL = 1 << 0;
        static const int DUMP_FLAG_PRIORITY_HIGH = 1 << 1;
        static const int DUMP_FLAG_PRIORITY_NORMAL = 1 << 2;
        /**
         * Services are by default registered with a DEFAULT dump priority. DEFAULT priority has the
         * same priority as NORMAL priority but the services are not called with dump priority
         * arguments.
         */
        static const int DUMP_FLAG_PRIORITY_DEFAULT = 1 << 3;
        static const int DUMP_FLAG_PRIORITY_ALL = DUMP_FLAG_PRIORITY_CRITICAL |
                DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PRIORITY_DEFAULT;
        static const int DUMP_FLAG_PROTO = 1 << 4;
    
        /**
         * Retrieve an existing service, blocking for a few seconds
         * if it doesn't yet exist.
         */
        virtual sp<IBinder>         getService( const String16& name) const = 0;
    
        /**
         * Retrieve an existing service, non-blocking.
         */
        virtual sp<IBinder>         checkService( const String16& name) const = 0;
    
        /**
         * Register a service.
         */
        virtual status_t addService(const String16& name, const sp<IBinder>& service,
                                    bool allowIsolated = false,
                                    int dumpsysFlags = DUMP_FLAG_PRIORITY_DEFAULT) = 0;
    
        /**
         * Return list of all existing services.
         */
        virtual Vector<String16> listServices(int dumpsysFlags = DUMP_FLAG_PRIORITY_ALL) = 0;
    
        enum {
            GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
            CHECK_SERVICE_TRANSACTION,
            ADD_SERVICE_TRANSACTION,
            LIST_SERVICES_TRANSACTION,
        };
    }
    

    先看下DECLARE_META_INTERFACE宏当中是如何定义的
    frameworks/native/include/binder/IInterface.h

    #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;    
    //定义一个asInterface函数                    
    static ::android::sp<IServiceManger> asInterface(                     
                const android::sp<android::IBinder>& obj)        
    virtual const android::String16& getInterfaceDescriptor() const;  
    //定义IServiceManger的构造方法
    IServiceManger();                                                     
    virtual ~ IServiceManger(); 
    

    DECLARE_META_INTERFACE宏定义了一些方法,这些方法的实现是在IServiceManger.cpp中,查找IServiceManger.cpp发现了另外一个宏
    frameworks/native/libs/binder/IServiceManager.cpp

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

    继续跟进,发现IMPLEMENT_META_INTERFACE定义在了IInterface.h文件

    frameworks/native/include/binder/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 IServiceManger::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< IServiceManager > intr;                               
            if (obj != NULL) {                                              
                intr = static_cast< IServiceManager*>(                          
                    obj->queryLocalInterface(                               
                            IServiceManager::descriptor).get());               
                if (intr == NULL) {      
                    //obj就是BpBinder
                    //此处实际上真正返回的是一个BpServiceManager对象                                   
                    intr = new BpServiceManager(obj);                          
                }                                                           
            }                                                               
            return intr;                                                    
        }                                                                   
       IServiceManager::IServiceManager() { }                                    
       IServiceManager::~IServiceManager() { }                                   
    
    

    到此,我们发现inferface_cast函数最终返回了一个BpServiceManager对象,这个BpServiceManager就是将BpBinder转化成了一个IServiceManager对象,最终返回给了defaultServiceManager()函数。

    这里又出现了一个BpServiceManager,既然inferface_cast方法要求返回的是一个IServiceManager,那么BpServiceManager一定是它的一个派生类,接下来介绍下IServiceManager家族

    2.3.2 IServiceManager家族

    IServiceManager家族图谱

    由图可知,BpServiceManager与BbServiceManager不同,BbServiceManager是通过实现BBinder接口进行通信,BpServiceManager又是如何实现通信的呢?上文中创建一个BpServiceManager需要一个BpBinder参数,所以BpServiceManager是通过设置BpBinder变量,通过这个BpBinder来实现通信的。查看BpServiceManager的父接口BpInterface

    frameworks/native/include/binder/IInterface.h

    //定义构造方法
    inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote): 
    BpRefBase(remote){}
    

    BpRefBase的实现如下
    frameworks/native/libs/binder/Binder.cpp

    BpRefBase::BpRefBase(const sp<IBinder>& o)
       //mRemote变量最终等于new出来的BpBinder
       : 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的一个变量mRemote指向了BpBinder。至此,我们的魔术表演结束,回想一下defaultServiceManager函数,可以得到以下两个关键对象:
    1.有一个BpBinder对象,它的handle值是0。
    2.有一个BpServiceManager对象,它的mRemote值是BpBinder。

    2.4 MediaPlayerService的注册

    frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp

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

    defaultServiceManager()函数返回的实际上是BpServiceManager,BpServiceManager定义在IServiceManager.cpp文件中,BpServiceManager的addService函数如下:
    frameworks/native/libs/binder/IServiceManager.cpp

    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实际上是BpBinder,实际传输数据的方法
            status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
            return err == NO_ERROR ? reply.readExceptionCode() : err;
        }
    

    至此,我们完成了业务层的数据打包,然后进入到传输层传输数据。

    2.4.1 BpBinder的transact函数

    frameworks/native/libs/binder/BpBinder.cpp

    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) {
            status_t status = IPCThreadState::self()->transact(
                mHandle, code, data, reply, flags);
            if (status == DEAD_OBJECT) mAlive = 0;
            return status;
        }
    
        return DEAD_OBJECT;
    }
    

    这里看到了一个方法IPCThreadState::self()->transact(mHandle, code, data, reply, flags),实际上传输过程是调用了该函数,我们先看下IPCThreadState::self()函数

    frameworks/native/libs/binder/IPCThreadState.cpp

    IPCThreadState* IPCThreadState::self()
    {
        if (gHaveTLS) {//第一次进来为false
    restart:
            //TLS为Thread local storage线程本地存储空间的简称,该空间每条线程都有,且不共享
            const pthread_key_t k = gTLS;
            //pthread_getspecific/pthread_setspecific可以获取/设置空间内容
            //从线程本地存储空间可以获取到IPCThreadState对象
            //如果该空间设置了IPCThreadState则直接返回
            IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
            if (st) return st;
            //否则创建一个IPCThreadState返回
            return new IPCThreadState;
        }
    
        if (gShutdown) {
            ALOGW("Calling IPCThreadState::self() during shutdown is dangerous, expect a crash.\n");
            return NULL;
        }
    
        pthread_mutex_lock(&gTLSMutex);
        if (!gHaveTLS) {//第一次进来为false
            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 NULL;
            }
            gHaveTLS = true;
        }
        pthread_mutex_unlock(&gTLSMutex);
        goto restart;
    }
    

    接下来看下IPCThreadState的构造函数
    frameworks/native/libs/binder/IPCThreadState.cpp

    IPCThreadState::IPCThreadState()
        : mProcess(ProcessState::self()),
          mStrictModePolicy(0),
          mLastTransactionBinderFlags(0)
    {
        //将自己设置到本地线程的存储空间中
        pthread_setspecific(gTLS, this);
        clearCaller();
        //mIn是接收数据的,mOut是把发送的数据写入缓冲的
        //设置mIn的数据长度
        mIn.setDataCapacity(256);
        //设置mOut的数据长度
        mOut.setDataCapacity(256);
    }
    

    每个线程都有一个唯一的IPCThreadState,每个IPCThreadState都有一个mIn和mOut对象,mIn对象是用来接收来自Binder的数据,mOut是用于把从客户端传输到服务的数据,写入缓冲。

    分析完IPCThreadState的self和构造函数后,接下来分析下IPCThreadState的transact方法,这个方法实际上就是BpBinder中真正传输数据的方法。
    frameworks/native/libs/binder/IPCThreadState.cpp

    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;
    
        IF_LOG_TRANSACTIONS() {
            TextOutput::Bundle _b(alog);
            alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
                << handle << " / code " << TypeCode(code) << ": "
                << indent << data << dedent << endl;
        }
    
        LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
            (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
        //BC_XXX的标记,是从客户端传输数据到服务端,BR_XXX的标记是从服务端传输到客户端
        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);
            }
            #if 0
            if (code == 4) { // relayout
                ALOGI("<<<<<< RETURNING transaction 4");
            } else {
                ALOGI("<<<<<< RETURNING transaction %d", code);
            }
            #endif
    
            IF_LOG_TRANSACTIONS() {
                TextOutput::Bundle _b(alog);
                alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
                    << handle << ": ";
                if (reply) alog << indent << *reply << dedent << endl;
                else alog << "(none requested)" << endl;
            }
        } else {
            err = waitForResponse(NULL, NULL);
        }
    
        return err;
    }
    

    此段代码,简单来说就是先发送数据到服务,然后再等待服务传输数据回来的过程。

    先来看一下writeTransactionData函数
    frameworks/native/libs/binder/IPCThreadState.cpp

    status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
        int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
    {
        //要发送的数据
        binder_transaction_data tr;
    
        tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
        tr.target.handle = handle;
        tr.code = code;
        tr.flags = binderFlags;
        tr.cookie = 0;
        tr.sender_pid = 0;
        tr.sender_euid = 0;
    
        const status_t err = data.errorCheck();
        if (err == NO_ERROR) {
            tr.data_size = data.ipcDataSize();
            tr.data.ptr.buffer = data.ipcData();
            tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
            tr.data.ptr.offsets = data.ipcObjects();
        } 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中,并不直接发送到服务
        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) {
            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;
            }
        }
    
    finish:
        if (err != NO_ERROR) {
            if (acquireResult) *acquireResult = err;
            if (reply) reply->setError(err);
            mLastError = err;
        }
    
        return err;
    }
    

    先看下其中的talkWithDriver函数

     status_t IPCThreadState::talkWithDriver(bool doReceive)
    {
        if (mProcess->mDriverFD <= 0) {
            return -EBADF;
        }
    
        binder_write_read bwr;
    
        // 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) {
            //接收数据缓冲区的填充,如果收到服务的数据,直接写在mIn里
            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(__ANDROID__)
            //用于与服务端传输数据的方法,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) {
            if (bwr.write_consumed > 0) {
                if (bwr.write_consumed < mOut.dataSize())
                    mOut.remove(0, bwr.write_consumed);
                else {
                    mOut.setDataSize(0);
                    processPostWriteDerefs();
                }
            }
            if (bwr.read_consumed > 0) {
                mIn.setDataSize(bwr.read_consumed);
                mIn.setDataPosition(0);
            }
            IF_LOG_COMMANDS() {
                TextOutput::Bundle _b(alog);
                alog << "Remaining data size: " << mOut.dataSize() << endl;
                alog << "Received commands from driver: " << indent;
                const void* cmds = mIn.data();
                const void* end = mIn.data() + mIn.dataSize();
                alog << HexDump(cmds, mIn.dataSize()) << endl;
                while (cmds < end) cmds = printReturnCommand(alog, cmds);
                alog << dedent;
            }
            return NO_ERROR;
        }
    
        return err;
    }
    

    talkWithDriver完成了把注册信息传输到服务,并接收服务返回到信息写入到mIn中的过程,接下来再来看下如何处理服务返回的信息,处理方法就是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:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
            ALOG_ASSERT(refs->refBase() == obj,
                       "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
                       refs, obj, refs->refBase());
            obj->incStrong(mProcess.get());
            IF_LOG_REMOTEREFS() {
                LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
                obj->printRefs();
            }
            mOut.writeInt32(BC_ACQUIRE_DONE);
            mOut.writePointer((uintptr_t)refs);
            mOut.writePointer((uintptr_t)obj);
            break;
    
        case BR_RELEASE:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
            ALOG_ASSERT(refs->refBase() == obj,
                       "BR_RELEASE: object %p does not match cookie %p (expected %p)",
                       refs, obj, refs->refBase());
            IF_LOG_REMOTEREFS() {
                LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
                obj->printRefs();
            }
            mPendingStrongDerefs.push(obj);
            break;
    
        case BR_INCREFS:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
            refs->incWeak(mProcess.get());
            mOut.writeInt32(BC_INCREFS_DONE);
            mOut.writePointer((uintptr_t)refs);
            mOut.writePointer((uintptr_t)obj);
            break;
    
        case BR_DECREFS:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
            // NOTE: This assertion is not valid, because the object may no
            // longer exist (thus the (BBinder*)cast above resulting in a different
            // memory address).
            //ALOG_ASSERT(refs->refBase() == obj,
            //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
            //           refs, obj, refs->refBase());
            mPendingWeakDerefs.push(refs);
            break;
    
        case BR_ATTEMPT_ACQUIRE:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
    
            {
                const bool success = refs->attemptIncStrong(mProcess.get());
                ALOG_ASSERT(success && refs->refBase() == obj,
                           "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
                           refs, obj, refs->refBase());
    
                mOut.writeInt32(BC_ACQUIRE_RESULT);
                mOut.writeInt32((int32_t)success);
            }
            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;
    
                //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
    
                Parcel reply;
                status_t error;
                IF_LOG_TRANSACTIONS() {
                    TextOutput::Bundle _b(alog);
                    alog << "BR_TRANSACTION thr " << (void*)pthread_self()
                        << " / obj " << tr.target.ptr << " / code "
                        << TypeCode(tr.code) << ": " << indent << buffer
                        << dedent << endl
                        << "Data addr = "
                        << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
                        << ", offsets addr="
                        << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
                }
       
                if (tr.target.ptr) {
                    // We only have a weak reference on the target object, so we must first try to
                    // safely acquire a strong reference before doing anything else with it.
                    if (reinterpret_cast<RefBase::weakref_type*>(
                            tr.target.ptr)->attemptIncStrong(this)) {
                        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 {
                    error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
                }
    
                //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
                //     mCallingPid, origPid, origUid);
    
                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;
    
                IF_LOG_TRANSACTIONS() {
                    TextOutput::Bundle _b(alog);
                    alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
                        << tr.target.ptr << ": " << indent << reply << dedent << endl;
                }
    
            }
            break;
    
        case BR_DEAD_BINDER:
            {
                BpBinder *proxy = (BpBinder*)mIn.readPointer();
                proxy->sendObituary();
                mOut.writeInt32(BC_DEAD_BINDER_DONE);
                mOut.writePointer((uintptr_t)proxy);
            } break;
    
        case BR_CLEAR_DEATH_NOTIFICATION_DONE:
            {
                BpBinder *proxy = (BpBinder*)mIn.readPointer();
                proxy->getWeakRefs()->decWeak(proxy);
            } break;
    
        case BR_FINISHED:
            result = TIMED_OUT;
            break;
    
        case BR_NOOP:
            break;
    
        case BR_SPAWN_LOOPER:
            //这里将收到来自驱动的指示,创建一个线程,用于和binder通信
            mProcess->spawnPooledThread(false);
            break;
    
        default:
            ALOGE("*** BAD COMMAND %d received from Binder driver\n", cmd);
            result = UNKNOWN_ERROR;
            break;
        }
    
        if (result != NO_ERROR) {
            mLastError = result;
        }
    
        return result;
    }
    

    2.5 startThreadPool和joinThreadPool

    frameworks/av/media/mediaserver/main_mediaserver.cpp

    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
    

    startThreadPool()代码如下,
    frameworks/native/libs/binder/ProcessState.cpp

    void ProcessState::startThreadPool()
    {
        AutoMutex _l(mLock);
        //如果没有startPool则调用
        if (!mThreadPoolStarted) {
            mThreadPoolStarted = true;
            spawnPooledThread(true);
        }
    }
    

    再跟进看下spawnPooledThread
    frameworks/native/libs/binder/ProcessState.cpp

    void ProcessState::spawnPooledThread(bool isMain)
    {
        if (mThreadPoolStarted) {
            String8 name = makeBinderThreadName();
            ALOGV("Spawning new pooled thread, name=%s\n", name.string());
            sp<Thread> t = new PoolThread(isMain);
            t->run(name.string());
        }
    }
    

    继续跟进PoolThread

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

    PoolThread是定义在ProcessState.cpp中的定义的Thread的子类,从代码上来看,最终调用的还是joinThreadPool,再看下joinThreadPool函数

    void IPCThreadState::joinThreadPool(bool isMain)
    {
        LOG_THREADPOOL("**** THREAD %p (PID %d) IS JOINING THE THREAD POOL\n", (void*)pthread_self(), getpid());
    
        mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);
    
        status_t result;
        do {
            processPendingDerefs();
            // now get the next command to be processed, waiting if necessary
            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();
            }
    
            // 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);
        talkWithDriver(false);
    }
    

    至此,我们发现一个有两个线程在与Binder通信,一个是通过ProcessState::self()->startThreadPool()函数,开启的一个子线程进行通信,一个是通过IPCThreadState::self()->joinThreadPool()函数,主线程进行通信。

    三.ServiceManager

    3.1 ServiceManager原理

    defaultServiceManager返回的是一个BpServiceManager,通过它可以把命令请求发送给handle值为0的目的端。按照IServiceManager“家谱”来看,无论如何也应该有一个类从BnServiceManager派生出来并处理这些来自远方的请求吧?很可惜,源码中竟然没有这样一个类存在!但确实又有这么一个程序完成了BnServiceManager未尽的工作,这个程序就是ServiceManager,它的代码在Service_manager.c中。

    3.1.1 ServiceManager入口函数

    ServiceManager的入口函数如下:
    frameworks/native/cmds/servicemanager/service_manager.c

    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";
        }
        //1.打开binder设备
        bs = binder_open(driver, 128*1024);
        if (!bs) {
    #ifdef VENDORSERVICEMANAGER
            ALOGW("failed to open binder driver %s\n", driver);
            while (true) {
                sleep(UINT_MAX);
            }
    #else
            ALOGE("failed to open binder driver %s\n", driver);
    #endif
            return -1;
        }
        //2.成为大管家
        if (binder_become_context_manager(bs)) {
            ALOGE("cannot become context manager (%s)\n", strerror(errno));
            return -1;
        }
    
        cb.func_audit = audit_callback;
        selinux_set_callback(SELINUX_CB_AUDIT, cb);
        cb.func_log = selinux_log_callback;
        selinux_set_callback(SELINUX_CB_LOG, cb);
    
    #ifdef VENDORSERVICEMANAGER
        sehandle = selinux_android_vendor_service_context_handle();
    #else
        sehandle = selinux_android_service_context_handle();
    #endif
        selinux_status_open(true);
    
        if (sehandle == NULL) {
            ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
            abort();
        }
    
        if (getcon(&service_manager_context) != 0) {
            ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
            abort();
        }
    
        //循环处理来自client的请求
        binder_loop(bs, svcmgr_handler);
    
        return 0;
    }
    
    

    3.12 打开binder设备

    binder_open代码如下
    frameworks/native/cmds/servicemanager/binder.c

    struct binder_state *binder_open(const char* driver, size_t mapsize)
    {
        struct binder_state *bs;
        struct binder_version vers;
    
        bs = malloc(sizeof(*bs));
        if (!bs) {
            errno = ENOMEM;
            return NULL;
        }
        //1.打开设备
        bs->fd = open(driver, O_RDWR | O_CLOEXEC);
        if (bs->fd < 0) {
            fprintf(stderr,"binder: cannot open %s (%s)\n",
                    driver, 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;
        }
        //2.内存映射
        bs->mapsize = mapsize;
        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;
    }
    

    3.1.3 成为大管家

    frameworks/native/cmds/servicemanager/binder.c

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

    3.1.4 binder_loop

    frameworks/native/cmds/servicemanager/binder.c

    
    /*
      binder_handler func参数是一个函数指针,这些请求最终调用binder_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(bs, readbuf, sizeof(uint32_t));
    
        for (;;) {
            bwr.read_size = sizeof(readbuf);
            bwr.read_consumed = 0;
            bwr.read_buffer = (uintptr_t) readbuf;
    
            res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
    
            if (res < 0) {
                ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
                break;
            }
           //接收请求,并解析,最终交给binder_handler函数类型的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;
            }
        }
    }
    
    

    3.1.5 集中处理

    frameworks/native/cmds/servicemanager/service_manager.c

    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;
        uint32_t dumpsys_priority;
    
        //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;
    
        // Equivalent to Parcel::enforceInterface(), reading the RPC
        // header with the strict mode policy mask and the interface name.
        // Note that we ignore the strict_policy and don't propagate it
        // further (since we do no outbound RPCs anyway).
        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) {
    #ifdef VENDORSERVICEMANAGER
            struct selabel_handle *tmp_sehandle = selinux_android_vendor_service_context_handle();
    #else
            struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
    #endif
            if (tmp_sehandle) {
                selabel_close(sehandle);
                sehandle = tmp_sehandle;
            }
        }
    
        switch(txn->code) {
        //获取服务
        case SVC_MGR_GET_SERVICE:
        case SVC_MGR_CHECK_SERVICE:
            //s表示服务名
            s = bio_get_string16(msg, &len);
            if (s == NULL) {
                return -1;
            }
            handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
            if (!handle)
                break;
            bio_put_ref(reply, handle);
            return 0;
        //注册服务
        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;
            dumpsys_priority = bio_get_uint32(msg);
            if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
                               txn->sender_pid))
                return -1;
            break;
        //获取所有已注册的服务的名字
        case SVC_MGR_LIST_SERVICES: {
            uint32_t n = bio_get_uint32(msg);
            uint32_t req_dumpsys_priority = bio_get_uint32(msg);
    
            if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
                ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
                        txn->sender_euid);
                return -1;
            }
            si = svclist;
            // walk through the list of services n times skipping services that
            // do not support the requested priority
            while (si) {
                if (si->dumpsys_priority & req_dumpsys_priority) {
                    if (n == 0) break;
                    n--;
                }
                si = si->next;
            }
            if (si) {
                bio_put_string16(reply, si->name);
                return 0;
            }
            return -1;
        }
        default:
            ALOGE("unknown code %d\n", txn->code);
            return -1;
        }
    
        bio_put_uint32(reply, 0);
        return 0;
    }
    
    

    3.2 服务的注册

    svcmgr_handler中switch/case语句块中,就是ServiceManager处理来自所有客户端的请求的代码块,其中SVC_MGR_ADD_SERVICE分支表示的就是注册服务的内容。代码块中do_add_service就是真正处理注册服务的逻辑。
    frameworks/native/cmds/servicemanager/service_manager.c

    int do_add_service(struct binder_state *bs, const uint16_t *s, size_t len, uint32_t handle,
                       uid_t uid, int allow_isolated, uint32_t dumpsys_priority, pid_t spid) {
        struct svcinfo *si;
    
        //ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,
        //        allow_isolated ? "allow_isolated" : "!allow_isolated", uid);
    
        if (!handle || (len == 0) || (len > 127))
            return -1;
        //判断是否可以注册
        if (!svc_can_register(s, len, spid, uid)) {
            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));
            if (!si) {
                ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n",
                     str8(s, len), handle, uid);
                return -1;
            }
            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->dumpsys_priority = dumpsys_priority;
            si->next = svclist;
            svclist = si;
        }
    
        binder_acquire(bs, handle);
        binder_link_to_death(bs, handle, &si->death);
        return 0;
    }
    

    3.2.1 不是所有服务都可以注册

    do_add_service函数中的svc_can_register函数是用来判断这个注册服务的请求是否可以注册。代码如下:

    static int svc_can_register(const uint16_t *name, size_t name_len, pid_t spid, uid_t uid)
    {
        const char *perm = "add";
        //不允许app去注册
        if (multiuser_get_app_id(uid) >= AID_APP) {
            return 0; /* Don't allow apps to register services */
        }
    
        return check_mac_perms_from_lookup(spid, uid, perm, str8(name, name_len)) ? 1 : 0;
    }
    

    四.MediaPlayerService和它的Client

    4.1 查询ServiceManager

    一个Client想要得到某个Service的信息,就必须先和ServiceManager打交道,通过调用getService函数来获取对应Service的信息。以IMediaDeathNotifier.cpp中的getMediaPlayerService()为例,它的代码如下所示:
    frameworks/av/media/libmedia/IMediaDeathNotifier.cpp

    IMediaDeathNotifier::getMediaPlayerService()
    {
        ALOGV("getMediaPlayerService");
        Mutex::Autolock _l(sServiceLock);
        if (sMediaPlayerService == 0) {
            //此处就是与ServiceManager打交道,获取一个BpServiceManager
            sp<IServiceManager> sm = defaultServiceManager();
            sp<IBinder> binder;
            do {
                //通过名字,查询服务,获取到一个BpBinder
                binder = sm->getService(String16("media.player"));
                if (binder != 0) {
                    break;
                }
                ALOGW("Media player service not published, waiting...");
                //如果还没有注册,等待0.5s
                usleep(500000); // 0.5 s
            } while (true);
    
            if (sDeathNotifier == NULL) {
                sDeathNotifier = new DeathNotifier();
            }
            binder->linkToDeath(sDeathNotifier);
            //还是通过interface_cast函数,获取到一个BpMediaPlayerService
            sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
        }
        ALOGE_IF(sMediaPlayerService == 0, "no media player service!?");
        return sMediaPlayerService;
    }
    

    这段代码与之前的服务注册几乎流程差不多,只不过之前的是注册服务,最终调用的是addService,此处是getService。这段代码主要做了三件事
    1.调用defaultServiceManager(),获取一个BpServiceManager对象,也就是ServiceManager。
    2.通过ServiceManager调用的getService方法,通过名字获取到一个BpBinder。
    3.再通过interface_cast函数,通过内部的宏获取到一个BpMediaPlayerService,返回。

    最终我们的到了一个MediaPlayerService,我们可以通过它来调用MediaPlayerService的服务方法,例如createMediaRecorder和createMetadataRetriever等

    4.2 服务与Client通信

    MediaPlayerService驻留在MediaServer进程中,这个进程有两个线程在talkWithDriver。假设其中有一个线程收到了请求信息,它最终会通过executeCommand调用来处理这个请求,实现代码如下所示:

    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:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
            ALOG_ASSERT(refs->refBase() == obj,
                       "BR_ACQUIRE: object %p does not match cookie %p (expected %p)",
                       refs, obj, refs->refBase());
            obj->incStrong(mProcess.get());
            IF_LOG_REMOTEREFS() {
                LOG_REMOTEREFS("BR_ACQUIRE from driver on %p", obj);
                obj->printRefs();
            }
            mOut.writeInt32(BC_ACQUIRE_DONE);
            mOut.writePointer((uintptr_t)refs);
            mOut.writePointer((uintptr_t)obj);
            break;
    
        case BR_RELEASE:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
            ALOG_ASSERT(refs->refBase() == obj,
                       "BR_RELEASE: object %p does not match cookie %p (expected %p)",
                       refs, obj, refs->refBase());
            IF_LOG_REMOTEREFS() {
                LOG_REMOTEREFS("BR_RELEASE from driver on %p", obj);
                obj->printRefs();
            }
            mPendingStrongDerefs.push(obj);
            break;
    
        case BR_INCREFS:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
            refs->incWeak(mProcess.get());
            mOut.writeInt32(BC_INCREFS_DONE);
            mOut.writePointer((uintptr_t)refs);
            mOut.writePointer((uintptr_t)obj);
            break;
    
        case BR_DECREFS:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
            // NOTE: This assertion is not valid, because the object may no
            // longer exist (thus the (BBinder*)cast above resulting in a different
            // memory address).
            //ALOG_ASSERT(refs->refBase() == obj,
            //           "BR_DECREFS: object %p does not match cookie %p (expected %p)",
            //           refs, obj, refs->refBase());
            mPendingWeakDerefs.push(refs);
            break;
    
        case BR_ATTEMPT_ACQUIRE:
            refs = (RefBase::weakref_type*)mIn.readPointer();
            obj = (BBinder*)mIn.readPointer();
    
            {
                const bool success = refs->attemptIncStrong(mProcess.get());
                ALOG_ASSERT(success && refs->refBase() == obj,
                           "BR_ATTEMPT_ACQUIRE: object %p does not match cookie %p (expected %p)",
                           refs, obj, refs->refBase());
    
                mOut.writeInt32(BC_ACQUIRE_RESULT);
                mOut.writeInt32((int32_t)success);
            }
            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;
    
                //ALOGI(">>>> TRANSACT from pid %d uid %d\n", mCallingPid, mCallingUid);
    
                Parcel reply;
                status_t error;
                IF_LOG_TRANSACTIONS() {
                    TextOutput::Bundle _b(alog);
                    alog << "BR_TRANSACTION thr " << (void*)pthread_self()
                        << " / obj " << tr.target.ptr << " / code "
                        << TypeCode(tr.code) << ": " << indent << buffer
                        << dedent << endl
                        << "Data addr = "
                        << reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer)
                        << ", offsets addr="
                        << reinterpret_cast<const size_t*>(tr.data.ptr.offsets) << endl;
                }
                if (tr.target.ptr) {
                    // We only have a weak reference on the target object, so we must first try to
                    // safely acquire a strong reference before doing anything else with it.
                    if (reinterpret_cast<RefBase::weakref_type*>(
                            tr.target.ptr)->attemptIncStrong(this)) {
                    //调用了BBinder的transact返回了信息
                        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 {
                    error = the_context_object->transact(tr.code, buffer, &reply, tr.flags);
                }
    
                //ALOGI("<<<< TRANSACT from pid %d restore pid %d uid %d\n",
                //     mCallingPid, origPid, origUid);
    
                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;
    
                IF_LOG_TRANSACTIONS() {
                    TextOutput::Bundle _b(alog);
                    alog << "BC_REPLY thr " << (void*)pthread_self() << " / obj "
                        << tr.target.ptr << ": " << indent << reply << dedent << endl;
                }
    
            }
            break;
    
        case BR_DEAD_BINDER:
            {
                BpBinder *proxy = (BpBinder*)mIn.readPointer();
                proxy->sendObituary();
                mOut.writeInt32(BC_DEAD_BINDER_DONE);
                mOut.writePointer((uintptr_t)proxy);
            } break;
    
        case BR_CLEAR_DEATH_NOTIFICATION_DONE:
            {
                BpBinder *proxy = (BpBinder*)mIn.readPointer();
                proxy->getWeakRefs()->decWeak(proxy);
            } break;
    
        case BR_FINISHED:
            result = TIMED_OUT;
            break;
    
        case BR_NOOP:
            break;
    
        case BR_SPAWN_LOOPER:
            mProcess->spawnPooledThread(false);
            break;
    
        default:
            ALOGE("*** BAD COMMAND %d received from Binder driver\n", cmd);
            result = UNKNOWN_ERROR;
            break;
        }
    
        if (result != NO_ERROR) {
            mLastError = result;
        }
    
        return result;
    }
    
    

    BBinder和业务层有什么关系?我们以MediaPlayerService为例,来梳理一下其派生关系,如图所示:


    MediaPlayerService家族谱

    BnMediaPlayerService实现了onTransact函数,它将根据消息码调用对应的业务逻辑函数,这些业务逻辑函数由MediaPlayerService来实现。这一路的历程,如下面的代码所示:
    frameworks/native/libs/binder/Binder.cpp

    status_t BBinder::transact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
        data.setDataPosition(0);
    
        status_t err = NO_ERROR;
        switch (code) {
            case PING_TRANSACTION:
                reply->writeInt32(pingBinder());
                break;
            default:
                //调用子类的onTransact()
                err = onTransact(code, data, reply, flags);
                break;
        }
    
        if (reply != NULL) {
            reply->setDataPosition(0);
        }
    
        return err;
    }
    

    frameworks/av/media/libmedia/IMediaPlayerService.cpp

    status_t BnMediaPlayerService::onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
    {
        switch (code) {
            case CREATE: {
                CHECK_INTERFACE(IMediaPlayerService, data, reply);
                sp<IMediaPlayerClient> client =
                    interface_cast<IMediaPlayerClient>(data.readStrongBinder());
                audio_session_t audioSessionId = (audio_session_t) data.readInt32();
                sp<IMediaPlayer> player = create(client, audioSessionId);
                reply->writeStrongBinder(IInterface::asBinder(player));
                return NO_ERROR;
            } break;
            case CREATE_MEDIA_RECORDER: {
                CHECK_INTERFACE(IMediaPlayerService, data, reply);
                const String16 opPackageName = data.readString16();
                //子类要实现createMediaRecorder
                sp<IMediaRecorder> recorder = createMediaRecorder(opPackageName);
                reply->writeStrongBinder(IInterface::asBinder(recorder));
                return NO_ERROR;
            } break;
            case CREATE_METADATA_RETRIEVER: {
                CHECK_INTERFACE(IMediaPlayerService, data, reply);
                //子类要实现createMetadataRetriever()
                sp<IMediaMetadataRetriever> retriever = createMetadataRetriever();
                reply->writeStrongBinder(IInterface::asBinder(retriever));
                return NO_ERROR;
            } break;
            case ADD_BATTERY_DATA: {
                CHECK_INTERFACE(IMediaPlayerService, data, reply);
                uint32_t params = data.readInt32();
                addBatteryData(params);
                return NO_ERROR;
            } break;
            case PULL_BATTERY_DATA: {
                CHECK_INTERFACE(IMediaPlayerService, data, reply);
                pullBatteryData(reply);
                return NO_ERROR;
            } break;
            case LISTEN_FOR_REMOTE_DISPLAY: {
                CHECK_INTERFACE(IMediaPlayerService, data, reply);
                const String16 opPackageName = data.readString16();
                sp<IRemoteDisplayClient> client(
                        interface_cast<IRemoteDisplayClient>(data.readStrongBinder()));
                if (client == NULL) {
                    reply->writeStrongBinder(NULL);
                    return NO_ERROR;
                }
                String8 iface(data.readString8());
                sp<IRemoteDisplay> display(listenForRemoteDisplay(opPackageName, client, iface));
                reply->writeStrongBinder(IInterface::asBinder(display));
                return NO_ERROR;
            } break;
            case GET_CODEC_LIST: {
                CHECK_INTERFACE(IMediaPlayerService, data, reply);
                sp<IMediaCodecList> mcl = getCodecList();
                reply->writeStrongBinder(IInterface::asBinder(mcl));
                return NO_ERROR;
            } break;
            default:
                return BBinder::onTransact(code, data, reply, flags);
        }
    }
    

    相关文章

      网友评论

          本文标题:深入理解Android Binder机制

          本文链接:https://www.haomeiwen.com/subject/yyuewltx.html