二、Framework层支持多camera
1、Camera.java文件
首先看一下文件Framework/base/core/java/android/hardware/camera.java。
添加了三个接口函数,分别为getNumberOfCameras(),getCameraInfo(),setCameraId(),它们的CODE如下:
/**
* Returns the number of physical cameras available on this device.
*/
public native static int getNumberOfCameras();
/**
* Returns the information about a particular camera.
* If {@link #getNumberOfCameras()} returns N, the valid id is 0 to N-1.
*/
public native static void getCameraInfo(int cameraId, CameraInfo cameraInfo);
public native static int setCameraId(int cameraId);
同时定义了CameraInfo类,在application层CameraHolder.java和Camera.java这两个文件中引用了该类。其CODE如下:
/**
* Information about a camera
*/
public static class CameraInfo {
/**
* The facing of the camera is opposite to that of the screen.
*/
public static final int CAMERA_FACING_BACK = 0;
/**
* The facing of the camera is the same as that of the screen.
*/
public static final int CAMERA_FACING_FRONT = 1;
/**
* The direction that the camera faces to. It should be
* CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
*/
public int facing;
/**
* The orientation of the camera image. The value is the angle that the
* camera image needs to be rotated clockwise so it shows correctly on
* the display in its natural orientation. It should be 0, 90, 180, or 270.
*
* For example, suppose a device has a naturally tall screen. The
* back-facing camera sensor is mounted in landscape. You are looking at
* the screen. If the top side of the camera sensor is aligned with the
* right edge of the screen in natural orientation, the value should be
* 90. If the top side of a front-facing camera sensor is aligned with
* the right of the screen, the value should be 270.
*
* @see #setDisplayOrientation(int)
* @see #setRotation(int)
* @see #setPreviewSize(int, int)
* @see #setPictureSize(int, int)
* @see #setJpegThumbnailSize(int, int)
*/
public int orientation;
};
2、android_hardware_camera.cpp文件
下面介绍Framework/base/core/jni/android_hardwrea_camera.cpp,该文件为JNI文件。
首先在结构体fields_t中添加了两个成员:facing和orientation,其具体定义为:
struct fields_t {
jfieldID context;
jfieldID surface;
jfieldID facing;
jfieldID orientation;
jmethodID post_event;
};
接下来定义了三个函数,分别为android_hardware_Camera_getNumberOfCameras(),android_hardware_Camera_getCameraInfo()和android_hardware_Camera_setCameraId()。其CODE如下:
static jint android_hardware_Camera_getNumberOfCameras(JNIEnv *env, jobject thiz)
{
return Camera::getNumberOfCameras();
}
static void android_hardware_Camera_getCameraInfo(JNIEnv *env, jobject thiz,
jint cameraId, jobject info_obj)
{
CameraInfo cameraInfo;
status_t rc = Camera::getCameraInfo(cameraId, &cameraInfo);
if (rc != NO_ERROR) {
jniThrowException(env, "java/lang/RuntimeException",
"Fail to get camera info");
return;
}
env->SetIntField(info_obj, fields.facing, cameraInfo.facing);
env->SetIntField(info_obj, fields.orientation, cameraInfo.orientation);
}
static jint android_hardware_Camera_setCameraId(JNIEnv *env, jobject thiz,jint cameraId)
{
return Camera::setCameraId(cameraId);
}
同时修改了JNINativeMethod,将上述三个函数的信息添加进去。
static JNINativeMethod camMethods[] = {
{ "getNumberOfCameras",
"()I",
(void *)android_hardware_Camera_getNumberOfCameras },
{ "getCameraInfo",
"(ILandroid/hardware/Camera$CameraInfo;)V",
(void*)android_hardware_Camera_getCameraInfo },
{ "setCameraId",
"(I)I",
(void *)android_hardware_Camera_setCameraId },
{ "native_setup",
"(Ljava/lang/Object;)V",
(void*)android_hardware_Camera_native_setup },
{ "native_release",
"()V",
(void*)android_hardware_Camera_release },
修改了函数register_android_hardware_Camera(),将结构体CameraInfo的两个成员添加到了fields_to_find。其CODE如下:
// Get all the required offsets in java class and register native functions
int register_android_hardware_Camera(JNIEnv *env)
{
field fields_to_find[] = {
{ "android/hardware/Camera", "mNativeContext", "I", &fields.context },
{ "android/view/Surface", "mSurface", "I", &fields.surface },
{ "android/hardware/Camera$CameraInfo", "facing", "I", &fields.facing },
{ "android/hardware/Camera$CameraInfo", "orientation", "I", &fields.orientation },
};
3、Camera.h文件
Framework/base/include/camera/camera.h是Framework里Camera.java和android_hardware_camera.cpp的接口文件。
首先定义了结构体CameraInfo,其具体定义如下:
enum {
CAMERA_FACING_BACK = 0, /* The facing of the camera is opposite to that of the screen. */
CAMERA_FACING_FRONT = 1 /* The facing of the camera is the same as that of the screen. */
};
struct CameraInfo {
/**
* The direction that the camera faces to. It should be
* CAMERA_FACING_BACK or CAMERA_FACING_FRONT.
*/
int facing;
/**
* The orientation of the camera image. The value is the angle that the
* camera image needs to be rotated clockwise so it shows correctly on
* the display in its natural orientation. It should be 0, 90, 180, or 270.
*
* For example, suppose a device has a naturally tall screen. The
* back-facing camera sensor is mounted in landscape. You are looking at
* the screen. If the top side of the camera sensor is aligned with the
* right edge of the screen in natural orientation, the value should be
* 90. If the top side of a front-facing camera sensor is aligned with
* the right of the screen, the value should be 270.
*/
int orientation;
};
在Camera类中增加了三个成员函数,其定义如下:
static int32_t getNumberOfCameras();
static status_t getCameraInfo(int cameraId, struct CameraInfo* cameraInfo);
static int32_t setCameraId(int cameraId);
4、Camera.cpp
Framework/base/libs/camera/camera.cpp是对Camera.h文件的实现。它实现了下面三个函数,其CODE如下:
int32_t Camera::getNumberOfCameras()
{
const sp<ICameraService>& cs = getCameraService();
if (cs == 0) return 0;
return cs->getNumberOfCameras();
}
status_t Camera::getCameraInfo(int cameraId,
struct CameraInfo* cameraInfo) {
const sp<ICameraService>& cs = getCameraService();
if (cs == 0) return UNKNOWN_ERROR;
return cs->getCameraInfo(cameraId, cameraInfo);
}
int32_t Camera::setCameraId(int cameraId)
{
const sp<ICameraService>& cs = getCameraService();
if (cs == 0) return 0;
return cs->setCameraId(cameraId);
}
它调用ICameraService.h中的三个接口,下面对ICameraService.h作以介绍。(待续)