Binder機制分析(2)——從MediaService中看Binder的實現和使用(1)

yangxi_001發表於2016-12-27

本文是對《Android技術內幕-系統卷》第三章的摘抄和整理。


1. MediaService入口, 獲取ServiceManager

下面我們就從MediaService的原始碼入手進行分析,首先,MediaService的入口函式的實現位於“framework\base\media\mediaServer\main_mediaserver.cpp”。
    int main(int argc, char* argv)  
    {  
        //獲得ProcessState例項  
        sp<ProcessState> proc(ProcessState::self());  
        //得到一個ServiceManager物件  
        sp<IServiceManager> sm = defaultServiceManager();  
        LOGI("ServiceManager: %p", sm.get());  
        //初始化MediaService服務  
        AudioFlinger::instantiate();  
        MediaPlayerService::instantiate();  
        CameraService::instantiate();  
        AudioPolicyService::instantiate();  
        //啟動程式的執行緒池  
        ProcessState::self()->startThreadPool();  
       //將自己加入到執行緒池  
        IPCThreadState::self()->joinThreadPool();  
    } 
    
    1.1 defaultServiceManager()的實現
    sp<IServiceManager> defaultServiceManager()  
    {  
        if (gDefaultServiceManager != NULL) return gDefaultServiceManager;  
        {  
            AutoMutex _l(gDefaultServiceManagerLock);  
            if (gDefaultServiceManager == NULL) {  
                //建立gDefaultServiceManager  
                gDefaultServiceManager = interface_cast<IServiceManager>(  
                    ProcessState::self()->getContextObject(NULL));  
            }  
        }  
        return gDefaultServiceManager;  
    } 
    這裡採用了singleton模式,如果全域性的gDefaultServiceManager不為NULL,則直接返回;否則,建立一個gDefaultServiceManager。
    
    1.2 getContextObject()的實現
    sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)  
    {  
        if (supportsProcesses()) {  
            return getStrongProxyForHandle(0);  
        } else {  
            return getContextObject(String16("default"), caller);  
        }  
    } 
    
    1.3 getStrongProxyForHandle的實現
    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)) {
                b = new BpBinder(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);
            }
        }
        return result;
    }
    將建立過程交給ProcessState::getStrongProxyForHandle()函式來實現,第一次進入該函式則會建立一個BpBinder物件並返回。
    
    1.4 interface_cast的實現
    大家可能會疑惑,明明建立的是一個BpBinder物件,為什麼最後卻通過interface_cast函式強制轉換為IServiceManager。
    template<typename INTERFACE> 
    inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)  
    {  
        return INTERFACE::asInterface(obj);  
    } 
    替換INTERFACE:
    inline sp<IServiceManager> interface_cast(const sp<IBinder>& obj)  
    {  
        return IServiceManager::asInterface(obj);  
    } 
    其中,INTERFACE對應於IServiceManager,因此我們需要繼續找到IServiceManager::asInterface(...)的實現。在IServiceManager中我們可以看到一個如下所示的巨集:
    DECLARE_META_INTERFACE(ServiceManager);
    
    1.5 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(); 
            
     替換INTERFACE:
     #define DECLARE_META_INTERFACE(INTERFACE)  
        static const Android::String16 descriptor;  
        static android::sp<IServiceManager> asInterface(  
                const Android::sp<android::IBinder>& obj);  
        virtual const android::String16& getInterfaceDescriptor() const;  
        IServiceManager();  
        virtual ~IServiceManager(); 
    
    1.6 IMPLEMENT_META_INTERFACE分析
        IMPLEMENT_META_INTERFACE(ServiceManager, "Android.os.IServiceManager"); //IServiceManager.cpp 
        
        #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() { } 
        替換INTERFACE:
        #define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)      
            const Android::String16 IServiceManager::descriptor("Android.os.IServiceManager");  
            const android::String16&  
                    IServiceManager::getInterfaceDescriptor() const {  
                return IServiceManager::descriptor;  
            }  
            Android::sp<IServiceManager> ServiceManager::asInterface(  
                    const Android::sp<android::IBinder>& obj)  //實際上obj = BpBinder(0);
            {  
                Android::sp<IServiceManager> intr;  
                if (obj != NULL) {  
                    intr = static_cast<IServiceManager*>(  
                        obj->queryLocalInterface(  
                                IServiceManager::descriptor).get());  
                    if (intr == NULL) {  
                        intr = new BpServiceManager(obj);  //實際上obj = BpBinder(0);
                    }  
                }  
                return intr;  
            }  
            IServiceManager::IServiceManager() { }  
            IServiceManager::~IServiceManager() { } 
    
    1.7 asInterface的實現
    該函式首先會根據描述符去查詢本地的Interface,如果沒有查詢到,則會執行“new Bp##INTERFACE(obj);”,實際上就是建立了一個BpServiceManager例項。
    因為這個命名也以Bp開頭,也許它與上一節介紹的Binder機制的伺服器代理物件有關,其實BpServiceManager就是ServiceManager的Binder代理物件。
    
    1.8 BpServiceManager實現 
    在IServiceManager.cpp中可以找到BpServiceManager的實現:
        BpServiceManager(const sp<IBinder>& impl)  //實際上impl = BpBinder(0);
        : BpInterface<IServiceManager>(impl)  
    {  
    } 
    這裡的impl就是之前通過ProcessState::getContextObject建立的BpBinder物件。接著進入BpInterface的建構函式,它位於IInterface.h中:
    inline BpInterface<IServiceManager>::BpInterface(const sp<IBinder>& remote)  //實際上remote = BpBinder(0);
        : BpRefBase(remote)  
    {  
    } 
    最終會進入BpRefBase的建構函式,它位於Binder.cpp中:
    BpRefBase::BpRefBase(const sp<IBinder>& o)  //實際上o = BpBinder(0);
        : mRemote(o.get()), mRefs(NULL), mState(0)   //實際上mRemote = BpBinder(0);
    {  
        extendObjectLifetime(OBJECT_LIFETIME_WEAK);  
        if (mRemote) {  
            mRemote->incStrong(this);               //Removed on first  
            mRefs = mRemote->createWeak(this);      //Held for our entire  
        }  
    } 
    o.get()實際上就是之前通過ProcessState::getContextObject建立的BpBinder物件,即mRemote指向BpBinder物件。也就是說,“sp<IServiceManager> sm = defaultServiceManager();”語句返回的實際上是BpServiceManager,它的remote物件是BpBinder,傳入的handle引數是0。
    得到了BpServiceManager物件後,我們就可以通過Binder與ServiceManager進行互動了。
    
 
