Binder系列2 Binder概念及相关接口和类

Binder系列1 Binder总体设计思想中,主要从宏观上讲了 Binder 的总体设计思想和一些关键部分的设计细节,比如接收缓存管理,接收线程优化和线程池管理,接收包管理等.在系列2中会进一步细化 Binder 的概念和介绍实现 Binder 通信架构所用到的相关接口和类.

一 什么是Binder

简单地说,Binder 是 Android 平台上的一种跨进程通信技术。该技术最早并不是由 Google 公司提出的,它的前身是 Be Inc 公司开发的 OpenBinder,而且在 Palm 中也有应用。后来 OpenBinder 的作者 Dianne Hackborn 加入了 Google公司,并负责Android平台的开发工作,所以把这项技术也带进了 Android.

在 Android 的应用层次上,基本上已经没有过去的进程概念了。取而代之的都是 Activity,Service,BroadcastReceiver,和 ContentProvider 等各个组件.然而在实现层次,它毕竟还是要建构在一个个进程之上的。实际上,在 Android 内部,那些支撑应用程序的各个组件,往往会身处于不同的进程,那么应用程序的底层,必然会牵涉到大量的跨进程通信。为了保证通信的高效性,Android 提供了 Binder 机制.

 Binder 机制具有两层含义: 
1) 是一种跨进程通信手段(IPC,Inter-Process Communication)。 
2) 是一种远程过程调用手段(RPC,Remote Procedure Call)。

从实现的角度来说,Binder 的核心被实现成了一个 Linux 驱动程序,并运行于内核态。这样它才能具有强大的跨进程访问能力。

1.1 简述Binder的跨进程通信机制

为了理解 Binder,我们可以先画一张最简单的跨进程通信示意图:

初始篇001

这个很容易理解,不需赘言。到了 Android 平台上,IPC 机制就变成了 Binder 机制,情况类似,只不过为了便于说明问题,我们需要稍微调整一下示意图:

初始篇002

图中A侧的圆形块,表示“Binder代理方”也叫 Binder 引用,主要用于向远方发送语义,而B侧的方形块则表示“Binder响应方”也叫 Binder 实体,主要用于响应语义。需要说明的是,这种图形表示方法只是为了便于理解,个人觉得这种图形非常简便,所以在分析 Android 架构时,会经常使用这种表示法。

在后文中,我们可以看到,Binder 代理方对应于 C++ 层次的 BpBinder 对象,而 Binder 响应方则对应于 BBinder 对象。这两个对象在后文会详细阐述,此处不必太细究。

然而,上图的 Binder 代理方主要只负责了“传递信息”的数据传输工作,并没有起到“远程过程调用”的作用,如果要支持远程过程调用,我们还必须提供“接口代理方”和“接口实现体”。这样,我们的示意图就需要再调整一下,如下:

初始篇003

 

从图中可以看到,A进程并不直接和 BpBinder(Binder代理)打交道,而是通过调用 BpInterface(接口代理)的成员函数来完成远程调用的。此时,BpBinder 已经被聚合进 BpInterface 了,它在 BpInterface 内部完成了一切跨进程通信的机制。另一方面,与 BpInterface 相对的响应端实体就是 BnInterface(接口实现)了。需要注意的是,BnInterface 是继承于 BBinder 的,它并没有采用聚合的方式来包含一个 BBinder 对象,所以上图中B侧的 BnInterface 块和 BBinder 块的背景图案是相同的,BpBinder 是聚合进 BpInterface,而 BnInterface 是继承自 BBinder,了解和理解这一点非常重要。

        这样看来,对于远程调用的客户端而言,主要搞的就是两个东西,一个是 Binder 代理:BpBinder,另外一个就是“接口代理”:BpInterface。而服务端主要搞的则是“接口实现体”:BnInterface。因为 Binder 是一种跨进程通信机制,为了便于管理Binder服务,和便于 Client 获取 Binder 引用,Binder 机制就搞了一个专门的管理器来为通信两端牵线搭桥,这个管理器就是 SMgr。不过目前我们可以先放下 ServiceManager,在Binder系列3 ServiceManager启动和实现中会详细研究。

