Android Binder 修煉之道(三)Binder 系統C++實現 BpXXX代理類分析

    在 Binder 系統中,分爲 Client ServiceManager Server 三部分,C++是面向對象的語言,因此,這三者對應三個類的實例。ServiceManager 由 Android系統實現,我們只需要實現我們自己的 client 和 Server 類即可。
    在 Binder 系統 C 的實現中,我們的 Client 和 Server 都實現了 sddone 和 reduceone 函數,名稱一樣,內容不一樣,因此在 C++ 中,將這些函數統一封裝成一個接口類 ICalculateService ,放在 ICalculateService.h 中。
1
template<typename INTERFACE>
2
class BnInterface : public INTERFACE, public BBinder
3
{
4
public:
5
    virtual sp<IInterface>      queryLocalInterface(const String16& _descriptor);
6
    virtual const String16&     getInterfaceDescriptor() const;
7
8
protected:
9
    virtual IBinder*            onAsBinder();
10
};
    可以看到,這個ICalculateService接口非常簡單,定義了兩個純虛函數,所謂的純虛函數就是作爲標準接口,在子類中實現。
同時可以看到,這裏還定義了一個 BnCalculateService ,它就是我們的 Server ,這個 BnCalculateService 繼承自 BnInterface 模板類ICalculateService 類 和 BBinder 類,BBinder 繼承自 IBindre,他們都是抽象類,其中 onTransact 就是在 BBinder 類中定義的。
    BnCalculateService 的意思是 Binder native Calculate Service ,函數實現放在:BnCalculateService.cpp 中
定義好了這個 Server 類如何使用?
1
/* 參考: frameworks\av\media\mediaserver\Main_mediaserver.cpp */
2
3
#define LOG_TAG "HelloService"
4
//#define LOG_NDEBUG 0
5
6
#include <fcntl.h>
7
#include <sys/prctl.h>
8
#include <sys/wait.h>
9
#include <binder/IPCThreadState.h>
10
#include <binder/ProcessState.h>
11
#include <binder/IServiceManager.h>
12
#include <cutils/properties.h>
13
#include <utils/Log.h>
14
15
#include "ICalculateService.h"
16
17
18
using namespace android;
19
20
int main(void)
21
{
22
    /* addService */
23
24
    /* while(1){ read data, 解析數據, 調用服務函數 } */
25
26
    /* 打開驅動, mmap */
27
    sp<ProcessState> proc(ProcessState::self());
28
29
    /* 獲得BpServiceManager */
30
    sp<IServiceManager> sm = defaultServiceManager();
31
32
    sm->addService(String16("calculate"), new BnCalculateService());
33
34
    /* 循環體 */
35
    ProcessState::self()->startThreadPool();
36
    IPCThreadState::self()->joinThreadPool();
37
38
    return 0;
39
}

下面來看 Client

1
#define LOG_TAG "CalculateService"
2
//#define LOG_NDEBUG 0
3
4
#include <fcntl.h>
5
#include <sys/prctl.h>
6
#include <sys/wait.h>
7
#include <binder/IPCThreadState.h>
8
#include <binder/ProcessState.h>
9
#include <binder/IServiceManager.h>
10
#include <cutils/properties.h>
11
#include <utils/Log.h>
12
13
#include "ICalculateService.h"
14
15
using namespace android;
16
17
/* ./test_client hello
18
 * ./test_client hello <name>
19
 */
20
int main(int argc, char **argv)
21
{
22
    int cnt;
23
    
24
    if (argc < 2){
25
        ALOGI("Usage:\n");
26
        ALOGI("%s <hello|goodbye>\n", argv[0]);
27
        ALOGI("%s <hello|goodbye> <name>\n", argv[0]);
28
        return -1;
29
    }
30
31
    /* getService */
32
    /* 打開驅動, mmap */
33
    sp<ProcessState> proc(ProcessState::self());
34
35
    /* 獲得BpServiceManager */
36
    sp<IServiceManager> sm = defaultServiceManager();
37
38
    sp<IBinder> binder =
39
        sm->getService(String16("calculate"));
40
41
    if (binder == 0)
42
    {
43
        ALOGI("can't get calculate service\n");
44
        return -1;
45
    }
46
47
    /* service肯定是BpCalculateServie指針 */
48
    sp<ICalculateService> service =
49
        interface_cast<ICalculateService>(binder);
50
51
52
    /* 多態,調用Service的函數 */
53
    cnt = service->reduceone(argv[2]);
54
    ALOGI("client call reduceone, result = %d", cnt);
55
    
56
    return 0;
57
}
58
IBinder 如何轉換成 ICalculateService ?
可以看出,interface_cast 是個模板函數,在這,它將調用 ICalculateService::asInterface(binder)
asInterface 從哪來的?
1
class ICalculateService: public IInterface
2
{
3
public:
4
    DECLARE_META_INTERFACE(CalculcateService);
5
    virtual void addone(int n) = 0;
6
    virtual int reduceone(int n) = 0;
7
};
實際是:
1
#define DECLARE_META_INTERFACE(INTERFACE)                               \
2
    static const android::String16 descriptor;                          \
3
    static android::sp<ICalculcateService> asInterface(                       \
4
            const android::sp<android::IBinder>& obj);                  \
