Android框架之Camera(3)透过Camera服务看Binder进程间通信
来源:互联网 发布:杨千嬅歌曲评价知乎 编辑:程序博客网 时间:2024/06/06 11:37
Android 6.0Android Binder用来管理Android进程,用途有两个:
1、IPC(Inter Process Communication)工具,用于进程间通信。
2、RPC(Remote Procedure Call)远程函数调用,使得当前进程调用另一个进程的函数就像调用自身的函数一样。当然,她也属于IPC范畴。
关于Binder的历史、驱动实现、在Android中的框架实现等内容,参考结尾列出的极好的资料;这里通过Camera服务的实现、使用,熟悉一个本地服务(C服务)的创建。
一个Binder服务大体来说由3个角色构成:
1、服务接口
2、服务实现
3、服务代理
以Camera服务为例,她们之间关系如下图:
Camera服务接口
服务接口声明某个服务需要实现的功能函数,这里只负责声明,然后在服务和代理中实现。比如上图Camera服务的getCameraInfo()函数。
static sp<IBinder> asBinder(const IInterface*);接口中的asBinder()函数将服务接口类型转换为IBinder类型,作用是在进行Binder IPC通信时,IBinder对象需要保存到RPC数据中传递给Binder驱动。
asInterface()函数由宏DECLARE_META_INTERFACE/IMPLEMENT_META_INTERFACE生成,用于将IBinder转化为服务接口:
android::sp<ICameraService> ICameraService::asInterface(const android::sp<android::IBinder>& obj){ android::sp<ICameraService> intr; if (obj != NULL) { intr = static_cast<ICameraService*>( obj->queryLocalInterface( ICameraService::descriptor).get()); if (intr == NULL) { intr = new BpCameraService(obj); } } return intr;}之前在“Android框架之Camera(1)Camera服务的前世今生”Camera服务的C/C++示例中就是通过asInterface()函数获取服务。
Camera服务
服务函数在CameraService类中实现。
CameraService继承BinderService是为了向系统中注册自己(服务),详见:“Android框架之Camera(1)Camera服务的前世今生”。
CameraService继承BnCameraService为了实现Camera服务的功能。
Camera服务代理
服务代理用来传递Binder RPC需要的RPC代码/数据,这个需求在具体的服务代理类中实现。
下面通过getCameraInfo()函数的调用过程实地体验之。
1、接口ICameraService定义getCameraInfo()函数:
ICameraService.h (frameworks\av\include\camera)class ICameraService : public IInterface {public:// 纯虚函数virtual status_t getCameraInfo(int cameraId, /*out*/ struct CameraInfo* cameraInfo) = 0;};
2、Camera的使用方调用getCameraInfo()函数:
// 1、获取服务:private ICameraService mCameraService;IBinder cameraServiceBinder = ServiceManager.getService("media.camera");mCameraService = ICameraService.Stub.asInterface(cameraServiceBinder);// 2、调用getCameraInfo()函数:CameraInfo info = new CameraInfo();cameraService.getCameraInfo(id, /*out*/info);
3、服务代理BpCameraService复写的getCameraInfo()函数得到调用:
ICameraService.cpp (frameworks\av\camera)class BpCameraService: public BpInterface<ICameraService>{public: BpCameraService(const sp<IBinder>& impl) : BpInterface<ICameraService>(impl) { } virtual status_t getCameraInfo(int cameraId, struct CameraInfo* cameraInfo) { Parcel data, reply; data.writeInterfaceToken(ICameraService::getInterfaceDescriptor()); data.writeInt32(cameraId); remote()->transact(BnCameraService::GET_CAMERA_INFO, data, &reply); if (readExceptionCode(reply)) return -EPROTO; status_t result = reply.readInt32(); if (reply.readInt32() != 0) { cameraInfo->facing = reply.readInt32(); cameraInfo->orientation = reply.readInt32(); } return result; }}还记得,ICameraService::asInterface(binder)操作new出来的就是BpCameraService对象。
BpCameraService继承BpInterface,用来通过remote()获取IBinder对象,然后以函数功能编号(GET_CAMERA_INFO)、数据作参数调用transact()函数。Binder通信的结果、返回数据写入reply变量。
BpCameraService继承ICameraService接口,用来把远程调用请求构成RPC数据,发起远程调用。
4、BnCameraService处理第3不的RPC请求:
ICameraService.cpp (frameworks\av\camera)status_t BnCameraService::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags){ switch(code) { case GET_CAMERA_INFO: { CHECK_INTERFACE(ICameraService, data, reply); CameraInfo cameraInfo = CameraInfo(); memset(&cameraInfo, 0, sizeof(cameraInfo)); status_t result = getCameraInfo(data.readInt32(), &cameraInfo); reply->writeNoException(); reply->writeInt32(result); // Fake a parcelable object here reply->writeInt32(1); // means the parcelable is included reply->writeInt32(cameraInfo.facing); reply->writeInt32(cameraInfo.orientation); return NO_ERROR; } break; default: return BBinder::onTransact(code, data, reply, flags); }}
CHECK_INTERFACE:确定请求的正确性,方法就是通过判断入参(ICameraService::getInterfaceDescriptor())是否为“android.hardware.ICameraService”来确定。
第9行,调用Camera服务实现的getCameraInfo()方法。BnCameraService的RPC处理流程:
5、Camera服务实现getCameraInfo()方法:
CameraService.h (frameworks\av\services\camera\libcameraservice)class CameraService : public BinderService<CameraService>, public BnCameraService,{ friend class BinderService<CameraService>;public:virtual status_t getCameraInfo(int cameraId, struct CameraInfo* cameraInfo);}CameraService.cpp (frameworks\av\services\camera\libcameraservice)status_t CameraService::getCameraInfo(int cameraId, struct CameraInfo* cameraInfo) { struct camera_info info;// HAL的getCameraInfo()函数得到调用 status_t rc = mModule->getCameraInfo(cameraId, &info); cameraInfo->facing = info.facing; cameraInfo->orientation = info.orientation; return rc;}CameraService继承BinderService是为了项Service Manager注册自己。
CameraService继承BnCameraService:
status_t CameraService::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {return BnCameraService::onTransact(code, data, reply, flags);}
这样,整个IPC就完成了。以自己实现的xxx服务为例,总结下流程:
Bpxxx::func()->xxx::onTransact()->Bnxxx::onTransact()->xxx::func()->返回到Bpxxx::func()
----------remote()->transact()执行------------------------------->transact()执行完
“纸上读来终觉浅,绝知此事要躬行”,下面实现自己的Binder本地服务:OurService,文件列表:
执行测试应用,log:
测试例程源码:Android Binder本地服务例程
参考资料:
1、Android深入浅出之Binder机制
2、Android框架揭秘
- Android框架之Camera(3)透过Camera服务看Binder进程间通信
- Android框架之Camera(1)Camera服务的前世今生
- Android之 Camera 框架
- Camera Service Binder框架
- android camera binder
- Android 之 Binder与进程间通信
- Android 之 Binder与进程间通信
- Android 之 Binder与进程间通信
- Android 之 Binder与进程间通信
- Android 之 Binder与进程间通信
- Android 之 Binder与进程间通信
- Android 之 Binder与进程间通信
- Android 之 Binder与进程间通信
- Android 进程间通信之Binder & AIDL
- Android 之 Binder与进程间通信
- Android Camera子系统之进程/文件View
- Android进程通信Binder(2)-Android系统服务与Binder
- Camera服务之--Client
- 最简单的聊天室界面编程
- GO struct 小结
- Spring(五)spring整合jdbc
- Docker Toolbox 使用小技巧-复制粘贴-批量处理-循环语句-dm别名
- linux 扩展swap分区大小
- Android框架之Camera(3)透过Camera服务看Binder进程间通信
- PHP四种基础排序算法--冒泡,直接插入,快速和选择排序
- (2) JDBC建立连接实例
- Karen and Morning
- centos 下ueditor上传图片502
- servlet基础及过滤器简介
- 我的第一个shell脚本
- Asp.net控件集了解
- 音视频基础