2792329531
Resolve CLANG compilation errors CRs-Fixed: 981949 Change-Id: Ibeaac796b5e5f0defae76a8ab9bd88d3d1e4c164
605 lines
19 KiB
C++
605 lines
19 KiB
C++
/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are
|
|
* met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above
|
|
* copyright notice, this list of conditions and the following
|
|
* disclaimer in the documentation and/or other materials provided
|
|
* with the distribution.
|
|
* * Neither the name of The Linux Foundation nor the names of its
|
|
* contributors may be used to endorse or promote products derived
|
|
* from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
*/
|
|
|
|
#define LOG_TAG "QCamera2Factory"
|
|
|
|
// System dependencies
|
|
#include <stdlib.h>
|
|
#include <utils/Errors.h>
|
|
|
|
// Camera dependencies
|
|
#include "camera.h"
|
|
#include "camera3.h"
|
|
#include "HAL/QCamera2HWI.h"
|
|
#include "HAL3/QCamera3HWI.h"
|
|
#include "util/QCameraFlash.h"
|
|
#include "QCamera2Factory.h"
|
|
#include "QCameraMuxer.h"
|
|
|
|
extern "C" {
|
|
#include "mm_camera_dbg.h"
|
|
}
|
|
|
|
using namespace android;
|
|
|
|
namespace qcamera {
|
|
|
|
QCamera2Factory *gQCamera2Factory = NULL;
|
|
QCameraMuxer *gQCameraMuxer = NULL;
|
|
pthread_mutex_t gCamLock = PTHREAD_MUTEX_INITIALIZER;
|
|
//Total number of cameras opened simultaneously.
|
|
//This variable updation is protected by gCamLock.
|
|
uint8_t gNumCameraSessions = 0;
|
|
|
|
volatile uint32_t gKpiDebugLevel = 1;
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : QCamera2Factory
|
|
*
|
|
* DESCRIPTION: default constructor of QCamera2Factory
|
|
*
|
|
* PARAMETERS : none
|
|
*
|
|
* RETURN : None
|
|
*==========================================================================*/
|
|
QCamera2Factory::QCamera2Factory()
|
|
{
|
|
camera_info info;
|
|
mHalDescriptors = NULL;
|
|
mCallbacks = NULL;
|
|
mNumOfCameras = get_num_of_cameras();
|
|
int bDualCamera = 0;
|
|
char propDefault[PROPERTY_VALUE_MAX];
|
|
char prop[PROPERTY_VALUE_MAX];
|
|
property_get("persist.camera.HAL3.enabled", prop, "1");
|
|
int isHAL3Enabled = atoi(prop);
|
|
|
|
// Signifies whether system has to enable dual camera mode
|
|
snprintf(propDefault, PROPERTY_VALUE_MAX, "%d", isDualCamAvailable(isHAL3Enabled));
|
|
property_get("persist.camera.dual.camera", prop, propDefault);
|
|
bDualCamera = atoi(prop);
|
|
LOGH("dualCamera:%d ", bDualCamera);
|
|
|
|
if(bDualCamera) {
|
|
LOGI("Enabling QCamera Muxer");
|
|
if (!gQCameraMuxer) {
|
|
QCameraMuxer::getCameraMuxer(&gQCameraMuxer, mNumOfCameras);
|
|
if (!gQCameraMuxer) {
|
|
LOGE("Error !! Failed to get QCameraMuxer");
|
|
}
|
|
}
|
|
}
|
|
if (!gQCameraMuxer && (mNumOfCameras > 0) &&
|
|
(mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {
|
|
mHalDescriptors = new hal_desc[mNumOfCameras];
|
|
if ( NULL != mHalDescriptors) {
|
|
uint32_t cameraId = 0;
|
|
|
|
for (int i = 0; i < mNumOfCameras ; i++, cameraId++) {
|
|
mHalDescriptors[i].cameraId = cameraId;
|
|
// Set Device version to 3.x when both HAL3 is enabled & its BAYER sensor
|
|
if (isHAL3Enabled && !(is_yuv_sensor(cameraId))) {
|
|
mHalDescriptors[i].device_version =
|
|
CAMERA_DEVICE_API_VERSION_3_0;
|
|
} else {
|
|
mHalDescriptors[i].device_version =
|
|
CAMERA_DEVICE_API_VERSION_1_0;
|
|
}
|
|
//Query camera at this point in order
|
|
//to avoid any delays during subsequent
|
|
//calls to 'getCameraInfo()'
|
|
getCameraInfo(i, &info);
|
|
}
|
|
} else {
|
|
LOGE("Not enough resources to allocate HAL descriptor table!");
|
|
}
|
|
} else {
|
|
LOGI("%d camera devices detected!", mNumOfCameras);
|
|
}
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : ~QCamera2Factory
|
|
*
|
|
* DESCRIPTION: deconstructor of QCamera2Factory
|
|
*
|
|
* PARAMETERS : none
|
|
*
|
|
* RETURN : None
|
|
*==========================================================================*/
|
|
QCamera2Factory::~QCamera2Factory()
|
|
{
|
|
if ( NULL != mHalDescriptors ) {
|
|
delete [] mHalDescriptors;
|
|
}
|
|
if (gQCameraMuxer) {
|
|
delete gQCameraMuxer;
|
|
gQCameraMuxer = NULL;
|
|
}
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : get_number_of_cameras
|
|
*
|
|
* DESCRIPTION: static function to query number of cameras detected
|
|
*
|
|
* PARAMETERS : none
|
|
*
|
|
* RETURN : number of cameras detected
|
|
*==========================================================================*/
|
|
int QCamera2Factory::get_number_of_cameras()
|
|
{
|
|
int numCameras = 0;
|
|
|
|
if (!gQCamera2Factory) {
|
|
gQCamera2Factory = new QCamera2Factory();
|
|
if (!gQCamera2Factory) {
|
|
LOGE("Failed to allocate Camera2Factory object");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if(gQCameraMuxer)
|
|
numCameras = gQCameraMuxer->get_number_of_cameras();
|
|
else
|
|
numCameras = gQCamera2Factory->getNumberOfCameras();
|
|
|
|
LOGH("num of cameras: %d", numCameras);
|
|
return numCameras;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : get_camera_info
|
|
*
|
|
* DESCRIPTION: static function to query camera information with its ID
|
|
*
|
|
* PARAMETERS :
|
|
* @camera_id : camera ID
|
|
* @info : ptr to camera info struct
|
|
*
|
|
* RETURN : int32_t type of status
|
|
* NO_ERROR -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::get_camera_info(int camera_id, struct camera_info *info)
|
|
{
|
|
int rc = NO_ERROR;
|
|
|
|
if(gQCameraMuxer)
|
|
rc = gQCameraMuxer->get_camera_info(camera_id, info);
|
|
else
|
|
rc = gQCamera2Factory->getCameraInfo(camera_id, info);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : set_callbacks
|
|
*
|
|
* DESCRIPTION: static function to set callbacks function to camera module
|
|
*
|
|
* PARAMETERS :
|
|
* @callbacks : ptr to callback functions
|
|
*
|
|
* RETURN : NO_ERROR -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::set_callbacks(const camera_module_callbacks_t *callbacks)
|
|
{
|
|
int rc = NO_ERROR;
|
|
if(gQCameraMuxer)
|
|
rc = gQCameraMuxer->set_callbacks(callbacks);
|
|
else
|
|
rc = gQCamera2Factory->setCallbacks(callbacks);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : open_legacy
|
|
*
|
|
* DESCRIPTION: Function to open older hal version implementation
|
|
*
|
|
* PARAMETERS :
|
|
* @hw_device : ptr to struct storing camera hardware device info
|
|
* @camera_id : camera ID
|
|
* @halVersion: Based on camera_module_t.common.module_api_version
|
|
*
|
|
* RETURN : 0 -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::open_legacy(const struct hw_module_t* module,
|
|
const char* id, uint32_t halVersion, struct hw_device_t** device)
|
|
{
|
|
int rc = NO_ERROR;
|
|
if (module != &HAL_MODULE_INFO_SYM.common) {
|
|
LOGE("Invalid module. Trying to open %p, expect %p",
|
|
module, &HAL_MODULE_INFO_SYM.common);
|
|
return INVALID_OPERATION;
|
|
}
|
|
if (!id) {
|
|
LOGE("Invalid camera id");
|
|
return BAD_VALUE;
|
|
}
|
|
if(gQCameraMuxer)
|
|
rc = gQCameraMuxer->open_legacy(module, id, halVersion, device);
|
|
else
|
|
rc = gQCamera2Factory->openLegacy(atoi(id), halVersion, device);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : set_torch_mode
|
|
*
|
|
* DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
|
|
*
|
|
* PARAMETERS :
|
|
* @camera_id : camera ID
|
|
* @on : Indicates whether to turn the flash on or off
|
|
*
|
|
* RETURN : 0 -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::set_torch_mode(const char* camera_id, bool on)
|
|
{
|
|
return gQCamera2Factory->setTorchMode(camera_id, on);
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : getNumberOfCameras
|
|
*
|
|
* DESCRIPTION: query number of cameras detected
|
|
*
|
|
* PARAMETERS : none
|
|
*
|
|
* RETURN : number of cameras detected
|
|
*==========================================================================*/
|
|
int QCamera2Factory::getNumberOfCameras()
|
|
{
|
|
return mNumOfCameras;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : getCameraInfo
|
|
*
|
|
* DESCRIPTION: query camera information with its ID
|
|
*
|
|
* PARAMETERS :
|
|
* @camera_id : camera ID
|
|
* @info : ptr to camera info struct
|
|
*
|
|
* RETURN : int32_t type of status
|
|
* NO_ERROR -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::getCameraInfo(int camera_id, struct camera_info *info)
|
|
{
|
|
int rc;
|
|
|
|
if (!mNumOfCameras || camera_id >= mNumOfCameras || !info ||
|
|
(camera_id < 0)) {
|
|
LOGE("Error getting camera info!! mNumOfCameras = %d,"
|
|
"camera_id = %d, info = %p",
|
|
mNumOfCameras, camera_id, info);
|
|
return -ENODEV;
|
|
}
|
|
|
|
if ( NULL == mHalDescriptors ) {
|
|
LOGE("Hal descriptor table is not initialized!");
|
|
return NO_INIT;
|
|
}
|
|
|
|
LOGI("Camera id %d API version %d",
|
|
camera_id, mHalDescriptors[camera_id].device_version);
|
|
|
|
// Need ANDROID_FLASH_INFO_AVAILABLE property for flashlight widget to
|
|
// work and so get the static data regardless of HAL version
|
|
rc = QCamera3HardwareInterface::getCamInfo(
|
|
mHalDescriptors[camera_id].cameraId, info);
|
|
if (mHalDescriptors[camera_id].device_version ==
|
|
CAMERA_DEVICE_API_VERSION_1_0) {
|
|
info->device_version = CAMERA_DEVICE_API_VERSION_1_0;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : setCallbacks
|
|
*
|
|
* DESCRIPTION: set callback functions to send asynchronous notifications to
|
|
* frameworks.
|
|
*
|
|
* PARAMETERS :
|
|
* @callbacks : callback function pointer
|
|
*
|
|
* RETURN :
|
|
* NO_ERROR -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::setCallbacks(const camera_module_callbacks_t *callbacks)
|
|
{
|
|
int rc = NO_ERROR;
|
|
mCallbacks = callbacks;
|
|
|
|
rc = QCameraFlash::getInstance().registerCallbacks(callbacks);
|
|
if (rc != 0) {
|
|
LOGE("Failed to register callbacks with flash module!");
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : cameraDeviceOpen
|
|
*
|
|
* DESCRIPTION: open a camera device with its ID
|
|
*
|
|
* PARAMETERS :
|
|
* @camera_id : camera ID
|
|
* @hw_device : ptr to struct storing camera hardware device info
|
|
*
|
|
* RETURN : int32_t type of status
|
|
* NO_ERROR -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::cameraDeviceOpen(int camera_id,
|
|
struct hw_device_t **hw_device)
|
|
{
|
|
int rc = NO_ERROR;
|
|
if (camera_id < 0 || camera_id >= mNumOfCameras)
|
|
return -ENODEV;
|
|
|
|
if ( NULL == mHalDescriptors ) {
|
|
LOGE("Hal descriptor table is not initialized!");
|
|
return NO_INIT;
|
|
}
|
|
|
|
LOGI("Open camera id %d API version %d",
|
|
camera_id, mHalDescriptors[camera_id].device_version);
|
|
|
|
if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
|
|
QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId,
|
|
mCallbacks);
|
|
if (!hw) {
|
|
LOGE("Allocation of hardware interface failed");
|
|
return NO_MEMORY;
|
|
}
|
|
rc = hw->openCamera(hw_device);
|
|
if (rc != 0) {
|
|
delete hw;
|
|
}
|
|
} else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
|
|
QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);
|
|
if (!hw) {
|
|
LOGE("Allocation of hardware interface failed");
|
|
return NO_MEMORY;
|
|
}
|
|
rc = hw->openCamera(hw_device);
|
|
if (rc != NO_ERROR) {
|
|
delete hw;
|
|
}
|
|
} else {
|
|
LOGE("Device version for camera id %d invalid %d",
|
|
camera_id,
|
|
mHalDescriptors[camera_id].device_version);
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : camera_device_open
|
|
*
|
|
* DESCRIPTION: static function to open a camera device by its ID
|
|
*
|
|
* PARAMETERS :
|
|
* @camera_id : camera ID
|
|
* @hw_device : ptr to struct storing camera hardware device info
|
|
*
|
|
* RETURN : int32_t type of status
|
|
* NO_ERROR -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::camera_device_open(
|
|
const struct hw_module_t *module, const char *id,
|
|
struct hw_device_t **hw_device)
|
|
{
|
|
int rc = NO_ERROR;
|
|
if (module != &HAL_MODULE_INFO_SYM.common) {
|
|
LOGE("Invalid module. Trying to open %p, expect %p",
|
|
module, &HAL_MODULE_INFO_SYM.common);
|
|
return INVALID_OPERATION;
|
|
}
|
|
if (!id) {
|
|
LOGE("Invalid camera id");
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
if(gQCameraMuxer)
|
|
rc = gQCameraMuxer->camera_device_open(module, id, hw_device);
|
|
else
|
|
rc = gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device);
|
|
|
|
return rc;
|
|
}
|
|
|
|
struct hw_module_methods_t QCamera2Factory::mModuleMethods = {
|
|
.open = QCamera2Factory::camera_device_open,
|
|
};
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : openLegacy
|
|
*
|
|
* DESCRIPTION: Function to open older hal version implementation
|
|
*
|
|
* PARAMETERS :
|
|
* @camera_id : camera ID
|
|
* @halVersion: Based on camera_module_t.common.module_api_version
|
|
* @hw_device : ptr to struct storing camera hardware device info
|
|
*
|
|
* RETURN : 0 -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::openLegacy(
|
|
int32_t cameraId, uint32_t halVersion, struct hw_device_t** hw_device)
|
|
{
|
|
int rc = NO_ERROR;
|
|
|
|
LOGI("openLegacy halVersion: %d", halVersion);
|
|
//Assumption: all cameras can support legacy API version
|
|
if (cameraId < 0 || cameraId >= gQCamera2Factory->getNumberOfCameras())
|
|
return -ENODEV;
|
|
|
|
switch(halVersion)
|
|
{
|
|
case CAMERA_DEVICE_API_VERSION_1_0:
|
|
{
|
|
QCamera2HardwareInterface *hw =
|
|
new QCamera2HardwareInterface((uint32_t)cameraId);
|
|
if (!hw) {
|
|
LOGE("Allocation of hardware interface failed");
|
|
return NO_MEMORY;
|
|
}
|
|
rc = hw->openCamera(hw_device);
|
|
if (rc != NO_ERROR) {
|
|
delete hw;
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
LOGE("Device API version: %d for camera id %d invalid",
|
|
halVersion, cameraId);
|
|
return BAD_VALUE;
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : setTorchMode
|
|
*
|
|
* DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
|
|
*
|
|
* PARAMETERS :
|
|
* @camera_id : camera ID
|
|
* @on : Indicates whether to turn the flash on or off
|
|
*
|
|
* RETURN : 0 -- success
|
|
* none-zero failure code
|
|
*==========================================================================*/
|
|
int QCamera2Factory::setTorchMode(const char* camera_id, bool on)
|
|
{
|
|
int retVal(0);
|
|
long cameraIdLong(-1);
|
|
int cameraIdInt(-1);
|
|
char* endPointer = NULL;
|
|
errno = 0;
|
|
QCameraFlash& flash = QCameraFlash::getInstance();
|
|
|
|
cameraIdLong = strtol(camera_id, &endPointer, 10);
|
|
|
|
if ((errno == ERANGE) ||
|
|
(cameraIdLong < 0) ||
|
|
(cameraIdLong >= static_cast<long>(get_number_of_cameras())) ||
|
|
(endPointer == camera_id) ||
|
|
(*endPointer != '\0')) {
|
|
retVal = -EINVAL;
|
|
} else if (on) {
|
|
cameraIdInt = static_cast<int>(cameraIdLong);
|
|
retVal = flash.initFlash(cameraIdInt);
|
|
|
|
if (retVal == 0) {
|
|
retVal = flash.setFlashMode(cameraIdInt, on);
|
|
if ((retVal == 0) && (mCallbacks != NULL)) {
|
|
mCallbacks->torch_mode_status_change(mCallbacks,
|
|
camera_id,
|
|
TORCH_MODE_STATUS_AVAILABLE_ON);
|
|
} else if (retVal == -EALREADY) {
|
|
// Flash is already on, so treat this as a success.
|
|
retVal = 0;
|
|
}
|
|
}
|
|
} else {
|
|
cameraIdInt = static_cast<int>(cameraIdLong);
|
|
retVal = flash.setFlashMode(cameraIdInt, on);
|
|
|
|
if (retVal == 0) {
|
|
retVal = flash.deinitFlash(cameraIdInt);
|
|
if ((retVal == 0) && (mCallbacks != NULL)) {
|
|
mCallbacks->torch_mode_status_change(mCallbacks,
|
|
camera_id,
|
|
TORCH_MODE_STATUS_AVAILABLE_OFF);
|
|
}
|
|
} else if (retVal == -EALREADY) {
|
|
// Flash is already off, so treat this as a success.
|
|
retVal = 0;
|
|
}
|
|
}
|
|
|
|
return retVal;
|
|
}
|
|
|
|
/*===========================================================================
|
|
* FUNCTION : isDualCamAvailable
|
|
*
|
|
* DESCRIPTION: Function to check whether we have dual Camera HW available
|
|
*
|
|
* PARAMETERS :
|
|
* @hal3Enabled : HAL3 enable flag
|
|
*
|
|
* RETURN : bool - true : have Dual Camera HW available
|
|
* false : not have Dual Camera HW available
|
|
*==========================================================================*/
|
|
bool QCamera2Factory::isDualCamAvailable(int hal3Enabled)
|
|
{
|
|
bool rc = FALSE;
|
|
int i = 0;
|
|
camera_info info;
|
|
cam_sync_type_t cam_type = CAM_TYPE_MAIN;
|
|
|
|
for (i = 0; i < mNumOfCameras; i++) {
|
|
if (!hal3Enabled) {
|
|
QCamera2HardwareInterface::getCapabilities(i, &info, &cam_type);
|
|
}
|
|
|
|
if(cam_type == CAM_TYPE_AUX) {
|
|
LOGH("Have Dual Camera HW Avaiable.");
|
|
rc = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
}; // namespace qcamera
|
|
|