现在的位置: 首页 > 综合 > 正文

Android-IPC-Binder(2)

2013年01月29日 ⁄ 综合 ⁄ 共 7305字 ⁄ 字号 评论关闭

Generate AudioFlinger Service

media_server程序会启动AudioFlinger服务。相关代码如下:

AudioFlinger::instantiate()函数会调用IServiceManager::addService远程调用。

AudioFlinger继承自BnAudioFlinger,BnAudioFlinger是一个BnInterface模板类的实例。

BnInterface继承自BBinder。

根据BnInterface的实现,我们看到传递给IServiceManager::addService的参数是一个AudioFlinger实例的地址。BBinder继承自IBinder,它的transact()函数调用onTransact虚函数(多态)。

最重要的虚函数是onTransact()。BnAudioFlinger实现了该虚函数。在本文的例子中我们只需要关注SET_MODE分支。

media_server会通过IPCThreadState::joinThreadPool进入一个循环,就像service_manager,它会通过调用talkWithDriver()函数等待其他进程传入数据。

 

假设你想要实现你自己的IFunnyTest服务,必须遵循以下步骤:

  • 实现你自己的BnFunnyTest类;
  • 在执行你的服务的进程中,调用IPCThreadState::joinThreadPool()函数

RPC Call IServiceManager::addService

当我们调用IServiceManager::addService时,实际上调用的是BpServiceManager::addService。

Parcel类型很简单。我们可以把它认为是一块连续的缓冲区。注意,参数service是指向BBinder对象(AudioFlinger从Bn继承来)的指针。

flatten_binder会生成一个Binder命令。因为BBinder是一个本地的binder对象,因此该代码分支标为红色。

注意红色的代码行。本地地址被放入到一个包(以后会用到)中。在该addService远程调用的包构造完成后,BpServiceManager::addService()将会调用BpBinder的transact()函数。

BpBinder调用IPCThreadState::transact来根据mHandle启动一个针对binder对象的(处理)事务。在本文的例子中,mHandle为0。

IPCThreadState::transact首先调用writeTransactionData函数为binder内核驱动构造一个transaction结构。注意以下几行,它对于binder内核驱动识别事务(transaction)目标非常重要

然后waitForResponse()通过talkWithDriver()函数去调用BINDER_WRITE_READ的ioctl()。

于是到现在为止,事务数据已经发送到了binder内核驱动。

小结:

Proxy(代理)对象会为RPC调用生成必需的包,然后调用BINDER_WRITE_READ将包写入binder内核驱动。该包为格式化的。对于RPC调用,它是BC_TRANSACTION类型的包。

假设你要实现你自己的IFunnyTest的服务,你必须要:

  • 在服务运行的进程中调用IServiceManager::addService()函数将服务注册到servier_manger。

 

抱歉!评论已关闭.