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

Android IPC 通讯机制源码分析【下】

2011-10-09 09:54 525 查看
client获取Service的远程IBinder接口

以CameraService为例(camera.cpp):

const sp<ICameraService>& Camera::getCameraService()

{

Mutex::Autolock _l(mLock);

if (mCameraService.get() == 0) {

sp<IServiceManager> sm = defaultServiceManager();

sp<IBinder> binder;

do {

binder = sm->getService(String16("media.camera"));

if (binder != 0)

break;

LOGW("CameraService not published, waiting...");

usleep(500000); // 0.5 s

} while(true);

if (mDeathNotifier == NULL) {

mDeathNotifier = new DeathNotifier();

}

binder->linkToDeath(mDeathNotifier);

mCameraService = interface_cast<ICameraService>(binder);

}

LOGE_IF(mCameraService==0, "no CameraService!?");

return mCameraService;

}

由前面的分析可知sm是BpCameraService对象:

virtual sp<IBinder> getService(const String16& name) const

{

unsigned n;

for (n = 0; n < 5; n++){

sp<IBinder> svc = checkService(name);

if (svc != NULL) return svc;

LOGI("Waiting for sevice %s...\n", String8(name).string());

sleep(1);

}

return NULL;

}

virtual sp<IBinder> checkService( const String16& name) const

{

Parcel data, reply;

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

data.writeString16(name);

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

return reply.readStrongBinder();

}

这里的remote就是我们前面得到BpBinder对象。所以checkService将调用BpBinder中的transact函数:

status_t BpBinder::transact(

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

{

// Once a binder has died, it will never come back to life.

if (mAlive) {

status_t status = IPCThreadState::self()->transact(

mHandle, code, data, reply, flags);

if (status == DEAD_OBJECT) mAlive = 0;

return status;

}

return DEAD_OBJECT;

}

mHandle为0,BpBinder继续往下调用IPCThreadState:transact函数将数据发给与mHandle相关联的Service Manager Process。

status_t IPCThreadState::transact(int32_t handle,

uint32_t code, const Parcel& data,

Parcel* reply, uint32_t flags)

{

............................................................

if (err == NO_ERROR) {

LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),

(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");

err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);

}

if (err != NO_ERROR) {

if (reply) reply->setError(err);

return (mLastError = err);

}

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

if (reply) {

err = waitForResponse(reply);

} else {

Parcel fakeReply;

err = waitForResponse(&fakeReply);

}

..............................

return err;

}

通过writeTransactionData构造要发送的数据

status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,

int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)

{

binder_transaction_data tr;

tr.target.handle = handle; //这个handle将传递到service_manager

tr.code = code;

tr.flags = bindrFlags;

。。。。。。。。。。。。。。

}

waitForResponse将调用talkWithDriver与对Binder kernel进行读写操作。当Binder kernel接收到数据后,service_mananger线程的ThreadPool就会启动,service_manager查找到 CameraService服务后调用binder_send_reply,将返回的数据写入Binder kernel,Binder kernel。

status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)

{

int32_t cmd;

int32_t err;

while (1) {

if ((err=talkWithDriver()) < NO_ERROR) break;

..............................................

}

status_t IPCThreadState::talkWithDriver(bool doReceive)

{

............................................

#if defined(HAVE_ANDROID_OS)

if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)

err = NO_ERROR;

else

err = -errno;

#else

err = INVALID_OPERATION;

#endif

...................................................

}

通过上面的ioctl系统函数中BINDER_WRITE_READ对binder kernel进行读写。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: