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
/* 参考: frameworks\av\include\media\IMediaPlayerService.h */
2
3
#ifndef ANDROID_ICALCULATESRVICE_H
4
#define ANDROID_ICALCULATESRVICE_H
5
6
#include <utils/Errors.h>  // for status_t
7
#include <utils/KeyedVector.h>
8
#include <utils/RefBase.h>
9
#include <utils/String8.h>
10
#include <binder/IInterface.h>
11
#include <binder/Parcel.h>
12
13
#define SVR_CMD_ADD_ONE     0
14
#define SVR_CMD_REDUCE_ONE  1
15
16
17
namespace android {
18
19
class ICalculateService: public IInterface
20
{
21
public:
22
    DECLARE_META_INTERFACE(CalculcateService);
23
    virtual void addone(int n) = 0;
24
    virtual int reduceone(int n) = 0;
25
};
26
27
class BnCalculateService: public BnInterface<ICalculateService>
28
{
29
public:
30
    virtual status_t    onTransact( uint32_t code,
31
                                    const Parcel& data,
32
                                    Parcel* reply,
33
                                    uint32_t flags = 0);
34
35
    virtual void addone(int n);
36
    virtual int reduceone(int n);
37
38
};
39
}
40
41
#endif
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 ,这个 BnCalculateServic e 继 承自  BnInterface 模板类 ICalculateService 类 和 BBinder 类,BBinder 继承自 IBindre,他们都是抽象类,其中 onTransact 就是在 BBinder 类中定义的。
    BnCalculateService 的意思是 Binder native Calculate Service ,函数实现放在:BnCalculateService.cpp 中
1
/* 参考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */
2
3
#define LOG_TAG "CalculateService"
4
5
#include "ICalculateService.h"
6
7
8
namespace android {
9
10
status_t BnCalculateService::onTransact( uint32_t code,
11
                                const Parcel& data,
12
                                Parcel* reply,
13
                                uint32_t flags)
14
{
15
    /* 解析数据,调用addone/reduceone */
16
17
    switch (code) {
18
        case SVR_CMD_ADD_ONE: {
19
            int32_t policy =  data.readInt32();
20
            int32_t n = data.readInt32();
21
22
            /* 把返回值写入reply传回去 */
23
            reply->writeInt32(result);
24
            
25
            return NO_ERROR;
26
        } break;
27
        
28
        case SVR_CMD_REDUCE_ONE: {
29
30
            /* 从data中取出参数 */
31
            int32_t policy =  data.readInt32();
32
            int32_t n = data.readInt32();
33
34
            /* 把返回值写入reply传回去 */
35
            reply->writeInt32(result);
36
            
37
            return NO_ERROR;
38
        } break;
39
        default:
40
            return BBinder::onTransact(code, data, reply, flags);
41
    }
42
}
43
44
int32_t BnCalculateService::addone(int32_t n)
45
{
46
    ALOGI("server add one : %d\n", cnt++);
47
    return ++n;
48
49
int32_t BnCalculateService::sayhello_to(int32_t n)
50
{
51
    ALOGI("server reduce one : %d\n", n);
52
    return --n;
53
}
54
55
}
定义好了这个 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
/* 参考: frameworks\av\media\libmedia\IMediaPlayerService.cpp */
2
3
#include "ICalculateService.h"
4
5
namespace android {
6
7
class BpCalculateService: public BpInterface<ICalculateService>
8
{
9
public:
10
    BpCalculateService(const sp<IBinder>& impl)
11
        : BpInterface<ICalculateService>(impl)
12
    {
13
    }
14
15
    int addone(int n)
16
    {
17
        Parcel data, reply;
18
19
        data.writeInt32(0);
20
        data.writeInt32(n);
21
22
23
        remote()->transact(SVR_CMD_REDUCE_ONE, data, &reply);
24
25
        return reply.readInt32();
26
    }
27
    
28
    int reduceone(int n)
29
    {
30
        /* 构造/发送数据 */
31
        Parcel data, reply;
32
33
        data.writeInt32(0);
34
        data.writeInt32(n);
35
36
37
        remote()->transact(SVR_CMD_REDUCE_ONE, data, &reply);
38
39
        return reply.readInt32();
40
    }
41
42
};
43
44
IMPLEMENT_META_INTERFACE(CalculateService, "android.media.ICalculateService");
45
46
}
47

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 ?
1
template<typename INTERFACE>
2
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
3
{
4
    return INTERFACE::asInterface(obj);
5
}
可以看出,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<I##INTERFACE> asInterface(                       \
4
            const android::sp<android::IBinder>& obj);                  \
