Implementation principle and debugging of camera binder mechanism

King of heaven and earth tiger 626 2021-04-02 01:25:13 阅读数:699

本文一共[544]字,预计阅读时长:1分钟~
implementation principle debugging camera binder
Camera App adopt framework in Camera java Class entry jni part , stay android_hardware_Camera.cpp in :
android_hardware_Camera_native_setup()
{
sp<Camera> camera = Camera::connect();
}
 
This call Camera Class connect function , Return to one Camera Strong indicators . Follow up such as startPreview, takePicture All the actions are for this Camera Operation of objects .



 
Camera::connect(),Camera.cpp
{
sp<Camera> c = new Camera();
const sp<ICameraService>& cs = getCameraService();
c->mCamera = cs->connect(c);
return c;
}
 
Here, first of all, new One Camera thing .getCameraService() Will return cross process ICameraService, Then call... On it connect:
 
Camera::getCameraService()
{
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
binder = sm->getService(String16("media.camera"));
mCameraService = interface_cast<ICameraService>(binder);
return mCameraService;
}
First, achieve cross process IServiceManager, And then get camera service( This service stay mediaserver Register at startup ). The most important , Take this back to binder The object passes through interface_cast<ICameraService> transformation , Turned into BpCameraService class ​​ type :
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() in cs->connect(c) Will be called to BpCameraService::connect(const sp<ICameraClient>& cameraClient) function :
 
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());
}
It's going to remote((1)) To launch a transaction, And then in reply Read from binder, after interface_cast<ICamera> Convert to BpCamera type .



 
class CameraService Inherited BnCameraService, While the above remote For the actual CameraService type , So it's actually caused by CameraService::onTransact To deal with it CONNECT Business .
CameraService::onTransact()
{
BnCameraService::onTransact(code, data, reply, flags);
}
Called parent class BnCameraService Function of :
BnCameraService::onTransact()
{
sp<ICameraClient> cameraClient = interface_cast<ICameraClient>(data.readStrongBinder());
sp<ICamera> camera = connect(cameraClient);
reply->writeStrongBinder(camera->asBinder());
}
connect stay BnCameraService There is no implementation in , Calling subclass connect:
sp<ICamera> CameraService::connect(const sp<ICameraClient>& cameraClient)
{
client = new Client(this, cameraClient, callingPid);
return client;
}
 
Here comes client Of ICameraClient Type of cameraClient( Save in client Of mCameraClient Among members ), And to client Back to CameraService::Client thing , This can be achieved client and server Two way call . From CameraService To Camera Frame data of :
CameraService::Client::dataCallback()
{
sp<ICameraClient> c = client->mCameraClient;
c->dataCallbackTimestamp(timestamp, msgType, dataPtr);
}
This call Camera::dataCallbackTimestamp Go to Camera We're sending information from the other side .ICameraClient Inheritance relationships :
class Camera : public BnCameraClient
Camera Inherit BnCameraClient, Express Camera As native End . in addition , from Camera To CameraService The end of the call is through Camera Class sp<ICamera> mCamera Members implement , The specific call will be described below , The inheritance relationship of related classes is :
class Client : public BnCamera
Client Inherit BnCamera, Express Client As Native End .
 
stay Camera.cpp in , Follow up startPreview And other functions will return BpCamera On the operation . such , startPreview It's in BpCamera::startPreview:
 
status_t startPreview()
{
Parcel data, reply;
data.writeInterfaceToken(ICamera::getInterfaceDescriptor());
remote()->transact(STAR​​T_PREVIEW, data, &reply);
return reply.readInt32();
}
This is going to launch a remote START_PREVIEW Of transaction. This transaction I'll give it to you BnCamera Handle ( Because subclasses CameraService::Client This function is not implemented ):
 
BnCamera::onTransact()
{
case START_PREVIEW: {
LOGV("START_PREVIEW");
CHECK_INTERFACE(ICamera, data, reply);
reply->writeInt32(startPreview());
return NO_ERROR;
} break;
}
startPreview() Into subclasses CameraService::Client Of startPreview():
 
status_t CameraService::Client::startPreview()
{
return startCameraMode(CAMERA_PREVIEW_MODE);
}
 
summary :
- Camera obtain CameraService
- call CameraService Of connect, And introduce your own Camera thing
- CameraService::onTransact Handle CONNECT request
- CameraService Will the incoming Camera The object is stored in Client Class mCameraClient Among members , And to Camera return Client Class object
- If you have information from CameraService To Camera,CameraService from mCameraClient call Camera Class data callback
- If there is an order request from Camera To CameraService, Camera call CameraService::Client The correlation function of
 
(1) remote() What is it? ?
remote() The return is BpRefBase Class mRemote member . stay Binder.cpp in BpRefBase In the constructor of ,mRemote Is initialized to IBinder indicators :
BpRefBase::BpRefBase(const sp<IBinder>& o)
: mRemote(o.get()), mRefs(NULL), mState(0)
{
}
 
stay Camera.cpp In order to get ICameraService when ,
Camera::getCameraService()
{
sp<IBinder> binder;
binder = sm->getService(String16("media.camera"));
mCameraService = interface_cast<ICameraService>(binder);
}
 
getService Back to binder Incoming .interface_cast<ICameraService> Would call 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; \
}
This triggers the call new BpCameraService(obj), obj by binder type .
 
BpCameraService(const sp<IBinder>& impl)
: BpInterface<ICameraService>(impl)
{
}
 
Get into BpInterface Constructor for .
 
template<typename INTERFACE>
inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
: BpRefBase(remote)
{
}
 
call BpRefBase Constructor for . therefore ,remote() It's actually getService Back to binder.
Share :
 
 
版权声明:本文为[King of heaven and earth tiger 626]所创,转载请带上原文链接,感谢。 https://netfreeman.com/2021/03/20210331085955526t.html