Home | History | Annotate | Download | only in QCamera2
      1 /* Copyright (c) 2012-2015, The Linux Foundataion. All rights reserved.
      2 *
      3 * Redistribution and use in source and binary forms, with or without
      4 * modification, are permitted provided that the following conditions are
      5 * met:
      6 *     * Redistributions of source code must retain the above copyright
      7 *       notice, this list of conditions and the following disclaimer.
      8 *     * Redistributions in binary form must reproduce the above
      9 *       copyright notice, this list of conditions and the following
     10 *       disclaimer in the documentation and/or other materials provided
     11 *       with the distribution.
     12 *     * Neither the name of The Linux Foundation nor the names of its
     13 *       contributors may be used to endorse or promote products derived
     14 *       from this software without specific prior written permission.
     15 *
     16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 *
     28 */
     29 
     30 #define LOG_TAG "QCamera2Factory"
     31 //#define LOG_NDEBUG 0
     32 
     33 #include <stdlib.h>
     34 #include <utils/Log.h>
     35 #include <utils/Errors.h>
     36 #include <hardware/camera.h>
     37 #include <hardware/camera3.h>
     38 
     39 #include "HAL/QCamera2HWI.h"
     40 #include "HAL3/QCamera3HWI.h"
     41 #include "util/QCameraFlash.h"
     42 #include "QCamera2Factory.h"
     43 
     44 using namespace android;
     45 
     46 namespace qcamera {
     47 
     48 QCamera2Factory *gQCamera2Factory = NULL;
     49 
     50 /*===========================================================================
     51  * FUNCTION   : QCamera2Factory
     52  *
     53  * DESCRIPTION: default constructor of QCamera2Factory
     54  *
     55  * PARAMETERS : none
     56  *
     57  * RETURN     : None
     58  *==========================================================================*/
     59 QCamera2Factory::QCamera2Factory()
     60 {
     61     camera_info info;
     62     mHalDescriptors = NULL;
     63     mCallbacks = NULL;
     64     mNumOfCameras = get_num_of_cameras();
     65     char prop[PROPERTY_VALUE_MAX];
     66     property_get("persist.camera.HAL3.enabled", prop, "1");
     67     int isHAL3Enabled = atoi(prop);
     68 
     69     if ((mNumOfCameras > 0) && (mNumOfCameras <= MM_CAMERA_MAX_NUM_SENSORS)) {
     70         mHalDescriptors = new hal_desc[mNumOfCameras];
     71         if ( NULL != mHalDescriptors) {
     72             uint32_t cameraId = 0;
     73 
     74             for (int i = 0; i < mNumOfCameras ; i++, cameraId++) {
     75                 mHalDescriptors[i].cameraId = cameraId;
     76                 if (isHAL3Enabled) {
     77                     mHalDescriptors[i].device_version = CAMERA_DEVICE_API_VERSION_3_0;
     78                 } else {
     79                     mHalDescriptors[i].device_version = CAMERA_DEVICE_API_VERSION_1_0;
     80                 }
     81                 //Query camera at this point in order
     82                 //to avoid any delays during subsequent
     83                 //calls to 'getCameraInfo()'
     84                 getCameraInfo(i, &info);
     85             }
     86         } else {
     87             ALOGE("%s: Not enough resources to allocate HAL descriptor table!",
     88                   __func__);
     89         }
     90     } else {
     91         ALOGE("%s: %d camera devices detected!", __func__, mNumOfCameras);
     92     }
     93 }
     94 
     95 /*===========================================================================
     96  * FUNCTION   : ~QCamera2Factory
     97  *
     98  * DESCRIPTION: deconstructor of QCamera2Factory
     99  *
    100  * PARAMETERS : none
    101  *
    102  * RETURN     : None
    103  *==========================================================================*/
    104 QCamera2Factory::~QCamera2Factory()
    105 {
    106     if ( NULL != mHalDescriptors ) {
    107         delete [] mHalDescriptors;
    108     }
    109 }
    110 
    111 /*===========================================================================
    112  * FUNCTION   : get_number_of_cameras
    113  *
    114  * DESCRIPTION: static function to query number of cameras detected
    115  *
    116  * PARAMETERS : none
    117  *
    118  * RETURN     : number of cameras detected
    119  *==========================================================================*/
    120 int QCamera2Factory::get_number_of_cameras()
    121 {
    122     if (!gQCamera2Factory) {
    123         gQCamera2Factory = new QCamera2Factory();
    124         if (!gQCamera2Factory) {
    125             ALOGE("%s: Failed to allocate Camera2Factory object", __func__);
    126             return 0;
    127         }
    128     }
    129     return gQCamera2Factory->getNumberOfCameras();
    130 }
    131 
    132 /*===========================================================================
    133  * FUNCTION   : get_camera_info
    134  *
    135  * DESCRIPTION: static function to query camera information with its ID
    136  *
    137  * PARAMETERS :
    138  *   @camera_id : camera ID
    139  *   @info      : ptr to camera info struct
    140  *
    141  * RETURN     : int32_t type of status
    142  *              NO_ERROR  -- success
    143  *              none-zero failure code
    144  *==========================================================================*/
    145 int QCamera2Factory::get_camera_info(int camera_id, struct camera_info *info)
    146 {
    147     return gQCamera2Factory->getCameraInfo(camera_id, info);
    148 }
    149 
    150 /*===========================================================================
    151  * FUNCTION   : set_callbacks
    152  *
    153  * DESCRIPTION: static function to set callbacks function to camera module
    154  *
    155  * PARAMETERS :
    156  *   @callbacks : ptr to callback functions
    157  *
    158  * RETURN     : NO_ERROR  -- success
    159  *              none-zero failure code
    160  *==========================================================================*/
    161 int QCamera2Factory::set_callbacks(const camera_module_callbacks_t *callbacks)
    162 {
    163     return gQCamera2Factory->setCallbacks(callbacks);
    164 }
    165 
    166 /*===========================================================================
    167  * FUNCTION   : open_legacy
    168  *
    169  * DESCRIPTION: Function to open older hal version implementation
    170  *
    171  * PARAMETERS :
    172  *   @hw_device : ptr to struct storing camera hardware device info
    173  *   @camera_id : camera ID
    174  *   @halVersion: Based on camera_module_t.common.module_api_version
    175  *
    176  * RETURN     : 0  -- success
    177  *              none-zero failure code
    178  *==========================================================================*/
    179 int QCamera2Factory::open_legacy(const struct hw_module_t* module,
    180             const char* id, uint32_t halVersion, struct hw_device_t** device)
    181 {
    182     if (module != &HAL_MODULE_INFO_SYM.common) {
    183         ALOGE("Invalid module. Trying to open %p, expect %p",
    184             module, &HAL_MODULE_INFO_SYM.common);
    185         return INVALID_OPERATION;
    186     }
    187     if (!id) {
    188         ALOGE("Invalid camera id");
    189         return BAD_VALUE;
    190     }
    191     return gQCamera2Factory->openLegacy(atoi(id), halVersion, device);
    192 }
    193 
    194 /*===========================================================================
    195  * FUNCTION   : set_torch_mode
    196  *
    197  * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
    198  *
    199  * PARAMETERS :
    200  *   @camera_id : camera ID
    201  *   @on        : Indicates whether to turn the flash on or off
    202  *
    203  * RETURN     : 0  -- success
    204  *              none-zero failure code
    205  *==========================================================================*/
    206 int QCamera2Factory::set_torch_mode(const char* camera_id, bool on)
    207 {
    208     return gQCamera2Factory->setTorchMode(camera_id, on);
    209 }
    210 
    211 /*===========================================================================
    212  * FUNCTION   : getNumberOfCameras
    213  *
    214  * DESCRIPTION: query number of cameras detected
    215  *
    216  * PARAMETERS : none
    217  *
    218  * RETURN     : number of cameras detected
    219  *==========================================================================*/
    220 int QCamera2Factory::getNumberOfCameras()
    221 {
    222     return mNumOfCameras;
    223 }
    224 
    225 /*===========================================================================
    226  * FUNCTION   : getCameraInfo
    227  *
    228  * DESCRIPTION: query camera information with its ID
    229  *
    230  * PARAMETERS :
    231  *   @camera_id : camera ID
    232  *   @info      : ptr to camera info struct
    233  *
    234  * RETURN     : int32_t type of status
    235  *              NO_ERROR  -- success
    236  *              none-zero failure code
    237  *==========================================================================*/
    238 int QCamera2Factory::getCameraInfo(int camera_id, struct camera_info *info)
    239 {
    240     int rc;
    241     ALOGV("%s: E, camera_id = %d", __func__, camera_id);
    242 
    243     if (!mNumOfCameras || camera_id >= mNumOfCameras || !info ||
    244         (camera_id < 0)) {
    245         return -ENODEV;
    246     }
    247 
    248     if ( NULL == mHalDescriptors ) {
    249         ALOGE("%s : Hal descriptor table is not initialized!", __func__);
    250         return NO_INIT;
    251     }
    252 
    253     if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
    254         rc = QCamera3HardwareInterface::getCamInfo(mHalDescriptors[camera_id].cameraId, info);
    255     } else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
    256         rc = QCamera2HardwareInterface::getCapabilities(mHalDescriptors[camera_id].cameraId, info);
    257     } else {
    258         ALOGE("%s: Device version for camera id %d invalid %d",
    259               __func__,
    260               camera_id,
    261               mHalDescriptors[camera_id].device_version);
    262         return BAD_VALUE;
    263     }
    264 
    265     ALOGV("%s: X", __func__);
    266     return rc;
    267 }
    268 
    269 /*===========================================================================
    270  * FUNCTION   : setCallbacks
    271  *
    272  * DESCRIPTION: set callback functions to send asynchronous notifications to
    273  *              frameworks.
    274  *
    275  * PARAMETERS :
    276  *   @callbacks : callback function pointer
    277  *
    278  * RETURN     :
    279  *              NO_ERROR  -- success
    280  *              none-zero failure code
    281  *==========================================================================*/
    282 int QCamera2Factory::setCallbacks(const camera_module_callbacks_t *callbacks)
    283 {
    284     int rc = NO_ERROR;
    285     mCallbacks = callbacks;
    286 
    287     rc = QCameraFlash::getInstance().registerCallbacks(callbacks);
    288     if (rc != 0) {
    289         ALOGE("%s : Failed to register callbacks with flash module!", __func__);
    290     }
    291 
    292     return rc;
    293 }
    294 
    295 /*===========================================================================
    296  * FUNCTION   : cameraDeviceOpen
    297  *
    298  * DESCRIPTION: open a camera device with its ID
    299  *
    300  * PARAMETERS :
    301  *   @camera_id : camera ID
    302  *   @hw_device : ptr to struct storing camera hardware device info
    303  *
    304  * RETURN     : int32_t type of status
    305  *              NO_ERROR  -- success
    306  *              none-zero failure code
    307  *==========================================================================*/
    308 int QCamera2Factory::cameraDeviceOpen(int camera_id,
    309                     struct hw_device_t **hw_device)
    310 {
    311     int rc = NO_ERROR;
    312     if (camera_id < 0 || camera_id >= mNumOfCameras)
    313         return -ENODEV;
    314 
    315     if ( NULL == mHalDescriptors ) {
    316         ALOGE("%s : Hal descriptor table is not initialized!", __func__);
    317         return NO_INIT;
    318     }
    319 
    320     if ( mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_3_0 ) {
    321         QCamera3HardwareInterface *hw = new QCamera3HardwareInterface(mHalDescriptors[camera_id].cameraId,
    322                 mCallbacks);
    323         if (!hw) {
    324             ALOGE("Allocation of hardware interface failed");
    325             return NO_MEMORY;
    326         }
    327         rc = hw->openCamera(hw_device);
    328         if (rc != 0) {
    329             delete hw;
    330         }
    331     } else if (mHalDescriptors[camera_id].device_version == CAMERA_DEVICE_API_VERSION_1_0) {
    332         QCamera2HardwareInterface *hw = new QCamera2HardwareInterface((uint32_t)camera_id);
    333         if (!hw) {
    334             ALOGE("Allocation of hardware interface failed");
    335             return NO_MEMORY;
    336         }
    337         rc = hw->openCamera(hw_device);
    338         if (rc != NO_ERROR) {
    339             delete hw;
    340         }
    341     } else {
    342         ALOGE("%s: Device version for camera id %d invalid %d",
    343               __func__,
    344               camera_id,
    345               mHalDescriptors[camera_id].device_version);
    346         return BAD_VALUE;
    347     }
    348 
    349     return rc;
    350 }
    351 
    352 /*===========================================================================
    353  * FUNCTION   : camera_device_open
    354  *
    355  * DESCRIPTION: static function to open a camera device by its ID
    356  *
    357  * PARAMETERS :
    358  *   @camera_id : camera ID
    359  *   @hw_device : ptr to struct storing camera hardware device info
    360  *
    361  * RETURN     : int32_t type of status
    362  *              NO_ERROR  -- success
    363  *              none-zero failure code
    364  *==========================================================================*/
    365 int QCamera2Factory::camera_device_open(
    366     const struct hw_module_t *module, const char *id,
    367     struct hw_device_t **hw_device)
    368 {
    369     if (module != &HAL_MODULE_INFO_SYM.common) {
    370         ALOGE("Invalid module. Trying to open %p, expect %p",
    371             module, &HAL_MODULE_INFO_SYM.common);
    372         return INVALID_OPERATION;
    373     }
    374     if (!id) {
    375         ALOGE("Invalid camera id");
    376         return BAD_VALUE;
    377     }
    378     return gQCamera2Factory->cameraDeviceOpen(atoi(id), hw_device);
    379 }
    380 
    381 struct hw_module_methods_t QCamera2Factory::mModuleMethods = {
    382     open: QCamera2Factory::camera_device_open,
    383 };
    384 
    385 /*===========================================================================
    386  * FUNCTION   : openLegacy
    387  *
    388  * DESCRIPTION: Function to open older hal version implementation
    389  *
    390  * PARAMETERS :
    391  *   @camera_id : camera ID
    392  *   @halVersion: Based on camera_module_t.common.module_api_version
    393  *   @hw_device : ptr to struct storing camera hardware device info
    394  *
    395  * RETURN     : 0  -- success
    396  *              none-zero failure code
    397  *==========================================================================*/
    398 int QCamera2Factory::openLegacy(
    399         int32_t cameraId, uint32_t halVersion, struct hw_device_t** hw_device)
    400 {
    401     int rc = NO_ERROR;
    402 
    403     ALOGI(":%s openLegacy halVersion: %d", __func__, halVersion);
    404     //Assumption: all cameras can support legacy API version
    405     if (cameraId < 0 || cameraId >= gQCamera2Factory->getNumberOfCameras())
    406         return -ENODEV;
    407 
    408     switch(halVersion)
    409     {
    410         case CAMERA_DEVICE_API_VERSION_1_0:
    411         {
    412             QCamera2HardwareInterface *hw =
    413                 new QCamera2HardwareInterface((uint32_t)cameraId);
    414             if (!hw) {
    415                 ALOGE("%s: Allocation of hardware interface failed", __func__);
    416                 return NO_MEMORY;
    417             }
    418             rc = hw->openCamera(hw_device);
    419             if (rc != NO_ERROR) {
    420                 delete hw;
    421             }
    422             break;
    423         }
    424         default:
    425             ALOGE("%s: Device API version: %d for camera id %d invalid",
    426                 __func__, halVersion, cameraId);
    427             return BAD_VALUE;
    428     }
    429 
    430     return rc;
    431 }
    432 
    433 /*===========================================================================
    434  * FUNCTION   : setTorchMode
    435  *
    436  * DESCRIPTION: Attempt to turn on or off the torch mode of the flash unit.
    437  *
    438  * PARAMETERS :
    439  *   @camera_id : camera ID
    440  *   @on        : Indicates whether to turn the flash on or off
    441  *
    442  * RETURN     : 0  -- success
    443  *              none-zero failure code
    444  *==========================================================================*/
    445 int QCamera2Factory::setTorchMode(const char* camera_id, bool on)
    446 {
    447     int retVal(0);
    448     long cameraIdLong(-1);
    449     int cameraIdInt(-1);
    450     char* endPointer = NULL;
    451     errno = 0;
    452     QCameraFlash& flash = QCameraFlash::getInstance();
    453 
    454     cameraIdLong = strtol(camera_id, &endPointer, 10);
    455 
    456     if ((errno == ERANGE) ||
    457             (cameraIdLong < 0) ||
    458             (cameraIdLong >= static_cast<long>(get_number_of_cameras())) ||
    459             (endPointer == camera_id) ||
    460             (*endPointer != '\0')) {
    461         retVal = -EINVAL;
    462     } else if (on) {
    463         cameraIdInt = static_cast<int>(cameraIdLong);
    464         retVal = flash.initFlash(cameraIdInt);
    465 
    466         if (retVal == 0) {
    467             retVal = flash.setFlashMode(cameraIdInt, on);
    468             if ((retVal == 0) && (mCallbacks != NULL)) {
    469                 mCallbacks->torch_mode_status_change(mCallbacks,
    470                         camera_id,
    471                         TORCH_MODE_STATUS_AVAILABLE_ON);
    472             } else if (retVal == -EALREADY) {
    473                 // Flash is already on, so treat this as a success.
    474                 retVal = 0;
    475             }
    476         }
    477     } else {
    478         cameraIdInt = static_cast<int>(cameraIdLong);
    479         retVal = flash.setFlashMode(cameraIdInt, on);
    480 
    481         if (retVal == 0) {
    482             retVal = flash.deinitFlash(cameraIdInt);
    483             if ((retVal == 0) && (mCallbacks != NULL)) {
    484                 mCallbacks->torch_mode_status_change(mCallbacks,
    485                         camera_id,
    486                         TORCH_MODE_STATUS_AVAILABLE_OFF);
    487             }
    488         } else if (retVal == -EALREADY) {
    489             // Flash is already off, so treat this as a success.
    490             retVal = 0;
    491         }
    492     }
    493 
    494     return retVal;
    495 }
    496 
    497 }; // namespace qcamera
    498 
    499