美文网首页
从MediaPlayerService看Binder

从MediaPlayerService看Binder

作者: 勇敢地追 | 来源:发表于2020-04-25 15:19 被阅读0次

    MediaPlayerService是系统多媒体服务的一种,系统多媒体服务是由一个叫做MediaServer的服务进程提供的,它是一个可执行程序,在Android系统启动时,MediaServer也被启动,它的入口函数如下所示。
    frameworks/av/media/mediaserver/main_mediaserver.cpp

    int main(int argc __unused, char** argv)
    {
            ......
            sp<ProcessState> proc(ProcessState::self());//step 1
            sp<IServiceManager> sm = defaultServiceManager();//step 2
            ALOGI("ServiceManager: %p", sm.get());
            AudioFlinger::instantiate();
            MediaPlayerService::instantiate();//step 3
            ResourceManagerService::instantiate();
            CameraService::instantiate();
            AudioPolicyService::instantiate();
            SoundTriggerHwService::instantiate();
            RadioService::instantiate();
            registerExtensions();
            ProcessState::self()->startThreadPool();
            IPCThreadState::self()->joinThreadPool();
    }
    

    这次分析的是MediaPlayerService,所以只需要关注标注出来的三个step

    step1

    frameworks/native/libs/binder/ProcessState.cpp

    sp<ProcessState> ProcessState::self()
    {
        Mutex::Autolock _l(gProcessMutex);
        if (gProcess != NULL) {
            return gProcess;
        }
        gProcess = new ProcessState;
        return gProcess;
    }
    

    生成一个 ProcessState。看看里面做了什么
    frameworks/native/libs/binder/ProcessState.cpp

    ProcessState::ProcessState()
        : mDriverFD(open_driver())//--------------------------------
        , 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) {
            // 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;
            }
        }
    
        LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
    }
    

    先要open_driver,然后mmap

    • mmap函数,它会在内核虚拟地址空间中申请一块与用户虚拟内存相同大小的内存,然后再申请物理内存,将同一块物理内存分别映射到内核虚拟地址空间和用户虚拟内存空间,实现了内核虚拟地址空间和用户虚拟内存空间的数据同步操作,也就是内存映射。
    static int open_driver()
    {
        int fd = open("/dev/binder", O_RDWR | O_CLOEXEC);
        ......
        return fd;
    }
    

    总结:打开/dev/binder设备,通过mmap为binder分配一块虚拟地址空间

    step2

    frameworks/native/libs/binder/IServiceManager.cpp

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

    主要就是两步:ProcessState::self()->getContextObject 和 interface_cast

    2.1 getContextObject
    sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
    {
        return getStrongProxyForHandle(0);//注意,这里传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;
            if (b == NULL || !e->refs->attemptIncWeak(this)) {
                if (handle == 0) {
                    Parcel data;
                    status_t status = IPCThreadState::self()->transact(
                            0, IBinder::PING_TRANSACTION, data, NULL, 0);
                    if (status == DEAD_OBJECT)
                       return NULL;
                }
    
                b = new BpBinder(handle); 
                e->binder = b;
                if (b) e->refs = b->getWeakRefs();
                result = b;
            } else {
                e->refs->decWeak(this);
            }
        }
    
        return result;
    }
    

    很明显,生成一个 BpBinder 。
    说到BpBinder,不得不提到BBinder,它们都继承了IBinder。BpBinder是Client端与Server交互的代理类,而BBinder则代表了Server端。BpBinder和BBinder是一一对应的。其实这两者是很好区分,对于service来说继承了BBinder。因为BBinder有onTransact消息处理函数,而对于与service通信的client来说需要继承BpBinder(BpInterface),因为BpBinder有消息传递函数transcat。
    PS:IPCThreadState::self()->transact 这个函数后面讲

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

    因为 INTERFACE=IServiceManager ,所以去看 IServiceManager::asInterface
    先看一下 IServiceManager 的声明

    class IServiceManager : public IInterface
    {
    public:
        DECLARE_META_INTERFACE(ServiceManager);//这里
    
        /**
         * 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) = 0;
    
        /**
         * Return list of all existing services.
         */
        virtual Vector<String16>    listServices() = 0;
    };
    

    再看 DECLARE_META_INTERFACE

    #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();                                            \
    
    #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() { }                                   \
    

    上面是声明,下面是实现。将对应的参数代入就是

        ::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) {                                         
                    intr = new BpServiceManager(obj);//1                        
                }                                                           
            }                                                               
            return intr;                                                    
        }      
    

    很明显 asInterface 生成一个 BpServiceManager。看一下它的构造函数

    class BpServiceManager : public BpInterface<IServiceManager>
    {
    public:
        explicit BpServiceManager(const sp<IBinder>& impl)
            : BpInterface<IServiceManager>(impl)
        {
        }
    }
    
    template<typename INTERFACE>
    inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
        : BpRefBase(remote)
    {
    }
    
    BpRefBase::BpRefBase(const sp<IBinder>& o)
        : 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.
        }
    }
    

    mRemote是一个IBinder* 指针,它最终的指向为BpBinder,也就是说BpServiceManager的mRemote指向了BpBinder。那么BpServiceManager的作用也就知道了,就是它实现了IServiceManager,并且通过BpBinder来实现通信。

    总结:生成 BpServiceManager,并且通过BpBinder来实现通信

    step3

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

    很明显,defaultServiceManager 就是 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);
            status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
            return err == NO_ERROR ? reply.readExceptionCode() : err;
        }
    

    remote()指的是mRemote,也就是BpBinder。addService函数的作用就是将请求数据打包成data,然后传给BpBinder的transact函数(ADD_SERVICE_TRANSACTION)

    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 干了些啥?

    IPCThreadState* IPCThreadState::self()
    {
        if (gHaveTLS) {
    restart:
            const pthread_key_t k = gTLS;
            IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k);
            if (st) return st;
            return new IPCThreadState;
        }
        pthread_mutex_lock(&gTLSMutex);
        if (!gHaveTLS) {
            int key_create_value = pthread_key_create(&gTLS, threadDestructor);
            if (key_create_value != 0) {
                pthread_mutex_unlock(&gTLSMutex);
                ALOGW("IPCThreadState::self() unable to create TLS key, expect a crash: %s\n",
                        strerror(key_create_value));
                return NULL;
            }
            gHaveTLS = true;
        }
        pthread_mutex_unlock(&gTLSMutex);
        goto restart;
    }
    

    很明显,创建一个 IPCThreadState

    IPCThreadState::IPCThreadState()
        : mProcess(ProcessState::self()),
          mMyThreadId(gettid()),
          mStrictModePolicy(0),
          mLastTransactionBinderFlags(0)
    {
        pthread_setspecific(gTLS, this);
        clearCaller();
        mIn.setDataCapacity(256);
        mOut.setDataCapacity(256);
    }
    

    IPCThreadState中还包含mIn、一个mOut,其中mIn用来接收来自Binder驱动的数据,mOut用来存储发往Binder驱动的数据,它们默认大小都为256字节(形式上是不是和socket很像???)

    status_t IPCThreadState::transact(int32_t handle,
                                      uint32_t code, const Parcel& data,
                                      Parcel* reply, uint32_t flags)
    {
        ......
        if (err == NO_ERROR) {
            err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
        }
        ......
        if ((flags & TF_ONE_WAY) == 0) {
            if (reply) {
                err = waitForResponse(reply);
            } else {
                Parcel fakeReply;
                err = waitForResponse(&fakeReply);
            }
        } else {
            err = waitForResponse(NULL, NULL);
        }
        return err;
    }
    

    writeTransactionData 和 waitForResponse 代码就不贴了,很简单,就是与Binder驱动进行通信
    总结:发送 ADD_SERVICE_TRANSACTION 和binder通信

    流程图

    流程图

    参考文章:
    https://www.jianshu.com/p/fd83f85b9f5e
    https://www.jianshu.com/p/643356d5df93

    相关文章

      网友评论

          本文标题:从MediaPlayerService看Binder

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