二 Binder相关接口和类

由于 Android 系统是分层次的系统,所以跨进程通信的 Binder,不但会在底层使用,也会在上层使用,所以需要提供 Java 和C++ 两个层次的支持。

2.1 Java层次的Binder元素

Java 层次里并没有我们前文图中所表示的 BpBinder、BpInterface、BBinder、BnInterface 等较低层次的概念,取而代之的是IBinder 接口、IInterface 等接口。Android 要求所有的 Binder 实体都必须实现 IBinder 接口,该接口的定义截选如下: 

frameworks/base/core/java/android/os/IBinder.java

public interface IBinder 
{
    . . . . . .
    public String getInterfaceDescriptor() throws RemoteException;
    public boolean pingBinder();
    public boolean isBinderAlive();
    public IInterface queryLocalInterface(String descriptor);
    public void dump(FileDescriptor fd, String[] args) throws RemoteException;
    public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException;
    public void shellCommand(@Nullable FileDescriptor in, @Nullable FileDescriptor out,
            @Nullable FileDescriptor err,
            @NonNull String[] args, @Nullable ShellCallback shellCallback,
            @NonNull ResultReceiver resultReceiver) throws RemoteException;

    public boolean transact(int code, @NonNull Parcel data, @Nullable Parcel reply, int flags)
    throws RemoteException;
    
    public interface DeathRecipient {
        public void binderDied();
    }
    public void linkToDeath(DeathRecipient recipient, int flags)throws RemoteException;
    public boolean unlinkToDeath(DeathRecipient recipient, int flags);
}

另外,不管是代理方还是实体方,都必须实现 IInterface 接口:

public interface IInterface
{
    /**
     * Retrieve the Binder object associated with this interface.
     * You must use this instead of a plain cast, so that proxy objects
     * can return the correct result.
     */
    public IBinder asBinder();
}

Java 层次中,与 Binder 相关的接口或类的继承关系如下:

初始篇004

 

在实际使用中,我们并不需要编写上图的 XXXXNative、XXXXProxy,它们会由 ADT 根据我们编写的 AIDL 脚本自动生成。用户只需继承 XXXXNative 编写一个具体的 XXXXService 即可,这个 XXXXService 就是远程通信的服务实体类,而 XXXXProxy 则是其对应的代理类。

        关于 Java 层次的 Binder 组件,我们就先说这么多,主要是先介绍一个大概。就研究跨进程通信而言,其实质内容基本上都是在 C++ 层次,Java 层次只是一个壳而已。以后我会写专文来打通 Java 层次和 C++ 层次,看看它们是如何通过 JNI 技术关联起来的。现在我们还是把注意力集中在 C++ 层次吧。

2.2 C++层次的Binder元素

在 C++ 层次,就能看到我们前文所说的 BpBinder 类和 BBinder 类了。这两个类都继承于 IBinder,IBinder 的定义截选如下:

frameworks/native/include/binder/IBinder.h

class IBinder : public virtual RefBase
{
public:
    .........

    IBinder();
  
    virtual sp<IInterface>  queryLocalInterface(const String16& descriptor);
    virtual const String16& getInterfaceDescriptor() const = 0;

    virtual bool            isBinderAlive() const = 0;
    virtual status_t        pingBinder() = 0;
    virtual status_t        dump(int fd, const Vector<String16>& args) = 0;
    static  status_t        shellCommand(const sp<IBinder>& target, int in, int out, int err,
                                         Vector<String16>& args, const sp<IShellCallback>& callback,
                                         const sp<IResultReceiver>& resultReceiver);

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

   
    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;

