參考:
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回調函數傳來的數據和消息。