camera binder 機制實現原理 與 調試

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(STAR​​T_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。
分享:
 
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章