5
    virtual const android::String16& getInterfaceDescriptor() const;    \
6
    I##INTERFACE();                                                     \
7
    virtual ~I##INTERFACE(); 
实际是:
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
class BpCalculateService: public BpInterface<ICalculateService>
2
{
3
public:
4
    BpCalculateService(const sp<IBinder>& impl)
5
        : BpInterface<ICalculateService>(impl)
6
    {
7
    }
8
9
    int addone(int n)
10
    {
11
         ...
12
    }
13
    
14
    int reduceone(int n)
15
    {
16
         ...
17
    }
18
19
};
20
21
IMPLEMENT_META_INTERFACE(CalculateService, "android.media.ICalculateService");
22
23
}
24
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
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       \
2
    const android::String16 ICalculcateService::descriptor(NAME);             \
3
    const android::String16&                                            \
4
            ICalculcateService::getInterfaceDescriptor() const {              \
5
        return ICalculcateService::descriptor;                                \
6
    }                                                                   \
7
    android::sp<ICalculcateService> ICalculcateService::asInterface(                \
8
            const android::sp<android::IBinder>& obj)                   \
9
    {                                                                   \
10
        android::sp<ICalculcateService> intr;                                 \
11
        if (obj != NULL) {                                              \
12
            intr = static_cast<ICalculcateService*>(                          \
13
                obj->queryLocalInterface(                               \
14
                        ICalculcateService::descriptor).get());               \
15
            if (intr == NULL) {                                         \
16
                intr = new BpCalculcateService(obj);                          \
17
            }                                                           \
18
        }                                                               \
19
        return intr;                                                    \
20
    }                                                                   \
21
    ICalculcateService::ICalculcateService() { }                                    \
22
    ICalculcateService::~ICalculcateService() { }    
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
1
BpRefBase::BpRefBase(const sp<IBinder>& o)
2
    : mRemote(o.get()), mRefs(NULL), mState(0)
3
{
4
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
5
6
    if (mRemote) {
7
        mRemote->incStrong(this);           // Removed on first IncStrong().
8
        mRefs = mRemote->createWeak(this);  // Held for our entire lifetime.
9
    }
10
}
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
    virtual sp<IBinder> getService(const String16& name) const
2
    {
3
        unsigned n;
4
        for (n = 0; n < 5; n++){
5
            sp<IBinder> svc = checkService(name);
6
            if (svc != NULL) return svc;
7
            ALOGI("Waiting for service %s...\n", String8(name).string());
8
            sleep(1);
9
        }
10
        return NULL;
11
    }
12
13
    virtual sp<IBinder> checkService( const String16& name) const
14
    {
15
        Parcel data, reply;
16
        data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
17
        data.writeString16(name);
18
        remote()->transact(CHECK_SERVICE_TRANSACTION, data, &reply);
19
        return reply.readStrongBinder();
20
    }
1
sp<IBinder> Parcel::readStrongBinder() const
2
{
3
    sp<IBinder> val;
4
    unflatten_binder(ProcessState::self(), *this, &val);
5
    return val;
6
}
1
status_t unflatten_binder(const sp<ProcessState>& proc,
2
    const Parcel& in, sp<IBinder>* out)
3
{
4
    const flat_binder_object* flat = in.readObject(false);
5
6
    if (flat) {
7
        switch (flat->type) {
8
            case BINDER_TYPE_BINDER:
9
                *out = reinterpret_cast<IBinder*>(flat->cookie);
10
                return finish_unflatten_binder(NULL, *flat, in);
11
            case BINDER_TYPE_HANDLE:
12
                *out = proc->getStrongProxyForHandle(flat->handle);
13
                return finish_unflatten_binder(
14
                    static_cast<BpBinder*>(out->get()), *flat, in);
15
        }
16
    }
17
    return BAD_TYPE;
18
}
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> sm = defaultServiceManager();
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 如何注册服务的,收到消息如何处理的
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值