5.5 服务代理与服务通信

Client获取到AudioFlingerProxy后,便可以通过其提供的接口使用Service提供的相应服务。服务代理与服务通信的过程如图5-3所示。

5.5 服务代理与服务通信 - 图1

图 5-3 服务代理与服务通信的过程

AudioFlingerProxy中定义了很多接口,以setMasterVolume为例,代码如下:


virtual status_t setMasterVolume(float value)

{

Parcel data, reply;

data.writeInterfaceToken(IAudioFlinger:getInterfaceDescriptor());

data.writeFloat(value);

remote()->transact(SET_MASTER_VOLUME, data,&reply);

return reply.readInt32();

}


已知remote()返回的是指定服务的BpBinder对象,调用其transact方法的过程与addService和getService是类似的,所不同的是Binder驱动程序将把IPC请求转发给指定Service所在进程,该进程便是mediaserver。

mediaserver运行过程中会启动两个Binder线程用于处理Binder通信。每个线程都会talkWithDriver等待Client请求,接收到请求后会从talkWithDriver返回,进而执行executeCommand这部分内容在joinThreadPool中已经分析过。接下来直接分析executeCommand函数,其位于IPCThreadState.cpp中,代码如下:


status_t IPCThreadState:executeCommand(int32_t cmd)

{

BBinder*obj;

RefBase:weakref_type*refs;

status_t result=NO_ERROR;

switch(cmd){

……

case BR_TRANSACTION:

{

binder_transaction_data tr;

result=mIn.read(&tr, sizeof(tr));

if(result!=NO_ERROR)break;

Parcel buffer;

……

Parcel reply;

if(tr.target.ptr){

//将服务对象存入BBinder类型的变量b中

sp<BBinder>b((BBinder*)tr.cookie);

const status_t error=b->transact(tr.code, buffer,

&reply, tr.flags);//调用b的transact方法

if(error<NO_ERROR)reply.setError(error);

}else{

……

}

if((tr.flags&TF_ONE_WAY)==0){

sendReply(reply,0);

}else{//Client不需要返回数据时

}

……

}

break;

……

case BR_SPAWN_LOOPER://Binder可以请求增加Binder线程池中线程数量

mProcess->spawnPooledThread(false);

break;

……

return result;

}


上述代码的transact方法定义在BBinder中,其代码如下:


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://将执行switch代码块的default分支

err=onTransact(code, data, reply, flags);

break;

}

if(reply!=NULL){

reply->setDataPosition(0);

}

return err;

}


调用BBinder:transact进而调用到onTransact方法,该方法由子类覆盖,代码如下:


status_t AudioFlinger:onTransact(

uint32_t code, const Parcel&data, Parcel*reply, uint32_t flags)

{

return BnAudioFlinger:onTransact(code, data, reply, flags);

}


AudioFlinger在onTransact方法中复用了其父类BnAudioFlinger的onTransact方法,代码如下:


status_t BnAudioFlinger:onTransact(

uint32_t code, const Parcel&data, Parcel*reply, uint32_t flags)

{

switch(code){

……

case SET_MASTER_VOLUME:{

CHECK_INTERFACE(IAudioFlinger, data, reply);

reply->writeInt32(setMasterVolume(data.readFloat()));

return NO_ERROR;

}break;

……

default:

return BBinder:onTransact(code, data, reply, flags);


BnAudioFlinger:onTransact中定义了所有请求码对应的Server端处理函数。因此Client只需要发送请求码便可以通过Binder驱动转发到Server端,Server端根据请求码在onTransact方法中匹配处理函数,最终实现远程方法调用。