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
Android Binder 修炼之道(三)Binder 系统C++实现 BpXXX代理类分析
Android Binder 修炼之道(三)Binder 系统C++实现 BpXXX代理类分析 
总结:
访问服务先需要构造代理类,通过 handle 构造 BpBinder,BpBinder 中的 mHandle = handle
通过 BpBinder 构造 BpXXX 代理类对象(代理类对象中的 mRemote 指向 BpBinder)然后付给一个接口类的指针,比如 IServiceManager 或者 IHelloService 
利用多态的特性,用父类指针比如 IServiceManager 或者 IHelloService,直接调用 BpXXX 中的函数访问服务。

后面需要分析: 
    如何访问服务的?
    BnXXXService 如何注册服务的,收到消息如何处理的