Android camera系统开发之IPC (四)

来源:互联网 发布:网络安防公司 编辑:程序博客网 时间:2024/06/05 21:10

获取一个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;
}
由前面的分析可知smBpServiceManager对象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 driverservice_manager进程中处理。代码参见Android camera系统开发之IPC (三)svcmgr_handler()函数的SVC_MGR_CHECK_SERVICE分支。

此时service_manager会返回一个之前由CameraService映射的handleBpServiceManager::checkService()会由remote()->transact()调用返回。与IServiceManager的分析类似,它会通过readStrongBinder()创建一个新的BpBinder实例,这个BpBinder指向service_manager返回的handleinterface_cast<ICameraService>(binder) 最终返回一个BpCameraService实例。

 

小结:

 

与获取IServieManager类似,但是这一次是通过service_manager去获取一个handle。之前获取IServiceManagerhandle被设置为 0

我们还记得注册的时候,在调用trasact前,会进行WriteStrongBinder()处理,在获取的时候,会进行readStrongBinder()处理。前者告诉Binder Driver,需要通过CameraService对象转换为相应的handle,后者通过那个生成的handle来生成BpBinder对象。这样就实现了从Service到代理的一次转换。

Client就可以通过这个代理句柄来调用Service的服务函数。