三 获取一个CameraService服务代理
获取服务接口的唯一方法就是通过IServiceManager::getService()函数。假设Camera preview需要获取一个ICameraService。
@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;
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是BpServiceManager对象,getService()在
@IServiceManager.cpp
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;
}
@IServiceManager.cpp
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();
}
与Android camera系统开发之IPC (三)分析类似,该调用最终会通过binder driver在service_manager进程中处理。代码参见Android camera系统开发之IPC (三)svcmgr_handler()函数的SVC_MGR_CHECK_SERVICE分支。
此时service_manager会返回一个之前由CameraService映射的handle。BpServiceManager::checkService()会由remote()->transact()调用返回。与IServiceManager的分析类似,它会通过readStrongBinder()创建一个新的BpBinder实例,这个BpBinder指向service_manager返回的handle。interface_cast<ICameraService>(binder) 最终返回一个BpCameraService实例。
小结:
与获取IServieManager类似,但是这一次是通过service_manager去获取一个handle。之前获取IServiceManager时handle被设置为 0。
我们还记得注册的时候,在调用trasact前,会进行WriteStrongBinder()处理,在获取的时候,会进行readStrongBinder()处理。前者告诉Binder Driver,需要通过CameraService对象转换为相应的handle,后者通过那个生成的handle来生成BpBinder对象。这样就实现了从Service到代理的一次转换。
Client就可以通过这个代理句柄来调用Service的服务函数。