android6.0源码分析之Camera API1.0框架简介
1、架构简介
由于最近项目涉及到Camera,所以对Camera源码进行了研究,本文将分享Camera框架的基本知识。anroid6.0与5.0相比,Camera框架未曾改变,依然提供了两种API,即API1和API2,依然采用C/S的架构,而client和server两个线程间的通信依然使用IPC binder进程间通信的机制。
camera架构图如下:
由图可知:在framework层中,Java框架通过JNI的方式调用Native框架,此处的Native作为Client端只给上层应用提供调用接口,而具体的业务实现则是由Server端(CameraService)来实现,Client和Server则是通过Binder的方式进行通讯。
单独分析下Camera的C/S架构,其架构图如下:
2、代码结构
Camera的application部分:
packages/apps/legacycamera/src/com/android/camera/camera.java
packages/apps/legacycamera/src/com/android/camera/Util.java
packages/apps/legacycamera/src/com/android/camera/CameraHolder.java
Camera的framework部分:
frameworks/base/core/java/android/hardware/Camera.java
frameworks/base/core/jni/android_hardware_Camera.cpp
frameworks/av/camera/Camera.cpp
frameworks/av/camera/CameraBase.cpp
frameworks/av/camera/ICameraService.cpp
frameworks/av/services/camera/libcameraservice/CameraService.cpp
frameworks/av/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
其中Camera.java将会被编译成framework.jar,而android_hardware_Camera.cpp将会被编译成库libandroid_runtime.so,frameworks/av/camera将会被编译成库libcamera_client.so,最后服务部分也将会编译成库libcameraservice.so。
MTK平台的Camera HAL的代码放在vendor/mediatek/proprietary/hardware/mtkcam目录下面
总结:Camera的初始化流程简单的说就是:
->先是系统注册CameraService的服务
->APP层调用Camera.open()
->Camera.java调用JNI native_setup()
->JNI层调用 android_hardware_Camera_native_setup
-> HAL 客户端(Camera.cpp)调用connect与服务端(CameraService.cpp)连接,并得到CameraService中的CameraClient的一个实例,这里要注意的是CameraClient是在service端创建的,而app端只是获得了一个对应的proxy,如此之后HNI层有了一个Camera.cpp对象的实例camera,而这个实例里面有两个重要的对象分别是gCameraService和mCamera。其中gCameraService是CamerService的proxy,而mCamera是CameraClient的proxy。后续对Camera的实质性操作都是通过mCamera也就是Service端的CameraClient完成的。
->服务端CameraClient的初始化,实例化Camera Hal接口 CameraHardwareInterface,即mHardware。
->CameraClient里面也有一个重要的对象mRemoteCallback(其实是Camera.cpp),这个家伙是从app端传过来的一个binder,所以很显然是跨进程的,底层的一些消息和数据都是通过这个接口回调到应用端的.比如takePicture()就是通过hal调用底层拍照,然后mRemoteCallback回调告诉应用层。
->CameraHardwareInterface 打开Camera驱动,初始化完毕
最终的结果就是客户端会得到一个服务端CameraService中的CameraClient的一个实例,客户端的每一个函数操作其实最终都是调用CameraClient的函数