5
    virtual const android::String16& getInterfaceDescriptor() const;    \
6
    ICalculcateService();                                                     \
7
    virtual ~ICalculcateService(); 
那個這個 asInterface 函數的實現在哪?
1
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
2
    const android::String16 I##INTERFACE::descriptor(NAME);             \
3
    const android::String16&                                            \
4
            I##INTERFACE::getInterfaceDescriptor() const {              \
5
        return I##INTERFACE::descriptor;                                \
6
    }                                                                   \
7
    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                \
8
            const android::sp<android::IBinder>& obj)                   \
9
    {                                                                   \
10
        android::sp<I##INTERFACE> intr;                                 \
11
        if (obj != NULL) {                                              \
12
            intr = static_cast<I##INTERFACE*>(                          \
13
                obj->queryLocalInterface(                               \
14
                        I##INTERFACE::descriptor).get());               \
15
            if (intr == NULL) {                                         \
16
                intr = new Bp##INTERFACE(obj);                          \
17
            }                                                           \
18
        }                                                               \
19
        return intr;                                                    \
20
    }                                                                   \
21
    I##INTERFACE::I##INTERFACE() { }                                    \
22
    I##INTERFACE::~I##INTERFACE() { }    
替換完之後就是這個樣子:
1
sp<IInterface>  IBinder::queryLocalInterface(const String16& /*descriptor*/)
2
{
3
    return NULL;
4
}
因此,這裏直接返回的是,new BpCalculateService(binder)
也就是說 interface_cast<ICalculateService>(binder) 的最終結果 new BpCalculateService(binder)
binder 是通過 getService 構造的 BpBinder 對象的指針(BpBinder繼承自IBinder)
先不關心 binder 怎麼來的,先來看看如何用 binder(BpBinder)來構造BpXXXService
BpXXXService 繼承自 BpInterface<IXXXService> 繼承自 BpRefBase
o 是 binder ,o 是個智能指針,o.get() 返回這個指針所指向的對象的指針,也就是 mRemote 指向了 binder
也就是說 interface_cast<ICalculateService>(binder) 的最終結果,構造了一個 BpCalculateService 它裏邊的 mRemote 指向一個 BpBinder
binder 獲取的過程:
1
sp<IServiceManager> sm = defaultServiceManager();
2
3
    sp<IBinder> binder =
4
        sm->getService(String16("calculate"));
defaultServiceManager IServiceManager 類的接口,它的 getService 函數在 BpServiceManager 類中實現, 
1
sp<IBinder> Parcel::readStrongBinder() const
2
{
3
    sp<IBinder> val;
4
    unflatten_binder(ProcessState::self(), *this, &val);
5
    return val;
6
}
1
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
2
{
3
    sp<IBinder> result;
4
5
    AutoMutex _l(mLock);
6
7
    handle_entry* e = lookupHandleLocked(handle);
8
9
    IBinder* b = e->binder;
10
    if (b == NULL || !e->refs->attemptIncWeak(this)) {
11
12
        b = new BpBinder(handle); 
13
        e->binder = b;
14
        if (b) e->refs = b->getWeakRefs();
15
         result = b;
16
    } 
17
    
18
    return result;
19
}
getService 的過程:
構造數據發送數據,在 reply 中取出 handle,通過 handle 構造一個 BpBinder 對象,mHandle = handle
也就是說我們獲取服務的時候是得到了一個服務的 handle ,然後用這個 handle 構造對應的代理類,BpXXXService,在通過BpXXXService代理類的函數來訪問具體的服務。
前面說到,getService 函數也是在一個代理類中實現的,BpServiceManager 中,看看它是怎麼來的:
1
sp<IServiceManager> defaultServiceManager()
2
{
3
    if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
4
    
5
    {
6
        AutoMutex _l(gDefaultServiceManagerLock);
7
        while (gDefaultServiceManager == NULL) {
8
            gDefaultServiceManager = interface_cast<IServiceManager>(
9
                ProcessState::self()->getContextObject(NULL));
10
            if (gDefaultServiceManager == NULL)
11
                sleep(1);
12
        }
13
    }
14
    
15
    return gDefaultServiceManager;
16
}
剛開始的時候,gDefaultServiceManager 爲 NULL:
gDefaultServiceManager = interface_cast<IServiceManager>(ProcessState::self()->getContextObject(NULL));
1
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
2
{
3
    return getStrongProxyForHandle(0);//new BpBinder(0); 
4
}
也就是 interface_cast<IServiceManager>(new BpBinder(0))
和前面分析的一樣,這裏應該是用 BpBinder(0)構造一個 BpServiceManager對象,BpServiceManager 中的 mRemote 指向 BpBinder(0),mHandle = 0
 
總結:
訪問服務先需要構造代理類,通過 handle 構造 BpBinder,BpBinder 中的 mHandle = handle
通過 BpBinder 構造 BpXXX 代理類對象(代理類對象中的 mRemote 指向 BpBinder)然後付給一個接口類的指針,比如 IServiceManager 或者 IHelloService 
利用多態的特性,用父類指針比如 IServiceManager 或者 IHelloService,直接調用 BpXXX 中的函數訪問服務。

後面需要分析: 
    如何訪問服務的?
    BnXXXService 如何註冊服務的,收到消息如何處理的
閱讀更多 登錄後自動展開
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章