Android IPC 通讯机制源码分析【下】
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进行读写。