Android Binder(二)相关接口和类

Binder的跨进程机制

上一篇文章已近说了Binder的设计原理,再看一下Binder示意图。

图中A侧的圆形块,表示“Binder代理方”,主要用于向远方发送语义,而B侧的方形块则表示“Binder响应方”,主要用于响应语义。在后文中,我们可以看到,Binder代理方大概对应于C++层次的BpBinder对象,而Binder响应方则对应于BBinder对象。这两个对象在后文会详细阐述,此处不必太细究。

Binder代理方主要只负责了“传递信息”的工作,并没有起到“远程过程调用”的作用,如果要支持远程过程调用,我们还必须提供“接口代理方”和“接口实现体”。

A进程并不直接和BpBinder(Binder代理)打交道,而是通过调用BpInterface(接口代理)的成员函数来完成远程调用的。此时,BpBinder已经被聚合进BpInterface了,它在BpInterface内部完成了一切跨进程的机制。另一方面,与BpInterface相对的响应端实体就是BnInterface(接口实现)了。需要注意的是,BnInterface是继承于BBinder的,它并没有采用聚合的方式来包含一个BBinder对象,所以上图中B侧的BnInterface块和BBinder块的背景图案是相同的。

Binder相关接口和类

Android的整个跨进程通信机制都是基于Binder的,这种机制不但会在底层使用,也会在上层使用,所以必须提供Java和C++两个层次的支持。

Java层次的binder元素

Java层次里并没有我们前文图中所表示的BpBinder、BpInterface、BBinder等较低层次的概念,取而代之的是IBinder接口、IInterface等接口。Android要求所有的Binder实体都必须实现IBinder接口,该接口的定义截选如下:

frameworks/base/core/java/android/os/IBinder.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public interface IBinder 
{
. . . . . .
public String getInterfaceDescriptor() throws RemoteException;
public boolean pingBinder();
public boolean isBinderAlive();
public IInterface queryLocalInterface(String descriptor);
public void dump(FileDescriptor fd, String[] args) throws RemoteException;
public void dumpAsync(FileDescriptor fd, String[] args) throws RemoteException;
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws
RemoteException;

public interface DeathRecipient
{
public void binderDied();
}
public void linkToDeath(DeathRecipient recipient, int flags)throws
RemoteException;
public boolean unlinkToDeath(DeathRecipient recipient, int flags);
}

另外,不管是代理方还是实体方,都必须实现IInterface接口:

/**
 * Base class for Binder interfaces.  When defining a new interface,
 * you must derive it from IInterface.
 */
public interface IInterface
{
    /**
     * Retrieve the Binder object associated with this interface.
     * You must use this instead of a plain cast, so that proxy objects
     * can return the correct result.
     */
    public IBinder asBinder();
}

Java层次中,与Binder相关的接口或类的继承关系如下:

在实际使用中,我们并不需要编写上图的XXXXNative、XXXXProxy,它们会由ADT根据我们编写的aidl脚本自动生成。用户只需继承XXXXNative编写一个具体的XXXXService即可,这个XXXXService就是远程通信的服务实体类,而XXXXProxy则是其对应的代理类。

关于Java层次的binder组件,我们就先说这么多,主要是先介绍一个大概。就研究跨进程通信而言,其实质内容基本上都在C++层次,Java层次只是一个壳而已。以后我会写专文来打通Java层次和C++层次,看看它们是如何通过JNI技术关联起来的。现在我们还是把注意力集中在C++层次吧。

C++层次的binder元素

在C++层次,就能看到我们前文所说的BpBinder类和BBinder类了。这两个类都继承于IBinder,IBinder的定义截选如下:

frameworks/native/include/binder/IBinder.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
class IBinder : public virtual RefBase
{
public:
. . . . . .
IBinder();
virtual sp<IInterface> queryLocalInterface(const String16& descriptor);
virtual const String16& getInterfaceDescriptor() const = 0;

virtual bool isBinderAlive() const = 0;
virtual status_t pingBinder() = 0;
virtual status_t dump(int fd, const Vector<String16>& args) = 0;
virtual status_t transact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0) = 0;

class DeathRecipient : public virtual RefBase
{
public:
virtual void binderDied(const wp<IBinder>& who) = 0;
};
virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL, uint32_t flags = 0) = 0;
virtual status_t unlinkToDeath(const wp<DeathRecipient>& recipient,
void* cookie = NULL, uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL) = 0;

virtual bool checkSubclass(const void* subclassID) const;

typedef void (*object_cleanup_func)(const void* id, void* obj,
void* cleanupCookie);
virtual void attachObject(const void* objectID, void* object,
void* cleanupCookie, object_cleanup_func func)
= 0;
virtual void* findObject(const void* objectID) const = 0;
virtual void detachObject(const void* objectID) = 0;