    virtual BBinder*        localBinder();
    virtual BpBinder*       remoteBinder();

protected:
    virtual          ~IBinder();

private:
};

需要重点关注 transact 函数,这个函数在继承于 IBinder 的 BpBinder 和 BBinder 中都有使用,用来传输数据;还要关注localBinder 函数和 remoteBinder 函数,这2个函数的返回值分别为 BBinder 和 BbBinder,分别表示 Server 端的 Binder 实体和Client 端的 Binder 代理.

C++ 层次的继承关系图如下:

初始篇005

以上各个接口和类的继承关系一定要深刻理解并牢记,这些继承关系是 Binder 跨进程通信的具体实现方式.其中有以下几个很关键的类:

  • BpBinder
  • BpInterface
  • BBinder
  • BnInterface

它们扮演着很重要的角色。

2.2.1 BpBinder

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();

   .............

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

    private:
        const   int32_t             mHandle;



    ............
};

作为代理端的核心,BpBinder 最重要的职责,就是实现跨进程传输的传输机制,至于具体传输的是什么语义,它并不关心。我们观察它的 transact() 函数的参数,可以看到所有的语义都被打包成 Parcel 了。还需要关注 mHandle 这个成员变量,这个就是代理端 Binder 引用的句柄.其他的成员函数,我们先不深究,待我们储备了足够的基础知识后,再回过头研究它们不迟。 

2.2.2 BpInterface

另一个重要的类是BpInterface,它的定义如下:

template<typename INTERFACE>
    class BpInterface : public INTERFACE, public BpRefBase
{
public:
    explicit                    BpInterface(const sp<IBinder>& remote);

protected:
    virtual IBinder*            onAsBinder();
};

其基类 BpRefBase 的定义如下:

class BpRefBase : public virtual RefBase
{
protected:
    explicit                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;
    std::atomic<int32_t>    mState;
};

BpInterface 使用了模板技术,并且它继承了 BpRefBase,而 BpRefBase 中存在一个 IBinder 类型的变量 mRemote,所以BpInterface 先天上就聚合了一个 mRemote 成员,这个成员记录的就是前面所说的 BpBinder 对象。这个就是为什么我们前面说的 BpBinder 是聚合在 BpInterface 中的原因.以后我们还需要继承 BpInterface<Ixxxx> 实现我们自己的代理类。

在实际的代码中,我们完全可以创建多个聚合同一 BpBinder 对象的代理对象,这些代理对象就本质而言,对应着同一个远端Binder 实体。在 Android 框架中,常常把指向同一 Binder 实体的多个代理称为 token,这样即便这些代理分别处于不同的进程中,它们也具有了某种内在联系。这个知识点需要大家关注。

2.2.3 BBinder

Binder 远程通信的 Server 端的 Binder 实体,必须继承于 BBinder 类,该类和 BpBinder 相对,主要关心的只是传输方面的东西,不关心所传输的语义。

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

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

   .........
};

上面有二个函数需要重点关注:transact 函数和 onTransact 函数,我们先看上面的 transact() 成员函数,transact 函数的代码如下:

frameworks/native/libs/binder/Binder.cpp

status_t BBinder::transact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    data.setDataPosition(0);

    status_t err = NO_ERROR;
    switch (code) {
        case PING_TRANSACTION:
            reply->writeInt32(pingBinder());
            break;
        default:
            err = onTransact(code, data, reply, flags);
            break;
    }

    if (reply != NULL) {
        reply->setDataPosition(0);
    }

    return err;
}

看到了吗,transact() 内部会调用 onTransact(),这样当 Server 端的 Binder 实体继承了 BBinder,并且实现其中的 onTransact 函数后,就会自动调用到这个 Binder 实体实现的 onTransact() 里。这个 onTransact() 的一大作用就是接收跨进程传输过来的数据包,并解析数据包中的语义。

2.2.4 BnInterface

