IBinder接口

Binder通信的基类

IBinder定义了代理端、服务端通信的接口方法,实现该接口的子类都可称之为“Binder”。
定义了Binder通信的接口。
定义了内部类DeathRecipient用来处理远端连接断掉后的处理回调。
定义了获取自定义功能sp<IInterface>对象的方法,由子类实现。
定义了获取BBinder对象的方法,由子类实现。
定义了获取BpBinder对象的方法,由子类实现。

如何定义服务的接口

    任何一种服务,都需要提供接口供客户端调用才有意义,Android为这些接口提供了基类IInterface。该类包含返回一个
IBinder的强引用指针的方法。因此需要进行Binder通信时就可以通过它的asBinder()方法获取IBinder的对象。
    此外,IInterface还提供了将IBinder转换成IInterface接口的宏,当我们从Binder驱动获取到某个服务的Binder内存数据后,
就可以动态的将该内存数据转换成对应服务的代理类对象,它的形式通常是Bpxxxx。

谁做服务端

    服务端通过BBinder实现,它继承IBinder接口,有一个重要的onTransact()方法。该方法主要是服务器端对应于代理端所做出
的各种请求的具体实现;而与驱动通信的功能由服务器进程建立循环线程来实现,onTransact()会在该线程处理请求时被调用。
    BBinder已经实现了IBinder接口,IInterface的继承类实现了服务端的功能接口,真正的Binder对象是这两者的组合,由此而
诞生了BnInterface。它双重继承于IInterface和BBinder,因此它既具有Binder的通信功能又能够实现服务端提供的接口。该类是
最终提供给各种服务继承的基类,用户要先声明自定义的IInterface接口,再实现BnInterface的子类。

谁做代理端

    代理端通过BpBinder实现,它同样继承IBinder接口。从BpBinder的构造函数我们可以得知,Binder在代理端的形态是一个handle,
代理端通过这个handle与驱动进行通信,通信功能由BpBinder自身实现(使用IPCThreadState)。
    它还有一个内部类ObjectManager,用来管理一组BpBinder对象的列表,该列表与Java层的BpBinder相关联。
    上面提到服务端最终被用户使用的基类是BnInterface,代理端同样有与之相对应的类BpInterface。它双重继承于BpRefBase和
IInterface,这里有一个疑问,为什么代理端没有继承BpBinder,而是继承了BpRefBase类?我们去看BpRefBase的构造函数可以知道,
它需要一个sp<IBinder>作为参数,而这个IBinder就是BpBinder。BpRefBase的作用是维护BpBinder的引用计数。和服务端不同,
服务端的Binder实体只有一个,而代理端获取的是Binder引用,因此每个代理端得到Binder引用后都需要将自身引用加1,当释放的时候减1。

再探接口IInterface

    以上内容描述了接口、服务端、代理端的概念。我们回过头来再看IInterface.cpp和IInterface.h的定义和实现。首先它是
B*Interface的抽象基类,其次它提供了IBinder和B*Interface之间相互转换的方法。
    asBinder(): 实现从Interface转换成IBinder。该方法会调用子类的onAsBinder()。而子类BnInterface和BpInterface
的实现是不一样的,服务端直接返回this,即BBinder;而代理端返回remote(),即BpBinder。
    asInterface(): 实现从IBinder转换成Interface。该方法由DECLARE_META_INTERFACE和IMPLEMENT_META_INTERFACE宏实现,
服务端对象调用该方法,会直接返回BnInterface的子类对象,客户端对象调用该方法则返回BpInterface的子类对象。

要点总结

IBinder.h

IBinder

class IBinder : public virtual RefBase
{
public:
    enum {
        FIRST_CALL_TRANSACTION  = 0x00000001,
        LAST_CALL_TRANSACTION   = 0x00ffffff,

        PING_TRANSACTION        = B_PACK_CHARS('_','P','N','G'),
        DUMP_TRANSACTION        = B_PACK_CHARS('_','D','M','P'),
        INTERFACE_TRANSACTION   = B_PACK_CHARS('_', 'N', 'T', 'F'),

        // Corresponds to tfOneWay -- an asynchronous call.
        FLAG_ONEWAY             = 0x00000001
    };

                            IBinder();

    // 本地服务接口查询方法
    virtual sp<IInterface>  queryLocalInterface(const String16& descriptor);

    virtual const String16& getInterfaceDescriptor() const = 0;

    // 代理端Binder是否存在
    virtual bool            isBinderAlive() const = 0;
    // 向服务端发送PING_TRANSACTION命令,并返回状态
    virtual status_t        pingBinder() = 0;
    virtual status_t        dump(int fd, const Vector<String16>& args) = 0;

    // 发送命令请求
    virtual status_t        transact(   uint32_t code,
                                        const Parcel& data,
                                        Parcel* reply,
                                        uint32_t flags = 0) = 0;