2. 新增Service到ServiceManager:   
    2.1 MediaPlayerService::instantiate()分析
    void MediaPlayerService::instantiate() {  
        defaultServiceManager()->addService(  
                String16("media.player"), new MediaPlayerService());  
    }
    MediaPlayerService建構函式:  
    MediaPlayerService::MediaPlayerService()  
    {  
        LOGV("MediaPlayerService created");  
        mNextConnId = 1;  
    } 
    初始化過程為:首先,構造一個MediaPlayerService。
    然後,通過defaultServiceManager()獲得之前建立的BpServiceManager,並呼叫其addService函式。
    而MediaPlayerService又繼承自BnMediaPlayerService,實際上就是MediaPlayerService服務,對應於Binder機制中的服務端。
    
    2.2 BpServiceManager::addService的實現
    virtual status_t addService(const String16& name, const sp<IBinder>& service)  //service就是BnMediaPlayerService
    {  
        Parcel data, reply;  
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());  //通過巨集DECLARE_META_INTERFACE所定義的描述符"Android.os.Iservice Manager"。
        data.writeString16(name);  //name就是"media.player"
        data.writeStrongBinder(service);  //service就是BnMediaPlayerService
        status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);  //remote()返回mRemout,也就是BpBinder(0)
        return err == NO_ERROR ? reply.readInt32() : err;  
    } 
    首先呼叫writeInterfaceToken寫入Interface的名稱IServiceManager::getInterfaceDescriptor(),寫入的名稱實際上就是前面在IServiceManager中,
    然後,通過writeString16寫入服務的名稱,根據引數可以知道該服務的名稱為media.player;
    最後,通過writeStrongBinder寫入服務,也就是上面所說的MediaPlayerService,即BnMediaPlayerService。
    準備好要傳送的命令包後,通過remote()獲得其mRemote物件(前面分析過,該物件實際上就是在defaultServiceManager()中建立的BpBinder物件,也就是BpBinder(0));
    呼叫transact函式來傳送命令包,傳送的命令為新增服務ADD_SERVICE_TRANSACTION。
    2.3 IPCThreadState::self()->transact
    BpBinder::transact最終會呼叫 IPCThreadState::self()->transact來傳送資料。
    而在IPCThreadState中,最終還是通過writeTransactionData函式來完成資料的傳送的。
    傳送之後,waitForResponse函式會等待反饋的結果,在writeTransactionData中會將要傳送的資料整理為一個binder_transaction_data結構體(請參見Binder驅動的部分)。
    直到進入talkWithDriver函式中才會真正開始利用Binder驅動來進行通訊。對於驅動的操作,當然就是ioctl了。talkWithDriver函式中的傳送片段如程式碼清單3-60所示。
    talkWithDriver的實現片段
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)  
            err = NO_ERROR;  
        else  
            err = -errno;  
    BpServiceManager傳送的資訊應該由BnServiceManager來接收,但是Android中並沒有BnServiceManager。
    因此,具體的接收操作會由Service Manager來完成。具體操作流程請參考上一篇關於Service Manager的實現,也就是其中的svcmgr_handler函式。
    
3. 總結
    1)通過ProcessState::self()函式獲得ProcessState物件,並開啟Binder裝置。
    2)通過defaultServiceManager得到BpServiceManager例項。

    3)通過MediaPlayerService::instantiate()得到MediaPlayerService服務BnMediaPlayer Service,並通過BpServiceManager::addService將MediaPlayerService服務加入到Service Manager的list中。


相關文章