您的位置:首页 > 移动开发 > Android开发

Android camera系统开发之IPC (五)

2011-09-05 17:19 429 查看
四 连接建立后的client和Service的通信过程:这里以CameraService::connect()为例进行说明。

@Camera.cpp

sp<Camera> Camera::connect()

{

LOGV("connect");

sp<Camera> c = new Camera();

const sp<ICameraService>& cs = getCameraService();

//上面这条语句参见Android camera系统开发之IPC (四)说明

if (cs != 0) {

c->mCamera = cs->connect(c);//这条语句将进入BpCameraService::connect()

}

return c;

}

@ICameraService.cpp

virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient)

{

Parcel data, reply;

data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());

data.writeStrongBinder(cameraClient->asBinder());

remote()->transact(BnCameraService::CONNECT, data, &reply);

return interface_cast<ICamera>(reply.readStrongBinder());

}

这里remote是我们的CameraService映射的一个BpBinder对象

virtual sp<ICamera> ICameraService:: connect()会调用到BpBinder::transact()

à IPCThreadState::self()->transact(),并写入binder driver中,

Binder driver最终会唤醒media_server进程中的在IPCThreadState::joinThreadPool()中运行的读线程。

void IPCThreadState::joinThreadPool(bool isMain)

{ …

do {



result = talkWithDriver();

size_t IN = mIn.dataAvail();

if (IN < sizeof(int32_t)) continue;

cmd = mIn.readInt32();

result = executeCommand(cmd);

} while (result != -ECONNREFUSED && result != -EBADF);



}

这一次,talkWithDriver()函数会返回BpCameraService:: connect ()生成的数据包,并调用executeCommand()函数执行命令。在本例中,命令为BR_TRANSACTION。

status_t IPCThreadState::executeCommand(int32_t cmd)

{

......

switch(cmd){

......

case BR_TRANSACTION:

{

binder_transaction_data tr;

......

Parcel reply;

......

if (tr.target.ptr) {

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

const status_t error = b->transact(tr.code, buffer, &reply, 0);

}



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

LOG_ONEWAY("Sending reply to %d!", mCallingPid);

sendReply(reply, 0);

}

...

}

break;

......

} // end of switch

...

}

if(tr.target.ptr)为真的分支部分是最重要的。它从binder内核驱动中获取到一个地址并转换为BBinder类型的指针(该指针在执行IServiceManager::addService()函数时放入binder内核驱动)。记住,CameraService继承自BBinder。该指针实际上与CameraService实例是同一个指针。于是接下来的transact()函数将调用到CaermaService::onTransact(),再调用到BnCameraService::onTransact()虚函数。

@CameraService.cpp

status_t CameraService::onTransact(

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

{

switch (code) {

case BnCameraService::CONNECT:

IPCThreadState* ipc = IPCThreadState::self();

const int pid = ipc->getCallingPid();

const int self_pid = getpid();

if (pid != self_pid) {

// we're called from a different process, do the real check

if (!checkCallingPermission(

String16("android.permission.CAMERA")))

{

const int uid = ipc->getCallingUid();

LOGE("Permission Denial: "

"can't use the camera pid=%d, uid=%d", pid, uid);

return PERMISSION_DENIED;

}

}

break;

}

status_t err = BnCameraService::onTransact(code, data, reply, flags);

return err;

}

@ICameraService.cpp

status_t BnCameraService::onTransact(

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

{

switch(code) {

case CONNECT: {

CHECK_INTERFACE(ICameraService, data, reply);

sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());

sp<ICamera> camera = connect(cameraClient); //真正的处理函数

reply->writeStrongBinder(camera->asBinder());

return NO_ERROR;

} break;

default:

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

}

}

至此完成了一次从client到service的函数调用过程。

注意在这个函数中,系统将调用CameraService::connect()

通过以上4篇文章,基本上把Camera 系统开发下的IPC有个整体认识,对于认识其它应用的IPC也是一个很好的参考。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: