Android(安卓)Audio底层原理(二)
1. Hal层类关系图
以MediaPlayer功能为例,我们可以根据Android 8.1 (Oreo)源代码绘制出其类图
2. IMediaPlayerService.h
定义相关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类。
templateclass 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 //纯虚函数
3. IMediaPlayerService.cpp
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))
更多相关文章
- Android(安卓)Architecture Component之:深层次理解ViewModel
- android webview js
- Android笔面试题
- Android系统默认Home应用程序(Launcher)的启动过程源代码分析(2)
- 利用OpenGL ES、手机传感器、相机和调用百度语音包服务,实现AR+语
- Unity 与 Android(安卓)aar 包通讯
- MediaRecorder流程分析 java层到stagefright层
- Android的Lifecycle
- ril