Android C++底层Binder通信机制原理分析总结【通俗易懂】

Android C++底层Binder通信机制原理总结:
通过transact()方法可以向远端的IBinder对象发出调用,再通过onTransact()函数让你自己的远程对象能够响应接收到的调用。

例如MediaRecorder的继承关系(向右箭头表示继承关系,#XXX#中间是关键方法,/斜线表示多继承):

客户端:
1、MediaRecorder->BnMediaRecorderClient#onTransact()#->BnInterface->
BBinder#transact()#(->IBinder->RefBase)/IMediaRecorderClient#notify(xx)/asInterface(IBinder obj)#(->IInterface->RefBase)
2、代理:BpMediaRecorderClient(IBinder impl)->BpInterface(IBinder remote)->
BpRefBase(IBinder o)#remote()#->RefBase/IMediaRecorderClient#notify(xx)/asInterface(IBinder obj)#(->IInterface->RefBase)

服务器:
3、MediaRecorderClient->BnMediaRecorder->BnInterface->BBinder(->IBinder->RefBase)/IMediaRecorder(->IInterface->RefBase)
4、BpMediaRecorder(IBinder impl)->BpInterface(IBinder remote)->
BpRefBase(IBinder o)#remote()#->RefBase/IMediaRecorderClient#notify(xx)/asInterface(IBinder obj)#(->IInterface->RefBase)

5、【interface_cast模板方法】即asInterface(IBinder obj)是一个宏定义生成的函数,通过缓存查找或直接new一个Bp对象(BpMediaRecorderClient(BpBinder->IBinder obj)),
返回父类型对象即IBpMediaRecorderClient(IBinder obj)对象,因此也就创建了一个Bp代理对象;

6、以上可总结为:
6.1、BnXXX或BpXXX都派生自两个类:
class BpXXX : public IXXX, public BpRefBase;
class BnXXX : public IXXX, public BBinder;
6.2、BpXXX和BnXXX都派生自IXXX,IXXX可理解为定义业务逻辑,但BnXXX和BpXXX中具体实现方式却不同,如下分析:
BpXXX中:作为代理端,把对应的binder_transaction_data打包之后,通过BpRefBase中的mRemote即BpBinder对象实例发送出去,并等待结果。
BnXXX中:作为实现端,实现与BpXXX中对应的真正的业务逻辑,通过调用BnXXX派生类中的方法来实现,如MediaRecorderClient实现类;
6.3、IBinder用于进行进程间通信:
BpRefBase中的remote()方法返回的mRemote即BpBinder对象实例用来和Binder驱动交互使用(通过BpBinder.transact(xxx)调用IPCThreadState.transact(xxx)方法,
最后调用IPCThreadState.talkWithDriver(bool)方法中使用ioctl()函数将Parcel类型的mOut中缓存数据写入Binder驱动共享内存区域,并获取mIn返回值Parcel数据);
BBinder(transact()到onTransact()的调用)是从Binder驱动中接收相关请求,并进行相关处理的;
BpBinder(remote())则是和BinderDriver进行互通的;

7、Binder机制中与Binder驱动交互的桥梁:两个非常重要的类:ProcessState和IPCThreadState类。
ProcessState:是Client和Server两端公共的部分,作为Binder通信的基础。并且是个singleton单例类,每个进程只有一个对象,
该对象负责打开Binder驱动,建立线程池,使得该进程中的所有线程都能通过Binder通信。
IPCThreadState:是每个线程中都有一个IPCThreadState对象实例记录在Linux线程的上下文附属数据中,主要负责Binder的读取、写入和请求处理,
并且它在创建时会记录一个ProcessState类型的mProcess成员变量,以便用于获取到Binder句柄,从而进行binder_transaction_data事物数据在两个进程间的通信。

IPC通信简单分析例如:
1、 注册相关服务:【frameworks/av/media/mediaserver/main_mediaserver.cpp】中

int main(int argc __unused, char **argv __unused)
{
    
    
    sp<ProcessState> proc(ProcessState::self());
// 初始化注册服务管理中心即BpServiceManager
    sp<IServiceManager> sm(defaultServiceManager());
   // 实例化相关服务
    MediaPlayerService::instantiate();
    ResourceManagerService::instantiate();
    registerExtensions();
// 进入线程循环
    ProcessState::self()->startThreadPool();
    IPCThreadState::self()->joinThreadPool();
} 

分析:系统启动时init进程会初始化所有多媒体相关的服务在服务管理中心,以便此后直接进行获取。

void MediaPlayerService::instantiate() {
    
    
    defaultServiceManager()->addService(
            String16("media.player"), new MediaPlayerService());
}

分析:向注册服务管理中心注册自己的服务实现者即Bn实现对象,该服务对应名称是"media.player",以提供给Bp代理者代理操作实现的业务功能。

2、向注册服务管理中心获取自己的服务即Bp实现对象,也是Bn对象的在客户端的代理操作对象。

MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSource(NULL)
{
    
    
    const sp<IMediaPlayerService> service(getMediaPlayerService());
    if (service != NULL) {
    
    
        mMediaRecorder = service->createMediaRecorder(opPackageName);
    }
}
//【IMediaDeathNotifier.cpp】MediaRecorder继承了IMediaDeathNotifier类
IMediaDeathNotifier::getMediaPlayerService()
{
    
    
    Mutex::Autolock _l(sServiceLock);
if (sMediaPlayerService == 0) {
    
    
// 初始化注册服务管理中心即BpServiceManager
        sp<IServiceManager> sm = defaultServiceManager();
        sp<IBinder> binder;
			// 通过响应服务注册时的服务名称【"media.player"】获取注册过的服务
            binder = sm->getService(String16("media.player"));
          // 最后使用interface_cast转换成对应服务去的Bp代理对象
        sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
    }
    return sMediaPlayerService;
}

分析:MediaRecorder通过getMediaPlayerService()从ServiceManager层获取到此前已经注册进Service的BpMediaPlayerService服务,通过该服务在跨进程通信时通过createMediaRecorder()函数发送CREATE_MEDIA_RECORDER消息通知MediaPlayerService(BnMediaPlayerService)的BnMediaPlayerService::onTransact()方法,构造了一个MediaRecorderClient对象,并将该client对象放入MediaPlayerService类的全局SortedVector类型的列表中,然后返回结果client。
并且在构造MediaRecoderClient时通过AVMediaServiceFactory创建了一个StageFrightRecorder对象,该对象才是真正录制相关功能实现者如数据处理、编码、录制行为控制(如prepare、start、pause、resume、stop等)等。

例如:
setupMediaSource: 通过setupCameraSource去绑定CameraSource的listener,从而获取到driver层返回的数据。
setupVideoEncoder: 根据上层传入的video编码格式来创建对应的MediaCodecSource即Video编码器。
setupAudioEncoder: 根据上层传入的audio编码格式来创建对应的MediaCodecSource即Audio编码器。
使用MediaWriter(MPEG4Writer): 在MPEG4Writer的startWriterThread中开启MediaWriter线程,分track读取并在Track->dump(fd,args)中write(fd,result.string(),result.size())写入数据到最终文件中。

猜你喜欢

转载自blog.csdn.net/u012430727/article/details/110941068