    // 服务端异常或被杀死后的回调处理
    class DeathRecipient : public virtual RefBase
    {
    public:
        virtual void binderDied(const wp<IBinder>& who) = 0;
    };

    // 代理端要求Binder驱动当服务端死掉后,发送死亡通知给代理端,如果代理端设置了
    // DeathRecipient,便会调用它的binderDied回调。
    virtual status_t        linkToDeath(const sp<DeathRecipient>& recipient,
                                        void* cookie = NULL,
                                        uint32_t flags = 0) = 0;

    // 取消之前注册的死亡通知机制
    virtual status_t        unlinkToDeath(  const wp<DeathRecipient>& recipient,
                                            void* cookie = NULL,
                                            uint32_t flags = 0,
                                            wp<DeathRecipient>* outRecipient = NULL) = 0;

    virtual bool            checkSubclass(const void* subclassID) const;

    typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie);

    virtual void            attachObject(   const void* objectID,
                                            void* object,
                                            void* cleanupCookie,
                                            object_cleanup_func func) = 0;
    virtual void*           findObject(const void* objectID) const = 0;
    virtual void            detachObject(const void* objectID) = 0;

    // BBinder返回this
    virtual BBinder*        localBinder();
    // BpBinder返回this
    virtual BpBinder*       remoteBinder();

protected:
    virtual          ~IBinder();

private:
};

IInterface.h

IInterface

class IInterface : public virtual RefBase
{
public:
            IInterface();
            sp<IBinder>         asBinder();
            sp<const IBinder>   asBinder() const;
            
protected:
    virtual                     ~IInterface();
    virtual IBinder*            onAsBinder() = 0;
};

BnInterface

template<typename INTERFACE>
class BnInterface : public INTERFACE, public BBinder
{
public:
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
    virtual const String16&     getInterfaceDescriptor() const;

protected:
    virtual IBinder*            onAsBinder();
};

BnInterface::queryLocalInterface

template<typename INTERFACE>
inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
        const String16& _descriptor)
{
    if (_descriptor == INTERFACE::descriptor) return this;
    return NULL;
}

BnInterface::getInterfaceDescriptor

template<typename INTERFACE>
inline const String16& BnInterface<INTERFACE>::getInterfaceDescriptor() const
{
    return INTERFACE::getInterfaceDescriptor();
}

BnInterface::onAsBinder

template<typename INTERFACE>
IBinder* BnInterface<INTERFACE>::onAsBinder()
{
    return this;
}

BpInterface

template<typename INTERFACE>
class BpInterface : public INTERFACE, public BpRefBase
{
public:
                                BpInterface(const sp<IBinder>& remote);
protected:
    virtual IBinder*            onAsBinder();
};

BpInterface::BpInterface

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

BpInterface::onAsBinder

template<typename INTERFACE>
inline IBinder* BpInterface<INTERFACE>::onAsBinder()
{
    return remote();
}

INTERFACE宏

DECLARE_META_INTERFACE

#define DECLARE_META_INTERFACE(INTERFACE)                               \
    static const String16 descriptor;                                   \
    // IBinder转换成服务接口类                                         \
    static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj);        \
    virtual const String16& getInterfaceDescriptor() const;             \
    I##INTERFACE();                                                     \
    virtual ~I##INTERFACE();                                            \

IMPLEMENT_META_INTERFACE

#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
    const String16 I##INTERFACE::descriptor(NAME);                      \
    const String16& I##INTERFACE::getInterfaceDescriptor() const {      \
        return I##INTERFACE::descriptor;                                \
    }                                                                   \
    sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)  \
    {                                                                   \
        sp<I##INTERFACE> intr;                                          \
        if (obj != NULL) {                                              \
            // 首先查询是否是本地Binder                         \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            // 如果没有,则创建一个Bpxxxx的对象作为代理                 \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }                                                                   \
    I##INTERFACE::I##INTERFACE() { }                                    \
    I##INTERFACE::~I##INTERFACE() { }                                   \

IInterface.cpp

IInterface::asBinder

sp<IBinder> IInterface::asBinder()
{
    return this ? onAsBinder() : NULL;
}

IInterface::asBinder()

sp<const IBinder> IInterface::asBinder() const
{
    return this ? const_cast<IInterface*>(this)->onAsBinder() : NULL;
}

Binder.h

BBinder

class BBinder : public IBinder
{
public:
                        BBinder();

    virtual const String16& getInterfaceDescriptor() const;
    virtual bool        isBinderAlive() const;
    virtual status_t    pingBinder();
    virtual status_t    dump(int fd, const Vector<String16>& args);

    // 传输Binder数据
    virtual status_t    transact(   uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);

    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
                                    void* cookie = NULL,
                                    uint32_t flags = 0);

    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
                                        void* cookie = NULL,
                                        uint32_t flags = 0,
                                        wp<DeathRecipient>* outRecipient = NULL);

    virtual void        attachObject(   const void* objectID,
                                        void* object,
                                        void* cleanupCookie,
                                        object_cleanup_func func);
    virtual void*       findObject(const void* objectID) const;
    virtual void        detachObject(const void* objectID);

    virtual BBinder*    localBinder();

protected:
    virtual             ~BBinder();

    // 服务端实现代理端的请求
    virtual status_t    onTransact( uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);

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

    class Extras;

            Extras*     mExtras;
            void*       mReserved0;
    static  String16    sEmptyDescriptor;
};

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

