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 ,这个 BnCalculateService 继承自 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 如何注册服务的,收到消息如何处理的