allwinner_a64/android/hardware/aw/camera/HALCameraFactory.cpp
2018-08-08 17:00:29 +08:00

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