Android Binder机制(四) ------- 客户端分析

客户端首先通过defaultServiceManager获得IServiceManager接口。然后调用IServiceManager的getSerivice接口得到服务的IBInder接口,该接口指向一个BpBinder实体对象。但是问题是我们通过IBInder接口无法调用到我们的服务,还必须经过接口转化才能得到我们真正的服务代理接口。

*outService = interface_cast<INTERFACE>(sm->getService(name));
  • 模板函数interface_cast的功能就是将IBinder接口转化为对应的服务代理接口,看看它的实现
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}
  • 这函数也没干什么事,就是封装了下。调用INTERFACE::asInterface实现接口转化。asInterface接口的声明和实现是用宏定义。
#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() { }                                   \


#define CHECK_INTERFACE(interface, data, reply)                         \
    if (!data.checkInterface(this)) { return PERMISSION_DENIED; }       \
  • asInterface首先去查询本地接口,如果之后已经获得,返回之前的接口指针给intr。
  • 如果之前没有获得过该接口,intr为NULL,那么重新创建一个Bp##INTERFACE服务代理接口对象。
  • 最后返回去的就是Bp##INTERFACE对象指针,我们就可以用该接口指针调用所需要服务。
  • Bp##INTERFACE类的构造函数是一个IBinder引用,我们看下这个引用最终保存在哪里(这个引用很关键,与服务的交互就靠它了)
BpSurfaceComposer(const sp<IBinder>& impl)
        : BpInterface<ISurfaceComposer>(impl)
{
}

BpSurfaceComposer构造函数中将IBinder引用传给了其父类BpInterface,那继续往上看

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

BpInterface的构造函数又将IBinder引用传给了其父类BpRefBase,那我们在看看BpRefBase的构造函数

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

BpRefBase将IBinder引用赋值给了其成员变量mRemote中。在来看看BpRefBase的类定义

class BpRefBase : public virtual RefBase
{
protected:
                            BpRefBase(const sp<IBinder>& o);         
    virtual                 ~BpRefBase();    
    virtual void            onFirstRef();    
    virtual void            onLastStrongRef(const void* id);         
    virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);                                                                                                            

    inline  IBinder*        remote()                { return mRemote; }
    inline  IBinder*        remote() const          { return mRemote; }                                                                                                                      

private:
                            BpRefBase(const BpRefBase& o);           
    BpRefBase&              operator=(const BpRefBase& o);                                                                                                                                   

    IBinder* const          mRemote;
    RefBase::weakref_type*  mRefs;
    volatile int32_t        mState;
};

比较关键的是其成员函数remote()返回了mRemote的值。

先总结一下,Bp##INTERFACE的创建的时候会传入IBinder引用。构造函数会将IBinder引用保存在成员变量mRemote中。然后其成员函数remote()会返回mRemote的值。到这里Bp##INTERFACE代理接口对象构建完了,接下来在看看怎么调用里面的接口方法实现与服务进程的通讯。(以接口ISurfaceComposer的bootFinished方法为例 )

当客户端调通过接口指针(ISurfaceComposer *)调用bootFinished方法时,由于指针实际所指对象为BpSurfaceComposer。所以实质上调用BpSurfaceComposer的bootFinished方法。

virtual void bootFinished()         
{
    Parcel data, reply;
    data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
    remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
}
  • 通过remote()函数所返回的对象指针,调用transact函数
  • 由上文可知,remote()所返回的指针类类型为IBinder *, 但它所指向的对象为BpBinder
  • 所以最终调用BpBinder里的transact方法
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的transact方法
status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
    ......
       
    if (err == NO_ERROR) {
        LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(), 
            (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
        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函数,它将客户端请求封装成数据包binder_transaction_data
  • binder_transaction_data函数,调用talkWithDriver与Binder驱动进行数据交互。将请求写入到Binder驱动,并不断从Binder驱动中读取返回来的数据。
  • 将返回来的数据放在reply中,并返回给调用者

总结,客户端在调用Binder代理接口方法时,最终通过IPCThreadState::transact与Binder驱动通讯,将请求写入到Binder驱动,并Binder驱动中读取返回的结果,然后返回给调用者。客户端的调用流程就大致走完了。

posted @ 2018-03-27 10:20  qzhang1535  阅读(353)  评论(0编辑  收藏  举报