Android 5.0 Camera系统源码分析(2):Camera打开流程

本文深入分析了 Android 5.0 系统中 Camera 打开的完整流程,从 frameworks 层的 Camera.open() 开始,通过 JNI 接口进入 hal 层。在 frameworks 层,详细介绍了 getNumberOfCameras 函数和 Camera 构造函数的工作原理。在 hal 层,讲解了 open 函数、getPlatform 函数以及创建 Cam1Device 的过程,涉及动态库加载、设备初始化等关键步骤。整个流程揭示了 Camera 服务如何与硬件交互并建立连接。
摘要由CSDN通过智能技术生成

1. 前言

本文将分析Android系统源码,从frameworks层到hal层,暂不涉及app层和kernel层。由于某些函数比较复杂,在贴出代码时会适当对其进行简化。本文属于自己对源码的总结,仅仅是贯穿代码流程,不会深入分析各个细节。欢迎联系讨论,QQ:1026656828

2. app层

从apk开始,简单列出各个入口函数

[cpp]  view plain   copy
  1. private void initCamera()  
  2. {  
  3.     Camera mCamera = Camera.open();  
  4.     Camera.Parameters mParameters = mCamera.getParameters();  
  5.     mParameters.setPictureFormat(PixelFormat.JPEG);  
  6.     mCamera.setParameters(mParameters);  
  7.     mCamera.setPreviewDisplay(mSurfaceHolder);  
  8.     mCamera.startPreview();  
  9.     mCamera.takePicture(null, null , mJpegCallback);  
  10. }  

3. frameworks层

这里将重点介绍Camera.open函数,其余函数将在后续博文分析。先来看看Camera.open函数在frameworks层的实现,代码路径为: frameworks/base/core/java/android/hardware/Camera.java

[cpp]  view plain   copy
  1. public static Camera open() {  
  2.     if (!isPermissionGranted()) {  
  3.         return null;  
  4.     }      
  5.     int numberOfCameras = getNumberOfCameras();  
  6.     CameraInfo cameraInfo = new CameraInfo();  
  7.     for (int i = 0; i < numberOfCameras; i++) {  
  8.         getCameraInfo(i, cameraInfo);  
  9.         if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {  
  10.             return new Camera(i);  
  11.         }      
  12.     }      
  13.     return null;  
  14. }      
第5行, 通过getNumberOfCameras函数来获取Camera的个数。从上一篇博文 CameraService的启动流程 可以看出,这个信息保存在CameraService中。
第10行,需重点关注,构造一个Camera对象,并将它返回给app层。

3.1 getNumberOfCameras函数分析

getNumberOfCameras函数进入到CameraService获取Camera个数的流程如下:


Camera.Java调用的getNumberOfCameras函数是一个JNI接口,对应的函数是android_hardware_Camera.cpp里的android_hardware_Camera_getNumberOfCameras函数

[cpp]  view plain   copy
  1. static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz)  
  2. {  
  3.     return Camera::getNumberOfCameras();  
  4. }  
这里只是简单调用了Camera.cpp的getNumberOfCameras函数,Camera继承了CameraBase,该函数由它实现

[cpp]  view plain   copy
  1. template <typename TCam, typename TCamTraits>  
  2. int CameraBase<TCam, TCamTraits>::getNumberOfCameras() {  
  3.     const sp<ICameraService> cs = getCameraService();  
  4.     return cs->getNumberOfCameras();  
  5. }  
第3行, getCameraService函数用来获取ICameraService的Bp端,代码实现如下
[cpp]  view plain   copy
  1. const char* kCameraServiceName = "media.camera";  
  2.   
  3. template <typename TCam, typename TCamTraits>  
  4. const sp<ICameraService>& CameraBase<TCam, TCamTraits>::getCameraService()  
  5. {     
  6.     if (gCameraService.get() == 0) {  
  7.         sp<IServiceManager> sm = defaultServiceManager();  
  8.         sp<IBinder> binder;  
  9.         binder = sm->getService(String16(kCameraServiceName));         
  10.         gCameraService = interface_cast<ICameraService>(binder);  
  11.     }  
  12.     return gCameraService;  
  13. }  

android的Binder通讯机制

第1行, 获取的ServiceName为"media.camera",结合上一篇博文CameraService的启动流程可以看出Bn端的实现在CameraService.cpp

回到之前的getNumberOfCameras函数,在获取到ICameraService的Bp端后,就可以开始和Bn端通讯了。在第4行,当调用cs->getNumberOfCameras函数时,将会进入CameraService.cpp的getNumberOfCameras函数

[cpp]  view plain   copy
  1. int32_t CameraService::getNumberOfCameras() {  
  2.     return mNumberOfCameras;  
  3. }  
代码很简单,返回上一篇博文讲到的,千辛万苦从hal层拿到的数据

3.2 Camera构造函数分析

回到最开始的Camera.open函数,在第10行,将会构造一个Camera对象

[cpp]  view plain   copy
  1. private int cameraInitVersion(int cameraId, int halVersion) {  
  2.     ......  
  3.     Looper looper;  
  4.     if ((looper = Looper.myLooper()) != null) {  
  5.         mEventHandler = new EventHandler(this, looper);  
  6.     } else if ((looper = Looper.getMainLooper()) != null) {  
  7.         mEventHandler = new EventHandler(this, looper);  
  8.     } else {  
  9.         mEventHandler = null;  
  10.     }  
  11.   
  12.     String packageName = ActivityThread.currentPackageName();  
  13.   
  14.     return native_setup(new WeakReference<Camera>(this), cameraId, halVersion, packageName);  
  15. }  
  16.   
  17. private int cameraInitNormal(int cameraId) {  
  18.     return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);  
  19. }  
  20.   
  21. Camera(int cameraId) {  
  22.     int err = cameraInitNormal(cameraId);  
  23.     ......  
  24. }  
第14行, native_setup同样是个JNI接口,对应android_hardware_Camera.cpp里的android_hardware_Camera_native_setup函数
[cpp]  view plain   copy
  1. static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,  
  2.     jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)  
  3. {  
  4.     camera = Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID);  
  5.   
  6. #if 1 // defined(MTK_CAMERA_BSP_SUPPORT)  
  7.     sp<JNICameraContext> context = new MtkJNICameraContext(env, weak_this, clazz, camera);  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值