BpBinder.h

BpBinder

class BpBinder : public IBinder
{
public:
                        BpBinder(int32_t handle);

    inline  int32_t     handle() const { return mHandle; }

    virtual const String16&    getInterfaceDescriptor() const;
    virtual bool        isBinderAlive() const;
    virtual status_t    pingBinder();
    virtual status_t    dump(int fd, const Vector<String16>& args);

    virtual status_t    transact(   uint32_t code,
                                    const Parcel& data,
                                    Parcel* reply,
                                    uint32_t flags = 0);

    virtual status_t    linkToDeath(const sp<DeathRecipient>& recipient,
                                    void* cookie = NULL,
                                    uint32_t flags = 0);
    virtual status_t    unlinkToDeath(  const wp<DeathRecipient>& recipient,
                                        void* cookie = NULL,
                                        uint32_t flags = 0,
                                        wp<DeathRecipient>* outRecipient = NULL);

    virtual void        attachObject(   const void* objectID,
                                        void* object,
                                        void* cleanupCookie,
                                        object_cleanup_func func);
    virtual void*       findObject(const void* objectID) const;
    virtual void        detachObject(const void* objectID);

    virtual BpBinder*   remoteBinder();

            status_t    setConstantData(const void* data, size_t size);
            void        sendObituary();

    // 管理Java层的BpBinder对象
    class ObjectManager
    {
    public:
                    ObjectManager();
                    ~ObjectManager();

        void        attach( const void* objectID,
                            void* object,
                            void* cleanupCookie,
                            IBinder::object_cleanup_func func);
        void*       find(const void* objectID) const;
        void        detach(const void* objectID);

        void        kill();

    private:
                    ObjectManager(const ObjectManager&);
        ObjectManager& operator=(const ObjectManager&);

        struct entry_t
        {
            void* object;
            void* cleanupCookie;
            IBinder::object_cleanup_func func;
        };

        KeyedVector<const void*, entry_t> mObjects;
    };

protected:
    virtual             ~BpBinder();
    virtual void        onFirstRef();
    virtual void        onLastStrongRef(const void* id);
    virtual bool        onIncStrongAttempted(uint32_t flags, const void* id);

private:
    // 代理端的Binder以句柄形式存在
    const   int32_t             mHandle;

    // 关于死亡通知的结构
    struct Obituary {
        wp<DeathRecipient> recipient;
        void* cookie;
        uint32_t flags;
    };

            void                reportOneDeath(const Obituary& obit);
            bool                isDescriptorCached() const;

    mutable Mutex               mLock;
            volatile int32_t    mAlive;
            volatile int32_t    mObitsSent;
            // 保存死亡通知对象的容器
            Vector<Obituary>*   mObituaries;
            // 管理BpBinder对象的列表
            ObjectManager       mObjects;
            Parcel*             mConstantData;
    mutable String16            mDescriptorCache;
};

BpBinder.cpp

BpBinder::BpBinder

BpBinder::BpBinder(int32_t handle)
    : mHandle(handle)
    , mAlive(1)
    , mObitsSent(0)
    , mObituaries(NULL)
{
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    // 通知Binder驱动增加该引用计数
    IPCThreadState::self()->incWeakHandle(handle);
}

BpBinder::transact

status_t BpBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // 如果服务端挂掉,mAlive被置为0,代理端将再也不能连接到服务端
    // 这时需要向Biner驱动注册死亡通知的应答
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

IServiceManager.cpp

BpServerManager::addService

virtual status_t addService(const String16& name, const sp<IBinder>& service)
{
    Parcel data, reply;
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name);
    data.writeStrongBinder(service);
    status_t err = remote()->transact(ADD_SERVICE_TRANSACTION, data, &reply);
    return err == NO_ERROR ? reply.readInt32() : err;
}

BpServerManager::getService

virtual sp<IBinder> getService(const String16& name) const
{
    unsigned n;
    for (n = 0; n < 5; n++){
        sp<IBinder> svc = checkService(name);
        if (svc != NULL) return svc;
        sleep(1);
    }
    return NULL;
}

BpServerManager::checkService

virtual sp<IBinder> checkService( const String16& name) const
{
    Parcel data, reply;
    data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
    data.writeString16(name);
    remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
    return reply.readStrongBinder();
}