远程通信目标端的另一个重要类是 BnInterface<>,它是与 BpInterface<> 相对应的模板类,比较关心传输的语义。一般情况下,服务端并不直接使用 BnInterface<>,而是使用它的某个子类。为此,我们需要编写一个新的 BnXXX子类,继承 BnInterface<>,因为 BnInterface<> 又继承于 BBinder,所以这个 BnXXX 子类继承了 onTransact 函数,并重载实现了 onTransact() 成员函数,用来具体的解析通过 Binder 机制传输过来的数据包。

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<> 继承于 BBinder,但它并没有实现一个默认的 onTransact() 成员函数,所以在远程通信时,前文所说的BBinder::transact() 调用的 onTransact() 就是调用的 BnInterface<> 的某个子类 BnXXX 的 onTransact() 成员函数。

2.3 几个重要的C++宏或模板

为了便于编写新的接口和类,Android 在 C++ 层次提供了几个重要的宏和模板,比如我们在 IInterface.h 文件中,可以看到DECLARE_META_INTERFACE、IMPLEMENT_META_INTERFACE 的定义。

2.3.1 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();      

我们举个实际的例子,来说明如何使用这个宏:

framework/av/media/libmedia/include/media/IMediaPlayerService.h

class IMediaPlayerService: public IInterface
{
public:
    DECLARE_META_INTERFACE(MediaPlayerService);

   
.............
    virtual void addBatteryData(uint32_t params) = 0;
    virtual status_t pullBatteryData(Parcel* reply) = 0;
};

上例中 IMediaPlayerService 内部使用了 DECLARE_META_INTERFACE(MediaPlayerService),我们把宏展开后,可以看到IMediaPlayerService 类的定义相当于:

class IMediaPlayerService: public IInterface
{
public:

    static const ::android::String16 descriptor;                        
    static ::android::sp<IMediaPlayerService> asInterface(                     
            const ::android::sp<::android::IBinder>& obj);              
    virtual const ::android::String16& getInterfaceDescriptor() const;  
    IMediaPlayerService();                                                     
    virtual ~IMediaPlayerService(); 

   
.............
    virtual void addBatteryData(uint32_t params) = 0;
    virtual status_t pullBatteryData(Parcel* reply) = 0;
};

宏展开的部分就是中间那6行代码,其中最关键的就是 asInterface() 函数了,这个函数将承担把继承于 IBinder 的 BpBinder 打包成 BpInterface 的职责。

2.3.2 IMPLEMENT_META_INTERFACE()

与 DECLARE_META_INTERFACE 相对的就是 IMPLEMENT_META_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() { }   

其中,实现了关键的 asInterface() 函数。

实际使用 IMPLEMENT_META_INTERFACE 时,我们只需把它简单地写在 Binder 实体所处的 cpp 文件中即可,举例如下:

framework/av/media/libmedia/IMediaPlayerService.cpp

IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");

// ----------------------------------------------------------------------

status_t BnMediaPlayerService::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch (code) {
        case CREATE: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            sp<IMediaPlayerClient> client =
                interface_cast<IMediaPlayerClient>(data.readStrongBinder());
            audio_session_t audioSessionId = (audio_session_t) data.readInt32();
            sp<IMediaPlayer> player = create(client, audioSessionId);
            reply->writeStrongBinder(IInterface::asBinder(player));
            return NO_ERROR;
        } break;
        case CREATE_MEDIA_RECORDER: {
            CHECK_INTERFACE(IMediaPlayerService, data, reply);
            const String16 opPackageName = data.readString16();
            sp<IMediaRecorder> recorder = createMediaRecorder(opPackageName);
            reply->writeStrongBinder(IInterface::asBinder(recorder));
            return NO_ERROR;
        } break;
       ............................
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}

其中的 IMPLEMENT_META_INTERFACE(MediaPlayerService, "android.media.IMediaPlayerService");根据模板展开为:


    const ::android::String16 IMediaPlayerService::descriptor("android.media.IMediaPlayerService");           
    const ::android::String16&
