From 6616278131edd80a12545085e06ee6b0e0a0a788 Mon Sep 17 00:00:00 2001 From: Prateek Chaubey Date: Sun, 7 Jan 2018 20:55:14 +0530 Subject: msm8996-common: zuk: Import OSS Camera HAL Tag: LA.HB.1.3.2-32600-8x96.0 Signed-off-by: Davide Garberi --- camera/QCamera2/QCamera2Factory.cpp | 601 ++++++++++++++++++++++++++++++++++++ 1 file changed, 601 insertions(+) create mode 100644 camera/QCamera2/QCamera2Factory.cpp (limited to 'camera/QCamera2/QCamera2Factory.cpp') diff --git a/camera/QCamera2/QCamera2Factory.cpp b/camera/QCamera2/QCamera2Factory.cpp new file mode 100644 index 0000000..fa266f9 --- /dev/null +++ b/camera/QCamera2/QCamera2Factory.cpp @@ -0,0 +1,601 @@ +/* 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 +#include + +// 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() +{ + 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; + } + } + } 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; + cam_sync_type_t cam_type = CAM_TYPE_MAIN; + + 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(get_number_of_cameras())) || + (endPointer == camera_id) || + (*endPointer != '\0')) { + retVal = -EINVAL; + } else if (on) { + cameraIdInt = static_cast(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(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 + -- cgit v1.2.3