围棋少年二:从Camera来看Binder IPC机制

来源:百度文库 编辑:中财网 时间:2024/04/29 16:54:33
Camera App通过framework中Camera java类进入jni部分,在android_hardware_Camera.cpp中:android_hardware_Camera_native_setup(){  sp camera = Camera::connect();}
这里调用Camera类的connect函数,返回一个Camera强指针。后续如startPreview, takePicture的动作均为对这个Camera对象的操作。

Camera::connect(),Camera.cpp{  sp c = new Camera();  const sp& cs = getCameraService();  c->mCamera = cs->connect(c);  return c;}
这里首先new一个Camera对象。getCameraService()会返回跨进程的ICameraService,然后在其上调用connect:
Camera::getCameraService(){  sp sm = defaultServiceManager();  sp binder;  binder = sm->getService(String16("media.camera"));  mCameraService = interface_cast(binder);  return mCameraService;}首先取得跨进程的IServiceManager,然后取得camera service(这个service在mediaserver启动时注册)。最重要的,把这个返回的binder对象经过interface_cast转换,变成了BpCameraService类型:IInterface.h:templateinline sp interface_cast(const sp& obj){    return INTERFACE::asInterface(obj);}
    sp I##INTERFACE::asInterface(const sp& obj)  \    {                                                                   \        sp intr;                                          \        if (obj != NULL) {                                              \            intr = static_cast(                          \                obj->queryLocalInterface(                               \                        I##INTERFACE::descriptor).get());               \            if (intr == NULL) {                                         \                intr = new Bp##INTERFACE(obj);                          \            }                                                           \        }                                                               \        return intr;                                                    \    }                                                                   \
Camera::connect()中cs->connect(c)会调用到BpCameraService::connect(const sp& cameraClient)函数:
virtual sp connect(const sp& cameraClient){    Parcel data, reply;    data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());    data.writeStrongBinder(cameraClient->asBinder());    remote()->transact(BnCameraService::CONNECT, data, &reply);    return interface_cast(reply.readStrongBinder());}这里会向remote((1))发起一个transaction,然后在reply中读取binder,经过interface_cast转换为BpCamera类型。

类CameraService继承了BnCameraService,而上面的remote实际为CameraService类型,因此实际上由CameraService::onTransact来处理CONNECT事务。CameraService::onTransact(){  BnCameraService::onTransact(code, data, reply, flags);}调用了父类BnCameraService的函数:BnCameraService::onTransact(){  sp cameraClient = interface_cast(data.readStrongBinder());  sp camera = connect(cameraClient);  reply->writeStrongBinder(camera->asBinder());}connect在BnCameraService中没有实现,调用子类的connect:sp CameraService::connect(const sp& cameraClient){  client = new Client(this, cameraClient, callingPid);  return client;}
这里传入了client的ICameraClient类型的cameraClient(保存在client的mCameraClient成员中),并向client返回了CameraService::Client对象,这样可以实现client和server双向调用。对于从CameraService到Camera的帧数据:CameraService::Client::dataCallback(){  sp c = client->mCameraClient;  c->dataCallbackTimestamp(timestamp, msgType, dataPtr);}这里调用Camera::dataCallbackTimestamp往Camera侧发送数据。ICameraClient继承关系:class Camera : public BnCameraClientCamera继承BnCameraClient,表示Camera作为native端。另外,从Camera到CameraService端的调用是通过Camera类的sp mCamera成员实现的,具体调用下面会描述,相关类的继承关系为:class Client : public BnCameraClient继承BnCamera,表示Client作为Native端。
在Camera.cpp中,后续的startPreview等函数会在返回的BpCamera上操作。这样, startPreview就进入了BpCamera::startPreview:
status_t startPreview(){    Parcel data, reply;    data.writeInterfaceToken(ICamera::getInterfaceDescriptor());    remote()->transact(START_PREVIEW, data, &reply);    return reply.readInt32();}这里会向远端发起一个START_PREVIEW的transaction。这个transaction会交给BnCamera处理(因为子类CameraService::Client没有实现这个函数):
BnCamera::onTransact(){  case START_PREVIEW: {      LOGV("START_PREVIEW");      CHECK_INTERFACE(ICamera, data, reply);      reply->writeInt32(startPreview());      return NO_ERROR;  } break;}startPreview()进入了子类CameraService::Client的startPreview():
status_t CameraService::Client::startPreview(){    return startCameraMode(CAMERA_PREVIEW_MODE);}
总结: - Camera获取CameraService - 调用CameraService的connect,并传入自身的Camera对象 - CameraService::onTransact处理CONNECT请求 - CameraService将传入的Camera对象保存在Client类的mCameraClient成员中,并向Camera返回Client类对象 - 若有数据从CameraService到Camera,CameraService由mCameraClient呼叫Camera类的data callback - 若有命令请求从Camera到CameraService, Camera调用CameraService::Client的相关函数
(1) remote()是什么?remote()返回的是BpRefBase类的mRemote成员。在Binder.cpp中BpRefBase的构造函数中,mRemote被初始化为IBinder指针:BpRefBase::BpRefBase(const sp& o)    : mRemote(o.get()), mRefs(NULL), mState(0){}
在Camera.cpp中获取ICameraService时,Camera::getCameraService(){  sp binder;  binder = sm->getService(String16("media.camera"));  mCameraService = interface_cast(binder);}
getService返回的binder被传入。interface_cast会调用ICameraService::asInterface(const sp& obj):    sp I##INTERFACE::asInterface(const sp& obj)  \    {                                                                   \        sp intr;                                          \        if (obj != NULL) {                                              \            intr = static_cast(                          \                obj->queryLocalInterface(                               \                        I##INTERFACE::descriptor).get());               \            if (intr == NULL) {                                         \                intr = new Bp##INTERFACE(obj);                          \            }                                                           \        }                                                               \        return intr;                                                    \    }这里会触发调用new BpCameraService(obj), obj为binder类型。
    BpCameraService(const sp& impl)        : BpInterface(impl)    {    }
进入BpInterface的构造函数。
templateinline BpInterface::BpInterface(const sp& remote)    : BpRefBase(remote){}
调用BpRefBase的构造函数。因此,remote()实际上就是getService返回的binder