IMediaPlayerService::getInterfaceDescriptor() const{             
        return IMediaPlayerService::descriptor;                                
    }                                                                   
    ::android::sp<IMediaPlayerService> IMediaPlayerService::asInterface(              
         const ::android::sp<::android::IBinder>& obj)               
    {                                                                   
        ::android::sp<IMediaPlayerService> intr;                              
        if (obj != NULL) {                                              
            intr = static_cast<IMediaPlayerService*>(                          
                obj->queryLocalInterface(                               
                        IMediaPlayerService::descriptor).get());               
            if (intr == NULL) {                                         
                intr = new BpMediaPlayerService(obj);                          
            }                                                           
        }                                                               
        return intr;                                                    
    }                                                                   
    IMediaPlayerService::IMediaPlayerService() { }     
    IMediaPlayerService::~IMediaPlayerService() { } 

其中重点实现了 asInterface() 成员函数。请注意,asInterface() 函数中会先尝试调用 IBinder 的 queryLocalInterface() 函数来获取 intr。此时,如果 asInterface() 的 obj 参数是个代理对象(BpBinder),那么 intr = static_cast<MediaPlayerService*>(obj->queryLocalInterface(...) 一句得到的 intr 基本上就是 NULL 了。这是因为除非用户编写的代理类重载 queryLocalInterface() 函数,否则只会以默认函数为准。而 IBinder 类中的默认 queryLocalInterface() 函数如下:

frameworks/native/libs/binder/Binder.cpp

sp<IInterface>  IBinder::queryLocalInterface(const String16& /*descriptor*/)
{
    return NULL;
}

另一方面,如果 obj 参数是个实现体对象(BnInterface对象)的话,那么 queryLocalInterface() 函数的默认返回值就是实体对象的 this 指针了,代码如下:

frameworks/native/include/binder/IInterface.h

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

在我们所举的 MediaPlayerService 例子中,我们要研究的是如何将 BpBinder 转成 BpInterface,所以现在我们只阐述 obj 参数为BpBinder 的情况。此时 asInterface() 函数中 obj->queryLocalInterface() 的返回值为 NULL,于是 asInterface() 会走到 new BpMediaPlayerService(obj) 一句,这一句最关键。我们知道,BpMediaPlayerService 继承于BpInterface<IMediaPlayerService>,所以此时所创建的 BpMediaPlayerService 对象,正是可被 Client 端使用的 BpInterface 代理对象。

BpMediaPlayerService 的定义如下:

class BpMediaPlayerService: public BpInterface<IMediaPlayerService>
{
public:
    explicit BpMediaPlayerService(const sp<IBinder>& impl)
        : BpInterface<IMediaPlayerService>(impl)
    {
    }

    virtual sp<IMediaMetadataRetriever> createMetadataRetriever()
    {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
        remote()->transact(CREATE_METADATA_RETRIEVER, data, &reply);
        return interface_cast<IMediaMetadataRetriever>(reply.readStrongBinder());
    }

    virtual sp<IMediaPlayer> create(
            const sp<IMediaPlayerClient>& client, audio_session_t audioSessionId) {
        Parcel data, reply;
        data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
        data.writeStrongBinder(IInterface::asBinder(client));
        data.writeInt32(audioSessionId);

        remote()->transact(CREATE, data, &reply);
        return interface_cast<IMediaPlayer>(reply.readStrongBinder());
    }

  .....................
};

同学们有没有发现,在 BpMediaPlayerService 中,每个函数最后都会调用 remote()->transact() 函数,其中的 remote() 函数就是在 BpRefBase 中定义的,返回的是其中的变量 mRemote,这个变量前面在讨论 BpRefBase 中已经说明了,它就是 BpBinder,由此可以看到代理端的 BpXXX 中所调用的函数,最后都会通过调用聚合在其中的 BpBinder 的 transact() 函数来完成跨进程传输,这个一定要记住和理解.

至此,IMPLEMENT_META_INTERFACE 宏和 asInterface() 函数的关系就分析完毕了。

2.3.3 interface_cast

不过,我们经常使用的其实并不是 asInterface() 函数,而是 interface_cast(),它简单包装了 asInterface():

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

以上就是关于 C++ 层次中一些 Binder 元素的介绍,下面我们再进一步分析其他细节。

三 ProcessState

前文我们已经提到过,在 Android 的上层架构中,已经大幅度地弱化了进程的概念。应用程序员能看到的主要是 activity、service、content provider 等概念,再也找不到以前熟悉的 main() 函数了。然而,底层程序(C++层次)毕竟还是得跑在一个个进程之上,现在我们就来看底层进程是如何运用 Binder 机制来完成跨进程通信的。

在每个进程中,会有一个全局的 ProcessState 对象。这个很容易理解,ProcessState 的字面意思不就是“进程状态”吗,当然应该是每个进程对应一个 ProcessState。ProcessState 的定义位于 frameworks/native/include/binder/ProcessState.h 中,如下:

class ProcessState : public virtual RefBase
{
public:
    static  sp<ProcessState>    self();
    static  sp<ProcessState>    selfOrNull();
    /* initWithDriver() can be used to configure libbinder to use
     * a different binder driver dev node. It must be called *before*
     * any call to ProcessState::self(). /dev/binder remains the default.
     */
    static  sp<ProcessState>    initWithDriver(const char *driver);

            void                setContextObject(const sp<IBinder>& object);
            sp<IBinder>         getContextObject(const sp<IBinder>& caller);
        
            void                setContextObject(const sp<IBinder>& object,
                                                 const String16& name);
            sp<IBinder>         getContextObject(const String16& name,
                                                 const sp<IBinder>& caller);

            void                startThreadPool();
                        
    typedef bool (*context_check_func)(const String16& name,
                                       const sp<IBinder>& caller,
                                       void* userData);
        
            bool                isContextManager(void) const;
            bool                becomeContextManager(
                                    context_check_func checkFunc,
                                    void* userData);

            sp<IBinder>         getStrongProxyForHandle(int32_t handle);
            wp<IBinder>         getWeakProxyForHandle(int32_t handle);
            void                expungeHandle(int32_t handle, IBinder* binder);

            void                spawnPooledThread(bool isMain);
            
            status_t            setThreadPoolMaxThreadCount(size_t maxThreads);
            void                giveThreadPoolName();

            String8             getDriverName();

            ssize_t             getKernelReferences(size_t count, uintptr_t* buf);

private:
    friend class IPCThreadState;
    
                                ProcessState(const char* driver);
                                ~ProcessState();

                                ProcessState(const ProcessState& o);
            ProcessState&       operator=(const ProcessState& o);
            String8             makeBinderThreadName();

            struct handle_entry {
                IBinder* binder;
                RefBase::weakref_type* refs;
            };

            handle_entry*       lookupHandleLocked(int32_t handle);

            String8             mDriverName;
            int                 mDriverFD;
            void*               mVMStart;

            // Protects thread count variable below.
            pthread_mutex_t     mThreadCountLock;
            pthread_cond_t      mThreadCountDecrement;
            // Number of binder threads current executing a command.
            size_t              mExecutingThreadsCount;
            // Maximum number for binder threads allowed for this process.
            size_t              mMaxThreads;
            // Time when thread pool was emptied
            int64_t             mStarvationStartTimeMs;

    mutable Mutex               mLock;  // protects everything below.

            Vector<handle_entry>mHandleToObject;

            bool                mManagesContexts;
            context_check_func  mBinderContextCheckFunc;
            void*               mBinderContextUserData;

            KeyedVector<String16, sp<IBinder> >
                                mContexts;


            String8             mRootDir;
            bool                mThreadPoolStarted;
    volatile int32_t            mThreadPoolSeq;
};

我们知道,Binder 内核被设计成一个驱动程序,所以 ProcessState 里专门搞了个 mDriverFD 域,来记录 Binder 驱动对应的文件句柄值,以便随时和 Binder 驱动通信。ProcessState 对象采用了典型的单例模式,在一个应用进程中,只会有唯一的一个ProcessState 对象,它将被进程中的多个线程共用,因此每个进程里的线程其实是共用所打开的那个驱动句柄(mDriverFD)的,示意图如下:

初始篇008

 每个进程基本上都是这样的结构,组合起来的示意图就是

初始篇009

 我们常见的使用 ProcessState 的代码如下:

int main(int argc __unused, char **argv __unused)
{
    signal(SIGPIPE, SIG_IGN);

    sp<ProcessState> proc(ProcessState::self());
    ...........
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
}

因为 ProcessState 采用的是单例模式,所以它的构造函数是 private 的,我们只能通过调用 ProcessState::self() 来获取进程中唯一的一个 ProcessState 对象。self() 函数的代码如下:

frameworks/native/libs/binder/ProcessState.cpp

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

ProcessState 对象构造之时,就会打开 Binder 驱动:

ProcessState::ProcessState(const char *driver)
    : mDriverName(String8(driver))
    , mDriverFD(open_driver(driver))
    , mVMStart(MAP_FAILED)
    , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
    , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
    , mExecutingThreadsCount(0)
    , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
    , mStarvationStartTimeMs(0)
    , 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;
            mDriverName.clear();
        }
    }

    LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened.  Terminating.");
}

