小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

從Camera來看Binder IPC機(jī)制

 mandrave 2011-11-26
Camera App通過framework中Camera java類進(jìn)入jni部分,在android_hardware_Camera.cpp中:
android_hardware_Camera_native_setup()
{
  sp<Camera> camera = Camera::connect();
}

這里調(diào)用Camera類的connect函數(shù),返回一個(gè)Camera強(qiáng)指針。后續(xù)如startPreview, takePicture的動作均為對這個(gè)Camera對象的操作。


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

這里首先new一個(gè)Camera對象。getCameraService()會返回跨進(jìn)程的ICameraService,然后在其上調(diào)用connect:

Camera::getCameraService()
{
  sp<IServiceManager> sm = defaultServiceManager();
  sp<IBinder> binder;
  binder = sm->getService(String16("media.camera"));
  mCameraService = interface_cast<ICameraService>(binder);
  return mCameraService;
}
首先取得跨進(jìn)程的IServiceManager,然后取得camera service(這個(gè)service在mediaserver啟動時(shí)注冊)。最重要的,把這個(gè)返回的binder對象經(jīng)過interface_cast<ICameraService>轉(zhuǎn)換,變成了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)會調(diào)用到BpCameraService::connect(const sp<ICameraClient>& cameraClient)函數(shù):

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))發(fā)起一個(gè)transaction,然后在reply中讀取binder,經(jīng)過interface_cast<ICamera>轉(zhuǎn)換為BpCamera類型。


類CameraService繼承了BnCameraService,而上面的remote實(shí)際為CameraService類型,因此實(shí)際上由CameraService::onTransact來處理CONNECT事務(wù)。
CameraService::onTransact()
{
  BnCameraService::onTransact(code, data, reply, flags);
}
調(diào)用了父類BnCameraService的函數(shù):
BnCameraService::onTransact()
{
  sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
  sp<ICamera> camera = connect(cameraClient);
  reply->writeStrongBinder(camera->asBinder());
}
connect在BnCameraService中沒有實(shí)現(xiàn),調(diào)用子類的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對象,這樣可以實(shí)現(xiàn)client和server雙向調(diào)用。對于從CameraService到Camera的幀數(shù)據(jù):
CameraService::Client::dataCallback()
{
  sp<ICameraClient> c = client->mCameraClient;
  c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
}
這里調(diào)用Camera::dataCallbackTimestamp往Camera側(cè)發(fā)送數(shù)據(jù)。ICameraClient繼承關(guān)系:
class Camera : public BnCameraClient
Camera繼承BnCameraClient,表示Camera作為native端。另外,從Camera到CameraService端的調(diào)用是通過Camera類的sp<ICamera> mCamera成員實(shí)現(xiàn)的,具體調(diào)用下面會描述,相關(guān)類的繼承關(guān)系為:
class Client : public BnCamera
Client繼承BnCamera,表示Client作為Native端。

在Camera.cpp中,后續(xù)的startPreview等函數(shù)會在返回的BpCamera上操作。這樣, startPreview就進(jìn)入了BpCamera::startPreview:

status_t startPreview()
{
    Parcel data, reply;
    data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
    remote()->transact(START_PREVIEW, data, &reply);
    return reply.readInt32();
}
這里會向遠(yuǎn)端發(fā)起一個(gè)START_PREVIEW的transaction。這個(gè)transaction會交給BnCamera處理(因?yàn)樽宇怌ameraService::Client沒有實(shí)現(xiàn)這個(gè)函數(shù)):

BnCamera::onTransact()
{
  case START_PREVIEW: {
      LOGV("START_PREVIEW");
      CHECK_INTERFACE(ICamera, data, reply);
      reply->writeInt32(startPreview());
      return NO_ERROR;
  } break;
}
startPreview()進(jìn)入了子類CameraService::Client的startPreview():

status_t CameraService::Client::startPreview()
{
    return startCameraMode(CAMERA_PREVIEW_MODE);
}

總結(jié):
 - Camera獲取CameraService
 - 調(diào)用CameraService的connect,并傳入自身的Camera對象
 - CameraService::onTransact處理CONNECT請求
 - CameraService將傳入的Camera對象保存在Client類的mCameraClient成員中,并向Camera返回Client類對象
 - 若有數(shù)據(jù)從CameraService到Camera,CameraService由mCameraClient呼叫Camera類的data callback
 - 若有命令請求從Camera到CameraService, Camera調(diào)用CameraService::Client的相關(guān)函數(shù)

(1) remote()是什么?
remote()返回的是BpRefBase類的mRemote成員。在Binder.cpp中BpRefBase的構(gòu)造函數(shù)中,mRemote被初始化為IBinder指針:
BpRefBase::BpRefBase(const sp<IBinder>& o)
    : mRemote(o.get()), mRefs(NULL), mState(0)
{
}

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

getService返回的binder被傳入。interface_cast<ICameraService>會調(diào)用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;                                                    \
    }
這里會觸發(fā)調(diào)用new BpCameraService(obj), obj為binder類型。

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

進(jìn)入BpInterface的構(gòu)造函數(shù)。

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

調(diào)用BpRefBase的構(gòu)造函數(shù)。因此,remote()實(shí)際上就是getService返回的binder

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多