以MediaPlayer功能为例,我们可以根据Android 8.1 (Oreo)源代码绘制出其类图
定义相关API,方便binder进程调用。IMediaPlayerService理论上是MediaPlayerService的接口,故只定义API而把API具体实现都放在class MediaPlayerService中。
class IMediaPlayerService: public IInterface {
public:
DECLARE_META_INTERFACE(MediaPlayerService);
... ...
virtual sp create(const sp& client, audio_session_taudioSessionId = AUDIO_SESSION_ALLOCATE) = 0;
virtual sp getOMX() = 0;
virtual sp makeHDCP(bool createEncryptionModule) = 0;
virtual sp getCodecList() const = 0; };
class BnMediaPlayerService: public BnInterface {
public:
virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0);
};
2.1 BnMediaPlayerService
IMediaPlayerService主要有两个子类,一个是BpMediaPlayerServcie类,另一个是BnMediaPlayerService类。
IMediaPlayerService.h中,可以看到BnMediaPlayerService继承模板类BnInterface。在IInterface.h中可看到BnInterface的定义如下:
template
class BnInterface : public INTERFACE, public BBinder
{
public:
virtual sp queryLocalInterface(const String16& _descriptor);
virtual const String16& getInterfaceDescriptor() const;
protected:
virtual IBinder* onAsBinder();
};
根据模板类的概念,BnMediaPlayerService相当于继承IMediaPlayerService和BBinder。
同理,BpMediaPlayerService类相当于继承了IMediaPlayerService和BpRefBase类。
template
class BpInterface : public INTERFACE, public BpRefBase {
public:
explicit BpInterface(const sp& remote);
protected:
virtual IBinder* onAsBinder();
};
2.2 DECLARE_META_INTERFACE( )
DECLARE_META_INTERFACE( )同样位于IInterface.h,同样是一个模板函数。
#define DECLARE_META_INTERFACE(INTERFACE)
static const ::android::String16 descriptor;
static ::android::sp asInterface(const::android::sp<::android::IBinder>& obj);
virtual const ::android::String16& getInterfaceDescriptor() const;
I##INTERFACE();
virtual ~I##INTERFACE();
则DECLARE_META_INTERFACE( MediaPlayerService)可以翻译为:
static const ::android::String16 descriptor;
static ::android::sp asInterface(const::android::sp<::android::IBinder>& obj);
virtual const ::android::String16& getInterfaceDescriptor() const;
IMediaPlayerService();
virtual ~IMediaPlayerService(); //析构IMediaPlayerService对象
可以总结为IMediaPlayerService主要包含了以下几个虚函数,待子类 class MediaPlayerService实现。、
(1) sp
create(...) //纯虚函数 (2) sp
getOMX() //纯虚函数 (3) sp
makeHDCP(bool createEncryptionModule) //纯虚函数 (4) sp
getCodecList() const //纯虚函数
IMediaPlayer.cpp包含了class BpMediaPlayerService和class BnMediaPlayerService。
BpMediaPlayerService的主要设计满足代理模式(proxy),可以视为代理类,隔断客户端(访问对象)和服务端(被访问对象)。客户端对象必须通过代理类才能访问到BnMediaPlayerService中对象。
BpMediaPlayerService代理类的主要代码如下,主要作用是remote->transact( )调用。通知服务端具体调用。
status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
switch (code) {
case CREATE: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp client=interface_cast player = create(client, audioSessionId);
reply->writeStrongBinder(IInterface::asBinder(player));
return NO_ERROR;
} break;
... ...
case GET_OMX: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp omx = getOMX();
reply->writeStrongBinder(IInterface::asBinder(omx));
return NO_ERROR;
} break;
case MAKE_HDCP: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
bool createEncryptionModule = data.readInt32();
sp hdcp = makeHDCP(createEncryptionModule);
reply->writeStrongBinder(IInterface::asBinder(hdcp));
return NO_ERROR;
} break;
... ...
case LISTEN_FOR_REMOTE_DISPLAY: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
const String16 opPackageName = data.readString16();
sp client(interface_cast(data.readStrongBinder()));
if (client == NULL) {
reply->writeStrongBinder(NULL);
return NO_ERROR;
}
String8 iface(data.readString8());
sp display(listenForRemoteDisplay(opPackageName, client,iface));
reply->writeStrongBinder(IInterface::asBinder(display));
return NO_ERROR;
} break;
case GET_CODEC_LIST: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp mcl = getCodecList();
reply->writeStrongBinder(IInterface::asBinder(mcl));
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
BnMediaPlayerService作为实现类,重写onTransact( )函数,处理proxy发来的函数调用。
status_t BnMediaPlayerService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
switch (code) {
case CREATE: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp client =interface_cast player = create(client, audioSessionId);
reply->writeStrongBinder(IInterface::asBinder(player));
return NO_ERROR;
} break;
... ...
case GET_OMX: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp omx = getOMX();
reply->writeStrongBinder(IInterface::asBinder(omx));
return NO_ERROR;
} break;
case MAKE_HDCP: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
bool createEncryptionModule = data.readInt32();
sp hdcp = makeHDCP(createEncryptionModule);
reply->writeStrongBinder(IInterface::asBinder(hdcp));
return NO_ERROR;
} break;
... ...
case LISTEN_FOR_REMOTE_DISPLAY: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
const String16 opPackageName = data.readString16();
sp client(interface_cast(data.readStrongBinder()));
if (client == NULL) {
reply->writeStrongBinder(NULL);
return NO_ERROR;
}
String8 iface(data.readString8());
sp display(listenForRemoteDisplay(opPackageName, client, iface));
reply->writeStrongBinder(IInterface::asBinder(display));
return NO_ERROR;
} break;
case GET_CODEC_LIST: {
CHECK_INTERFACE(IMediaPlayerService, data, reply);
sp mcl = getCodecList();
reply->writeStrongBinder(IInterface::asBinder(mcl));
return NO_ERROR;
} break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
例如,当proxy发来调用服务端的getCodecList( )函数(getCodecList()函数为获取编码器列表)。则调用
remote()->transact(GET_CODEC_LIST,data,&reply);
经过binder驱动,会回调至onTransact( ),处理客户端需求。如GET_CODEC_LIST满足case GET_CODEC_LIST,则执行
而IMediaPlayerService类中的create( ),makeDHCP( ),getCodecList( )具体实现不在IMediaPlayerService类中。
writeStrongBinder(IInterface::asBinder(mcl))