Binder系統初探(一)

 

        雖說閱讀Binder的源代碼是學習Binder機制的最好的方式,但是也絕不能打無準備之仗,因爲Binder的相關源代碼是比較枯燥無味而且比較難以理解的,如果能夠輔予一些理論知識,那就更好了。閒話少說,網上關於Binder機制的資料還是不少的,這裏就不想再詳細寫一遍了,強烈推薦下面兩篇文章:

        Android深入淺出之Binder機制

        Android Binder設計與實現 – 設計篇
 

 

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


defaultServiceManager = BpServiceManager

class MediaPlayerService : public BnMediaPlayerService

Bn Binder Native層

Bp Binder Proxy  代理

BpServiceManager   BnServiceManager  BnMediaPlayerService  BpMediaPlayerService來和他交互呢


p<IServiceManager> defaultServiceManager()

{

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

  b = new BpBinder(handle); 

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

    DECLARE_META_INTERFACE(ServiceManager);

#define DECLARE_META_INTERFACE(INTERFACE)                               \
    static const android::String16 descriptor;                          \
    static android::sp<I##INTERFACE> asInterface(                       \
            const android::sp<android::IBinder>& obj);                  \
    virtual const android::String16& getInterfaceDescriptor() const;    \
    I##INTERFACE();                                                     \
    virtual ~I##INTERFACE();                                            \

怎麼和MFC這麼類似?微軟的影響很大啊!知道MFC的,有DELCARE肯定有IMPLEMENT


class BpServiceManager : public BpInterface<IServiceManager>
{
public:
    BpServiceManager(const sp<IBinder>& impl)
        : BpInterface<IServiceManager>(impl)
    {
    }

addService Parcel   writeInterfaceToken      ADD_SERVICE_TRANSACTION

remote transact


class BpRefBase : public virtual RefBase
{

  inline  IBinder*        remote()                { return mRemote; }


BpBinder::BpBinder(int32_t handle)


class BpServiceManager : public BpInterface<IServiceManager>
{
public:
    BpServiceManager(const sp<IBinder>& impl)
        : BpInterface<IServiceManager>(impl)
    {
    }

inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{
}

BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)
{


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;
    }

BpBinder轉換爲  IServiceManager :BpRefBase

status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{

//又繞回去了,調用IPCThreadState的transact。

//注意啊,這裏的mHandle爲0,code是ADD_SERVICE_TRANSACTION,data是命令包

//reply是回覆包,flags=0

status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{

            err = waitForResponse(reply);
            
            
            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.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
        
        
        reinterpret_cast<uintptr_t>(statusBuffer)
        
        
        
        上面把命令數據封裝成binder_transaction_data,然後

寫到mOut中,mOut是命令的緩衝區,也是一個Parcel

    mOut.writeInt32(cmd);

    mOut.write(&tr, sizeof(tr));

//僅僅寫到了Parcel中,Parcel好像沒和/dev/binder設備有什麼關聯啊?

恩,那隻能在另外一個地方寫到binder設備中去了。難道是在?

    return NO_ERROR;
    
    
    
    
    
    status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{

        //看見沒?這裏開始操作mIn了,看來talkWithDriver中

//把mOut發出去,然後從driver中讀到數據放到mIn中了。
status_t IPCThreadState::talkWithDriver(bool doReceive)
{

    binder_write_read bwr;
       if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
       
       
       好了,到這裏,我們發送addService的流程就徹底走完了。

BpServiceManager發送了一個addService命令到BnServiceManager,然後收到回覆。


int main(int argc __unused, char** argv)
{
     sp<ProcessState> proc(ProcessState::self());
        MediaLogService::instantiate();
        ProcessState::self()->startThreadPool();
       
        
        一個調用的函數是ProcessState::self(),然後賦值給了proc變量,程序運行完,proc會自動delete內部的內容,所以就自動釋放了先前分配的資源。
        

    bs = binder_open(128*1024);
    
     bs->fd = open("/dev/binder", O_RDWR);
     
      bs->mapped = mmap(NULL, mapsize, PROT_READ, MAP_PRIVATE, bs->fd, 0);//映射內存
      
      
     if (binder_become_context_manager(bs)) {
        ALOGE("cannot become context manager (%s)\n", strerror(errno));
        return -1;
    }
    
    int binder_become_context_manager(struct binder_state *bs)
{
    return ioctl(bs->fd, BINDER_SET_CONTEXT_MGR, 0);
}


    binder_loop(bs, svcmgr_handler);
    
    void binder_loop(struct binder_state *bs, binder_handler func)
{


    
        struct binder_write_read bwr;  binder_write(bs, readbuf, sizeof(uint32_t));
        
           res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
           
           
            res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);

        if (res < 0) {
            ALOGE("binder_loop: ioctl failed (%s)\n", strerror(errno));
            break;
        }

        res = binder_parse(bs, 0, (uintptr_t) readbuf, bwr.read_consumed, func);
        
        
        int binder_parse(struct binder_state *bs, struct binder_io *bio,
                 uintptr_t ptr, size_t size, binder_handler func)
{


恩,最後有一個類似handleMessage的地方處理各種各樣的命令。這個就是

svcmgr_handler,就在ServiceManager.c中


int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{

  struct binder_transaction_data *txn = (struct binder_transaction_data *) ptr;
  
   if (func) {
   
   
      if (do_add_service(bs, s, len, handle, txn->sender_euid,
            allow_isolated, txn->sender_pid))
   
   int do_add_service(struct binder_state *bs,
                   const uint16_t *s, size_t len,
                   uint32_t handle, uid_t uid, int allow_isolated,
                   pid_t spid)
                   


  //si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
  
  si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t))

  // memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
   memcpy(si-name,s, (len + 1) * sizeof(uint16_t))
   
    //si->next = svclist;
        //svclist = si;
        
        si->next = svclist
        svclist = si;
        
        喔,對於addService來說,看來ServiceManager把信息加入到自己維護的一個服務列表中了。
        
        
        
        ServiceManager存在的意義
        
        Android系統中Service信息都是先add到ServiceManager中,由ServiceManager來集中管理,這樣就可以查詢當前系統有哪些服務。而且,Android系統中某個服務例如MediaPlayerService的客戶端想要和MediaPlayerService通訊的話,必須先向ServiceManager查詢MediaPlayerService的信息,然後通過ServiceManager返回的東西再來和MediaPlayerService交互。

畢竟,要是MediaPlayerService身體不好,老是掛掉的話,客戶的代碼就麻煩了,就不知道後續新生的MediaPlayerService的信息了,所以只能這樣:


另外,ServiceManager的handle標示是0,所以只要往handle是0的服務發送消息了,最終都會被傳遞到ServiceManager中去


  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;
    }
    
    
     defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
    
    
    
    class MediaPlayerService : public BnMediaPlayerService
{


class BnMediaPlayerService: public BnInterface<IMediaPlayerService>
{
public:
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);
};


template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
兌現後變成

class BnInterface : public IMediaPlayerService, public BBinder

class PoolThread : public Thread
{

  t->run(name.string());


  ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
        
        void IPCThreadState::joinThreadPool(bool isMain)
{

./work/android-5.0.2/external/lldb/source/Target/Thread.cpp

        

 

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