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

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);  
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值