virtual BBinder* localBinder();
virtual BpBinder* remoteBinder();

protected:
virtual ~IBinder();
private:
};

C++层次的继承关系图如下:

其中有以下几个很关键的类:

  • BpBinder
  • BpInterface
  • BBinder
  • BnInterface

它们扮演着很重要的角色。

BpBinder
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class BpBinder : public IBinder
{
public:
BpBinder(int32_t handle);
inline int32_t handle() const { return mHandle; }

virtual const String16& getInterfaceDescriptor() const;
virtual bool isBinderAlive() const;
virtual status_t pingBinder();
virtual status_t dump(int fd, const Vector<String16>& args);

virtual status_t transact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0);
virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL, uint32_t flags = 0);
virtual status_t unlinkToDeath(const wp<DeathRecipient>& recipient,
void* cookie = NULL, uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL);

作为代理端的核心,BpBinder最重要的职责就是实现跨进程传输的传输机制,至于具体传输的是什么语义,它并不关心。我们观察它的transact()函数的参数,可以看到所有的语义都被打包成Parcel了。其他的成员函数,我们先不深究,待我们储备了足够的基础知识后,再回过头研究它们不迟。

BpInterface

另一个重要的类是BpInterface,它的定义如下:

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();
};

其基类BpRefBase的定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class BpRefBase : public virtual RefBase
{
protected:
BpRefBase(const sp<IBinder>& o);
virtual ~BpRefBase();
virtual void onFirstRef();
virtual void onLastStrongRef(const void* id);
virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
inline IBinder* remote() { return mRemote; }
inline IBinder* remote() const { return mRemote; }

private:
BpRefBase(const BpRefBase& o);
BpRefBase& operator=(const BpRefBase& o);
IBinder* const mRemote;
RefBase::weakref_type* mRefs;
volatile int32_t mState;
};

BpInterface使用了模板技术,而且因为它继承了BpRefBase,所以先天上就聚合了一个mRemote成员,这个成员记录的就是前面所说的BpBinder对象啦。以后,我们还需要继承BpInterface<>实现我们自己的代理类。

在实际的代码中,我们完全可以创建多个聚合同一BpBinder对象的代理对象,这些代理对象就本质而言,对应着同一个远端binder实体。在Android框架中,常常把指向同一binder实体的多个代理称为token,这样即便这些代理分别处于不同的进程中,它们也具有了某种内在联系。这个知识点需要大家关注。

BBinder

Binder远程通信的目标端实体必须继承于BBinder类,该类和BpBinder相对,主要关心的只是传输方面的东西,不太关心所传输的语义。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class BBinder : public IBinder
{
public:
BBinder();
virtual const String16& getInterfaceDescriptor() const;
virtual bool isBinderAlive() const;
virtual status_t pingBinder();
virtual status_t dump(int fd, const Vector<String16>& args);

virtual status_t transact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0);

virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
void* cookie = NULL, uint32_t flags = 0);

virtual status_t unlinkToDeath(const wp<DeathRecipient>& recipient,
void* cookie = NULL, uint32_t flags = 0,
wp<DeathRecipient>* outRecipient = NULL);

virtual void attachObject(const void* objectID, void* object,
void* cleanupCookie, object_cleanup_func func);
virtual void* findObject(const void* objectID) const;
virtual void detachObject(const void* objectID);

virtual BBinder* localBinder();

protected:
virtual ~BBinder();

virtual status_t onTransact(uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags = 0);
private:
BBinder(const BBinder& o);
BBinder& operator=(const BBinder& o);

class Extras;
Extras* mExtras;
void* mReserved0;
};

我们目前只需关心上面的transact()成员函数,其他函数留待以后再分析。transact函数的代码如下:

frameworks/native/libs/binder/Binder.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
status_t BBinder::transact(uint32_t code, const Parcel& data, 
Parcel* reply, uint32_t flags)
{
data.setDataPosition(0);
status_t err = NO_ERROR;
switch (code)
{
case PING_TRANSACTION:
reply->writeInt32(pingBinder());
break;
default:
err = onTransact(code, data, reply, flags);
break;
}

if (reply != NULL)
{
reply->setDataPosition(0);
}
return err;
}

transact()内部会调用onTransact(),从而走到用户所定义的子类的onTransact()里。这个onTransact()的一大作用就是解析经由Binder机制传过来的语义了。

BnInterface

远程通信目标端的另一个重要类是BnInterface<>,它是与BpInterface<>相对应的模板类,比较关心传输的语义。一般情况下,服务端并不直接使用BnInterface<>,而是使用它的某个子类。为此,我们需要编写一个新的BnXXX子类,并重载它的onTransact()成员函数。

BnInterface<>的定义如下:

