camera打开流程(Camera App--->JNI)

参考:

http://blog.csdn.net/vasvas/article/details/50109907

 
一.Android Camera 运行流程的综述

总体架构
   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

        CameraService::instantiate();
        可是我们到CameraService文件里面却找不到instantiate()这个函数,它在哪?继续追到它的一个父类BinderService,
        从以上定义可以看出CameraService 继承于BinderService,所以CameraService::instantiate(); 其实是调用BinderService中的instantiate。

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;
}
 

 

自己分析的流程

CameraManager.java (packages\apps\camera\src\com\android\camera)
onCreate
    Thread mCameraOpenThread = new Thread(new Runnable() //创建一个线程用于打开摄像头 
         mCameraDevice = Util.openCamera(Camera.this, mCameraId); //执行函数是打开摄像头方法
   mCameraOpenThread.start();     //启动这个线程,所以调用Util.openCamera(Camera.this, mCameraId);
         mCameraDevice = Util.openCamera(Camera.this, mCameraId);
            Util.java (packages\apps\legacycamera\src\com\android\camera)里面
            CameraHolder.instance().open(cameraId); 
                //CameraHolder.java (packages\apps\legacycamera\src\com\android\camera)
                mCameraDevice = android.hardware.Camera.open(cameraId); //进入framework层
 
 
 
 
四.framework到jni
    其中调用frameworks\base\core\java\android\hardware\Camera.java类的open方法 ,进入Framework层。
public static Camera open(int cameraId) 

其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回调函数传来的数据和消息

 
 
自己分析的流程
public static Camera open(int cameraId) 
    new Camera(cameraId);
        int err = cameraInitNormal(cameraId);
             cameraInitVersion(cameraId, CAMERA_HAL_API_VERSION_NORMAL_CONNECT);  //通过指定API版本号,进行初始化
                if ((looper = Looper.myLooper()) != null) {
                    mEventHandler = new EventHandler(this, looper);  //这里初始化一个消息等待队列
                native_setup(new WeakReference<Camera>(this), cameraId, halVersion, ActivityThread.currentOpPackageName()); //从这里进入JNI
 
 
 
 
五.JNI到HAL层

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 

             jint status = Camera::connectLegacy(cameraId, halVersion, clientName,Camera::USE_CALLING_UID, camera); //这里进入service

              sp<JNICameraContext> context = new MtkJNICameraContext(env, weak_this, clazz, camera); //用于处理底层Camera回调函数传来的数据和消息。

 
posted @ 2020-11-25 14:40  luoyuna  阅读(1537)  评论(0编辑  收藏  举报