1. 前言
本文将分析Android 系统源码,从frameworks层到hal层,暂不涉及app层和kernel层。由于某些函数比较复杂,在贴出代码时会适当对其进行简化。本文 属于自己对源码的总结,仅仅是贯穿代码流程,不会深入分析各个细节。欢迎联系讨论,QQ:1026656828
2. app层
从apk开始,简单列出各个入口函数
private void initCamera()
{
Camera mCamera = Camera.open();
Camera.Parameters mParameters = mCamera.getParameters();
mParameters.setPictureFormat(PixelFormat.JPEG);
mCamera.setParameters(mParameters);
mCamera.setPreviewDisplay(mSurfaceHolder);
mCamera.startPreview();
mCamera.takePicture(null, null , mJpegCallback);
}
3. frameworks层
这里将重点介绍Camera.open函数,其余函数将在后续博文分析。先来看看Camera.open函数在frameworks层的实现,代码路径为: frameworks/base/core/java/android/hardware/Camera.java
public static Camera open() {
if (!isPermissionGranted()) {
return null;
}
int numberOfCameras = getNumberOfCameras();
CameraInfo cameraInfo = new CameraInfo();
for ( int i = 0; i < numberOfCameras; i++) {
getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
return new Camera(i);
}
}
return null;
}
第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函数
static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz)
{
return Camera::getNumberOfCameras();
}
这里只是简单调用了Camera.cpp的getNumberOfCameras函数,Camera继承了CameraBase,该函数由它实现
template < typename TCam, typename TCamTraits>
int CameraBase<TCam, TCamTraits>::getNumberOfCameras() {
const sp<ICameraService> cs = getCameraService();
return cs->getNumberOfCameras();
}
第3行, getCameraService函数用来获取ICameraService的Bp端,代码实现如下
const char * kCameraServiceName = "media.camera" ;
template < typename TCam, typename TCamTraits>
const sp<ICameraService>& CameraBase<TCam, TCamTraits>::getCameraService()
{
if (gCameraService.get() == 0) {
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
binder = sm->getService(String16(kCameraServiceName));
gCameraService = interface_cast<ICameraService>(binder);
}
return gCameraService;
}
android 的Binder通讯机制
第1行, 获取的ServiceName为"media.camera",结合上一篇博文CameraService的启动流程 可以看出Bn端的实现在CameraService.cpp
回到之前的getNumberOfCameras函数,在获取到ICameraService的Bp端后,就可以开始和Bn端通讯了。在第4行,当调用cs->getNumberOfCameras函数时,将会进入CameraService.cpp的getNumberOfCameras函数
int32_t CameraService::getNumberOfCameras() {
return mNumberOfCameras;
}
代码很简单,返回上一篇博文讲到的,千辛万苦从hal层拿到的数据
3.2 Camera构造函数分析
回到最开始的Camera.open函数,在第10行,将会构造一个Camera对象
private int cameraInitVersion( int cameraId, int halVersion) {
......
Looper looper;
if ((looper = Looper.myLooper()) != null) {
mEventHandler = new EventHandler( this , looper);
} else if ((looper = Looper.getMainLooper()) != null) {
mEventHandler = new EventHandler( this , looper);
} else {
mEventHandler = null;
}
String packageName = ActivityThread.currentPackageName();
return native_setup( new WeakReference<Camera>( this ), cameraId, halVersion, packageName);
}
private int cameraInitNormal( int cameraId) {
return cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);
}
Camera(int cameraId) {
int err = cameraInitNormal(cameraId);
......
}
第14行, native_setup同样是个JNI接口,对应android_hardware_Camera.cpp里的android_hardware_Camera_native_setup函数
static jint android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz,
jobject weak_this, jint cameraId, jint halVersion, jstring clientPackageName)
{
camera = Camera::connect(cameraId, clientName, Camera::USE_CALLING_UID);
#if 1 // defined(MTK_CAMERA_BSP_SUPPORT)
sp<JNICameraContext> context = new MtkJNICameraContext(env, weak_this, clazz, camera);