1
2
3
4
5
6
7
8
9
10
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<>继承于BBinder,但它并没有实现一个默认的onTransact()成员函数,所以在远程通信时,前文所说的BBinder::transact()调用的onTransact()应该就是BnInterface<>的某个子类的onTransact()成员函数。

几个重要的C++宏或模板

为了便于编写新的接口和类,Android在C++层次提供了几个重要的宏和模板,比如我们在IInterface.h文件中,可以看到DECLARE_META_INTERFACE、IMPLEMENT_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(); \

我们举个实际的例子,来说明如何使用这个宏:

1
2
3
4
5
class ICamera: public IInterface
{
public:
DECLARE_META_INTERFACE(Camera);
};

上例中IDvbCallback内部使用了DECLARE_META_INTERFACE(Camera),我们把宏展开后,可以看到ICamera类的定义相当于:

1
2
3
4
5
6
7
8
9
10
class ICamera: public IInterface
{
public:

static const android::String16 descriptor;
static android::sp<ICamera> asInterface( const android::sp<android::IBinder>& obj);
virtual const android::String16& getInterfaceDescriptor() const;
ICamera();
virtual ~ICamera();
}

宏展开的部分就是中间那5行代码,其中最关键的就是asInterface()函数了,这个函数将承担把BpBinder打包成BpInterface的职责。

IMPLEMENT_META_INTERFACE()

与DECLARE_META_INTERFACE相对的就是IMPLEMENT_META_INTERFACE宏。它的定义如下:

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() { } \

其中,实现了关键的asInterface()函数。

实际使用IMPLEMENT_META_INTERFACE时,我们只需把它简单地写在binder实体所处的cpp文件中即可,举例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
IMPLEMENT_META_INTERFACE(Camera, "android.hardware.ICamera");

status_t BnCamera::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch (code)
{
case IBinder::FIRST_CALL_TRANSACTION:
{
...
}
default:
return BBinder::onTransact(code, data, reply, flags);
}
}

其中的IMPLEMENT_META_INTERFACE(Camera, “android.hardware.ICamera”);一句相当于以下这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const android::String16 ICamera::descriptor(“android.hardware.ICamera”);
const android::String16& ICamera::getInterfaceDescriptor() const
{
return ICamera::descriptor;
}

android::sp<ICamera> ICamera::asInterface(const android::sp<android::IBinder>& obj)
{
android::sp<ICamera > intr;
if (obj != NULL)
{
intr = static_cast<ICamera*>(obj->queryLocalInterface(
ICamera::descriptor).get());
if (intr == NULL)
{
intr = new BpCamera(obj);
}
}
return intr;
}

ICamera::ICamera() { }
ICamera::~ICamera () { }

看来,其中重点实现了asInterface()成员函数。请注意,asInterface()函数中会先尝试调用queryLocalInterface()来获取intr。此时,如果asInterface()的obj参数是个代理对象(BpBinder),

那么intr = static_cast<ICamera*>(obj->queryLocalInterface(...)一句得到的intr基本上就是NULL啦。这是因为除非用户编写的代理类重载queryLocalInterface()函数,否则只会以默认函数为准。而IBinder类中的默认queryLocalInterface()函数如下:

frameworks/native/libs/binder/Binder.cpp

1
2
3
4
sp<IInterface>  IBinder::queryLocalInterface(const String16& descriptor)
{
return NULL;
}

另一方面,如果obj参数是个实现体对象(BnInterface对象)的话,那么queryLocalInterface()函数的默认返回值就是实体对象的this指针了,代码如下:

frameworks/native/include/binder/IInterface.h

1
2
3
4
5
6
7
template<typename INTERFACE>
inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(const String16& _descriptor)
{
if (_descriptor == INTERFACE::descriptor)
return this;
return NULL;
}

所举的例子中,我们要研究的是如何将BpBinder转成BpInterface,所以现在我们只阐述obj参数为BpBinder的情况。此时asInterface()函数中obj->queryLocalInterface()的返回值为NULL,于是asInterface()会走到new BpCamera(obj)一句,这一句是最关键的一句。我们知道,BpCamera继承于BpInterface,所以此时所创建的BpCamera对象正是可被App使用的BpInterface代理对象。

BpCamera的定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class BpCamera: public BpInterface<ICamera>
{
public:
BpCamera(const sp<IBinder>& impl)
: BpInterface<ICamera>(impl)
{
}

// disconnect from camera service
void disconnect()
{
LOGV("disconnect");
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(DISCONNECT, data, &reply);
}
. . . . . .

至此,IMPLEMENT_META_INTERFACE宏和asInterface()函数的关系就分析完毕了。

interface_cast

不过,我们经常使用的其实并不是asInterface()函数,而是interface_cast(),它简单包装了asInterface():

1
2
3
4
5
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}

原文:https://blog.csdn.net/codefly/article/details/17058607