camera打开流程(Camera App--->JNI)
参考:
http://blog.csdn.net/vasvas/article/details/50109907
总体架构
CameraService服务的注册
client端的应用层到JNI层Camera App---JNI
client到service的连接
HAL层
驱动层
1.总体架构
Android Camera 框架从整体上看是一个 client/service 的架构,
有两个进程:
client 进程,可以看成是 AP 端,主要包括 JAVA 代码与一些 native c/c++代码;
service 进 程,属于服务端,是 native c/c++代码,主要负责和 linux kernel 中的 camera driver 交互,搜集 linuxkernel 中 cameradriver 传上来的数据,并交给显示系统显示。
client 进程与 service 进程通过 Binder 机制通信, client 端通过调用 service 端的接口实现各个具体的功能。
二.CameraService服务的注册
SystemServer.java (frameworks\base\services\java\com\android\server)
在systemsever里面注册很多服务,包括CameraService
startOtherServices
mSystemServiceManager.startService(CameraService.class);
Main_mediaserver.cpp (frameworks\av\media\mediaserver)
main
BinderService的定义在frameworks/av/base/include/binder/BinderService.h中
// ---------------------------------------------------------------------------
namespace android {
template<typename SERVICE>
class BinderService
{
public:
static status_t publish() {
sp<IServiceManager> sm(defaultServiceManager());
return sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
}
static void publishAndJoinThreadPool() {}
static void publishAndJoinThreadPool() {
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SERVICE::getServiceName()), new SERVICE());
ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();
}}}
static void instantiate() { publish(); }
static status_t shutdown() {
return NO_ERROR;
}
};};
}; // namespace android
// ---------------------------------------------------------------------------
可以发现在publish()函数中,CameraService完成服务的注册 。这里面有个SERVICE,源码中有说明 template<typename SERVICE>
这表示SERVICE是个模板,这里是注册CameraService,所以可以用CameraService代替
return sm->addService(String16(CameraService::getServiceName()), new CameraService());
这样,Camera就在ServiceManager完成服务注册,提供给client随时使用。
Main_MediaServer主函数由init.rc在启动是调用,所以在设备开机的时候Camera就会注册一个服务,用作binder通信。
三.client端的应用层到framework层
从第2节的分析中可知,Binder服务已注册,那接下来就看看client如何连上server端,并打开camera模块。先从camera app的源码入手。在onCreate()函数中专门有一个open Camera的线程。
应用层
camera app的源码文件在以下目录packages/apps/LegacyCamera/src/com/android/camera/camera.java
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
getPreferredCameraId();
String[] defaultFocusModes = getResources().getStringArray(
R.array.pref_camera_focusmode_default_array);
mFocusManager = new FocusManager(mPreferences, defaultFocusModes);
/*
* To reduce startup time, we start the camera open and preview threads.
* We make sure the preview is started at the end of onCreate.
*/
mCameraOpenThread.start();
................
mCameraPreviewThread = null;
}
再看看mCameraOpenThread
Thread mCameraOpenThread = new Thread(new Runnable() {
public void run() {
try {
mCameraDevice = Util.openCamera(Camera.this, mCameraId);
} catch (CameraHardwareException e) {
mOpenCameraFail = true;
} catch (CameraDisabledException e) {
mCameraDisabled = true;
}
}
});
继续追Util.openCamera ,Util类的定义在以下目录:packages/apps/LegacyCamera/src/com/android/camera/Util.java
public static android.hardware.Camera openCamera(Activity activity, int cameraId)
throws CameraHardwareException, CameraDisabledException {
// Check if device policy has disabled the camera.
...............
try {
return CameraHolder.instance().open(cameraId);
} catch (CameraHardwareException e) {
// In eng build, we throw the exception so that test tool
// can detect it and report it
if ("eng".equals(Build.TYPE)) {
throw new RuntimeException("openCamera failed", e);
} else {
throw e;
}
}
}
又来了个CameraHolder,该类用一个实例open Camera
CameraHolder的定义在以下目录:packages/apps/LegacyCamera/src/com/android/camera/CameraHolder.java
public synchronized android.hardware.Camera open(int cameraId)
throws CameraHardwareException {
..............
if (mCameraDevice == null) {
try {
Log.v(TAG, "open camera " + cameraId);
mCameraDevice = android.hardware.Camera.open(cameraId);//进入framework层
mCameraId = cameraId;
} catch (RuntimeException e) {
Log.e(TAG, "fail to connect Camera", e);
throw new CameraHardwareException(e);
}
mParameters = mCameraDevice.getParameters();
} else {
............
}
++mUsers;
mHandler.removeMessages(RELEASE_CAMERA);
mKeepBeforeTime = 0;
return mCameraDevice;
}
自己分析的流程
其Framework层的open函数定义在如下文件中:frameworks\base\core\java\android\hardware\Camera.java
return new Camera(cameraId);
}
这里调用了Camera的构造函数,对Camera类的一些参数进行简单初始化,其构造函数如下:
Camera(int cameraId) {
mShutterCallback = null;
mRawImageCallback = null;
mJpegCallback = null;
mPreviewCallback = null;
mPostviewCallback = null;
mZoomListener = null;
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;
}
native_setup(new WeakReference<Camera>(this), cameraId); //调用JNI
}
从这里开始通过JNI调用到native_setup( ),这里在系统上电时已经把JNI的一个对象注册成类Camer的Listener。
native_setup( )接口在libandroid_runtime.so中实现,由Framework层通过JNI调用该接口。该接口主要是实现如下两个功能:
1、实现CameraC/S架构的客户端和服务端的连接(通过调用connect方法,进入libcamera_client.so)
2、set一个监听类,用于处理底层Camera回调函数传来的数据和消息
native_setup()的定义在如下源文件中:frameworks/base/core/jni/android_hardware_Camera.cpp
static JNINativeMethod camMethods[] = {
{ "native_setup", "(Ljava/lang/Object;I)V", (void*)android_hardware_Camera_native_setup },
{ "startPreview","()V", (void *)android_hardware_Camera_startPreview },
{ "native_autoFocus","()V", (void *)android_hardware_Camera_autoFocus },
..................
};
通过这个定义,使得native_setup( )和android_hardware_Camera_native_setup( )关联起来。所以,native_setup(new WeakReference<Camera>(this), cameraId);这个调用即是对下面android_hardware_Camera_native_setup( )这个函数的调用:
// connect to camera service
static void android_hardware_Camera_native_setup(JNIEnv *env, jobject thiz, jobject weak_this, jint cameraId)
{
sp<Camera> camera = Camera::connect(cameraId);
...........
// make sure camera hardware is alive
if (camera->getStatus() != NO_ERROR) {
jniThrowRuntimeException(env, "Camera initialization failed");
return;
}
...........
// We use a weak reference so the Camera object can be garbage collected.
// The reference is only used as a proxy for callbacks.
sp<JNICameraContext> context = new JNICameraContext(env, weak_this, clazz, camera);
context->incStrong(thiz);
camera->setListener(context);
// save context in opaque field
env->SetIntField(thiz, fields.context, (int)context.get());
}
JNI函数里面,我们找到Camera C/S架构的客户端了,它调用connect函数向服务器发送连接请求。JNICameraContext这个类是一个监听类,用于处理底层Camera回调函数传来的数据和消息。
自己分析的流程
static JNINativeMethod camMethods[] = {
{ "native_setup","(Ljava/lang/Object;IILjava/lang/String;)I", (void*)android_hardware_Camera_native_setup }, //对应的调用android_hardware_Camera_native_setup
android_hardware_Camera_native_setup
sp<JNICameraContext> context = new MtkJNICameraContext(env, weak_this, clazz, camera); //用于处理底层Camera回调函数传来的数据和消息。