2016年1月6日 星期三

[轉] Binder 機制詳解—Binder 本地框架

http://www.cloudchou.com/android/post-547.html


Binder本地框架

本地Binder框架包含以下類(frameworks/native/libs/binder):
RefBase, IInterface,BnInterface,BpInterface,BpRefBase,Parcel 等等
下圖描述了實例《Binder service入門–創建native binder service》使用的ITestService與本地Binder框架類庫的關係:(若看不清,請點擊看大圖)
native_binde_framework
  • 1) RefBase類(frameworks/native/include/utils/RefBase.h)

    引用的基類,android本地代碼裡採用了智能指針,有強指針,也有弱指針。不過不用糾結於這些細節。
  • 2) IInterface(frameworks/native/include/binder/IInterface.h)

    自定義的binder service接口必須繼承自IInterface(如ITestService),它的onAsBinder方法為抽象方法,該方法的實現在BpInterface和BnInterface模版類裡。
  • 3) BpRefBase(frameworks/native/include/binder/Binder.h)

    客戶端間接用到該類,用於保存IBinder指針,remote()方法即返回IBinder指針。
  • 4) ITestService

    聲明的binder service接口,在該接口裡會聲明所有提供的服務方法(使用純虛函數),並用宏DECLARE_META_INTERFACE進行聲明,這樣會添加靜態字段descriptor,靜態方法asInterface,虛方法getInterfaceDescriptor,以及構造函數和析構函數。另外只需要使用IMPLEMENT_META_INTERFACE(INTERFACE, NAME)來即可定義用宏DECLARE_META_INTERFACE聲明的這些方法和字段。
    DECLARE_META_INTERFACE宏的源碼如下所示:
    1
    2
    3
    4
    5
    6
    7
    
    #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();
    若使用DECLARE_META_INTERFACE(TestService); 則會擴展為:
    1
    2
    3
    4
    5
    6
    
    static const android::String16 descriptor;                       \
    static android::sp<ITestService> asInterface(                    \
                const android::sp<android::IBinder>& obj);           \
    virtual const android::String16& getInterfaceDescriptor() const; \
    ITestService();                                                  \
    virtual ~ITestService();
    宏函數IMPLEMENT_META_INTERFACE(INTERFACE, NAME)的源碼如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    #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() { }                          \
    若使用IMPLEMENT_META_INTERFACE(TestService, 「android.TestServer.ITestService」)則會被替換成:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    const android::String16 
        ITestService::descriptor("android.TestServer.ITestService"); \
        const android::String16&                                     \
                ITestService::getInterfaceDescriptor() const {       \
            return ITestService::descriptor;                         \
        }                                                            \
        android::sp<ITestService> ITestService::asInterface(         \
                const android::sp<android::IBinder>& obj)            \
        {                                                            \
            android::sp<ITestService> intr;                          \
            if (obj != NULL) {                                       \
                intr = static_cast<ITestService*>(                   \
                    obj->queryLocalInterface(                        \
                            ITestService::descriptor).get());        \
                if (intr == NULL) {                                  \
                    intr = new BpTestService(obj);                   \
                }                                                    \
            }                                                        \
            return intr;                                             \
        }                                                            \
        ITestService::ITestService() { }                             \
        ITestService::~ITestService() { }                            \
  • 5) BpInterface(frameworks/native/include/binder/Binder.h)

    該類是一個模版類,需和某個繼承自IIterface的類結合使用。
    它的聲明如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    
     template<typename INTERFACE>
    class BpInterface : public INTERFACE, public BpRefBase
    {
    public:
                                    BpInterface(const sp<IBinder>& remote);
     
    protected:
        virtual IBinder*            onAsBinder();
    };
    因此BpInterface會繼承兩個類,一個父類是繼承自IInterface的類,一個是BpRefbase,我們通常聲明的客戶端代理類會繼承自BpInterface
  • 6) BnInterface(frameworks/native/include/binder/IInterface.h)

    該類也是一個模版類,需和某個繼承自IIterface的類結合使用。
    它的聲明如下所示:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
     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也會繼承兩個類,一個父類是繼承自IInterface的binder service接口類,一個是代表Binder service服務端的BBinder類,我們通常聲明的服務端類會直接繼承自BnInterface。
    該類實現了IBinder聲明的另外兩個方法,queryLocalInterface和getInterfaceDescriptor。
再介紹一個重要的宏函數interface_cast,它的源碼如下所示:
1
2
3
4
5
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}
若使用interface_cast < ITestService > (binder),會被擴展為:
1
2
3
4
inline sp< ITestService > interface_cast(const sp<IBinder>& obj)
{
    return ITestService::asInterface(obj);
}
而ITestService::asInterface方法是ITestService接口聲明時使用DECLARE_META_INTERFACE(TestService)聲明的函數

IServiceManager類圖

從先前的博客《Binder IPC程序結構》可知,servicemanager其實是init.rc裡聲明的本地服務,由init進程啟動它作為一個單獨的進程運行。不管是提供binder service的服務端還是使用binder service的客戶端,都是在單獨的進程,他們都需要首先獲得servicemananger的IBinder指針,然後利用IBinder指針建立IServiceManager接口對象。通過《Binder 機制詳解—重要函數調用流程分析》我們已經知道如何獲得servicemananger的IBinder指針,並利用該IBinder指針建立IServiceMananger接口對象。
IServiceManager相關類如下圖所示:(若看不清,請點擊看大圖)
native_binder_framework_servicemananger
IServiceManager是表示servicemanager的接口,有如下方法:
1) getService獲得binder service引用,
2) checkService獲得binder service引用,
3) addService添加binder service,
4) listServices 列舉所有binder service。
servicemanager的binder service服務端其實是在frameworks/base/cmds/servicemanager 裡實現,BnServiceMananger實際上並未使用。BpServiceMananger就是利用獲得的IBinder指針建立的IServiceMananger對象的實際類型。

沒有留言:

張貼留言