camera binder 机制实现原理 与 调试

天王盖地虎626 2021-03-31 09:00:55 阅读数:524

本文一共[544]字,预计阅读时长:1分钟~
Android c++ mremote
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。
分享:
 
 
版权声明:本文为[天王盖地虎626]所创,转载请带上原文链接,感谢。 https://my.oschina.net/u/920274/blog/5003818