447 lines
14 KiB
C++
Executable file
447 lines
14 KiB
C++
Executable file
|
|
#include "CameraDebug.h"
|
|
#if DBG_CAMERA_FACTORY
|
|
#define LOG_NDEBUG 0
|
|
#endif
|
|
#define LOG_TAG "HALCameraFactory"
|
|
#include <cutils/log.h>
|
|
#include <android/log.h>
|
|
|
|
#include <binder/IPCThreadState.h>
|
|
#include <cutils/properties.h>
|
|
|
|
#include "HALCameraFactory.h"
|
|
#include "CCameraConfig.h"
|
|
|
|
extern camera_module_t HAL_MODULE_INFO_SYM;
|
|
|
|
/* A global instance of HALCameraFactory is statically instantiated and
|
|
* initialized when camera emulation HAL is loaded.
|
|
*/
|
|
android::HALCameraFactory gEmulatedCameraFactory;
|
|
|
|
namespace android {
|
|
|
|
|
|
#define GET_CALLING_PID (IPCThreadState::self()->getCallingPid())
|
|
|
|
#if 0
|
|
void getCallingProcessName(char *name)
|
|
{
|
|
char proc_node[128];
|
|
|
|
if (name == 0)
|
|
{
|
|
LOGE("error in params");
|
|
return;
|
|
}
|
|
|
|
memset(proc_node, 0, sizeof(proc_node));
|
|
sprintf(proc_node, "/proc/%d/cmdline", GET_CALLING_PID);
|
|
int fp = ::open(proc_node, O_RDONLY);
|
|
if (fp > 0)
|
|
{
|
|
memset(name, 0, 128);
|
|
::read(fp, name, 128);
|
|
::close(fp);
|
|
fp = 0;
|
|
LOGD("Calling process is: %s", name);
|
|
}
|
|
else
|
|
{
|
|
LOGE("Obtain calling process failed");
|
|
}
|
|
}
|
|
#endif
|
|
|
|
void getCallingProcessName(char *name)
|
|
{
|
|
char value[1024];
|
|
if(name == 0)
|
|
{
|
|
ALOGE("error in params");
|
|
return;
|
|
}
|
|
int getpersist;
|
|
getpersist = property_get("persist.sys.cts", value, NULL);
|
|
ALOGD("Initialize getpersist = %d value=%s", getpersist, value);
|
|
strcpy(name, value);
|
|
}
|
|
|
|
HALCameraFactory::HALCameraFactory()
|
|
: mHardwareCameras(NULL),
|
|
mAttachedCamerasNum(0),
|
|
mRemovableCamerasNum(0),
|
|
mConstructedOK(false)
|
|
{
|
|
F_LOG;
|
|
|
|
LOGD("camera hal version: %s", CAMERA_HAL_VERSION);
|
|
|
|
memset(&mHalCameraInfo,0,sizeof(mHalCameraInfo));
|
|
|
|
/* Make sure that array is allocated. */
|
|
if (mHardwareCameras == NULL) {
|
|
mHardwareCameras = new CameraHardware*[MAX_NUM_OF_CAMERAS];
|
|
if (mHardwareCameras == NULL) {
|
|
LOGE("%s: Unable to allocate V4L2Camera array for %d entries",
|
|
__FUNCTION__, MAX_NUM_OF_CAMERAS);
|
|
return;
|
|
}
|
|
memset(mHardwareCameras, 0, MAX_NUM_OF_CAMERAS * sizeof(CameraHardware*));
|
|
}
|
|
|
|
/* Create the cameras */
|
|
for (int id = 0; id < MAX_NUM_OF_CAMERAS; id++)
|
|
{
|
|
// camera config information
|
|
mCameraConfig[id] = new CCameraConfig(id);
|
|
if(mCameraConfig[id] == 0)
|
|
{
|
|
LOGW("create CCameraConfig failed");
|
|
}
|
|
else
|
|
{
|
|
mCameraConfig[id]->initParameters();
|
|
mCameraConfig[id]->dumpParameters();
|
|
}
|
|
|
|
mHardwareCameras[id] = new CameraHardware(&HAL_MODULE_INFO_SYM.common, mCameraConfig[id]);
|
|
if (mHardwareCameras[id] == NULL)
|
|
{
|
|
mHardwareCameras--;
|
|
LOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// check camera cfg
|
|
if (mCameraConfig[0] != NULL)
|
|
{
|
|
mAttachedCamerasNum = mCameraConfig[0]->numberOfCamera();
|
|
|
|
if ((mAttachedCamerasNum == 2)
|
|
&& (mCameraConfig[1] == NULL))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
mConstructedOK = true;
|
|
}
|
|
|
|
HALCameraFactory::~HALCameraFactory()
|
|
{
|
|
F_LOG;
|
|
if (mHardwareCameras != NULL)
|
|
{
|
|
for (int n = 0; n < MAX_NUM_OF_CAMERAS; n++)
|
|
{
|
|
if (mHardwareCameras[n] != NULL)
|
|
{
|
|
delete mHardwareCameras[n];
|
|
mHardwareCameras[n] = NULL;
|
|
}
|
|
}
|
|
delete[] mHardwareCameras;
|
|
mHardwareCameras = NULL;
|
|
}
|
|
|
|
for (int n = 0; n < MAX_NUM_OF_CAMERAS; n++)
|
|
{
|
|
if (mCameraConfig[n] != NULL)
|
|
{
|
|
delete mCameraConfig[n];
|
|
mCameraConfig[n] = NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Camera HAL API handlers.
|
|
*
|
|
* Each handler simply verifies existence of an appropriate CameraHardware
|
|
* instance, and dispatches the call to that instance.
|
|
*
|
|
***************************************************************************/
|
|
|
|
int HALCameraFactory::getCameraHardwareNum()
|
|
{
|
|
int ret = 0;
|
|
char dev_node[16];
|
|
int orientation = 0;
|
|
|
|
if (mCameraConfig[0] != NULL)
|
|
{
|
|
orientation = mCameraConfig[0]->getCameraOrientation();
|
|
}
|
|
|
|
mRemovableCamerasNum = 0;
|
|
|
|
// there are two attached cameras.
|
|
if (mAttachedCamerasNum == 2)
|
|
{
|
|
for (int i = 0; i < MAX_NUM_OF_CAMERAS; i++)
|
|
{
|
|
strcpy(mHalCameraInfo[i].device_name, mCameraConfig[i]->cameraDevice());
|
|
mHalCameraInfo[i].device_id = mCameraConfig[i]->getDeviceID();
|
|
mHalCameraInfo[i].facing = mCameraConfig[i]->cameraFacing();
|
|
mHalCameraInfo[i].orientation = mCameraConfig[i]->getCameraOrientation();
|
|
mHalCameraInfo[i].fast_picture_mode = mCameraConfig[i]->supportFastPictureMode();
|
|
mHalCameraInfo[i].is_uvc = false;
|
|
}
|
|
}
|
|
else if (mAttachedCamerasNum == 1)
|
|
{
|
|
// There is one attached cameras.
|
|
strcpy(mHalCameraInfo[0].device_name, mCameraConfig[0]->cameraDevice());
|
|
mHalCameraInfo[0].device_id = mCameraConfig[0]->getDeviceID();
|
|
mHalCameraInfo[0].facing = mCameraConfig[0]->cameraFacing();
|
|
mHalCameraInfo[0].orientation = mCameraConfig[0]->getCameraOrientation();
|
|
mHalCameraInfo[0].fast_picture_mode = mCameraConfig[0]->supportFastPictureMode();
|
|
mHalCameraInfo[0].is_uvc = false;
|
|
|
|
// There may be another USB camera. Then, the device node would be "/dev/video0" or "/dev/video1".
|
|
if (!strcmp(mHalCameraInfo[0].device_name, "/dev/video1"))
|
|
{
|
|
sprintf(dev_node, "/dev/video0");
|
|
}
|
|
else
|
|
{
|
|
sprintf(dev_node, "/dev/video1");
|
|
}
|
|
ret = access(dev_node, F_OK);
|
|
if(ret == 0)
|
|
{
|
|
mRemovableCamerasNum = 1;
|
|
strcpy(mHalCameraInfo[1].device_name, dev_node);
|
|
mHalCameraInfo[1].device_id = 0;
|
|
mHalCameraInfo[1].facing = (mCameraConfig[0]->cameraFacing() == CAMERA_FACING_BACK) ? CAMERA_FACING_FRONT : CAMERA_FACING_BACK;
|
|
mHalCameraInfo[1].orientation = orientation;
|
|
mHalCameraInfo[1].fast_picture_mode = false;
|
|
mHalCameraInfo[1].is_uvc = true;
|
|
}
|
|
}
|
|
else if (mAttachedCamerasNum == 0)
|
|
{
|
|
// There is not attached cameras.
|
|
for (int i = 0; i < MAX_NUM_OF_CAMERAS; i++)
|
|
{
|
|
sprintf(dev_node, "/dev/video%d", i);
|
|
ret = access(dev_node, F_OK);
|
|
if(ret == 0)
|
|
{
|
|
strcpy(mHalCameraInfo[mRemovableCamerasNum].device_name, dev_node);
|
|
mHalCameraInfo[mRemovableCamerasNum].device_id = i;
|
|
mRemovableCamerasNum++;
|
|
}
|
|
}
|
|
|
|
if (mRemovableCamerasNum == 1)
|
|
{
|
|
mHalCameraInfo[0].facing = CAMERA_FACING_FRONT;
|
|
mHalCameraInfo[0].orientation = orientation;
|
|
mHalCameraInfo[0].fast_picture_mode = false;
|
|
mHalCameraInfo[0].is_uvc = true;
|
|
}
|
|
else if(mRemovableCamerasNum == 2)
|
|
{
|
|
mHalCameraInfo[0].facing = CAMERA_FACING_BACK;
|
|
mHalCameraInfo[0].orientation = orientation;
|
|
mHalCameraInfo[0].fast_picture_mode = false;
|
|
mHalCameraInfo[0].is_uvc = true;
|
|
mHalCameraInfo[1].facing = CAMERA_FACING_FRONT;
|
|
mHalCameraInfo[1].orientation = orientation;
|
|
mHalCameraInfo[1].fast_picture_mode = false;
|
|
mHalCameraInfo[1].is_uvc = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LOGE("error number of attached cameras: %d in camera.cfg", mAttachedCamerasNum);
|
|
return 0;
|
|
}
|
|
|
|
LOGD("There is %d attached cameras and %d removable cameras", mAttachedCamerasNum, mRemovableCamerasNum);
|
|
|
|
// total numbers include attached and removable cameras
|
|
return mAttachedCamerasNum + mRemovableCamerasNum;
|
|
}
|
|
|
|
int HALCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
|
|
{
|
|
//LOGV("%s: id = %d", __FUNCTION__, camera_id);
|
|
|
|
int total_num_of_cameras = mAttachedCamerasNum + mRemovableCamerasNum;
|
|
char calling_process[256];
|
|
|
|
if (!isConstructedOK()) {
|
|
LOGE("%s: HALCameraFactory has failed to initialize", __FUNCTION__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (camera_id < 0 || camera_id >= total_num_of_cameras) {
|
|
LOGE("%s: Camera id %d is out of bounds (%d)",
|
|
__FUNCTION__, camera_id, total_num_of_cameras);
|
|
return -EINVAL;
|
|
}
|
|
|
|
info->orientation = mHalCameraInfo[camera_id].orientation;
|
|
info->facing = mHalCameraInfo[camera_id].facing;
|
|
info->static_camera_characteristics = NULL;
|
|
|
|
// single camera
|
|
if (total_num_of_cameras == 1)
|
|
{
|
|
getCallingProcessName(calling_process);
|
|
if ((strcmp(calling_process, "com.tencent.mobileqq") == 0)
|
|
|| (strcmp(calling_process, "com.tencent.mobileqq:video") == 0))
|
|
{
|
|
// cts, mobile qq need facing-back camera
|
|
info->facing = CAMERA_FACING_BACK;
|
|
}
|
|
else if ((strcmp(calling_process, "com.google.android.talk") == 0)
|
|
|| (strcmp(calling_process, "com.android.facelock") == 0))
|
|
{
|
|
// gtalk, facelock need facing-front camera
|
|
info->facing = CAMERA_FACING_FRONT;
|
|
}
|
|
}
|
|
|
|
char property[PROPERTY_VALUE_MAX];
|
|
if (property_get("ro.sf.hwrotation", property, NULL) > 0)
|
|
{
|
|
//displayOrientation
|
|
switch (atoi(property))
|
|
{
|
|
case 270:
|
|
if(info->facing == CAMERA_FACING_BACK)
|
|
{
|
|
info->orientation = (info->orientation + 90) % 360;
|
|
}
|
|
else if(info->facing == CAMERA_FACING_FRONT)
|
|
{
|
|
info->orientation = (info->orientation + 270) % 360;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
int HALCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
|
|
{
|
|
LOGV("%s: id = %d", __FUNCTION__, camera_id);
|
|
|
|
*device = NULL;
|
|
|
|
if (!isConstructedOK()) {
|
|
LOGE("%s: HALCameraFactory has failed to initialize", __FUNCTION__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (camera_id < 0 || camera_id >= (mAttachedCamerasNum + mRemovableCamerasNum)) {
|
|
LOGE("%s: Camera id %d is out of bounds (%d)",
|
|
__FUNCTION__, camera_id, mAttachedCamerasNum + mRemovableCamerasNum);
|
|
return -EINVAL;
|
|
}
|
|
|
|
if (!mHardwareCameras[0]->isCameraIdle()
|
|
|| !mHardwareCameras[1]->isCameraIdle())
|
|
{
|
|
LOGW("camera device is busy, wait a moment");
|
|
usleep(500000);
|
|
}
|
|
|
|
mHardwareCameras[camera_id]->setCameraHardwareInfo(&mHalCameraInfo[camera_id]);
|
|
|
|
#ifdef USE_CSI_VIN_DRIVER
|
|
int id = 0;
|
|
for (id; id < MAX_NUM_OF_CAMERAS; id++) {
|
|
if (mHardwareCameras[id]->mV4L2CameraDevice->isConnected()) {
|
|
LOGE("%s: user has connected camera", __FUNCTION__);
|
|
return -EUSERS;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
if (mHardwareCameras[camera_id]->connectCamera(device) != NO_ERROR)
|
|
{
|
|
LOGE("%s: Unable to connect camera", __FUNCTION__);
|
|
return -EUSERS;
|
|
}
|
|
|
|
if (mHardwareCameras[camera_id]->Initialize() != NO_ERROR)
|
|
{
|
|
LOGE("%s: Unable to Initialize camera", __FUNCTION__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return NO_ERROR;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Camera HAL API callbacks.
|
|
***************************************************************************/
|
|
|
|
int HALCameraFactory::get_number_of_cameras(void)
|
|
{
|
|
return gEmulatedCameraFactory.getCameraHardwareNum();
|
|
}
|
|
|
|
int HALCameraFactory::get_camera_info(int camera_id,
|
|
struct camera_info* info)
|
|
{
|
|
return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
|
|
}
|
|
|
|
int HALCameraFactory::device_open(const hw_module_t* module,
|
|
const char* name,
|
|
hw_device_t** device)
|
|
{
|
|
/*
|
|
* Simply verify the parameters, and dispatch the call inside the
|
|
* HALCameraFactory instance.
|
|
*/
|
|
|
|
if (module != &HAL_MODULE_INFO_SYM.common) {
|
|
LOGE("%s: Invalid module %p expected %p",
|
|
__FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
|
|
return -EINVAL;
|
|
}
|
|
if (name == NULL) {
|
|
LOGE("%s: NULL name is not expected here", __FUNCTION__);
|
|
return -EINVAL;
|
|
}
|
|
|
|
return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
|
|
}
|
|
|
|
/********************************************************************************
|
|
* Initializer for the static member structure.
|
|
*******************************************************************************/
|
|
|
|
/* Entry point for camera HAL API. */
|
|
struct hw_module_methods_t HALCameraFactory::mCameraModuleMethods = {
|
|
open: HALCameraFactory::device_open
|
|
};
|
|
|
|
}; /* namespace android */
|
|
|
|
camera_module_t HAL_MODULE_INFO_SYM = {
|
|
common: {
|
|
tag: HARDWARE_MODULE_TAG,
|
|
module_api_version: CAMERA_DEVICE_API_VERSION_1_0,
|
|
hal_api_version: HARDWARE_HAL_API_VERSION,
|
|
id: CAMERA_HARDWARE_MODULE_ID,
|
|
name: "V4L2Camera Module",
|
|
author: "XSJ",
|
|
methods: &android::HALCameraFactory::mCameraModuleMethods,
|
|
dso: NULL,
|
|
reserved: {0},
|
|
},
|
|
get_number_of_cameras: android::HALCameraFactory::get_number_of_cameras,
|
|
get_camera_info: android::HALCameraFactory::get_camera_info,
|
|
};
|
|
|