• NOTE
  • Binder 进程间通讯库
    • IInterfaceh
    • Binderh
      • 1 class BBinder
      • 2 class BpRefBase
    • BpBinderh
    • IPCThreadStateh
    • ProcessStateh
    • Service 组件实现原理类图
    • Client 组件实现原理类图


NOTE

  • 源码版本:Android 7.1.2。
  • 内核版本:android-goldfish-3.4
  • 内核下载:git clone https://aosp.tuna.tsinghua.edu.cn/kernel/goldfish.git (清华镜像站)
  • 以下分析思路均来自老罗的《Android 系统源代码情景分析(修订版)》

Binder 进程间通讯库

  • Android 在框架层中将各种 Binder 驱动程序封装成了一个通讯库。
  • 在库中 BinderService 组件与 Client 组件分别采用模板类 BnInterfaceBpInterface 来描述。
  • BnInterface
    • Binder 本地对象。
    • 对应 Binder 驱动中的 Binder 实体对象。
  • BpInterface
    • Binder 代理对象。
    • 对应 Binder 驱动中的 Binder 引用对象。

1. IInterface.h

  • 位置:frameworks/native/include/binder/IInterface.h
  • class BnInterface
template<typename INTERFACE>class BnInterface : public INTERFACE, public BBinder{public:    virtual sp      queryLocalInterface(const String16& _descriptor);    virtual const String16&     getInterfaceDescriptor() const;protected:    virtual IBinder*            onAsBinder();};
  • class BpInterface
template<typename INTERFACE>class BpInterface : public INTERFACE, public BpRefBase{public:                                BpInterface(const sp& remote);protected:    virtual IBinder*            onAsBinder();};
  • NOTE
    1. 模板参数 INTERFACE 是由进程自定义的 Service 组件接口,而 BnInterfaceBpInterface 都要实现这个接口。
    2. 除了 Service 组件接口外,还需要实现相应的一个 Bn 类和一个 Bp 类,它们分别继承于 BnInterfaceBpInterface

2. Binder.h

  • 位置:frameworks/native/include/binder/Binder.h

2.1 class BBinder

  • BnInterface 类继承了 BBinder 类。
  • BBinder 为本地对象提供了抽象的进程间通信接口。
  • 该类有两个重要的成员函数 transactonTransact
    1. 当一个 Binder 代理对象通过驱动向一个本地对象发出通信请求时,驱动则会调用该本地对象的成员函数 transact 来处理请求。
    2. onTransact 是由 Binder 本地对象类实现的,它负责分发与业务相关的进程间通信请求。
    3. 与业务相关的进程间通信请求是由本地对象类的子类,即 Service 组件类来负责处理的。
    4. BBinder 类继承了 IBinder 类,而后者继承了 RefBase 类。
    5. 由于继承了 RefBase,则可知 Binder 本地对象是通过引用计数技术来维护其生命周期的。
    6. Binder 本地对象收到驱动中的实体对象以及运行在 Client 进程中的 Binder 代理对象引用,所以它的引用计数技术更加复杂,这一部分以后再慢慢了解。
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& args);    virtual status_t    transact(   uint32_t code,                                    const Parcel& data,                                    Parcel* reply,                                    uint32_t flags = 0);    virtual status_t    linkToDeath(const sp& recipient,                                    void* cookie = NULL,                                    uint32_t flags = 0);    virtual status_t    unlinkToDeath(  const wp& recipient,                                        void* cookie = NULL,                                        uint32_t flags = 0,                                        wp* 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;    std::atomic mExtras;            void*       mReserved0;};

2.2 class BpRefBase

  • BpInterface 类继承了 BpRefBase 类。
  • 类似本地对象,代理对象也采用引用计数技术维护生命周期。
  • BpRefBase 类中有一个比较重要的成员 mRemote,它指向一个 BpBinder 对象,而 BpBinder 类则实现了 BpRefBase 类的进程间通信接口。
class BpRefBase : public virtual RefBase{protected:                            BpRefBase(const sp& 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    mState;};

3. BpBinder.h

