分享

从Camera来看Binder IPC机制

 mandrave 2011-11-26
Camera App通过framework中Camera java类进入jni部分,在android_hardware_Camera.cpp中:
android_hardware_Camera_native_setup()
{
  sp<Camera> camera = Camera::connect();
}

这里调用Camera类的connect函数,返回一个Camera强指针。后续如startPreview, takePicture的动作均为对这个Camera对象的操作。


Camera::connect(),Camera.cpp
{
  sp<Camera> c = new Camera();
  const sp<ICameraService>& cs = getCameraService();
  c->mCamera = cs->connect(c);
  return c;
}

这里首先new一个Camera对象。getCameraService()会返回跨进程的ICameraService,然后在其上调用connect:

Camera::getCameraService()
{
  sp<IServiceManager> sm = defaultServiceManager();
  sp<IBinder> binder;
  binder = sm->getService(String16("media.camera"));
  mCameraService = interface_cast<ICameraService>(binder);
  return mCameraService;
}
首先取得跨进程的IServiceManager,然后取得camera service(这个service在mediaserver启动时注册)。最重要的,把这个返回的binder对象经过interface_cast<ICameraService>转换,变成了BpCameraService类型:
IInterface.h:
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
    return INTERFACE::asInterface(obj);
}

    sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)  \
    {                                                                   \
        sp<I##INTERFACE> intr;                                          \
        if (obj != NULL) {                                              \
            intr = static_cast<I##INTERFACE*>(                          \
                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<ICameraClient>& cameraClient)函数:

virtual sp<ICamera> connect(const sp<ICameraClient>& cameraClient)
{
    Parcel data, reply;
    data.writeInterfaceToken(ICameraService::getInterfaceDescriptor());
    data.writeStrongBinder(cameraClient->asBinder());
    remote()->transact(BnCameraService::CONNECT, data, &reply);
    return interface_cast<ICamera>(reply.readStrongBinder());
}
这里会向remote((1))发起一个transaction,然后在reply中读取binder,经过interface_cast<ICamera>转换为BpCamera类型。


类CameraService继承了BnCameraService,而上面的remote实际为CameraService类型,因此实际上由CameraService::onTransact来处理CONNECT事务。
CameraService::onTransact()
{
  BnCameraService::onTransact(code, data, reply, flags);
}
调用了父类BnCameraService的函数:
BnCameraService::onTransact()
{
  sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
  sp<ICamera> camera = connect(cameraClient);
  reply->writeStrongBinder(camera->asBinder());
}
connect在BnCameraService中没有实现,调用子类的connect:
sp<ICamera> CameraService::connect(const sp<ICameraClient>& 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<ICameraClient> c = client->mCameraClient;
  c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
}
这里调用Camera::dataCallbackTimestamp往Camera侧发送数据。ICameraClient继承关系:
class Camera : public BnCameraClient
Camera继承BnCameraClient,表示Camera作为native端。另外,从Camera到CameraService端的调用是通过Camera类的sp<ICamera> mCamera成员实现的,具体调用下面会描述,相关类的继承关系为:
class Client : public BnCamera
Client继承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<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)
{
}

在Camera.cpp中获取ICameraService时,
Camera::getCameraService()
{
  sp<IBinder> binder;
  binder = sm->getService(String16("media.camera"));
  mCameraService = interface_cast<ICameraService>(binder);
}

getService返回的binder被传入。interface_cast<ICameraService>会调用ICameraService::asInterface(const sp<IBinder>& obj):
    sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj)  \
    {                                                                   \
        sp<I##INTERFACE> intr;                                          \
        if (obj != NULL) {                                              \
            intr = static_cast<I##INTERFACE*>(                          \
                obj->queryLocalInterface(                               \
                        I##INTERFACE::descriptor).get());               \
            if (intr == NULL) {                                         \
                intr = new Bp##INTERFACE(obj);                          \
            }                                                           \
        }                                                               \
        return intr;                                                    \
    }
这里会触发调用new BpCameraService(obj), obj为binder类型。

    BpCameraService(const sp<IBinder>& impl)
        : BpInterface<ICameraService>(impl)
    {
    }

进入BpInterface的构造函数。

template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
    : BpRefBase(remote)
{
}

调用BpRefBase的构造函数。因此,remote()实际上就是getService返回的binder

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多