注意上面那句 mDriverFD(open_driver(driver)),其中的 open_driver() 就负责打开“/dev/binder”驱动:

static int open_driver(const char *driver)
{
    int fd = open(driver, O_RDWR | O_CLOEXEC);
    if (fd >= 0) {
        int vers = 0;
        status_t result = ioctl(fd, BINDER_VERSION, &vers);
        if (result == -1) {
            ALOGE("Binder ioctl to obtain version failed: %s", strerror(errno));
            close(fd);
            fd = -1;
        }
        if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
          ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! ioctl() return value: %d",
                vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
            close(fd);
            fd = -1;
        }
        size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
        result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
        if (result == -1) {
            ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
        }
    } else {
        ALOGW("Opening '%s' failed: %s\n", driver, strerror(errno));
    }
    return fd;
}

从以上代码可以看到,open_driver 函数打开了“/dev/binder”驱动,获得了文件描述符fd,然后返回这个fd,并赋值给了mDriverFD

ProcessState 中还有一个域很重要,是 mHandleToObject:Vector<handle_entry>mHandleToObject,这个里边存储的是BpBinder,这个 mHandleToObject 向量表,记录了本进程中所有的 BpBinder,这个非常重要.我们前文已经说过,BpBinder 是代理端的核心,现在终于看到它的藏身之处了。在 Binder 架构中,Client 进程是通过“Binder句柄”来找到对应的 BpBinder 的。从这张向量表中我们可以看到,那个句柄值其实对应着这个向量表的下标。这张表的子项类型为 handle_entry,定义如下:

struct handle_entry {
                IBinder* binder;
                RefBase::weakref_type* refs;
            };

其中的 binder 域,记录的就是 BpBinder 对象。

初始篇010

四 总结

本篇文章主要介绍了 Binder 的概念和 Binder 架构的具体实现方式,包括涉及到的相关接口和类,比如 BpBinder,BpInterface,BBinder,BnInterface 以及之间的相互继承关系,还介绍了便于生成 BpInterface<IXXX> 而设计的相关模板类,并举了具体的例子来便于理解,最后介绍了进程相关的 ProcessState.大家要多思考,多提出疑问,然后结合代码验证自己的结论,如果有意见和建议请评论留言,谢谢

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值