  • 位置:frameworks/native/include/binder/BpBinder.h
  • 成员变量 mHandle 是一个整数,表示一个 Client 组件的句柄值,其值可以通过成员函数 handle() 获取。
  • 成员函数 transact()
    1. 向运行在 Server 进程中的 Service 组件发送通信请求,通过 Binder 驱动间接实现。
    2. BpBinder 类的成员 mHandle 以及进程间通信数据发送给驱动。
    3. 驱动根据句柄找到对应 Binder 引用对象,从而找到最终的实体对象,这样才能将数据发送给对应的 Service 组件。
class BpBinder : public IBinder{public:                        BpBinder(int32_t handle);    inline  int32_t     handle() const { return mHandle; }    ......    virtual status_t    transact(   uint32_t code,                                    const Parcel& data,                                    Parcel* reply,                                    uint32_t flags = 0);    ......private:    const   int32_t             mHandle;    ......};

4. IPCThreadState.h

  • 位置:frameworks/native/include/binder/IPCThreadState.h
  • 对于每个 Binder 线程,其内部都有一个 IPCThreadState 对象。
  • 通过 IPCTreadState 类的 self() 函数可以获取相应的对象,并且通过调用它的成员函数 transact() 就可以与驱动进行交互。
  • 在函数 transact() 内部,它通过成员函数 talkWithDriver() 实现与驱动的交互:
    • 一方面它负责向驱动发送进程间通信请求。
    • 另一方面它也负责接收来自驱动的通信请求。
  • 成员变量 mProcess 指向一个 ProcessState 对象,它是线程与驱动建立连接的关键。
class IPCThreadState{public:    static  IPCThreadState*     self();    ......            status_t            transact(int32_t handle,                                         uint32_t code, const Parcel& data,                                         Parcel* reply, uint32_t flags);    ......private:    ......            status_t            talkWithDriver(bool doReceive=true);    ......    const   sp    mProcess;    ......};

5. ProcessState.h

  • 位置:frameworks/native/include/binder/ProcessState.h
  • 对于每个使用了 Binder 机制的进程来说,它的内部都有一个 ProcessState 对象:
    • 负责初始化 Binder 设备,即打开 /dev/binder
    • 将设备文件映射到进程的地址空间,即请求驱动为进程分配内核缓冲区。
  • ProcessState 对象在进程范围内是唯一的,因此 Binder 线程池中线程都可以通过它与 Binder 驱动程序建立连接。
  • 可以通过 self() 函数获取相应的 ProcessState 对象:
    • 若非第一次调用,则直接返回 ProcessState 对象。
    • 若为第一次调用,Binder 库会为进程创建一个 ProcessState 对象,并且调用 open() 函数打开设备文件,接着调用 mmap() 将设备文件映射到进程地址空间。
  • 映射地址空间后,得到的内核缓冲区用户地址保存在成员变量 mVMStart 中。
class ProcessState : public virtual RefBase{public:    static  sp    self();    ......private:    ......            int                 mDriverFD;            void*               mVMStart;    ......};

6. Service 组件实现原理类图

7. Client 组件实现原理类图

!

更多相关文章

  1. android 核心组件( 1 ) 常用布局, adapter, handler, UI
  2. Android开发实践教程
  3. android 怎样为多媒体文件生成缩略图
  4. android root权限相关bin程序rageagainsttheca
  5. Android(安卓)SystemService类注释
  6. Android源码解析
  7. Android实现使用流媒体播放远程mp3文件的方法
  8. Android(安卓)BitTube 学习
  9. Android(安卓)BroadCast

随机推荐

  1. 如何在 Mac 上更改“聚焦”偏好设置?
  2. linux if 判断
  3. 如何使用iMovie模板创建新预告片?
  4. 记一次奇怪的速度测试现象
  5. ***武器库---Metasploit***测试框架实战
  6. CSS:box-sizing理解与相对定位与绝对定位
  7. 金币问题
  8. CAD 入门 平面图
  9. elasticsearch历史数据清理
  10. gitlab迁移及迁移后500问题